perbaikan generate dan scan tiket

This commit is contained in:
Fanrouver
2026-01-15 14:32:21 +07:00
parent eac6529a77
commit 8aa5ab2ded
4 changed files with 154 additions and 222 deletions

No files matched your search

+2 -2
View File
@@ -1517,14 +1517,14 @@ watch(lastRegisteredPatient, (newVal) => {
.clinic-available {
border-color: var(--color-success-600);
background: var(--color-success-200);
background: var(--color-success-100);
}
.clinic-closed {
opacity: 0.65;
cursor: not-allowed;
border-color: var(--color-danger-600);
background: var(--color-danger-200);
background: var(--color-danger-100);
}
.clinic-content {
+20 -69
View File
@@ -2295,48 +2295,24 @@ const onDetect = async (decodedText: string) => {
console.log('🔍 Cleaned input:', cleanInput);
console.log('📊 Total patients in store:', queueStore.allPatients.length);
// Cari pasien di queueStore berdasarkan berbagai kriteria
// Prioritas: exact barcode match (case-insensitive, whitespace-insensitive)
// Kemudian: noAntrian match dengan kode + angka (tidak hanya angka saja)
// IMPORTANT: Hanya cari dengan EXACT barcode match untuk menghindari false positive
// Format barcode: YYMMDD + 5 digit (contoh: 26011500001)
// Jangan gunakan fallback ke noAntrian atau no karena bisa menyebabkan false positive
// Contoh masalah: RA020 dengan barcode 26011500001 terdeteksi sebagai RA002 dengan barcode 26011500198
const foundPatient = queueStore.allPatients.find(p => {
if (!p) return false;
// Normalize barcode untuk comparison (remove whitespace, case-insensitive)
const patientBarcode = String(p.barcode || '').trim();
const patientBarcodeUpper = patientBarcode.toUpperCase();
const patientBarcodeNormalized = patientBarcodeUpper.replace(/\s+/g, '');
const cleanInputNormalized = cleanInputUpper.replace(/\s+/g, '');
// 1. Exact barcode match (case-insensitive, whitespace-insensitive) - PRIORITAS TERTINGGI
// EXACT barcode match (case-insensitive, whitespace-insensitive)
// Ini adalah satu-satunya cara yang aman untuk match pasien
if (patientBarcode === cleanInput ||
patientBarcodeNormalized === cleanInputNormalized ||
patientBarcodeUpper === cleanInputUpper) {
patientBarcode.toLowerCase() === cleanInput.toLowerCase()) {
console.log('✅ Found by exact barcode match:', patientBarcode, '===', cleanInput);
return true;
}
// 2. Match noAntrian dengan kode + angka (tidak hanya angka saja)
// Ini mencegah false positive ketika angka sama tapi kode beda (misalnya UM0014 vs AN0014)
if (p.noAntrian && matchNoAntrian(cleanInput, p.noAntrian)) {
console.log('✅ Found by noAntrian match (kode + angka):', p.noAntrian);
return true;
}
// 3. Try parsing as number and match with no (fallback)
// IMPORTANT: Hanya gunakan fallback jika input TIDAK punya kode (hanya angka)
// Ini mencegah false positive: "RA004" (kode: RA) tidak boleh match dengan pasien no: 4 yang punya kode berbeda
const inputHasCode = /^[A-Z]+/.test(cleanInput);
if (!inputHasCode) {
// Input hanya angka, boleh match dengan no (tapi tetap prioritas ke barcode dan noAntrian)
const parsedNo = parseInt(cleanInput.replace(/[^0-9]/g, '')) || parseInt(searchBarcode);
if (!isNaN(parsedNo) && p.no === parsedNo) {
console.log('✅ Found by no (input tanpa kode):', p.no);
return true;
}
}
// Jika input punya kode (seperti "RA004"), jangan gunakan fallback ke no
// karena bisa match dengan pasien yang punya kode berbeda
return false;
});
@@ -2378,13 +2354,13 @@ const onDetect = async (decodedText: string) => {
// IMPORTANT: Refresh data pasien dari queueStore untuk mendapatkan status REAL-TIME
// Jangan gunakan foundPatient.status karena mungkin sudah stale
// Cari ulang pasien dari queueStore untuk mendapatkan data terbaru
// Cari ulang pasien dari queueStore dengan EXACT barcode match
const freshPatient = queueStore.allPatients.find(p => {
const patientBarcode = String(p.barcode || '').trim();
// Hanya exact barcode match untuk menghindari false positive
return patientBarcode === foundPatient.barcode ||
patientBarcode === searchBarcode ||
patientBarcode === decodedText ||
p.no === foundPatient.no;
patientBarcode === cleanInput;
});
if (!freshPatient) {
@@ -2606,49 +2582,24 @@ const checkInManual = async () => {
console.log('🔍 Cleaned input:', cleanInput);
console.log('📊 Total patients in store:', queueStore.allPatients.length);
// Cari pasien di queueStore menggunakan logika yang sama dengan onDetect
// Prioritas: exact barcode match (case-insensitive, whitespace-insensitive)
// Kemudian: noAntrian match dengan kode + angka (tidak hanya angka saja)
// Fallback: hanya jika input tidak punya kode (hanya angka)
// IMPORTANT: Hanya cari dengan EXACT barcode match untuk menghindari false positive
// Format barcode: YYMMDD + 5 digit (contoh: 26011500001)
// Jangan gunakan fallback ke noAntrian atau no karena bisa menyebabkan false positive
// Contoh masalah: RA020 dengan barcode 26011500001 terdeteksi sebagai RA002 dengan barcode 26011500198
const foundPatient = queueStore.allPatients.find(p => {
if (!p) return false;
// Normalize barcode untuk comparison (remove whitespace, case-insensitive)
const patientBarcode = String(p.barcode || '').trim();
const patientBarcodeUpper = patientBarcode.toUpperCase();
const patientBarcodeNormalized = patientBarcodeUpper.replace(/\s+/g, '');
const cleanInputNormalized = cleanInputUpper.replace(/\s+/g, '');
// 1. Exact barcode match (case-insensitive, whitespace-insensitive) - PRIORITAS TERTINGGI
// EXACT barcode match (case-insensitive, whitespace-insensitive)
// Ini adalah satu-satunya cara yang aman untuk match pasien
if (patientBarcode === cleanInput ||
patientBarcodeNormalized === cleanInputNormalized ||
patientBarcodeUpper === cleanInputUpper) {
patientBarcode.toLowerCase() === cleanInput.toLowerCase()) {
console.log('✅ Found by exact barcode match:', patientBarcode, '===', cleanInput);
return true;
}
// 2. Match noAntrian dengan kode + angka (tidak hanya angka saja)
// Ini mencegah false positive ketika angka sama tapi kode beda (misalnya UM0014 vs AN0014)
if (p.noAntrian && matchNoAntrian(cleanInput, p.noAntrian)) {
console.log('✅ Found by noAntrian match (kode + angka):', p.noAntrian);
return true;
}
// 3. Try parsing as number and match with no (fallback)
// IMPORTANT: Hanya gunakan fallback jika input TIDAK punya kode (hanya angka)
// Ini mencegah false positive: "RA004" (kode: RA) tidak boleh match dengan pasien no: 4 yang punya kode berbeda
const inputHasCode = /^[A-Z]+/.test(cleanInput);
if (!inputHasCode) {
// Input hanya angka, boleh match dengan no (tapi tetap prioritas ke barcode dan noAntrian)
const parsedNo = parseInt(cleanInput.replace(/[^0-9]/g, '')) || parseInt(searchBarcode);
if (!isNaN(parsedNo) && p.no === parsedNo) {
console.log('✅ Found by no (input tanpa kode):', p.no);
return true;
}
}
// Jika input punya kode (seperti "RA004"), jangan gunakan fallback ke no
// karena bisa match dengan pasien yang punya kode berbeda
return false;
});
@@ -2692,13 +2643,13 @@ const checkInManual = async () => {
// IMPORTANT: Refresh data pasien dari queueStore untuk mendapatkan status REAL-TIME
// Jangan gunakan foundPatient.status karena mungkin sudah stale
// Cari ulang pasien dari queueStore untuk mendapatkan data terbaru
// Cari ulang pasien dari queueStore dengan EXACT barcode match
const freshPatient = queueStore.allPatients.find(p => {
const patientBarcode = String(p.barcode || '').trim();
// Hanya exact barcode match untuk menghindari false positive
return patientBarcode === foundPatient.barcode ||
patientBarcode === searchBarcode ||
patientBarcode === inputValue ||
p.no === foundPatient.no;
patientBarcode === cleanInput;
});
if (!freshPatient) {