QRcode update

This commit is contained in:
Fanrouver
2026-01-14 11:04:47 +07:00
parent f3e90adea3
commit 6c80c08a83
5 changed files with 589 additions and 162 deletions
+65 -42
View File
@@ -17,61 +17,84 @@ export const useQueueStore = defineStore('queue', () => {
return loket1 ? loket1.namaLoket : 'Loket A';
};
// Helper function untuk generate barcode dengan format: YYMMDD + 5 digit random
// Format: YY (tahun 2 digit) + MM (bulan 2 digit) + DD (tanggal 2 digit) + XXXXX (5 digit random)
// Contoh: 25011212345 (12 Januari 2025 dengan random 5 digit 12345)
// IMPORTANT: Memastikan barcode selalu UNIQUE meskipun reset harian
// Menggunakan timestamp milisecond + random untuk memastikan uniqueness
// Helper function untuk generate barcode dengan format: YYMMDD + 5 digit sequential
// Format: YY (tahun 2 digit terakhir) + MM (bulan 2 digit) + DD (tanggal 2 digit) + XXXXX (5 digit sequential)
// Contoh: 26011400001, 26011400002, dst
// Counter akan reset setiap ganti tanggal (mulai dari 00001 lagi)
// IMPORTANT: Memastikan barcode selalu UNIQUE dan sequential per tanggal
// NOTE: allPatientsRef adalah optional parameter untuk menghindari TDZ error saat seed initialization
const generateBarcode = (existingBarcodes = [], allPatientsRef = null) => {
const now = new Date();
const year = String(now.getFullYear()).slice(-2); // 2 digit tahun terakhir
const month = String(now.getMonth() + 1).padStart(2, '0'); // 2 digit bulan
const day = String(now.getDate()).padStart(2, '0'); // 2 digit tanggal
const datePrefix = `${year}${month}${day}`; // YYMMDD
// Generate 5 digit code dari timestamp milisecond untuk memastikan uniqueness
// Ambil 5 digit terakhir dari timestamp + random untuk menghindari duplikasi
const timestamp = Date.now();
const randomOffset = Math.floor(Math.random() * 1000); // 0-999
const uniqueCode = String((timestamp % 100000) + randomOffset).slice(-5).padStart(5, '0');
// Pastikan barcode unique dengan mengecek di existingBarcodes atau allPatientsRef
let barcode = `${year}${month}${day}${uniqueCode}`;
let attempts = 0;
const maxAttempts = 100;
// Cek apakah barcode sudah ada
// NOTE: allPatientsRef adalah optional untuk menghindari TDZ error saat seed initialization
const checkExists = (b) => {
if (existingBarcodes.includes(b)) return true;
// Hanya cek allPatientsRef jika diberikan (tidak null/undefined)
if (allPatientsRef && allPatientsRef.value && allPatientsRef.value.some(p => p.barcode === b)) return true;
return false;
};
// Generate ulang jika duplikat
while (checkExists(barcode) && attempts < maxAttempts) {
const newTimestamp = Date.now();
const newRandomOffset = Math.floor(Math.random() * 1000);
const newUniqueCode = String((newTimestamp % 100000) + newRandomOffset).slice(-5).padStart(5, '0');
barcode = `${year}${month}${day}${newUniqueCode}`;
attempts++;
}
// Jika masih duplikat setelah maxAttempts, tambahkan counter berdasarkan existing barcodes
if (attempts >= maxAttempts) {
const datePrefix = `${year}${month}${day}`;
// Check if localStorage is available (browser environment)
if (typeof window !== 'undefined' && typeof localStorage !== 'undefined') {
// Key untuk localStorage berdasarkan tanggal
const STORAGE_KEY = `barcode_counter_${datePrefix}`;
const LAST_DATE_KEY = 'barcode_last_date';
// Cek apakah tanggal sudah berubah (reset counter)
const lastDate = localStorage.getItem(LAST_DATE_KEY);
const currentDate = datePrefix;
let counter = 1; // Default mulai dari 1
if (lastDate === currentDate) {
// Tanggal sama, lanjutkan counter dari localStorage
const storedCounter = localStorage.getItem(STORAGE_KEY);
if (storedCounter) {
counter = parseInt(storedCounter, 10) || 1;
}
} else {
// Tanggal berbeda, reset counter ke 1
counter = 1;
// Hapus counter lama untuk tanggal sebelumnya (cleanup)
if (lastDate) {
localStorage.removeItem(`barcode_counter_${lastDate}`);
}
}
// Generate barcode dengan counter saat ini
let barcode = `${datePrefix}${String(counter).padStart(5, '0')}`;
// Cek apakah barcode sudah ada di existingBarcodes atau allPatientsRef
const checkExists = (b) => {
if (existingBarcodes.includes(b)) return true;
// Hanya cek allPatientsRef jika diberikan (tidak null/undefined)
if (allPatientsRef && allPatientsRef.value && allPatientsRef.value.some(p => p.barcode === b)) return true;
return false;
};
let attempts = 0;
const maxAttempts = 1000; // Maksimal 1000 pasien per hari
// Cek uniqueness dan increment jika duplikat
while (checkExists(barcode) && attempts < maxAttempts) {
counter++;
barcode = `${datePrefix}${String(counter).padStart(5, '0')}`;
attempts++;
}
// Increment counter untuk next call dan simpan
counter++;
localStorage.setItem(STORAGE_KEY, String(counter));
localStorage.setItem(LAST_DATE_KEY, currentDate);
return barcode;
} else {
// Fallback untuk SSR atau environment tanpa localStorage
// Gunakan counter berdasarkan existing barcodes atau allPatientsRef
const existingCount = existingBarcodes.filter(b => b && b.startsWith(datePrefix)).length;
// Hanya cek allPatientsRef jika diberikan (tidak null/undefined)
const allCount = allPatientsRef && allPatientsRef.value
? allPatientsRef.value.filter(p => p.barcode && p.barcode.startsWith(datePrefix)).length
: 0;
const counter = Math.max(existingCount, allCount) + 1;
const counterCode = String(counter).padStart(5, '0');
barcode = `${datePrefix}${counterCode}`;
return `${datePrefix}${counterCode}`;
}
return barcode;
};
// Seed data for easy reset during dev
// IMPORTANT: Setiap pasien HARUS memiliki barcode UNIK untuk menghindari konflik
@@ -1056,7 +1079,7 @@ export const useQueueStore = defineStore('queue', () => {
? `${String(visitDateTime.getHours()).padStart(2, "0")}:${String(visitDateTime.getMinutes()).padStart(2, "0")}`
: `${String(timestamp.getHours()).padStart(2, "0")}:${String(timestamp.getMinutes()).padStart(2, "0")}`;
// Generate barcode dengan format: YYMMDD + 5 digit random
// Generate barcode dengan format: YYMMDD + 5 digit sequential
const barcode = generateBarcode([], allPatients);
// Tentukan apakah pasien Eksekutif/Grand Pavilion (jika ada namaDokter, berarti Eksekutif)