307 lines
10 KiB
Vue
307 lines
10 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(
|
|
square,
|
|
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(
|
|
v-else,
|
|
v-model="docData[data.dataKey][field.key]",
|
|
:name="field.key",
|
|
@update:model-value="checkChangeDocData",
|
|
:readonly="!isEdit",
|
|
:type="field.type",
|
|
textColor="var(--font-dark-blue-color)",
|
|
:width="302",
|
|
:standout="!isEdit",
|
|
:outlined="isEdit",
|
|
:mask="field?.inputMask",
|
|
:rule="[(val) => !personDataField.includes(field.key) ? checkPassportFields(val, field.rules) : field.rules(val)]",
|
|
:autogrow="field.key === 'issued_by_org'"
|
|
)
|
|
.icon-copy.my-auto.text-lg.label-field(
|
|
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 BaseInput from "@/components/base/BaseInput.vue";
|
|
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";
|
|
export default {
|
|
name: "DocumentsForm",
|
|
components: {
|
|
MedicalFormWrapper,
|
|
BaseInput,
|
|
BaseAvatar,
|
|
BaseModal,
|
|
BaseUploadPhoto,
|
|
TheNotificationProvider,
|
|
},
|
|
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.series
|
|
) {
|
|
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 (!this.approvedPassportData)
|
|
passportFormData.append(elem.name, elem.modelValue ?? "");
|
|
} else documentsFormData.append(elem.name, elem.modelValue ?? "");
|
|
});
|
|
if (!this.approvedPassportData)
|
|
this.checkChengePhoto("passport", "photo", passportFormData);
|
|
this.checkChengePhoto(
|
|
"insurance_number",
|
|
"photo_insurance_number",
|
|
documentsFormData
|
|
);
|
|
this.checkChengePhoto(
|
|
"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
|
|
request.push(
|
|
this.sendData(
|
|
`general/identity_document/${this.initialDocData.passport?.id}/update/`,
|
|
passportFormData
|
|
)
|
|
);
|
|
}
|
|
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();
|
|
});
|
|
}
|
|
});
|
|
},
|
|
checkChengePhoto(updatedObjId, field, formData) {
|
|
if (this.docData[updatedObjId][field]?.file)
|
|
formData.append(field, this.docData[updatedObjId][field]?.file[0]);
|
|
},
|
|
async sendData(url, body) {
|
|
return await fetchWrapper.post(url, body, "formData");
|
|
},
|
|
addErrorNotification(title, message) {
|
|
addNotification(title + message, title, message, "error", 5000);
|
|
},
|
|
},
|
|
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>
|