666 lines
19 KiB
Vue
666 lines
19 KiB
Vue
<script setup lang="ts">
|
|
import { reactive, ref, watch } from 'vue';
|
|
import { InstitutionPayload } from 'src/stores/institution/types';
|
|
import { Icon } from '@iconify/vue/dist/iconify.js';
|
|
|
|
import { useInstitution } from 'src/stores/institution';
|
|
import { baseUrl } from 'src/stores/utils';
|
|
|
|
import DrawerInfo from 'src/components/DrawerInfo.vue';
|
|
import DialogForm from 'src/components/DialogForm.vue';
|
|
import ProfileBanner from 'src/components/ProfileBanner.vue';
|
|
import SideMenu from 'src/components/SideMenu.vue';
|
|
import FormBank from 'src/components/01_branch-management/FormBank.vue';
|
|
import FormBasicInfoAgencies from 'src/components/07_agencies-management/FormBasicInfoAgencies.vue';
|
|
import {
|
|
UndoButton,
|
|
SaveButton,
|
|
EditButton,
|
|
DeleteButton,
|
|
} from 'src/components/button';
|
|
import AddressForm from 'src/components/form/AddressForm.vue';
|
|
import ImageUploadDialog from 'src/components/ImageUploadDialog.vue';
|
|
import { BankBook } from 'src/stores/branch/types';
|
|
import QrCodeUploadDialog from 'src/components/QrCodeUploadDialog.vue';
|
|
|
|
const institutionStore = useInstitution();
|
|
|
|
const model = defineModel<boolean>({ required: true, default: false });
|
|
const drawerModel = defineModel<boolean>('drawerModel', {
|
|
required: true,
|
|
default: false,
|
|
});
|
|
const imageListOnCreate = defineModel<{
|
|
selectedImage: string;
|
|
list: { url: string; imgFile: File | null; name: string }[];
|
|
}>('imageListOnCreate', { default: { selectedImage: '', list: [] } });
|
|
const deletesStatusQrCodeBankImag = defineModel<number[]>(
|
|
'deletesStatusQrCodeBankImag',
|
|
{ default: [] },
|
|
);
|
|
|
|
const imageState = reactive({
|
|
imageDialog: false,
|
|
isImageEdit: false,
|
|
refreshImageState: false,
|
|
|
|
imageUrl: '',
|
|
});
|
|
|
|
const imageFile = ref<File | null>(null);
|
|
const imageList = ref<{ selectedImage: string; list: string[] }>();
|
|
|
|
const qrCodeDialog = ref(false);
|
|
const qrCodeImageUrl = ref<string>('');
|
|
const currentIndexQrCodeBank = ref<number>(-1);
|
|
const statusQrCodeFile = ref<File | undefined>(undefined);
|
|
const refQrCodeUpload = ref();
|
|
const statusQrCodeUrl = ref<string>('');
|
|
const statusDeletesQrCode = ref<boolean>(false);
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
readonly?: boolean;
|
|
isEdit?: boolean;
|
|
hideAction?: boolean;
|
|
hideDelete?: boolean;
|
|
|
|
dataId?: string;
|
|
}>(),
|
|
{ readonly: false, isEdit: false, dataId: '' },
|
|
);
|
|
|
|
defineExpose({ clearImageState });
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'submit'): void;
|
|
(e: 'close'): void;
|
|
(e: 'changeStatus'): void;
|
|
(e: 'drawerUndo'): void;
|
|
(e: 'drawerEdit'): void;
|
|
(e: 'drawerDelete'): void;
|
|
(e: 'addImage'): void;
|
|
(e: 'removeImage'): void;
|
|
(e: 'submitImage', name: string): void;
|
|
(e: 'deleteAttachment', name: string): void;
|
|
}>();
|
|
|
|
const data = defineModel<InstitutionPayload>('data', {
|
|
required: true,
|
|
default: {
|
|
group: '',
|
|
name: '',
|
|
nameEN: '',
|
|
contactName: '',
|
|
contactEmail: '',
|
|
contactTel: '',
|
|
code: '',
|
|
addressEN: '',
|
|
address: '',
|
|
soi: '',
|
|
soiEN: '',
|
|
moo: '',
|
|
mooEN: '',
|
|
street: '',
|
|
streetEN: '',
|
|
subDistrictId: '',
|
|
districtId: '',
|
|
provinceId: '',
|
|
selectedImage: '',
|
|
},
|
|
});
|
|
const formBankBook = defineModel<BankBook[]>('formBankBook', {
|
|
default: [
|
|
{
|
|
bankName: '',
|
|
accountNumber: '',
|
|
bankBranch: '',
|
|
accountName: '',
|
|
accountType: '',
|
|
currentlyUse: true,
|
|
bankUrl: '',
|
|
},
|
|
],
|
|
});
|
|
const attachment = defineModel<File[]>('attachment');
|
|
const attachmentList =
|
|
defineModel<{ name: string; url: string }[]>('attachmentList');
|
|
|
|
function viewImage() {
|
|
imageState.imageDialog = true;
|
|
imageState.isImageEdit = false;
|
|
}
|
|
|
|
function editImage() {
|
|
imageState.imageDialog = imageState.isImageEdit = true;
|
|
}
|
|
|
|
async function fetchImageList(id: string, selectedName: string) {
|
|
const res = await institutionStore.fetchImageListById(id);
|
|
imageList.value = {
|
|
selectedImage: selectedName,
|
|
list: res.map((n: string) => `institution/${id}/image/${n}`),
|
|
};
|
|
return res;
|
|
}
|
|
|
|
async function addImage(file: File | null) {
|
|
if (!file) return;
|
|
if (!props.dataId) return;
|
|
|
|
await institutionStore.addImageList(
|
|
file,
|
|
props.dataId,
|
|
Date.now().toString(),
|
|
);
|
|
await fetchImageList(props.dataId, data.value.selectedImage || '');
|
|
}
|
|
|
|
async function removeImage(name: string) {
|
|
if (!name) return;
|
|
if (!props.dataId) return;
|
|
|
|
const targetName = name.split('/').pop() || '';
|
|
await institutionStore.deleteImageByName(props.dataId, targetName);
|
|
await fetchImageList(props.dataId, data.value.selectedImage || '');
|
|
}
|
|
|
|
async function submitImage(name: string) {
|
|
if (model.value) {
|
|
imageState.imageUrl = name;
|
|
imageState.imageDialog = false;
|
|
} else {
|
|
imageState.refreshImageState = true;
|
|
emit('submitImage', name);
|
|
}
|
|
}
|
|
|
|
function clearImageState() {
|
|
imageState.imageDialog = false;
|
|
imageFile.value = null;
|
|
imageListOnCreate.value = { selectedImage: '', list: [] };
|
|
imageState.refreshImageState = false;
|
|
}
|
|
|
|
function triggerEditQrCodeBank(opts?: { save?: boolean }) {
|
|
if (opts?.save === undefined) {
|
|
qrCodeDialog.value = true;
|
|
statusDeletesQrCode.value = false;
|
|
statusQrCodeUrl.value =
|
|
formBankBook.value[currentIndexQrCodeBank.value].bankUrl || '';
|
|
statusDeletesQrCode.value = false;
|
|
} else {
|
|
formBankBook.value[currentIndexQrCodeBank.value].bankUrl =
|
|
statusQrCodeUrl.value;
|
|
|
|
formBankBook.value[currentIndexQrCodeBank.value].bankQr =
|
|
statusQrCodeFile.value;
|
|
|
|
if (statusDeletesQrCode.value === true) {
|
|
deletesStatusQrCodeBankImag.value.push(currentIndexQrCodeBank.value);
|
|
}
|
|
if (statusDeletesQrCode.value === false) {
|
|
deletesStatusQrCodeBankImag.value =
|
|
deletesStatusQrCodeBankImag.value.filter(
|
|
(item) => item !== currentIndexQrCodeBank.value,
|
|
);
|
|
}
|
|
|
|
currentIndexQrCodeBank.value = -1;
|
|
statusDeletesQrCode.value = false;
|
|
}
|
|
}
|
|
|
|
watch(
|
|
() => imageFile.value,
|
|
() => {
|
|
if (imageFile.value !== null) imageState.isImageEdit = true;
|
|
},
|
|
);
|
|
|
|
watch(
|
|
() => data.value.selectedImage,
|
|
() => {
|
|
imageState.imageUrl = `${baseUrl}/institution/${props.dataId}/image/${data.value.selectedImage}`;
|
|
imageList.value
|
|
? (imageList.value.selectedImage = data.value.selectedImage || '')
|
|
: '';
|
|
imageState.refreshImageState = false;
|
|
},
|
|
);
|
|
|
|
watch(
|
|
() => drawerModel.value,
|
|
async () => {
|
|
if (drawerModel.value) {
|
|
await fetchImageList(props.dataId, data.value.selectedImage || '');
|
|
imageState.imageUrl = `${baseUrl}/institution/${props.dataId}/image/${data.value.selectedImage}`;
|
|
} else {
|
|
imageList.value = { selectedImage: '', list: [] };
|
|
}
|
|
},
|
|
);
|
|
</script>
|
|
<template>
|
|
<DialogForm
|
|
hide-footer
|
|
:title="$t('general.add', { text: $t('agencies.title') })"
|
|
v-model:modal="model"
|
|
:submit="() => $emit('submit')"
|
|
:close="
|
|
() => {
|
|
imageState.imageUrl = '';
|
|
clearImageState();
|
|
$emit('close');
|
|
}
|
|
"
|
|
>
|
|
<div
|
|
:class="{
|
|
'q-mx-lg q-my-md': $q.screen.gt.sm,
|
|
'q-mx-md q-my-sm': !$q.screen.gt.sm,
|
|
}"
|
|
>
|
|
<ProfileBanner
|
|
prefix="dialog"
|
|
active
|
|
use-toggle
|
|
hide-fade
|
|
:toggle-title="$t('status.title')"
|
|
:icon="'ph-building-office'"
|
|
:img="imageState.imageUrl || null"
|
|
:title="data.name"
|
|
:caption="data.code"
|
|
:color="`hsla(var(--green-8-hsl)/1)`"
|
|
:bg-color="`hsla(var(--green-8-hsl)/0.1)`"
|
|
v-model:toggle-status="data.status"
|
|
@view="viewImage"
|
|
@edit="editImage"
|
|
@update:toggle-status="
|
|
() => {
|
|
data.status = data.status === 'CREATED' ? 'INACTIVE' : 'CREATED';
|
|
}
|
|
"
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
class="col surface-1 rounded bordered scroll row relative-position"
|
|
:class="{
|
|
'q-mb-lg q-mx-lg ': $q.screen.gt.sm,
|
|
'q-mb-sm q-mx-md': !$q.screen.gt.sm,
|
|
}"
|
|
id="group-form"
|
|
>
|
|
<div
|
|
class="col"
|
|
style="height: 100%; max-height: 100; overflow-y: auto"
|
|
v-if="$q.screen.gt.sm"
|
|
>
|
|
<div class="q-py-md q-pl-md q-pr-sm">
|
|
<SideMenu
|
|
:menu="[
|
|
{
|
|
name: $t('form.field.basicInformation'),
|
|
anchor: 'agencies-form-basic-info',
|
|
},
|
|
{
|
|
name: $t('general.address'),
|
|
anchor: 'agencies-form-address-info',
|
|
},
|
|
{
|
|
name: $t('agencies.bankInfo'),
|
|
anchor: 'agencies-form-bank-info',
|
|
},
|
|
]"
|
|
background="transparent"
|
|
:active="{
|
|
background: 'hsla(var(--blue-6-hsl) / .2)',
|
|
foreground: 'var(--blue-6)',
|
|
}"
|
|
scroll-element="#agencies-form-content"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="col-12 col-md-10"
|
|
id="agencies-form-content"
|
|
:class="{
|
|
'q-py-md q-pr-md ': $q.screen.gt.sm,
|
|
'q-pa-sm': !$q.screen.gt.sm,
|
|
}"
|
|
style="height: 100%; max-height: 100%; overflow-y: auto"
|
|
>
|
|
<div
|
|
class="rounded"
|
|
:class="{
|
|
'q-py-md q-px-lg': $q.screen.gt.sm,
|
|
'q-pa-sm': !$q.screen.gt.sm,
|
|
}"
|
|
style="position: absolute; z-index: 99999; top: 0; right: 0"
|
|
>
|
|
<div class="surface-1 row rounded">
|
|
<SaveButton id="btn-info-basic-save" icon-only type="submit" />
|
|
</div>
|
|
</div>
|
|
<FormBasicInfoAgencies
|
|
id="agencies-form-basic-info"
|
|
class="q-mb-xl"
|
|
v-model:group="data.group"
|
|
v-model:name="data.name"
|
|
v-model:name-en="data.nameEN"
|
|
v-model:contact-name="data.contactName"
|
|
v-model:email="data.contactEmail"
|
|
v-model:contact-tel="data.contactTel"
|
|
v-model:attachment="attachment"
|
|
/>
|
|
<AddressForm
|
|
id="agencies-form-address-info"
|
|
dense
|
|
:prefix-id="''"
|
|
v-model:address="data.address"
|
|
v-model:address-en="data.addressEN"
|
|
v-model:moo="data.moo"
|
|
v-model:moo-en="data.mooEN"
|
|
v-model:soi="data.soi"
|
|
v-model:soi-en="data.soiEN"
|
|
v-model:street="data.street"
|
|
v-model:street-en="data.streetEN"
|
|
v-model:province-id="data.provinceId"
|
|
v-model:district-id="data.districtId"
|
|
v-model:sub-district-id="data.subDistrictId"
|
|
/>
|
|
<FormBank
|
|
id="agencies-form-bank-info"
|
|
title="agencies.bankInfo"
|
|
class="q-pt-xl"
|
|
dense
|
|
v-model:bank-book-list="formBankBook"
|
|
@view-qr="
|
|
(i) => {
|
|
currentIndexQrCodeBank = i;
|
|
triggerEditQrCodeBank();
|
|
}
|
|
"
|
|
@edit-qr="
|
|
(i) => {
|
|
currentIndexQrCodeBank = i;
|
|
refQrCodeUpload && refQrCodeUpload.browse();
|
|
}
|
|
"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</DialogForm>
|
|
|
|
<DrawerInfo
|
|
bg-on
|
|
hide-action
|
|
:is-edit="isEdit"
|
|
:title="data.name"
|
|
v-model:drawerOpen="drawerModel"
|
|
:submit="() => $emit('submit')"
|
|
:close="
|
|
() => {
|
|
clearImageState();
|
|
$emit('close');
|
|
}
|
|
"
|
|
>
|
|
<div class="col column full-height">
|
|
<div
|
|
:class="{
|
|
'q-mx-lg q-my-md': $q.screen.gt.sm,
|
|
'q-mx-md q-my-sm': !$q.screen.gt.sm,
|
|
}"
|
|
>
|
|
<ProfileBanner
|
|
:prefix="data.name"
|
|
hide-fade
|
|
use-toggle
|
|
:readonly="hideAction"
|
|
:active="data.status !== 'INACTIVE'"
|
|
:toggle-title="$t('status.title')"
|
|
:icon="'ph-building-office'"
|
|
:title="data.name"
|
|
:caption="data.code"
|
|
:color="`hsla(var(${'--green-8'}-hsl)/1)`"
|
|
:bg-color="`hsla(var(${'--green-8'}-hsl)/0.1)`"
|
|
:img="
|
|
`${baseUrl}/institution/${dataId}/image/${data.selectedImage}`.concat(
|
|
imageState.refreshImageState ? `?ts=${Date.now()}` : '',
|
|
) || null
|
|
"
|
|
v-model:toggle-status="data.status"
|
|
@view="viewImage"
|
|
@edit="editImage"
|
|
@update:toggle-status="$emit('changeStatus')"
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
style="flex: 1; width: 100%; overflow-y: auto"
|
|
id="drawer-user-form"
|
|
:class="{
|
|
'q-px-lg q-pb-lg': $q.screen.gt.sm,
|
|
'q-px-md q-pb-sm': !$q.screen.gt.sm,
|
|
}"
|
|
>
|
|
<div
|
|
class="col surface-1 full-height rounded bordered scroll row relative-position"
|
|
>
|
|
<div
|
|
class="rounded row"
|
|
:class="{
|
|
'q-py-md q-px-lg': $q.screen.gt.sm,
|
|
'q-pa-sm': !$q.screen.gt.sm,
|
|
}"
|
|
style="position: absolute; z-index: 999; top: 0; right: 0"
|
|
>
|
|
<div
|
|
v-if="data.status !== 'INACTIVE' && !hideAction"
|
|
class="surface-1 row rounded"
|
|
>
|
|
<UndoButton
|
|
v-if="isEdit"
|
|
id="btn-info-basic-undo"
|
|
icon-only
|
|
@click="
|
|
() => {
|
|
$emit('drawerUndo');
|
|
}
|
|
"
|
|
type="button"
|
|
/>
|
|
<SaveButton
|
|
v-if="isEdit"
|
|
id="btn-info-basic-save"
|
|
icon-only
|
|
type="submit"
|
|
/>
|
|
<EditButton
|
|
v-if="!isEdit"
|
|
id="btn-info-basic-edit"
|
|
icon-only
|
|
@click="
|
|
() => {
|
|
$emit('drawerEdit');
|
|
// infoDrawerEdit = true;
|
|
// isImageEdit = true;
|
|
}
|
|
"
|
|
type="button"
|
|
/>
|
|
<DeleteButton
|
|
v-if="!isEdit && !hideDelete"
|
|
id="btn-info-basic-delete"
|
|
icon-only
|
|
@click="
|
|
() => {
|
|
$emit('drawerDelete');
|
|
}
|
|
"
|
|
type="button"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="col"
|
|
style="height: 100%; overflow-y: auto"
|
|
v-if="$q.screen.gt.sm"
|
|
>
|
|
<div class="q-py-md q-pl-md q-pr-sm">
|
|
<SideMenu
|
|
:menu="[
|
|
{
|
|
name: $t('form.field.basicInformation'),
|
|
anchor: 'agencies-basic-info',
|
|
},
|
|
{
|
|
name: $t('general.address'),
|
|
anchor: 'agencies-address-info',
|
|
},
|
|
{
|
|
name: $t('agencies.bankInfo'),
|
|
anchor: 'agencies-bank-info',
|
|
},
|
|
]"
|
|
background="transparent"
|
|
:active="{
|
|
background: 'hsla(var(--blue-6-hsl) / .2)',
|
|
foreground: 'var(--blue-6)',
|
|
}"
|
|
scroll-element="#agencies-view-content"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="col-12 col-md-10 relative-position"
|
|
:class="{
|
|
'q-py-md q-pr-md ': $q.screen.gt.sm,
|
|
'q-pa-sm': !$q.screen.gt.sm,
|
|
}"
|
|
id="agencies-view-content"
|
|
style="height: 100%; max-height: 100; overflow-y: auto"
|
|
>
|
|
<FormBasicInfoAgencies
|
|
id="agencies-basic-info"
|
|
:readonly
|
|
onDrawer
|
|
class="q-mb-xl"
|
|
v-model:group="data.group"
|
|
v-model:name="data.name"
|
|
v-model:name-en="data.nameEN"
|
|
v-model:contact-name="data.contactName"
|
|
v-model:email="data.contactEmail"
|
|
v-model:contact-tel="data.contactTel"
|
|
v-model:attachment="attachment"
|
|
:attachment-list="attachmentList"
|
|
@delete-attachment="(name) => $emit('deleteAttachment', name)"
|
|
/>
|
|
<AddressForm
|
|
id="agencies-address-info"
|
|
dense
|
|
:readonly
|
|
:prefix-id="data.code ? data.code : ''"
|
|
v-model:address="data.address"
|
|
v-model:address-en="data.addressEN"
|
|
v-model:moo="data.moo"
|
|
v-model:moo-en="data.mooEN"
|
|
v-model:soi="data.soi"
|
|
v-model:soi-en="data.soiEN"
|
|
v-model:street="data.street"
|
|
v-model:street-en="data.streetEN"
|
|
v-model:province-id="data.provinceId"
|
|
v-model:district-id="data.districtId"
|
|
v-model:sub-district-id="data.subDistrictId"
|
|
/>
|
|
<FormBank
|
|
id="agencies-bank-info"
|
|
title="agencies.bankInfo"
|
|
class="q-pt-xl"
|
|
dense
|
|
:readonly
|
|
v-model:bank-book-list="formBankBook"
|
|
@view-qr="
|
|
(i) => {
|
|
currentIndexQrCodeBank = i;
|
|
triggerEditQrCodeBank();
|
|
}
|
|
"
|
|
@edit-qr="
|
|
(i) => {
|
|
currentIndexQrCodeBank = i;
|
|
refQrCodeUpload && refQrCodeUpload.browse();
|
|
}
|
|
"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</DrawerInfo>
|
|
|
|
<ImageUploadDialog
|
|
v-model:dialog-state="imageState.imageDialog"
|
|
v-model:file="imageFile"
|
|
v-model:on-create-data-list="imageListOnCreate"
|
|
v-model:image-url="imageState.imageUrl"
|
|
v-model:data-list="imageList"
|
|
:changeDisabled="hideAction"
|
|
:on-create="model"
|
|
:hiddenFooter="!imageState.isImageEdit"
|
|
@add-image="addImage"
|
|
@remove-image="removeImage"
|
|
@submit="submitImage"
|
|
>
|
|
<template #title>
|
|
<span v-if="!model" class="justify-center flex text-bold">
|
|
{{ $t('general.image') }}
|
|
{{ $i18n.locale === 'eng' ? data.nameEN : data.name }}
|
|
</span>
|
|
</template>
|
|
|
|
<template #error>
|
|
<div class="full-height full-width" style="background: white">
|
|
<div
|
|
class="full-height full-width flex justify-center items-center"
|
|
style="
|
|
background: hsla(var(--green-8-hsl) / 0.1);
|
|
color: hsla(var(--green-8-hsl) / 1);
|
|
"
|
|
>
|
|
<Icon width="3rem" icon="ph-building-office" />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</ImageUploadDialog>
|
|
|
|
<QrCodeUploadDialog
|
|
ref="refQrCodeUpload"
|
|
v-model:dialog-state="qrCodeDialog"
|
|
v-model:file="statusQrCodeFile as File"
|
|
v-model:image-url="statusQrCodeUrl"
|
|
@save="
|
|
(_file) => {
|
|
qrCodeDialog = false;
|
|
if (currentIndexQrCodeBank !== -1) {
|
|
triggerEditQrCodeBank({ save: true });
|
|
}
|
|
}
|
|
"
|
|
@clear="statusDeletesQrCode = true"
|
|
clearButton
|
|
>
|
|
<template #error>
|
|
<div
|
|
class="full-width full-height flex items-center justify-center"
|
|
style="color: gray"
|
|
>
|
|
<q-icon size="15rem" name="mdi-qrcode" />
|
|
</div>
|
|
</template>
|
|
</QrCodeUploadDialog>
|
|
</template>
|
|
<style scoped></style>
|