Merge branch 'Antrean-Code' of https://git.rssa.top/arie.bagus.2905/web-antrean into Antrean-Code
This commit is contained in:
@@ -93,7 +93,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import TabelData from "../components/TabelData.vue"; // Pastikan path-nya benar
|
||||
import TabelData from "@/components/features/monitoring/TabelData.vue";
|
||||
|
||||
// Ini adalah data yang akan menjadi "single source of truth"
|
||||
// untuk tabel Anda. Data ini dikirim sebagai props ke komponen anak.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
variant="flat"
|
||||
@click="openTambahDialog"
|
||||
elevation="0"
|
||||
class="action-btn"
|
||||
class="action-btn text-white"
|
||||
>
|
||||
<v-icon left size="20">mdi-plus-circle</v-icon>
|
||||
Tambah Screen
|
||||
|
||||
+72
-7
@@ -26,11 +26,24 @@ export const useQueueStore = defineStore('queue', () => {
|
||||
* Sync patient status to apiPatientsPerLoket for reactivity
|
||||
*/
|
||||
const syncApiPatientStatus = (patient, newStatus) => {
|
||||
if (!patient || patient.registrationType !== 'api') return;
|
||||
if (!patient) return;
|
||||
|
||||
// Allow syncing if strictly 'api' OR if we can find a matching ID in the API store
|
||||
// This handles cases where we have an 'onsite' patient locally that corresponds to an API patient
|
||||
|
||||
const loketId = patient.loketId;
|
||||
if (loketId && apiPatientsPerLoket.value[loketId]) {
|
||||
const index = apiPatientsPerLoket.value[loketId].findIndex(p => p.no === patient.no);
|
||||
// Try to find patient in the API list
|
||||
const index = apiPatientsPerLoket.value[loketId].findIndex(p => {
|
||||
if (patient.registrationType === 'api' && p.no === patient.no) return true;
|
||||
|
||||
// Fallback matching for 'onsite' patients
|
||||
if (patient.idtiket && p.idtiket && String(patient.idtiket) === String(p.idtiket)) return true;
|
||||
if (patient.barcode && p.barcode && String(patient.barcode) === String(p.barcode)) return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (index !== -1) {
|
||||
const updated = [...apiPatientsPerLoket.value[loketId]];
|
||||
updated[index] = { ...updated[index], status: newStatus };
|
||||
@@ -258,18 +271,66 @@ export const useQueueStore = defineStore('queue', () => {
|
||||
apiPatientsPerLoket.value[loketId] = finalPatients;
|
||||
|
||||
// IMPORTANT: Also merge into allPatients so callMultiplePatients can find them
|
||||
// Remove any existing API patients for this loket first
|
||||
allPatients.value = allPatients.value.filter(p =>
|
||||
p.registrationType !== 'api' || String(p.loketId) !== String(loketId)
|
||||
);
|
||||
|
||||
// Add new API patients with loketId assigned
|
||||
// Prepare list of new API patients with loketId assigned
|
||||
const patientsWithLoketId = finalPatients.map(p => ({
|
||||
...p,
|
||||
loketId: parseInt(loketId),
|
||||
registrationType: 'api'
|
||||
}));
|
||||
|
||||
// ROBUST DEDUPLICATION & STATUS MERGE
|
||||
// 1. Identify matches between existing allPatients and new API patients
|
||||
const newPatientMap = new Map();
|
||||
patientsWithLoketId.forEach(p => {
|
||||
const key = p.idtiket ? `id-${p.idtiket}` : `bc-${p.barcode}`;
|
||||
newPatientMap.set(key, p);
|
||||
});
|
||||
|
||||
// 2. Iterate existing patients to find matches and preserve status
|
||||
const preservedStatuses = new Map();
|
||||
allPatients.value.forEach(p => {
|
||||
const key = p.idtiket ? `id-${p.idtiket}` : `bc-${p.barcode}`;
|
||||
if (newPatientMap.has(key)) {
|
||||
// If existing patient has more advanced status (waiting/di-loket), preserve it!
|
||||
// This handles cases where we updated status locally ('onsite' or 'api') but API is lagging
|
||||
const statusPriority = { 'di-loket': 3, 'waiting': 2, 'menunggu': 1 };
|
||||
const existingPrio = statusPriority[p.status] || 0;
|
||||
const newPatient = newPatientMap.get(key);
|
||||
const newPrio = statusPriority[newPatient.status] || 0;
|
||||
|
||||
if (existingPrio > newPrio) {
|
||||
preservedStatuses.set(key, p.status);
|
||||
// Also preserve lastCalledAt/calledByAdmin if available
|
||||
if (p.lastCalledAt) newPatient.lastCalledAt = p.lastCalledAt;
|
||||
if (p.calledByAdmin) newPatient.calledByAdmin = p.calledByAdmin;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 3. Update new patients with preserved status
|
||||
patientsWithLoketId.forEach(p => {
|
||||
const key = p.idtiket ? `id-${p.idtiket}` : `bc-${p.barcode}`;
|
||||
if (preservedStatuses.has(key)) {
|
||||
p.status = preservedStatuses.get(key);
|
||||
}
|
||||
});
|
||||
|
||||
// 4. Remove existing patients that collide with new ones (to be replaced)
|
||||
// AND remove stale 'api' patients for this loket
|
||||
allPatients.value = allPatients.value.filter(p => {
|
||||
const key = p.idtiket ? `id-${p.idtiket}` : `bc-${p.barcode}`;
|
||||
|
||||
// Remove if it's being replaced by new batch
|
||||
if (newPatientMap.has(key)) return false;
|
||||
|
||||
// Remove if it's a stale 'api' patient for this loket (that wasn't in the new batch)
|
||||
if (p.registrationType === 'api' && String(p.loketId) === String(loketId)) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// 5. Add merged patients
|
||||
allPatients.value.push(...patientsWithLoketId);
|
||||
|
||||
console.log(`✅ [queueStore] Successfully fetched ${finalPatients.length} unique patients for loket ${loketId} (Original: ${mappedPatients.length})`);
|
||||
@@ -757,6 +818,10 @@ export const useQueueStore = defineStore('queue', () => {
|
||||
if (newState.allPatients) allPatients.value = newState.allPatients;
|
||||
if (newState.quotaUsed !== undefined) quotaUsed.value = newState.quotaUsed;
|
||||
if (newState.currentProcessingPatient) currentProcessingPatient.value = newState.currentProcessingPatient;
|
||||
|
||||
// FIX: Hydrate apiPatientsPerLoket as well since it is persisted.
|
||||
// Failure to hydrate this causes "ping-pong" writes between tabs if they have different local values.
|
||||
if (newState.apiPatientsPerLoket) apiPatientsPerLoket.value = newState.apiPatientsPerLoket;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error hydrating from storage event:', e);
|
||||
|
||||
Reference in New Issue
Block a user