404 lines
13 KiB
Vue
404 lines
13 KiB
Vue
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
|
|
// Components
|
|
import AppViewHistory from '~/components/app/sep/view-history.vue'
|
|
|
|
// Types
|
|
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
|
|
import type { PatientEntity } from '~/models/patient'
|
|
import type { SepHistoryData } from '~/components/app/sep/list-cfg.history'
|
|
import type { SepVisitData } from '~/components/app/sep/list-cfg.visit'
|
|
|
|
// Constants
|
|
import {
|
|
serviceTypes,
|
|
serviceAssessments,
|
|
registerMethods,
|
|
trafficAccidents,
|
|
supportCodes,
|
|
procedureTypes,
|
|
purposeOfVisits,
|
|
} from '~/lib/constants.vclaim'
|
|
|
|
// Services
|
|
import { getPatientDetail, getPatients } from '~/services/patient.service'
|
|
import { getValueLabelList as getProvinceList } from '~/services/vclaim-region-province.service'
|
|
import { getValueLabelList as getCityList } from '~/services/vclaim-region-city.service'
|
|
import { getValueLabelList as getDistrictList } from '~/services/vclaim-region-district.service'
|
|
import { getValueLabelList as getDoctorLabelList } from '~/services/vclaim-doctor.service'
|
|
import { getValueLabelList as getHealthFacilityLabelList } from '~/services/vclaim-health-facility.service'
|
|
import { getValueLabelList as getDiagnoseLabelList } from '~/services/vclaim-diagnose.service'
|
|
import { getList as geMonitoringVisitList } from '~/services/vclaim-monitoring-visit.service'
|
|
import { getList as getMonitoringHistoryList } from '~/services/vclaim-monitoring-history.service'
|
|
import { create as createSep, createPayload as createSepPayload } from '~/services/vclaim-sep.service'
|
|
|
|
const route = useRoute()
|
|
const openPatient = ref(false)
|
|
const openLetter = ref(false)
|
|
const openHistory = ref(false)
|
|
const selectedPatient = ref('')
|
|
const selectedPatientObject = ref<PatientEntity | null>(null)
|
|
const selectedLetter = ref('SK22334442')
|
|
const selectedObjects = ref<any>({})
|
|
const selectedServiceType = ref<string>('')
|
|
const histories = ref<Array<SepHistoryData>>([])
|
|
const visits = ref<Array<SepVisitData>>([])
|
|
const patients = ref<Array<{ id: string; identity: string; number: string; bpjs: string; name: string }>>([])
|
|
const doctors = ref<Array<{ value: string | number; label: string }>>([])
|
|
const diagnoses = ref<Array<{ value: string | number; label: string }>>([])
|
|
const facilities = ref<Array<{ value: string | number; label: string }>>([])
|
|
const supportCodesList = ref<Array<{ value: string; label: string }>>([])
|
|
const serviceTypesList = ref<Array<{ value: string; label: string }>>([])
|
|
const registerMethodsList = ref<Array<{ value: string; label: string }>>([])
|
|
const accidentsList = ref<Array<{ value: string; label: string }>>([])
|
|
const purposeOfVisitsList = ref<Array<{ value: string; label: string }>>([])
|
|
const proceduresList = ref<Array<{ value: string; label: string }>>([])
|
|
const assessmentsList = ref<Array<{ value: string; label: string }>>([])
|
|
const provincesList = ref<Array<{ value: string; label: string }>>([])
|
|
const citiesList = ref<Array<{ value: string; label: string }>>([])
|
|
const districtsList = ref<Array<{ value: string; label: string }>>([])
|
|
const isPatientsLoading = ref(false)
|
|
const paginationMeta = ref<PaginationMeta>({
|
|
recordCount: 0,
|
|
page: 1,
|
|
pageSize: 10,
|
|
totalPage: 5,
|
|
hasNext: false,
|
|
hasPrev: false,
|
|
})
|
|
|
|
function mapPatientToRow(patient: PatientEntity) {
|
|
// Defensive mapping: try common field names that might be returned by the API
|
|
const identity = patient?.person?.residentIdentityNumber || '-'
|
|
const number = patient?.number || '-'
|
|
const bpjs = '-'
|
|
const name = patient?.person?.name || '-'
|
|
return { id: patient.id ? String(patient.id) : '-', identity, number, bpjs, name }
|
|
}
|
|
|
|
function mapPaginationMetaToRow(meta: any) {
|
|
const recordCount = meta['record_totalCount'] ? Number(meta['record_totalCount']) : 0
|
|
const currentCount = meta['record_currentCount'] ? Number(meta['record_currentCount']) : 0
|
|
const page = meta['page_number'] ? Number(meta['page_number']) : 1
|
|
const pageSize = meta['page_size'] ? Number(meta['page_size']) : 10
|
|
const totalPage = Math.ceil(recordCount / pageSize)
|
|
|
|
return {
|
|
recordCount,
|
|
page,
|
|
pageSize,
|
|
totalPage,
|
|
hasNext: currentCount < recordCount && page < totalPage,
|
|
hasPrev: page > 1,
|
|
}
|
|
}
|
|
|
|
async function getPatientsList(params: any = { 'page-size': 10 }) {
|
|
try {
|
|
isPatientsLoading.value = true
|
|
patients.value = []
|
|
paginationMeta.value = {} as PaginationMeta
|
|
const result = await getPatients(params)
|
|
if (result && result.success && result.body && Array.isArray(result.body.data)) {
|
|
const meta = result.body.meta
|
|
patients.value = result.body.data.map(mapPatientToRow)
|
|
paginationMeta.value = mapPaginationMetaToRow(meta)
|
|
} else {
|
|
patients.value = [] // fallback to empty array
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to fetch patients for SEP search:', err)
|
|
patients.value = []
|
|
} finally {
|
|
isPatientsLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function getPatientCurrent(id: string) {
|
|
try {
|
|
const result = await getPatientDetail(Number(id))
|
|
if (result && result.success && result.body && result.body.data) {
|
|
const patient = result.body.data || null
|
|
selectedPatientObject.value = patient
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to fetch patient:', err)
|
|
}
|
|
}
|
|
|
|
async function getMonitoringHistoryMappers() {
|
|
histories.value = []
|
|
const dateFirst = new Date()
|
|
const dateLast = new Date()
|
|
dateLast.setMonth(dateFirst.getMonth() - 3)
|
|
const result = await getMonitoringHistoryList({
|
|
nop: '0002078925513',
|
|
tglawal: dateFirst.toISOString().substring(0, 10),
|
|
tglakhir: dateLast.toISOString().substring(0, 10),
|
|
})
|
|
if (result && result.success && result.body) {
|
|
const historiesRaw = result.body?.response?.histori || []
|
|
if (!historiesRaw) return
|
|
historiesRaw.forEach((result: any) => {
|
|
histories.value.push({
|
|
sepNumber: result.noSep,
|
|
sepDate: result.tglSep,
|
|
referralNumber: result.noRujukan,
|
|
diagnosis:
|
|
result.diagnosa && typeof result.diagnosa === 'string' && result.diagnosa.length > 20
|
|
? result.diagnosa.toString().substring(0, 17) + '...'
|
|
: '-',
|
|
serviceType: !result.jnsPelayanan ? '-' : result.jnsPelayanan === '1' ? 'Rawat Jalan' : 'Rawat Inap',
|
|
careClass: result.kelasRawat,
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
async function getMonitoringVisitMappers() {
|
|
visits.value = []
|
|
const dateFirst = new Date()
|
|
const result = await geMonitoringVisitList({
|
|
nop: '0002078925513',
|
|
tglpelayanan: dateFirst.toISOString().substring(0, 10),
|
|
jnspelayanan: 1,
|
|
})
|
|
if (result && result.success && result.body) {
|
|
const visitsRaw = result.body?.response?.sep || []
|
|
|
|
// "diagnosa": "K65.0",
|
|
// "jnsPelayanan": "R.Inap",
|
|
// "kelasRawat": "2",
|
|
// "nama": "HANIF ABDURRAHMAN",
|
|
// "noKartu": "0001819122189",
|
|
// "noRujukan": "0301U01108180200084",
|
|
// "poli": null,
|
|
// "tglPlgSep": "2017-10-03",
|
|
// "tglSep": "2017-10-01"
|
|
|
|
if (!visitsRaw) return
|
|
visitsRaw.forEach((result: any) => {
|
|
visits.value.push({
|
|
letterNumber: result.noRujukan,
|
|
letterDate: result.tglSep,
|
|
sepNumber: result.noSep,
|
|
patientName: result.nama,
|
|
bpjsNumber: result.noKartu,
|
|
diagnosis: result.diagnosa,
|
|
poly: result.poli || '-',
|
|
serviceType: result.jnsPelayanan,
|
|
careClass: result.kelasRawat,
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
const letters = [
|
|
{
|
|
noSurat: 'SK22334442',
|
|
tglRencana: '12 Agustus 2025',
|
|
noSep: 'SEP3232332',
|
|
namaPasien: 'Ahmad Baidowi',
|
|
noBpjs: '33442331214',
|
|
klinik: 'Penyakit Dalam',
|
|
dokter: 'dr. Andi Prasetyo, Sp.PD-KHOM',
|
|
},
|
|
{
|
|
noSurat: 'SK99120039',
|
|
tglRencana: '12 Agustus 2025',
|
|
noSep: 'SEP4443232',
|
|
namaPasien: 'Bian Maulana',
|
|
noBpjs: '33442367656',
|
|
klinik: 'Gigi',
|
|
dokter: 'dr. Achmad Suparjo',
|
|
},
|
|
]
|
|
|
|
function handleSavePatient() {
|
|
selectedPatientObject.value = null
|
|
setTimeout(() => {
|
|
getPatientCurrent(selectedPatient.value)
|
|
}, 150)
|
|
}
|
|
|
|
function handleSaveLetter() {
|
|
console.log('Letter dipilih:', selectedLetter.value)
|
|
}
|
|
|
|
function handleEvent(menu: string, value: any) {
|
|
if (menu === 'admission-type') {
|
|
console.log('service-type:', value)
|
|
return
|
|
}
|
|
if (menu === 'search-patient') {
|
|
getPatientsList({ 'page-size': 10, includes: 'person' }).then(() => {
|
|
openPatient.value = true
|
|
})
|
|
return
|
|
}
|
|
if (menu === 'search-letter') {
|
|
getMonitoringVisitMappers().then(() => {
|
|
openLetter.value = true
|
|
})
|
|
return
|
|
}
|
|
if (menu === 'history-sep') {
|
|
getMonitoringHistoryMappers().then(() => {
|
|
openHistory.value = true
|
|
})
|
|
return
|
|
}
|
|
if (menu === 'back') {
|
|
navigateTo('/integration/bpjs/sep')
|
|
}
|
|
if (menu === 'save-sep') {
|
|
createSep(createSepPayload(value)).then(() => {
|
|
navigateTo('/integration/bpjs/sep')
|
|
})
|
|
}
|
|
}
|
|
|
|
async function handleFetch(params: any) {
|
|
const menu = params.menu || ''
|
|
const value = params.value || ''
|
|
if (menu === 'service-type') {
|
|
selectedServiceType.value = value
|
|
}
|
|
if (menu === 'diagnosis') {
|
|
diagnoses.value = await getDiagnoseLabelList({ diagnosa: value })
|
|
}
|
|
if (menu === 'clinic') {
|
|
facilities.value = await getHealthFacilityLabelList({
|
|
faskes: value,
|
|
'jenis-faskes': selectedServiceType.value || 1,
|
|
})
|
|
facilities.value = await getHealthFacilityLabelList({
|
|
faskes: 'Puskesmas',
|
|
'jenis-faskes': selectedLetter.value || 1,
|
|
})
|
|
doctors.value = await getDoctorLabelList({
|
|
'jenis-pelayanan': selectedServiceType.value || 1,
|
|
'tgl-pelayanan': new Date().toISOString().substring(0, 10),
|
|
'kode-spesialis': 0,
|
|
})
|
|
}
|
|
if (menu === 'province') {
|
|
citiesList.value = await getCityList({ province: value })
|
|
districtsList.value = []
|
|
}
|
|
if (menu === 'city') {
|
|
districtsList.value = await getDistrictList({ city: value })
|
|
}
|
|
}
|
|
|
|
async function handleInit() {
|
|
diagnoses.value = await getDiagnoseLabelList({ diagnosa: 'paru' })
|
|
facilities.value = await getHealthFacilityLabelList({
|
|
faskes: 'Puskesmas',
|
|
'jenis-faskes': selectedLetter.value || 1,
|
|
})
|
|
doctors.value = await getDoctorLabelList({
|
|
'jenis-pelayanan': selectedServiceType.value || 1,
|
|
'tgl-pelayanan': new Date().toISOString().substring(0, 10),
|
|
'kode-spesialis': 0,
|
|
})
|
|
provincesList.value = await getProvinceList()
|
|
serviceTypesList.value = Object.keys(serviceTypes).map((item) => ({
|
|
value: item.toString(),
|
|
label: serviceTypes[item],
|
|
})) as any
|
|
registerMethodsList.value = Object.keys(registerMethods)
|
|
.filter((item) => !['2', '4'].includes(item))
|
|
.map((item) => ({
|
|
value: item.toString(),
|
|
label: registerMethods[item],
|
|
})) as any
|
|
accidentsList.value = Object.keys(trafficAccidents).map((item) => ({
|
|
value: item.toString(),
|
|
label: trafficAccidents[item],
|
|
})) as any
|
|
purposeOfVisitsList.value = Object.keys(purposeOfVisits).map((item) => ({
|
|
value: item.toString(),
|
|
label: purposeOfVisits[item],
|
|
})) as any
|
|
proceduresList.value = Object.keys(procedureTypes).map((item) => ({
|
|
value: item.toString(),
|
|
label: procedureTypes[item],
|
|
})) as any
|
|
assessmentsList.value = Object.keys(serviceAssessments).map((item) => ({
|
|
value: item.toString(),
|
|
label: `${item.toString()} - ${serviceAssessments[item]}`,
|
|
})) as any
|
|
supportCodesList.value = Object.keys(supportCodes).map((item) => ({
|
|
value: item.toString(),
|
|
label: `${item.toString()} - ${supportCodes[item]}`,
|
|
})) as any
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await handleInit()
|
|
// getProvinceList().then((value) => {
|
|
// console.log('value:', value)
|
|
// })
|
|
// getCityList({ province: '14' }).then((value) => {
|
|
// console.log('value:', value)
|
|
// })
|
|
// getDistrictList({ city: '0187' }).then((value) => {
|
|
// console.log('value:', value)
|
|
// })
|
|
if (route.query) {
|
|
selectedObjects.value = { ...route.query }
|
|
}
|
|
console.log('selectedObjects:', selectedObjects.value)
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
|
<Icon
|
|
name="i-lucide-panel-bottom"
|
|
class="me-2"
|
|
/>
|
|
<span class="font-semibold">Tambah</span>
|
|
SEP
|
|
</div>
|
|
<AppSepEntryForm
|
|
:doctors="doctors"
|
|
:diagnoses="diagnoses"
|
|
:facilities="facilities"
|
|
:service-types="serviceTypesList"
|
|
:register-methods="registerMethodsList"
|
|
:accidents="accidentsList"
|
|
:purposes="purposeOfVisitsList"
|
|
:procedures="proceduresList"
|
|
:assessments="assessmentsList"
|
|
:support-codes="supportCodesList"
|
|
:provinces="provincesList"
|
|
:cities="citiesList"
|
|
:districts="districtsList"
|
|
:patient="selectedPatientObject"
|
|
@fetch="handleFetch"
|
|
@event="handleEvent"
|
|
/>
|
|
<AppSepTableSearchPatient
|
|
v-model:open="openPatient"
|
|
v-model:selected="selectedPatient"
|
|
:patients="patients"
|
|
:pagination-meta="paginationMeta"
|
|
@fetch="(value) => getPatientsList({ ...value, 'page-size': 10, includes: 'person' })"
|
|
@save="handleSavePatient"
|
|
/>
|
|
<AppSepTableSearchLetter
|
|
v-model:open="openLetter"
|
|
v-model:selected="selectedLetter"
|
|
:letters="letters"
|
|
@save="handleSaveLetter"
|
|
/>
|
|
<AppViewHistory
|
|
v-model:open="openHistory"
|
|
:histories="histories"
|
|
/>
|
|
</template>
|