363 lines
12 KiB
Vue
363 lines
12 KiB
Vue
<template lang="pug">
|
|
medical-form-wrapper(
|
|
title="Документы",
|
|
:is-check-change="isCheckChange",
|
|
:is-edit="isEdit",
|
|
:cancel="cancelEdit",
|
|
:open-edit="openEdit",
|
|
:save="saveChange"
|
|
)
|
|
q-form.form-wrap.gap-24.w-full(ref="documentForm", :no-error-focus="true")
|
|
.data-section.flex.flex-col.gap-4(v-for="data in configData", :key="data.dataLabel")
|
|
.font-semibold.text-sm.whitespace-nowrap {{data.dataLabel}}
|
|
.flex.w-full.justify-between.items-center.gap-4(
|
|
v-for="field in data.fields",
|
|
:key="field.label"
|
|
)
|
|
.label-field.font-sm.text-sm.whitespace-nowrap {{`${field.label} :`}}
|
|
.photo-field.flex.gap-3.items-center(v-if="field.type === 'photo'")
|
|
q-avatar(
|
|
rounded,
|
|
size="40px",
|
|
v-if="docData[data.dataKey][field.key]?.photo"
|
|
)
|
|
img.h-10.w-10.object-cover(
|
|
:src="docData[data.dataKey][field.key]?.photo",
|
|
:alt="docData[data.dataKey][field.label]"
|
|
)
|
|
q-badge.delete(
|
|
floating,
|
|
v-if="isEdit",
|
|
rounded,
|
|
@click="removeImage(data?.dataKey, field?.key)"
|
|
)
|
|
q-icon(name="app:icon-cancel", size="8px")
|
|
.replace-photo.font-medium.text-base.cursor-pointer(
|
|
v-if="isEdit",
|
|
@click="openModal(data.dataKey)",
|
|
) {{ docData[data.dataKey][field.key]?.photo ? "Заменить фото" : "Добавить фото"}}
|
|
base-modal(v-model="showModal", title="Загрузить изображение" v-if="photoId === data.dataKey")
|
|
base-upload-photo(
|
|
v-model="docData[photoId][field.key]",
|
|
:confirm-upload="confirmChangePhoto",
|
|
)
|
|
base-input-date(
|
|
v-if="field.type === 'date'",
|
|
v-model="docData[data.dataKey][field.key]",
|
|
:name="field.key",
|
|
@update:model-value="checkChangeDocData",
|
|
:readonly="!isEdit",
|
|
:width="302",
|
|
:mask="field?.inputMask",
|
|
:rule="[(val) => !personDataField.includes(field.key) ? checkPassportFields(val, field.rules) : field.rules(val)]",
|
|
:autogrow="field.key === 'issued_by_org'",
|
|
size="M"
|
|
)
|
|
base-input(
|
|
v-if="field.type === 'text'",
|
|
v-model="docData[data.dataKey][field.key]",
|
|
:name="field.key",
|
|
@update:model-value="checkChangeDocData",
|
|
:readonly="!isEdit",
|
|
:type="field.type",
|
|
:width="302",
|
|
:mask="field?.inputMask",
|
|
:rule="[(val) => !personDataField.includes(field.key) ? checkPassportFields(val, field.rules) : field.rules(val)]",
|
|
:autogrow="field.key === 'issued_by_org'",
|
|
:size="field.key !== 'issued_by_org' ? 'M' : 'auto'"
|
|
)
|
|
.icon-copy.my-auto.text-lg.label-field.cursor-pointer(
|
|
v-if="checkCopiedFields(field.key) && !!docData[data.dataKey][field.key]",
|
|
@click="copyValue(docData[data.dataKey][field.key])"
|
|
)
|
|
</template>
|
|
|
|
<script>
|
|
import MedicalFormWrapper from "@/pages/newMedicalCard/components/MedicalFormWrapper.vue";
|
|
import { documentForm } from "@/pages/newMedicalCard/utils/medicalConfig";
|
|
import BaseAvatar from "@/components/base/BaseAvatar.vue";
|
|
import BaseModal from "@/components/base/BaseModal.vue";
|
|
import BaseUploadPhoto from "@/components/base/BaseUploadPhoto.vue";
|
|
import {
|
|
checkChangeData,
|
|
getFieldsNameUnvalidated,
|
|
} from "@/shared/utils/changesObjects.js";
|
|
import { fetchWrapper } from "@/shared/fetchWrapper.js";
|
|
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
|
|
import { addNotification } from "@/components/Notifications/notificationContext";
|
|
import BaseInput from "@/components/base/BaseInput.vue";
|
|
import BaseInputDate from "@/components/base/BaseInputDate.vue";
|
|
export default {
|
|
name: "DocumentsForm",
|
|
components: {
|
|
MedicalFormWrapper,
|
|
BaseInput,
|
|
BaseAvatar,
|
|
BaseModal,
|
|
BaseUploadPhoto,
|
|
TheNotificationProvider,
|
|
BaseInputDate,
|
|
},
|
|
data() {
|
|
return {
|
|
configData: documentForm,
|
|
isEdit: false,
|
|
docData: null,
|
|
isCheckChange: false,
|
|
isLoadingData: true,
|
|
approvedPassportData: false,
|
|
copiedFields: [
|
|
"series",
|
|
"number",
|
|
"insurance_number",
|
|
"tax_identification_number",
|
|
],
|
|
initializationData: {
|
|
passport: {
|
|
id: null,
|
|
series: null,
|
|
number: null,
|
|
issued_by_org: null,
|
|
issued_by_org_code: null,
|
|
issued_by_date: null,
|
|
photo: null,
|
|
},
|
|
insurance_number: {
|
|
insurance_number: null,
|
|
photo_insurance_number: null,
|
|
},
|
|
tax_identification_number: {
|
|
tax_identification_number: null,
|
|
photo_tax_identification_number: null,
|
|
},
|
|
},
|
|
personDataField: ["insurance_number", "tax_identification_number"],
|
|
showModal: false,
|
|
photoId: "",
|
|
};
|
|
},
|
|
computed: {
|
|
initialDocData() {
|
|
return this.$store.state.medical?.documents;
|
|
},
|
|
passportFields() {
|
|
let excludedFields = ["photo", "id"];
|
|
return Object.keys(this.docData.passport).filter(
|
|
(key) => !excludedFields.includes(key)
|
|
);
|
|
},
|
|
},
|
|
methods: {
|
|
checkPassportFields(val, defaultRule) {
|
|
if (
|
|
this.passportFields.every((elem) => !this.docData.passport[elem]) &&
|
|
!this.initialDocData.passport?.id
|
|
) {
|
|
this.$refs.documentForm
|
|
.getValidationComponents()
|
|
.filter((elem) => !this.personDataField.includes(elem.name))
|
|
.forEach((elem) => elem.resetValidation());
|
|
this.approvedPassportData = true;
|
|
return true;
|
|
}
|
|
this.approvedPassportData = false;
|
|
return defaultRule(val);
|
|
},
|
|
removeImage(docKey, field) {
|
|
this.docData[docKey][field] = {};
|
|
this.isCheckChange = true;
|
|
},
|
|
copyValue(text) {
|
|
navigator.clipboard.writeText(text);
|
|
},
|
|
checkCopiedFields(key) {
|
|
return !this.isEdit && this.copiedFields.some((elem) => elem === key);
|
|
},
|
|
cancelEdit() {
|
|
this.docData = JSON.parse(JSON.stringify(this.initialDocData));
|
|
this.docData.passport.issued_by_date =
|
|
this.initialDocData?.passport?.issued_by_date;
|
|
this.isEdit = false;
|
|
this.isCheckChange = false;
|
|
this.$refs.documentForm.resetValidation();
|
|
},
|
|
openEdit() {
|
|
this.isEdit = true;
|
|
},
|
|
checkChangeDocData() {
|
|
this.isCheckChange = checkChangeData(this.initialDocData, this.docData);
|
|
},
|
|
openModal(id) {
|
|
this.photoId = id;
|
|
this.showModal = true;
|
|
},
|
|
confirmChangePhoto() {
|
|
this.showModal = false;
|
|
this.isCheckChange = true;
|
|
},
|
|
saveChange() {
|
|
const form = this.$refs.documentForm;
|
|
form.validate().then((validate) => {
|
|
if (!validate) {
|
|
getFieldsNameUnvalidated(form).forEach((elem) => {
|
|
let error = {};
|
|
this.configData.forEach(({ fields }) => {
|
|
let findedElem = fields.find((el) => el.key === elem);
|
|
if (findedElem) error = findedElem?.errorMessage;
|
|
});
|
|
this.addErrorNotification(error?.title, error?.message);
|
|
});
|
|
} else {
|
|
let passportFormData = new FormData();
|
|
let documentsFormData = new FormData();
|
|
form.getValidationComponents().forEach((elem) => {
|
|
if (!this.personDataField.includes(elem.name)) {
|
|
if (elem.name === "issued_by_date") {
|
|
passportFormData.append(
|
|
elem.name,
|
|
this.convertFormat(elem.modelValue) ?? ""
|
|
);
|
|
} else passportFormData.append(elem.name, elem.modelValue ?? "");
|
|
} else documentsFormData.append(elem.name, elem.modelValue ?? "");
|
|
});
|
|
this.checkChangePhoto("passport", "photo", passportFormData);
|
|
this.checkChangePhoto(
|
|
"insurance_number",
|
|
"photo_insurance_number",
|
|
documentsFormData
|
|
);
|
|
this.checkChangePhoto(
|
|
"tax_identification_number",
|
|
"photo_tax_identification_number",
|
|
documentsFormData
|
|
);
|
|
let request = [];
|
|
if (!this.approvedPassportData) {
|
|
if (!this.initialDocData.passport?.id) {
|
|
passportFormData.append("kind", "PASSPORT");
|
|
passportFormData.append(
|
|
"person",
|
|
this.$store.state.medical?.basicData?.personalData?.id
|
|
);
|
|
request.push(
|
|
this.sendData(
|
|
"general/identity_document/create/",
|
|
passportFormData
|
|
)
|
|
);
|
|
} else {
|
|
if (this.checkPhotoDeletion("passport", "photo"))
|
|
request.push(
|
|
this.deletePhoto(
|
|
`general/identity_document/${this.initialDocData.passport?.id}/delete_photo/`
|
|
)
|
|
);
|
|
request.push(
|
|
this.sendData(
|
|
`general/identity_document/${this.initialDocData.passport?.id}/update/`,
|
|
passportFormData
|
|
)
|
|
);
|
|
}
|
|
}
|
|
if (
|
|
this.checkPhotoDeletion(
|
|
"insurance_number",
|
|
"photo_insurance_number"
|
|
)
|
|
)
|
|
request.push(
|
|
this.deletePhoto(
|
|
`general/person/${this.$store.state.medical?.basicData?.personalData?.id}/delete_photo_insurance_number/`
|
|
)
|
|
);
|
|
if (
|
|
this.checkPhotoDeletion(
|
|
"tax_identification_number",
|
|
"photo_tax_identification_number"
|
|
)
|
|
)
|
|
request.push(
|
|
this.deletePhoto(
|
|
`general/person/${this.$store.state.medical?.basicData?.personalData?.id}/delete_photo_tax_identification_number/`
|
|
)
|
|
);
|
|
request.push(
|
|
this.sendData(
|
|
`general/person/${this.$store.state.medical?.basicData?.personalData?.id}/update/`,
|
|
documentsFormData
|
|
)
|
|
);
|
|
Promise.allSettled(request).then(() => {
|
|
this.$store.dispatch("getMedicalCardData");
|
|
this.isEdit = false;
|
|
this.isCheckChange = false;
|
|
this.$refs.form?.resetValidation();
|
|
});
|
|
}
|
|
});
|
|
},
|
|
checkChangePhoto(updatedObjId, field, formData) {
|
|
if (this.docData[updatedObjId][field]?.file)
|
|
formData.append(field, this.docData[updatedObjId][field]?.file[0]);
|
|
},
|
|
checkPhotoDeletion(updatedObjId, field) {
|
|
return (
|
|
!Object.keys(this.docData[updatedObjId][field]).length &&
|
|
this.initialDocData[updatedObjId][field]?.photo
|
|
);
|
|
},
|
|
async sendData(url, body) {
|
|
return await fetchWrapper.post(url, body, "formData");
|
|
},
|
|
async deletePhoto(url) {
|
|
return await fetchWrapper.del(url);
|
|
},
|
|
addErrorNotification(title, message) {
|
|
addNotification(title + message, title, message, "error", 5000);
|
|
},
|
|
convertFormat(date) {
|
|
return date ? date.split(".").reverse().join("-") : null;
|
|
},
|
|
},
|
|
watch: {
|
|
initialDocData: {
|
|
deep: true,
|
|
immediate: true,
|
|
handler(value) {
|
|
if (Object.keys(value).length) {
|
|
this.docData = JSON.parse(JSON.stringify(this.initialDocData));
|
|
this.docData.passport.issued_by_date =
|
|
this.initialDocData?.passport?.issued_by_date;
|
|
} else this.docData = this.initializationData;
|
|
},
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<style lang="sass" scoped>
|
|
.form-wrap
|
|
display: grid
|
|
grid-template-columns: repeat(3, 1fr)
|
|
grid-template-rows: repeat(1, 1fr)
|
|
@media(max-width: 1900px)
|
|
grid-template-columns: repeat(2, 1fr)
|
|
grid-template-rows: 2.5fr 0.5fr
|
|
@media(max-width: 1320px)
|
|
grid-template-columns: repeat(1, 1fr)
|
|
grid-template-rows: 2.5fr 0.5fr 0.5fr
|
|
.label-field
|
|
color: var(--font-grey-color)
|
|
.replace-photo
|
|
color: var(--btn-blue-color)
|
|
.photo-field
|
|
min-width: 302px
|
|
.icon-copy .cursor
|
|
cursor: pointer !important
|
|
.q-badge
|
|
padding: 4px
|
|
cursor: pointer
|
|
.delete
|
|
background-color: var(--btn-red-color)
|
|
</style>
|