From 90ab7197a292e4a7f3eb42fd73ee545058cf78bb Mon Sep 17 00:00:00 2001 From: DwCay Date: Fri, 3 Mar 2023 18:24:34 +0300 Subject: [PATCH] =?UTF-8?q?WIP=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D1=83?= =?UTF-8?q?=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20=D1=81=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=B4=20=D0=BA=D0=B0=D1=80=D1=82=D1=8B,=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/base/BaseDetailInfo.vue | 22 +- src/components/base/BaseInput.vue | 2 +- .../components/MedicalCardWrapper.vue | 309 +++++++++++------- src/pages/medicalCard/utils/medicalConfig.js | 8 +- .../medicalCard/utils/wrapperMedicalCard.js | 210 ++++++++++-- 5 files changed, 384 insertions(+), 167 deletions(-) diff --git a/src/components/base/BaseDetailInfo.vue b/src/components/base/BaseDetailInfo.vue index 4d07f6f..b2fdccf 100644 --- a/src/components/base/BaseDetailInfo.vue +++ b/src/components/base/BaseDetailInfo.vue @@ -4,13 +4,13 @@ span.text-sm.font-semibold.whitespace-normal {{title}} .flex.gap-y-4.px-4.py-3( :style="{height: `${height}px`}" - v-if="!isNoData" + v-if="isNoData" :class="{'flex-col': !directionRow}" ) slot .section-add.flex.justify-center.items-center.cursor-pointer( :style="{height: `${height}px`}" - v-if="isNoData" + v-if="!isNoData" @click="openAddDoc" ) Добавить данные @@ -21,28 +21,26 @@ export default { props: { title: String, height: Number, - data: Object, + data: Array, directionRow: Boolean, }, data() { return { - isNoData: true, + isNoData: false, }; }, methods: { openAddDoc() { - this.isNoData = false; + this.isNoData = true; }, }, watch: { data() { - Object.values(this.data) - .map((el) => (el !== undefined && el !== null ? el : undefined)) - .forEach((el) => { - if (el !== undefined) { - this.isNoData = false; - } - }); + this.data.forEach((el) => { + if (el !== undefined) { + this.isNoData = true; + } + }); }, }, }; diff --git a/src/components/base/BaseInput.vue b/src/components/base/BaseInput.vue index d76d87e..0f95b13 100644 --- a/src/components/base/BaseInput.vue +++ b/src/components/base/BaseInput.vue @@ -68,7 +68,7 @@ export default { lazyRule: [Boolean, String], noErrorIcon: Boolean, itemAligned: Boolean, - modelValue: [String, Date], + modelValue: [String, Date, Number], placeholder: String, disabled: Boolean, label: String, diff --git a/src/pages/medicalCard/components/MedicalCardWrapper.vue b/src/pages/medicalCard/components/MedicalCardWrapper.vue index 0747d80..3a96bb5 100644 --- a/src/pages/medicalCard/components/MedicalCardWrapper.vue +++ b/src/pages/medicalCard/components/MedicalCardWrapper.vue @@ -7,90 +7,90 @@ base-detail-info( :title="configData.identity_document.title" :height="configData.identity_document.height" - :data="medicalDataInit.identity_document" + :data="defineEmptyData(configData.identity_document.fields)" ) base-detail-input( v-for="field in configData.identity_document.fields" :field="field" - :data="medicalDataInit.identity_document" + :data="medicalDataInit" :mask="field.mask" ) .flex.flex-col.gap-30px base-detail-info( :title="configData.registration_address.title" :height="configData.registration_address.height" - :data="medicalDataInit.registration_address" + :data="defineEmptyData(configData.registration_address.fields)" ) base-detail-input( v-for="field in configData.registration_address.fields" :field="field" - :data="medicalDataInit.registration_address" + :data="medicalDataInit" ) base-detail-info( :title="configData.temporary_address.title" :height="configData.temporary_address.height" - :data="medicalDataInit.temporary_address" + :data="defineEmptyData(configData.temporary_address.fields)" ) base-detail-input( v-for="field in configData.temporary_address.fields" :field="field" - :data="medicalDataInit.temporary_address" + :data="medicalDataInit" ) .flex.flex-col.gap-2 base-detail-info( :title="configData.snils.title" :height="configData.snils.height" - :data="medicalDataInit.snils" + :data="defineEmptyData(configData.snils.fields)" ) base-detail-input( v-for="field in configData.snils.fields" :field="field" - :data="medicalDataInit.snils" + :data="medicalDataInit" :mask="field.mask" ) base-detail-info( :title="configData.policy.title" :height="configData.policy.height" - :data="medicalDataInit.policy" + :data="defineEmptyData(configData.policy.fields)" ) base-detail-input( v-for="field in configData.policy.fields" :field="field" - :data="medicalDataInit.policy" + :data="medicalDataInit" :mask="field.mask" ) base-detail-info( :title="configData.policy_organization.title" :height="configData.policy_organization.height" - :data="medicalDataInit.policy_organization" + :data="defineEmptyData(configData.policy_organization.fields)" ) base-detail-input( v-for="field in configData.policy_organization.fields" :field="field" - :data="medicalDataInit.policy_organization" + :data="medicalDataInit" ) .flex.flex-col.gap-4 base-detail-info( :title="configData.additional.title" :height="configData.additional.height" - :data="medicalDataInit.additional" + :data="defineEmptyData(configData.additional.fields)" ) base-detail-input( v-for="field in configData.additional.fields" :field="field" - :data="medicalDataInit.additional" + :data="medicalDataInit" :mask="field.mask" ) base-detail-info( :title="configData.agreement_form.title" :height="configData.agreement_form.height" - :data="medicalDataInit.agreement_form" + :data="defineEmptyData(configData.agreement_form.fields)" direction-row ) base-detail-input( v-for="field in configData.agreement_form.fields" :field="field" - :data="medicalDataInit.agreement_form" + :data="medicalDataInit" ) .flex.flex-col(class="px-92px gap-y-60px") .flex.flex-col(class="gap-y-2.5") @@ -116,7 +116,12 @@ import BaseDetailInfo from "@/components/base/BaseDetailInfo.vue"; import { formulaDataMap } from "@/pages/medicalCard/utils/medicalConfig"; import { medicalDetailConfig } from "@/pages/medicalCard/utils/medicalConfig"; import { mobilityMap } from "@/pages/medicalCard/utils/medicalConfig"; -import { createEntryMedicalCard } from "@/pages/medicalCard/utils/wrapperMedicalCard"; +import { + getDentalEntiesValue, + requestUpdateMedicalCard, + requestCreateMedicalCard, + getRequestDataPerson, +} from "@/pages/medicalCard/utils/wrapperMedicalCard"; import { fetchWrapper } from "@/shared/fetchWrapper"; import BaseInput from "@/components/base/BaseInput.vue"; import ClientDetailInput from "@/pages/clients/components/ClientDetailInput.vue"; @@ -132,140 +137,195 @@ export default { }, data() { return { - medicalCardData: undefined, + personId: "", + identityDocumentId: "", + responseMedicalCardData: undefined, + responseMedicalDentalData: {}, numberCard: "", configData: medicalDetailConfig, medicalDataInit: { - identity_document: { - number_series: null, - issued_by_org: null, - issued_by_org_code: null, - issued_by_date: null, - }, - registration_address: { - registration_address: null, - }, - temporary_address: { - temporary_address: null, - }, - snils: { - insurance_number: null, - }, - policy: { - series: null, - number: null, - }, - policy_organization: { - policy_organization: null, - }, - additional: { - name_confidant: null, - phone_confidant: null, - benefit_code: null, - }, - agreement_form: { - agreement: null, - agreement_date: null, - }, + number_series: undefined, + issued_by_org: undefined, + issued_by_org_code: undefined, + issued_by_date: undefined, + registration_address: undefined, + temporary_address: undefined, + insurance_number: undefined, + policy_series: undefined, + policy_number: undefined, + policy_organization: undefined, + name_confidant: undefined, + phone_confidant: undefined, + benefit_code: undefined, + agreement: undefined, + agreement_date: undefined, }, dentalIndications: { - complaints: "", - allergic_history: "", - past_diseases: "", - medications_taken: "", - thermometry: "", - tonometry: "", - disease_progress: "", - visual_examination: "", - oral_examination: "", + complaints: undefined, + allergic: undefined, + past_diseases: undefined, + medications_taken: undefined, + thermometry: undefined, + tonometry: undefined, + disease_progress: undefined, + visual_examination: undefined, + oral_examination: undefined, dental_formula: formulaDataMap, - dental_bite: "", - hygiene_index: "", - dmf_index: "", - diagnostic_findings: "", - icd_code: "", - survey_plan: "", - survey_data: "", - clinical_diagnosis: "", - treatment_plan: "", - treatment_protocol: "", + dental_bite: undefined, + hygiene_index: undefined, + dmf_index: undefined, + diagnostic_findings: undefined, + icd_code: undefined, + survey_plan: undefined, + survey_data: undefined, + clinical_diagnosis: undefined, + treatment_plan: undefined, + treatment_protocol: undefined, }, }; }, methods: { + defineEmptyData(fields) { + return fields.map((field) => this.medicalDataInit[field.label]); + }, validateFormCard() { + const dataRequestPerson = getRequestDataPerson( + this.medicalDataInit, + this.dentalIndications + ); + Object.keys(dataRequestPerson).forEach((key) => { + let valuesData = [ + ...new Set( + Object.values(this.responseMedicalCardData[key]).map((el) => + el === null || el === undefined ? undefined : el + ) + ), + ]; + let isUpdateData = false; + let isCreateData = + valuesData.length === 1 && + valuesData[0] === undefined && + Object.values(dataRequestPerson[key]).find((el) => el !== undefined); + Object.keys(dataRequestPerson[key]).forEach((entries) => { + if ( + this.responseMedicalCardData[key][entries] && + dataRequestPerson[key][entries] !== + this.responseMedicalCardData[key][entries] + ) { + isUpdateData = true; + } + }); + if (isUpdateData) { + requestUpdateMedicalCard( + dataRequestPerson[key], + key, + key === "identity_document" + ? this.identityDocumentId + : this.personId + ); + } + if (isCreateData) { + requestCreateMedicalCard( + dataRequestPerson[key], + key, + key === "identity_document" + ? this.identityDocumentId + : this.personId + ); + } + }); Object.keys(this.dentalIndications).forEach((key) => { if (key === "dental_formula") { const notEmptyEntries = this.dentalIndications.dental_formula[0].columns .concat(this.dentalIndications.dental_formula[1].columns) .filter((el) => el.dental_condition && el.tooth_mobility); - createEntryMedicalCard( - notEmptyEntries, - key, - localStorage.getItem("medicalId") - ); + notEmptyEntries.forEach((tooth) => { + const toothResponse = this.responseMedicalDentalData[key].find( + (el) => el.tooth_number === tooth.tooth_number + ); + const isCreate = + !toothResponse && + !!tooth.tooth_mobility && + !!tooth.dental_condition; + if (isCreate) { + requestCreateMedicalCard( + tooth, + key, + localStorage.getItem("medicalId") + ); + } + if ( + toothResponse && + toothResponse.tooth_mobility.label !== + tooth.tooth_mobility.label && + toothResponse.dental_condition !== tooth.dental_condition + ) { + requestUpdateMedicalCard(tooth, key, toothResponse.id); + } + }); } - if (this.dentalIndications[key] && !this.medicalCardData[key].length) { - createEntryMedicalCard( + if ( + key !== "dental_formula" && + !this.responseMedicalDentalData[key] && + this.dentalIndications[key] + ) { + requestCreateMedicalCard( this.dentalIndications[key], key, localStorage.getItem("medicalId") ); } + if ( + key !== "dental_formula" && + this.dentalIndications[key] && + getDentalEntiesValue(this.responseMedicalDentalData[key], key) !== + this.dentalIndications[key] + ) { + requestUpdateMedicalCard( + this.dentalIndications[key], + key, + this.responseMedicalDentalData[key]?.id + ); + } }); }, saveDataMedical(data) { - this.medicalCardData = data; + this.personId = data?.person?.id; this.numberCard = data?.number; const confidant = data ? data["confidant"] : undefined; const pass = data ? data?.person?.identity_document?.find((el) => el.kind === "PASSPORT") : null; + this.identityDocumentId = pass?.id; this.medicalDataInit = { - ...data, - identity_document: { - ...pass, - number_series: `${pass.series} ${pass.number}`, - issued_by_date: new Date(pass.issued_by_date), - }, - registration_address: { - registration_address: data?.person?.address?.find( - (el) => !el["registration_flg"] - )?.join_adress, - }, - temporary_address: { - temporary_address: data?.person?.address?.find( - (el) => !el["temporary_registration_flg"] - )?.join_adress, - }, - snils: { - insurance_number: data?.person["insurance_number"], - }, - policy: { - ...this.medicalDataInit.policy, - ...data?.person["insurance_policy"][0], - }, - policy_organization: { - ...this.medicalDataInit.policy_organization, - ...data?.person["insurance_policy"][0], - }, - additional: { - name_confidant: confidant - ? `${confidant?.last_name} ${confidant?.last_name} ${confidant?.patronymic}` - : null, - phone_confidant: confidant?.contacts?.find( - (el) => el?.kind === "PHONE" - )?.username, - benefit_code: data?.benefit_code, - }, - agreement_form: { - agreement: data?.agreement, - agreement_date: null, - }, + ...this.medicalDataInit, + issued_by_org: pass.issued_by_org, + issued_by_org_code: pass.issued_by_org_code, + number_series: `${pass.series} ${pass.number}`, + issued_by_date: new Date(pass.issued_by_date), + registration_address: data?.person?.address?.find( + (el) => el["registration_flg"] + )?.join_address, + temporary_address: data?.person?.address?.find( + (el) => el["temporary_registration_flg"] + )?.join_address, + insurance_number: data?.person["insurance_number"] || undefined, + policy_number: data?.person["insurance_policy"][0]?.number, + policy_series: data?.person["insurance_policy"][0]?.series, + policy_organization: data?.person["insurance_policy"][0]?.organization, + name_confidant: + confidant && + `${confidant?.last_name} ${confidant?.last_name} ${confidant?.patronymic}`, + phone_confidant: confidant?.contacts?.find((el) => el?.kind === "PHONE") + ?.username, + benefit_code: data?.person?.benefit_code, + agreement: data?.agreement, + agreement_date: undefined, }; Object.keys(this.dentalIndications).forEach((key) => { if (key === "dental_formula" && data[key].length) { + this.responseMedicalDentalData[key] = data[key]; data[key].forEach((tooth) => { if (tooth.dental_condition && tooth.tooth_mobility) { if (17 < tooth.tooth_number < 29) { @@ -308,15 +368,20 @@ export default { }); } else { this.dentalIndications[key] = data[key]?.length - ? data[key] - .map((el) => { - let value = el.title || el["index_calculation"]; - return value || ""; - }) - .join("") + ? getDentalEntiesValue(data[key].at(-1), key) + : this.dentalIndications[key]; + this.dentalIndications.allergic = data?.person?.allergic + ? data?.person?.allergic + : this.dentalIndications.allergic; + this.responseMedicalDentalData[key] = data[key]?.length + ? data[key].at(-1) : this.dentalIndications[key]; } }); + this.responseMedicalCardData = getRequestDataPerson( + this.medicalDataInit, + this.dentalIndications + ); }, async fetchDataMedicalCard() { await fetchWrapper diff --git a/src/pages/medicalCard/utils/medicalConfig.js b/src/pages/medicalCard/utils/medicalConfig.js index 7b1f535..0651b97 100644 --- a/src/pages/medicalCard/utils/medicalConfig.js +++ b/src/pages/medicalCard/utils/medicalConfig.js @@ -92,13 +92,13 @@ export const medicalDetailConfig = { title: "ПОЛИС", fields: [ { - label: "series", + label: "policy_series", title: "Серия", type: "text", mask: "####", }, { - label: "number", + label: "policy_number", title: "Номер", type: "text", mask: "#######", @@ -110,7 +110,7 @@ export const medicalDetailConfig = { title: "Страховая организация", fields: [ { - label: "organization", + label: "policy_organization", title: "Название", type: "text", }, @@ -172,7 +172,7 @@ export const medicalDetailConfig = { }, dental_indications: { complaints: "Жалобы", - allergic_history: "Аллергологический анамнез", + allergic: "Аллергологический анамнез", past_diseases: "Перенесённые и сопутствующие заболевания", medications_taken: "Принимаемые лекарственные препараты", thermometry: "Термометрия (по показаниям)", diff --git a/src/pages/medicalCard/utils/wrapperMedicalCard.js b/src/pages/medicalCard/utils/wrapperMedicalCard.js index d13c1cf..ab6455a 100644 --- a/src/pages/medicalCard/utils/wrapperMedicalCard.js +++ b/src/pages/medicalCard/utils/wrapperMedicalCard.js @@ -1,6 +1,11 @@ import { fetchWrapper } from "@/shared/fetchWrapper"; -export async function createEntryMedicalCard(entry, key, id) { +import moment from "moment"; +export function requestCreateMedicalCard(entry, key, id) { const url = `medical_card/${key}/create/`; + let arrayValue; + if (["tonometry", "dental_bite", "dmf_index"].includes(key)) { + arrayValue = entry.split(","); + } switch (key) { case "complaints": case "medications_taken": @@ -12,7 +17,7 @@ export async function createEntryMedicalCard(entry, key, id) { case "treatment_protocol": return fetchWrapper.post(url, { title: entry, - description: "string", + description: entry, medical_history: id, }); case "thermometry": @@ -24,30 +29,23 @@ export async function createEntryMedicalCard(entry, key, id) { case "tonometry": return fetchWrapper.post(url, { title: entry, - sys: Number(entry), - dia: Number(entry), - pul: Number(entry), + sys: Number(arrayValue[0]), + dia: Number(arrayValue[1]), + pul: Number(arrayValue[2]), medical_history: id, }); case "dental_bite": return fetchWrapper.post(url, { - custom: entry, - physiological: entry, - abnormal: entry, - medical_history: id, - }); - case "hygiene_index": - return fetchWrapper.post(url, { - number_teeth: Number(entry), - dental_plaque: Number(entry), - calculus_plaque: Number(entry), + custom: arrayValue[0], + physiological: arrayValue[1], + abnormal: arrayValue[2], medical_history: id, }); case "dmf_index": return fetchWrapper.post(url, { - caries: Number(entry), - filling: Number(entry), - remote: Number(entry), + caries: Number(arrayValue[0]), + filling: Number(arrayValue[1]), + remote: Number(arrayValue[2]), medical_history: id, }); case "clinical_diagnosis": @@ -58,15 +56,171 @@ export async function createEntryMedicalCard(entry, key, id) { icd10: id, }); case "dental_formula": - return Promise.all( - entry.map((el) => - fetchWrapper.post(url, { - ...el, - tooth_mobility: el.tooth_mobility ? el.tooth_mobility.label : "", - tooth_number: el.tooth_number, - medical_history: id, - }) - ) - ); + return fetchWrapper.post(url, { + ...entry, + tooth_mobility: entry.tooth_mobility ? entry.tooth_mobility.label : "", + tooth_number: entry.tooth_number, + medical_history: id, + }); + case "registration_address": + return fetchWrapper.post(`general/address/create/`, { + ...entry, + person: id, + registration_flg: true, + }); + case "temporary_address": + return fetchWrapper.post(`general/address/create/`, { + ...entry, + person: id, + temporary_registration_flg: true, + }); + case "identity_document": + return fetchWrapper.post(`general/identity_document/create/`, { + ...entry, + person: id, + }); + case "insurance_policy": + return fetchWrapper.post(`general/insurance_policy/create/`, { + ...entry, + title: "string", + person: id, + }); + } +} + +export function requestUpdateMedicalCard(entry, key, id) { + const url = `medical_card/${key}/${id}/update/`; + let arrayValue; + if (["tonometry", "dental_bite", "dmf_index"].includes(key)) { + arrayValue = entry.split(","); + } + switch (key) { + case "complaints": + case "medications_taken": + case "disease_progress": + case "visual_examination": + case "diagnostic_findings": + case "survey_plan": + case "treatment_plan": + case "treatment_protocol": + return fetchWrapper.post(url, { + title: entry, + description: entry, + }); + case "thermometry": + return fetchWrapper.post(url, { + title: entry, + temperature: Number(entry), + }); + case "tonometry": + return fetchWrapper.post(url, { + title: entry, + sys: Number(arrayValue[0]), + dia: Number(arrayValue[1]), + pul: Number(arrayValue[2]), + }); + case "dental_bite": + return fetchWrapper.post(url, { + custom: entry, + physiological: entry, + abnormal: entry, + }); + case "dmf_index": + return fetchWrapper.post(url, { + caries: Number(entry), + filling: Number(entry), + remote: Number(entry), + }); + case "clinical_diagnosis": + return fetchWrapper.post(url, { + title: entry, + description: "string", + icd10: id, + }); + case "dental_formula": + return fetchWrapper.post(url, { + ...entry, + tooth_mobility: entry.tooth_mobility ? entry.tooth_mobility.label : "", + tooth_number: entry.tooth_number, + }); + case "registration_address": + return fetchWrapper.post(`general/address/${id}/update/`, { + ...entry, + registration_flg: true, + }); + case "temporary_address": + return fetchWrapper.post(`general/address/${id}/update/`, { + ...entry, + temporary_registration_flg: true, + }); + case "identity_document": + return fetchWrapper.post(`general/identity_document/${id}/update/`, { + ...entry, + }); + case "insurance_policy": + return fetchWrapper.post(`general/insurance_policy/${id}/update/`, { + ...entry, + title: "string", + }); + case "person": + return fetchWrapper.post(`general/person/${id}/update/`, { + ...entry, + }); + } +} + +export function getRequestDataPerson(person, dental) { + const dataPersonRequest = { + identity_document: { + issued_by_org: person.issued_by_org, + issued_by_org_code: person.issued_by_org_code, + issued_by_date: moment(person.issued_by_date).format("YYYY-MM-DD"), + number: person.number_series.split(" ")[1], + series: person.number_series.split(" ")[0], + }, + registration_address: { + full_address: person.registration_address, + }, + temporary_address: { + full_address: person.temporary_address, + }, + insurance_policy: { + series: person.policy_series, + number: person.policy_number, + organization: person.policy_organization, + }, + person: { + insurance_number: person.insurance_number, + benefit_code: person.benefit_code, + allergic: dental.allergic, + }, + agreement: { + agreement: person.agreement, + }, + }; + return dataPersonRequest; +} +export function getDentalEntiesValue(data, key) { + switch (key) { + case "complaints": + case "medications_taken": + case "disease_progress": + case "visual_examination": + case "diagnostic_findings": + case "survey_plan": + case "treatment_plan": + case "treatment_protocol": + case "clinical_diagnosis": + return data?.description; + case "thermometry": + return `${data?.temperature}`; + case "tonometry": + return `${data?.sys},${data?.dia},${data?.pul}`; + case "dental_bite": + return `${data?.custom},${data?.physiological},${data?.abnormal}`; + case "dmf_index": + return data["index_calculation"]; + case "hygiene_index": + return data["index_calculation"]; } }