Merge branch '10-editing-blocks' into 'master'

Resolve "При нажатии не происходит перехода на мед.карту", "Редактирование основных данных на мед.карте"

Closes #10

See merge request astra/astra-frontend!503
This commit is contained in:
Kirill Andrusyak
2023-08-17 17:45:43 +00:00
7 changed files with 176 additions and 141 deletions

View File

@@ -33,14 +33,14 @@
size="M" size="M"
) )
base-input( base-input(
v-model="addresses.house_number", v-model="addresses.house",
label="Дом", label="Дом",
placeholder="Номер дома", placeholder="Номер дома",
disabled, disabled,
size="M" size="M"
) )
base-input( base-input(
v-model="addresses.apartment_number", v-model="addresses.flat",
label="Квартира", label="Квартира",
placeholder="Номер квартиры", placeholder="Номер квартиры",
disabled, disabled,

View File

@@ -24,7 +24,7 @@
.thumb.h-full.rounded(:style="thumbStyle") .thumb.h-full.rounded(:style="thumbStyle")
span.grey-color {{ medcardInfo?.filling_percentage || 0 }}% span.grey-color {{ medcardInfo?.filling_percentage || 0 }}%
.field(:style="{...headerStyle(headerConfig[6])}") .field(:style="{...headerStyle(headerConfig[6])}")
q-icon.medcard.cursor-pointer(name="app:medcard", size="20px") q-icon.medcard.cursor-pointer(name="app:medcard", size="20px", @click="openMedicalCard")
</template> </template>
<script> <script>
@@ -36,6 +36,7 @@ import * as moment from "moment/moment";
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider"; import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
import { addNotification } from "@/components/Notifications/notificationContext"; import { addNotification } from "@/components/Notifications/notificationContext";
import avatar from "@/assets/images/person.png"; import avatar from "@/assets/images/person.png";
import { mapActions } from "vuex";
export default { export default {
name: "MedicalCardSearchRow", name: "MedicalCardSearchRow",
components: { TheNotificationProvider }, components: { TheNotificationProvider },
@@ -72,6 +73,15 @@ export default {
}, },
}, },
methods: { methods: {
...mapActions({
getMedicalCardData: "getMedicalCardDataByPersonId",
}),
openMedicalCard() {
this.getMedicalCardData({
personId: this.medcardInfo.person_id,
successCallback: (id) => this.$router.push("medical-card/" + id),
});
},
convertDate(date) { convertDate(date) {
return moment(date)?.format("DD MMMM YYYY"); return moment(date)?.format("DD MMMM YYYY");
}, },

View File

@@ -4,7 +4,7 @@
:is-check-change="isCheckChange" :is-check-change="isCheckChange"
:is-loading-data="isLoadingData" :is-loading-data="isLoadingData"
:is-edit="isEdit" :is-edit="isEdit"
:save="saveChange" :save="updateBasicData"
:cancel="cancelEdit" :cancel="cancelEdit"
:open-edit="openEdit" :open-edit="openEdit"
) )
@@ -25,11 +25,11 @@
base-modal(v-model="showModal" title="Загрузить изображение") base-modal(v-model="showModal" title="Загрузить изображение")
base-upload-photo( base-upload-photo(
v-model="basic[data.dataKey][field.key]" v-model="basic[data.dataKey][field.key]"
:confirm-upload="confirmCahngeAvatar" :confirm-upload="confirmChangeAvatar"
) )
.select(v-else-if="field.type === 'select'") .select(v-else-if="field.type === 'select'")
base-select( base-select(
:readonly="!isEdit" readonly,
v-model="basic[data.dataKey][field.key]" v-model="basic[data.dataKey][field.key]"
@update:model-value="checkChangeInput" @update:model-value="checkChangeInput"
:hide-dropdown-icon="!isEdit" :hide-dropdown-icon="!isEdit"
@@ -43,13 +43,13 @@
v-else-if="field.type === 'date'", v-else-if="field.type === 'date'",
v-model="basic[data.dataKey][field.key]", v-model="basic[data.dataKey][field.key]",
size="M", size="M",
:readonly="!isEdit", readonly
@update:model-value="checkChangeInput", @update:model-value="checkChangeInput",
:width="302" :width="302"
) )
base-input( base-input(
v-else, v-else,
:readonly="!isEdit" :readonly="field.disabled || !this.isEdit"
v-model="basic[data.dataKey][field.key]" v-model="basic[data.dataKey][field.key]"
@update:model-value="checkChangeInput" @update:model-value="checkChangeInput"
:type="field.type" :type="field.type"
@@ -69,10 +69,7 @@ import MedicalFormWrapper from "@/pages/newMedicalCard/components/MedicalFormWra
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider.vue"; import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider.vue";
import { getFieldsNameUnvalidated } from "@/shared/utils/changesObjects"; import { getFieldsNameUnvalidated } from "@/shared/utils/changesObjects";
import { addNotification } from "@/components/Notifications/notificationContext"; import { addNotification } from "@/components/Notifications/notificationContext";
import { getRequestChangeData } from "@/shared/utils/wrapperRequestChangeData";
import { checkChangeData } from "@/shared/utils/changesObjects"; import { checkChangeData } from "@/shared/utils/changesObjects";
import { fetchWrapper } from "@/shared/fetchWrapper";
import moment from "moment";
import { import {
baseDataForm, baseDataForm,
genderOptions, genderOptions,
@@ -81,6 +78,8 @@ import {
import { mapGetters, mapState } from "vuex"; import { mapGetters, mapState } from "vuex";
import BaseInput from "@/components/base/BaseInput.vue"; import BaseInput from "@/components/base/BaseInput.vue";
import BaseInputDate from "@/components/base/BaseInputDate.vue"; import BaseInputDate from "@/components/base/BaseInputDate.vue";
import { mapActions } from "vuex";
import { removeEmptyFields } from "@/shared/utils/changesObjects";
export default { export default {
name: "BasicDataForm", name: "BasicDataForm",
@@ -115,13 +114,62 @@ export default {
basic: (state) => state.medical.basicData, basic: (state) => state.medical.basicData,
isNew: (state) => state.medical.medicalCard.type === "new", isNew: (state) => state.medical.medicalCard.type === "new",
medicalCard: (state) => state.medical.medicalCard, medicalCard: (state) => state.medical.medicalCard,
addresses: (state) => state.medical.medicalCard.person.addresses,
}), }),
}, },
methods: { methods: {
...mapActions({
createAddress: "postCreateAddress",
updateAddress: "postUpdateAddress",
}),
updateBasicData() {
const photoFormData = new FormData();
if (
this.basic.personalData.photo.file &&
this.basic.personalData.photo.photo !==
this.initDataBasic.personalData.photo.photo
) {
photoFormData.append("photo", this.basic.personalData?.photo?.file[0]);
console.log("photo_update");
}
Object.keys(this.basic).map((key) => {
if (key === "registrationAddress")
this.postAdresses(
this.basic.registrationAddress,
this.initDataBasic[key],
"REGISTRATION_ADDRESS"
);
if (key === "residenceAddress")
this.postAdresses(
this.basic.residenceAddress,
this.initDataBasic[key],
"CURRENT_ADDRESS"
);
});
this.isEdit = false;
},
postAdresses(updateData, initData, key) {
let isInitDataEmpty = [...Object.keys(removeEmptyFields(initData))]
.length;
if (Object.keys(removeEmptyFields(updateData)).length) {
if (!isInitDataEmpty)
return this.createAddress({
id: this.basic.personalData.id,
address: updateData,
category: key,
});
if (JSON.stringify(updateData) !== JSON.stringify(initData))
return this.updateAddress({
id: this.addresses.find(({ category }) => category === key).id,
address: updateData,
category: key,
});
}
},
checkChangeInput() { checkChangeInput() {
this.isCheckChange = checkChangeData(this.initDataBasic, this.basic); this.isCheckChange = checkChangeData(this.initDataBasic, this.basic);
}, },
confirmCahngeAvatar() { confirmChangeAvatar() {
this.showModal = false; this.showModal = false;
this.isCheckChange = true; this.isCheckChange = true;
}, },
@@ -130,89 +178,14 @@ export default {
this.isEdit = false; this.isEdit = false;
this.isCheckChange = false; this.isCheckChange = false;
}, },
updateBasicData() {
let registration = this.basic.registrationAddress;
let residence = this.basic.residenceAddress;
let personal = this.basic.personalData;
const personalFormData = new FormData();
personalFormData.append(
"full_name",
`${personal.last_name} ${personal.first_name} ${personal.patronymic}`
);
if (personal.birth_date) {
personalFormData.append(
"birth_date",
moment(personal.birth_date).format("YYYY-MM-DD")
);
}
if (personal.gender) {
personalFormData.append("gender", personal.gender?.id);
}
if (
personal.photo.file &&
personal.photo.photo !== this.initDataBasic.personalData.photo.photo
) {
personalFormData.append("photo", personal.photo.file[0]);
}
const request = Object.keys(this.basic).map((key) => {
if (key === "personalData") {
return fetchWrapper.post(
`general/person/${personal.id}/update/`,
personalFormData,
"formData"
);
}
if (key === "registrationAddress") {
let createRegistration = {
person: personal.id,
registration_flg: true,
...registration,
};
return getRequestChangeData(
createRegistration,
registration,
this.initDataBasic[key],
"address",
registration.id
);
}
if (key === "residenceAddress") {
let createResidence = {
person: personal.id,
residence_flg: true,
...residence,
};
return getRequestChangeData(
createResidence,
residence,
this.initDataBasic[key],
"address",
residence.id
);
}
});
return request;
},
saveChange() { saveChange() {
const form = this.$refs.formBasicData; const form = this.$refs.formBasicData;
form.validate().then((validate) => { form.validate().then((validate) => {
if (validate) { if (validate) {
let person = this.basic.personalData; this.updateBasicData();
this.$store.dispatch("setMedicalCardData", { this.isLoadingData = false;
...this.medicalCard, this.isEdit = false;
person: { this.isCheckChange = false;
...this.medicalCard.person,
...person,
},
});
//let updateBasic = this.updateBasicData();
// Promise.allSettled(updateBasic)
// .then(() => this.$store.dispatch("getMedicalCardData"))
// .then(() => {
// this.isLoadingData = false;
// this.isEdit = false;
// this.isCheckChange = false;
// });
} else { } else {
getFieldsNameUnvalidated(form).forEach((errorKey) => { getFieldsNameUnvalidated(form).forEach((errorKey) => {
addNotification( addNotification(

View File

@@ -74,9 +74,9 @@ import {
getFieldsNameUnvalidated, getFieldsNameUnvalidated,
} from "@/shared/utils/changesObjects"; } from "@/shared/utils/changesObjects";
import { contactsDataForm } from "@/pages/newMedicalCard/utils/medicalConfig"; import { contactsDataForm } from "@/pages/newMedicalCard/utils/medicalConfig";
import { getRequestArrayData } from "@/shared/utils/wrapperRequestChangeData";
import { mapState, mapGetters } from "vuex"; import { mapState, mapGetters } from "vuex";
import BaseInput from "@/components/base/BaseInput.vue"; import BaseInput from "@/components/base/BaseInput.vue";
import { mapActions } from "vuex";
export default { export default {
name: "ContactsForm", name: "ContactsForm",
@@ -106,13 +106,14 @@ export default {
}), }),
}, },
methods: { methods: {
...mapActions({
createContact: "postCreateContact",
updateContact: "postUpdateContact",
delContacts: "deleteContact",
}),
checkNetworksField(index) { checkNetworksField(index) {
if ( if (this.contacts.networks[index].kind)
this.contacts.networks[index].kind &&
this.contacts.networks[index].username
) {
this.contacts.networks[index].filled = true; this.contacts.networks[index].filled = true;
}
}, },
openEdit() { openEdit() {
this.isEdit = true; this.isEdit = true;
@@ -123,35 +124,46 @@ export default {
this.isCheckChange = false; this.isCheckChange = false;
}, },
updateContacts() { updateContacts() {
this.isLoadingData = true;
const allNewContacts = [ const allNewContacts = [
...this.contacts.phones, ...this.contacts.phones,
...this.contacts.emails, ...this.contacts.emails,
...this.contacts.networks, ...this.contacts.networks,
]; ];
const notEmptyContacts = allNewContacts.filter( const notEmptyContacts = allNewContacts.filter((el) => !el.id);
(el) => el.kind && el.username return this.changeContacts(this.initAllContacts, notEmptyContacts);
); },
return getRequestArrayData( changeContacts(initData, notEmptyContacts) {
this.initAllContacts, const deleteRequests = initData
notEmptyContacts, .filter((el) => !notEmptyContacts.find((data) => data.id === el.id))
"person", .map((el) => this.delContacts({ id: el.id }));
this.personId, const requests = notEmptyContacts.map((el) => {
"general", const requestObj = {
"contact" category: el.category || el.kind,
); value: el.value,
};
delete requestObj.id;
if (!el?.id)
return this.createContact({ obj: requestObj, id: this.personId });
if (
el?.id &&
checkChangeData(
initData.find((obj) => obj.id === el.id),
el
)
)
return this.updateContact({ obj: requestObj, id: el.id });
});
return requests.concat(deleteRequests);
}, },
saveChange() { saveChange() {
const form = this.$refs.formContacts; const form = this.$refs.formContacts;
form.validate().then((validate) => { form.validate().then((validate) => {
if (validate) { if (validate) {
this.isLoadingData = true; this.updateContacts();
Promise.allSettled(this.updateContacts())
.then(() => this.$store.dispatch("getMedicalCardData"))
.then(() => {
this.isLoadingData = false; this.isLoadingData = false;
this.isEdit = false; this.isEdit = false;
this.isCheckChange = false; this.isCheckChange = false;
});
} else { } else {
getFieldsNameUnvalidated(form).forEach((errorKey) => { getFieldsNameUnvalidated(form).forEach((errorKey) => {
addNotification( addNotification(
@@ -180,19 +192,17 @@ export default {
this.contacts[key].push({ this.contacts[key].push({
filled: false, filled: false,
kind: this.configData[key]?.kind, kind: this.configData[key]?.kind,
username: null,
}); });
} else { } else {
this.contacts[key].push({ this.contacts[key].push({
kind: this.configData[key]?.kind, kind: this.configData[key]?.kind,
username: null,
}); });
} }
} }
this.checkChangeInput(); this.checkChangeInput();
}, },
deleteContact(key, index) { deleteContact(key, index) {
this.contacts[key].splice(index, 1); this.contacts[key]?.splice(index, 1);
this.checkChangeInput(); this.checkChangeInput();
}, },
copyLinkNetwork(value) { copyLinkNetwork(value) {

View File

@@ -19,31 +19,37 @@ export const baseDataForm = [
key: "last_name", key: "last_name",
label: "Фамилия", label: "Фамилия",
type: "text", type: "text",
disabled: true,
}, },
{ {
key: "first_name", key: "first_name",
label: "Имя", label: "Имя",
type: "text", type: "text",
disabled: true,
}, },
{ {
key: "patronymic", key: "patronymic",
label: "Отчество", label: "Отчество",
type: "text", type: "text",
disabled: true,
}, },
{ {
key: "gender", key: "gender",
label: "Пол", label: "Пол",
type: "select", type: "select",
disabled: true,
}, },
{ {
key: "birth_date", key: "birth_date",
label: "Дата рождения", label: "Дата рождения",
type: "date", type: "date",
disabled: true,
}, },
{ {
key: "photo", key: "photo",
label: "Фото", label: "Фото",
type: "avatar", type: "avatar",
disabled: true,
}, },
], ],
}, },
@@ -55,27 +61,33 @@ export const baseDataForm = [
key: "region", key: "region",
label: "Регион", label: "Регион",
type: "text", type: "text",
rules: [(val) => ruleNotValue(val)],
error: "Поле 'Регион' должны быть заполнены",
}, },
{ {
key: "city", key: "city",
label: "Город", label: "Город",
type: "text", type: "text",
rules: [(val) => ruleNotValue(val)],
error: "Поле 'Город' должны быть заполнены",
}, },
{ {
key: "street", key: "street",
label: "Улица", label: "Улица",
type: "text", type: "text",
rules: [(val) => ruleNotValue(val)],
error: "Поле 'Улица' должны быть заполнены",
}, },
{ {
key: "house_number", key: "house",
label: "Дом", label: "Дом",
type: "text", type: "text",
rules: [(val) => !/^[\W0]/.test(val)], rules: [(val) => ruleNotValue(val)],
error: error:
"Номер дома должен начинатся не с нуля и только с цифробуквенного символа", "Номер дома должен начинатся не с нуля и только с цифробуквенного символа",
}, },
{ {
key: "apartment_number", key: "flat",
label: "Квартира", label: "Квартира",
type: "text", type: "text",
rules: [(val) => !/^[\W0]/.test(val)], rules: [(val) => !/^[\W0]/.test(val)],
@@ -104,7 +116,7 @@ export const baseDataForm = [
type: "text", type: "text",
}, },
{ {
key: "house_number", key: "house",
label: "Дом", label: "Дом",
type: "text", type: "text",
rules: [(val) => !/^[\W0]/.test(val)], rules: [(val) => !/^[\W0]/.test(val)],
@@ -112,7 +124,7 @@ export const baseDataForm = [
"Номер дома должен начинатся не с нуля и только с цифробуквенного символа", "Номер дома должен начинатся не с нуля и только с цифробуквенного символа",
}, },
{ {
key: "apartment_number", key: "flat",
label: "Квартира", label: "Квартира",
type: "text", type: "text",
rules: [(val) => !/^[\W0]/.test(val)], rules: [(val) => !/^[\W0]/.test(val)],
@@ -124,12 +136,12 @@ export const baseDataForm = [
]; ];
export const errorMap = { export const errorMap = {
house_number: { house: {
title: "Дом", title: "Дом",
error: error:
"Номер дома должен начинатся не с нуля и только с цифробуквенного символа", "Номер дома должен начинатся не с нуля и только с цифробуквенного символа",
}, },
apartment_number: { flat: {
title: "Квартира", title: "Квартира",
error: error:
"Номер квартиры должен начинатся не с нуля и только с цифробуквенного символа", "Номер квартиры должен начинатся не с нуля и только с цифробуквенного символа",

View File

@@ -45,7 +45,7 @@ function request(method, url, headers = {}, body, type = "") {
requestOptions.body = JSON.stringify(body); requestOptions.body = JSON.stringify(body);
} }
} }
if (method === "POST" || method === "PUT") { if (method === "POST" || method === "PUT" || method === "PATCH") {
if (type && type === "formData") { if (type && type === "formData") {
requestOptions = { requestOptions = {
method: method, method: method,
@@ -83,6 +83,10 @@ function post(url, body, type, headers, attempts = 3) {
return handleRequest("POST", url, headers, attempts, body, type); return handleRequest("POST", url, headers, attempts, body, type);
} }
function patch(url, body, type, headers, attempts = 3) {
return handleRequest("PATCH", url, headers, attempts, body, type);
}
function put(url, headers, body, attempts = 3) { function put(url, headers, body, attempts = 3) {
return handleRequest("PUT", url, headers, attempts, null, body); return handleRequest("PUT", url, headers, attempts, null, body);
} }
@@ -92,4 +96,5 @@ export const fetchWrapper = {
del, del,
post, post,
put, put,
patch,
}; };

View File

@@ -24,15 +24,15 @@ const state = () => ({
region: null, region: null,
city: null, city: null,
street: null, street: null,
house_number: null, house: null,
apartment_number: null, flat: null,
}, },
residenceAddress: { residenceAddress: {
region: null, region: null,
city: null, city: null,
street: null, street: null,
house_number: null, house: null,
apartment_number: null, flat: null,
}, },
insuranceDMS: { insuranceDMS: {
series: null, series: null,
@@ -134,10 +134,13 @@ const state = () => ({
const getters = { const getters = {
getBasicData(state, rootState) { getBasicData(state, rootState) {
let registrationAddress = let registrationAddress =
state.medicalCard?.person?.address?.find((el) => el.registration_flg) || state.medicalCard?.person?.addresses?.find(
{}; (el) => el.category === "REGISTRATION_ADDRESS"
) || {};
let residenceAddress = let residenceAddress =
state?.medicalCard?.person?.address?.find((el) => el.residence_flg) || {}; state?.medicalCard?.person?.addresses?.find(
(el) => el.category === "CURRENT_ADDRESS"
) || {};
let person = state.medicalCard.person; let person = state.medicalCard.person;
let OMS = person?.insurance_policy?.find((e) => e.title === "OMS"); let OMS = person?.insurance_policy?.find((e) => e.title === "OMS");
let DMS = person?.insurance_policy?.find((e) => e.title === "DMS"); let DMS = person?.insurance_policy?.find((e) => e.title === "DMS");
@@ -163,17 +166,15 @@ const getters = {
region: registrationAddress?.region || "", region: registrationAddress?.region || "",
city: registrationAddress?.city || "", city: registrationAddress?.city || "",
street: registrationAddress?.street || "", street: registrationAddress?.street || "",
house_number: registrationAddress?.house_number || "", house: registrationAddress?.house || "",
apartment_number: registrationAddress?.apartment_number || "", flat: registrationAddress?.flat || "",
id: registrationAddress?.id || "",
}, },
residenceAddress: { residenceAddress: {
region: residenceAddress?.region || "", region: residenceAddress?.region || "",
city: residenceAddress?.city || "", city: residenceAddress?.city || "",
street: residenceAddress?.street || "", street: residenceAddress?.street || "",
house_number: residenceAddress?.house_number || "", house: residenceAddress?.house || "",
apartment_number: residenceAddress?.apartment_number || "", flat: residenceAddress?.flat || "",
id: residenceAddress?.id || "",
}, },
insuranceDMS: { insuranceDMS: {
series: DMS?.series, series: DMS?.series,
@@ -259,7 +260,6 @@ const getters = {
state.medicalCard?.person?.contacts state.medicalCard?.person?.contacts
?.filter((el) => el.category === "PHONE") ?.filter((el) => el.category === "PHONE")
?.map((el) => { ?.map((el) => {
el.value = el.value.length > 10 ? el.value.slice(1) : el.value;
return { ...el }; return { ...el };
}) || []; }) || [];
let emails = let emails =
@@ -429,6 +429,31 @@ const getters = {
}; };
const actions = { const actions = {
postCreateAddress(context, { id, address, category }) {
fetchWrapper.post(`address`, {
person_id: id,
...address,
category: category,
});
},
postUpdateAddress(context, { id, address, category }) {
fetchWrapper.patch(`address/${id}`, {
...address,
category: category,
});
},
postCreateContact(context, { obj, id }) {
fetchWrapper.post("contacts", {
person_id: id,
...obj,
});
},
postUpdateContact(context, { obj, id }) {
fetchWrapper.patch(`contacts/${id}`, obj);
},
deleteContact(context, { id }) {
fetchWrapper.del(`contacts/${id}`);
},
deleteItemData({ commit }, props) { deleteItemData({ commit }, props) {
commit("setDataWithouDeleted", props); commit("setDataWithouDeleted", props);
}, },