242 lines
6.1 KiB
Vue
242 lines
6.1 KiB
Vue
<script setup lang="ts">
|
|
import { computed, ref, watch } from 'vue';
|
|
import { SaveButton, UndoButton } from 'components/button';
|
|
|
|
import { VuePDF, usePDF } from '@tato30/vue-pdf';
|
|
|
|
const currentFileSelected = ref<string>('');
|
|
const file = defineModel<
|
|
{
|
|
group?: string;
|
|
url?: string;
|
|
file?: File;
|
|
}[]
|
|
>('file', {
|
|
default: [],
|
|
});
|
|
|
|
const currentFile = computed(() => file.value.at(currentIndex.value));
|
|
const statusOcr = defineModel<boolean>('statusOcr', { default: false });
|
|
const currentIndex = ref(0);
|
|
|
|
const scale = ref(1);
|
|
const page = ref(1);
|
|
|
|
const currentIndexDropdownList = ref(0);
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
treeFile: { label: string; file: { label: string }[] }[];
|
|
dropdownList?: { label: string; value: string }[];
|
|
hideAction?: boolean;
|
|
}>(),
|
|
{
|
|
treeFile: () => [],
|
|
},
|
|
);
|
|
|
|
function browse() {
|
|
inputFile?.click();
|
|
}
|
|
|
|
const inputFile = (() => {
|
|
const _element = document.createElement('input');
|
|
_element.type = 'file';
|
|
_element.accept = 'image/jpeg,image/png';
|
|
_element.addEventListener('change', change);
|
|
return _element;
|
|
})();
|
|
|
|
function change(e: Event) {
|
|
const _element = e.target as HTMLInputElement | null;
|
|
const _file = _element?.files?.[0];
|
|
|
|
if (_file) {
|
|
const reader = new FileReader();
|
|
reader.readAsDataURL(_file);
|
|
reader.onload = () => {
|
|
if (file.value[currentIndex.value]) {
|
|
file.value[currentIndex.value].url = reader.result as string;
|
|
}
|
|
};
|
|
|
|
if (_file && file.value[currentIndex.value]) {
|
|
file.value[currentIndex.value].file = _file;
|
|
file.value[currentIndex.value].group =
|
|
props.dropdownList?.[currentIndexDropdownList.value].value;
|
|
} else {
|
|
file.value.push({
|
|
group: props.dropdownList?.[currentIndexDropdownList.value].value,
|
|
file: _file,
|
|
});
|
|
}
|
|
|
|
statusOcr.value = true;
|
|
|
|
emit(
|
|
'sendOcr',
|
|
props.dropdownList?.[currentIndexDropdownList.value].value || '',
|
|
inputFile?.files?.[0],
|
|
);
|
|
}
|
|
}
|
|
|
|
watch(currentFileSelected, () => {
|
|
file.value.findIndex((v, i) => {
|
|
if (v.url?.includes(currentFileSelected.value)) {
|
|
currentIndex.value = i;
|
|
}
|
|
});
|
|
});
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'sendOcr', dropdown: string, file?: File): void;
|
|
(e: 'save', เgroup: string, file?: File): void;
|
|
}>();
|
|
|
|
const { pdf, pages } = usePDF(computed(() => currentFile.value?.url));
|
|
</script>
|
|
|
|
<template>
|
|
<div class="full-width row" stlye="min-height: 500px">
|
|
<div>
|
|
<div class="q-pa-sm text-center bordered" style="height: 50px">
|
|
<q-btn-dropdown icon="mdi-upload" color="info" label="อัปโหลดเอกสาร">
|
|
<q-list v-for="(v, i) in dropdownList" :key="v.value">
|
|
<q-item
|
|
clickable
|
|
v-close-popup
|
|
@click="
|
|
() => {
|
|
currentIndexDropdownList = i;
|
|
browse();
|
|
}
|
|
"
|
|
>
|
|
<q-item-section>
|
|
<q-item-label>{{ $t(v.label) }}</q-item-label>
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-list>
|
|
</q-btn-dropdown>
|
|
</div>
|
|
|
|
<div class="full-height bordered-l bordered-b q-pa-sm">
|
|
<q-tree
|
|
:nodes="treeFile || []"
|
|
node-key="label"
|
|
label-key="label"
|
|
children-key="file"
|
|
selected-color="primary"
|
|
v-model:selected="currentFileSelected"
|
|
default-expand-all
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col">
|
|
<div
|
|
class="bordered row items-center justify-evenly q-pa-sm"
|
|
style="height: 50px"
|
|
>
|
|
<q-btn
|
|
@click="page = page > 1 ? page - 1 : page"
|
|
class="btn-next"
|
|
icon="mdi-chevron-left"
|
|
unelevated
|
|
dense
|
|
id="btn-prev-page-top"
|
|
/>
|
|
|
|
<div>Page {{ page }} of {{ pages }}</div>
|
|
|
|
<q-btn
|
|
@click="scale = scale > 0.25 ? scale - 0.25 : scale"
|
|
flat
|
|
dense
|
|
round
|
|
size="12px"
|
|
icon="mdi-magnify-minus-outline"
|
|
class="app-text-dark"
|
|
>
|
|
<q-tooltip>{{ $t('zoomOut') }}</q-tooltip>
|
|
</q-btn>
|
|
<div>{{ scale * 100 }}%</div>
|
|
|
|
<q-btn
|
|
flat
|
|
dense
|
|
round
|
|
size="12px"
|
|
class="app-text-dark"
|
|
icon="mdi-magnify-plus-outline"
|
|
@click="scale = scale < 2 ? scale + 0.25 : scale"
|
|
>
|
|
<q-tooltip>{{ $t('zoomIn') }}</q-tooltip>
|
|
</q-btn>
|
|
|
|
<q-btn
|
|
@click="page = page < pages ? page + 1 : page"
|
|
class="btn-next"
|
|
icon="mdi-chevron-right"
|
|
unelevated
|
|
dense
|
|
id="btn-prev-page-top"
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
class="flex flex-center surface-2 bordered-l bordered-r bordered-b full-height scroll"
|
|
>
|
|
<template v-if="statusOcr">
|
|
<q-spinner color="primary" size="3em" :thickness="2" />
|
|
</template>
|
|
|
|
<template v-else>
|
|
<VuePDF
|
|
v-if="
|
|
currentFile?.url?.split('?').at(0)?.endsWith('.pdf') ||
|
|
currentFile?.file?.type === 'application/pdf'
|
|
"
|
|
class="q-py-md"
|
|
:pdf="pdf"
|
|
:page="page"
|
|
:scale="scale"
|
|
/>
|
|
|
|
<q-img v-else class="q-py-md full-width" :src="currentFile?.url" />
|
|
</template>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-5">
|
|
<div
|
|
class="bordered row items-center justify-between q-pa-sm"
|
|
style="height: 50px"
|
|
>
|
|
ข้อมูลหนังสือเดินทาง
|
|
|
|
<div class="row" v-if="!hideAction">
|
|
<UndoButton icon-only type="button" />
|
|
<SaveButton
|
|
icon-only
|
|
type="button"
|
|
@click="
|
|
$emit(
|
|
'save',
|
|
dropdownList?.[currentIndexDropdownList].value || '',
|
|
inputFile?.files?.[0],
|
|
)
|
|
"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bordered-r bordered-b full-height">
|
|
<slot name="form" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss"></style>
|