WIP настроил сохранение данных аддреса, добавил блок детальной информации Документов

This commit is contained in:
DwCay
2022-11-03 20:03:21 +03:00
parent 0786baee42
commit 2a65bbdb2a
17 changed files with 115 additions and 116 deletions

14
package-lock.json generated
View File

@@ -9,6 +9,7 @@
"version": "0.1.0",
"dependencies": {
"moment": "^2.29.4",
"v-click-outside": "^3.2.0",
"vue": "^3.2.13",
"vue-router": "^4.1.5",
"vuex": "^4.0.2"
@@ -13201,6 +13202,14 @@
"uuid": "dist/bin/uuid"
}
},
"node_modules/v-click-outside": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/v-click-outside/-/v-click-outside-3.2.0.tgz",
"integrity": "sha512-QD0bDy38SHJXQBjgnllmkI/rbdiwmq9RC+/+pvrFjYJKTn8dtp7Penf9q1lLBta280fYG2q53mgLhQ+3l3z74w==",
"engines": {
"node": ">=6"
}
},
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -24242,6 +24251,11 @@
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true
},
"v-click-outside": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/v-click-outside/-/v-click-outside-3.2.0.tgz",
"integrity": "sha512-QD0bDy38SHJXQBjgnllmkI/rbdiwmq9RC+/+pvrFjYJKTn8dtp7Penf9q1lLBta280fYG2q53mgLhQ+3l3z74w=="
},
"validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",

View File

@@ -9,6 +9,7 @@
},
"dependencies": {
"moment": "^2.29.4",
"v-click-outside": "^3.2.0",
"vue": "^3.2.13",
"vue-router": "^4.1.5",
"vuex": "^4.0.2"

View File

@@ -1,12 +1,20 @@
<template lang="pug">
.header-wrapper.flex.justify-center.box-border.py-2.pl-4_75px.pr-6
.header-wrapper.relative.flex.justify-center.box-border.py-2.pl-4_75px.pr-6
base-client-form-create.right-6(v-if="isOpenCreate", @blure="isOpenCreate=false", :close-form="closeFormCreate")
.flex.items-center.box-border.cursor-pointer.mr-auto
img.logo-img.mr-29_25px(src="@/assets/images/logo.svg", alt="Logo")
header-inputs
//- .charge-person-container
//- header-active-client-panel(:info="chargePersonInfo")
.flex.ml-auto
base-button.mr-9(left-icon="icon-plus", :icon-left-size="10", :size="40", right-icon="icon-person", :icon-right-size="18")
base-button.mr-9(
left-icon="icon-plus",
:icon-left-size="10",
:size="40",
right-icon="icon-person",
:icon-right-size="18",
@click="isOpenCreate=true"
)
button.header-buttons.flex.justify-center.items-center.mr-8.p-0
.icon-bell.text-xxl
.flex.justify-centflexer.items-center
@@ -22,9 +30,10 @@ import chargePersonAvatar from "@/assets/images/charge-person-avatar.svg";
import HeaderInputs from "./HeaderInputs.vue";
import BaseAvatar from "@/components/base/BaseAvatar";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseClientFormCreate from "@/components/base/BaseClientFormCreate";
export default {
name: "TheHeader",
components: { HeaderInputs, BaseAvatar, BaseButton },
components: { HeaderInputs, BaseAvatar, BaseButton, BaseClientFormCreate },
data() {
return {
avatarSrc: img,
@@ -32,8 +41,14 @@ export default {
avatarSrc: chargePersonAvatar,
name: "Гордеев Николай Степанович",
},
isOpenCreate: false,
};
},
methods: {
closeFormCreate() {
this.isOpenCreate = false;
},
},
};
</script>

View File

@@ -1,5 +1,5 @@
<template lang="pug">
.wrapper-create.flex.flex-col.absolute.top-28.right-0.px-4.py-7.gap-y-8
.wrapper-create.flex.flex-col.absolute.top-28.px-4.py-7.gap-y-8
.icon-cancel.close.absolute.top-5.right-5.cursor-pointer(@click="closeForm")
span.title.text-xl.font-bold.px-4 Создание клиента
.flex.gap-x-4.h-fit.px-4
@@ -41,7 +41,7 @@ import BaseInput from "@/components/base/BaseInput";
import BaseSelect from "@/components/base/OldBaseSelect";
import BaseButton from "@/components/base/BaseButton";
export default {
name: "ClientsFormCreate",
name: "BaseClientFormClient",
components: {
BaseInput,
BaseSelect,
@@ -83,7 +83,6 @@ export default {
},
identity_document: {
pass: {
kind: "Паспорт",
series_number: "",
issued_by_org: "",
issued_by_date: "",
@@ -105,7 +104,7 @@ export default {
street: "",
house_number: "",
apartment_number: "",
index_of_address: "",
zip_code: "",
},
additional: [
{
@@ -162,12 +161,20 @@ export default {
},
methods: {
createIdentityDocument(id) {
Object.keys(
this.filterDataEmptyProperty(this.infoClient.identity_document.pass)
).length > 0 &&
fetchWrapper.post("general/identity_document/create/", {
...this.filterDataEmptyProperty(this.infoClient.identity_document.pass),
...this.filterDataEmptyProperty(
this.infoClient.identity_document.pass
),
person_id: id,
kind: "Паспорт",
});
},
createAddress(id) {
Object.keys(this.filterDataEmptyProperty(this.infoClient.addresses))
.length > 0 &&
fetchWrapper.post("general/address/create/", {
...this.filterDataEmptyProperty(this.infoClient.addresses),
person_id: id,
@@ -182,7 +189,6 @@ export default {
(el) => el.text === this.infoClient.basic.priority
).priority,
})
.then((res) => res.json())
.then((result) => {
this.createIdentityDocument(result.id);
this.createAddress(result.id);

View File

@@ -1,10 +1,10 @@
<template lang="pug">
.base-select(@click="open = !open", :class="{'open': open }")
.placeholder.text-base {{ itemsMap[value] || placeholder }}
.placeholder.text-base {{ value || placeholder }}
span.icon-down-arrow.open-icon(:class="{'open': open }")
base-menu(v-if="open")
.items-container(@click="open = false", @mouseleave="leaveSelect")
.item(v-for="item in items", :key="item.id" @click="clickItem(item.id)") {{ item.label }}
.item(v-for="item in items", :key="item.id" @click="clickItem(item.label)") {{ item.label }}
</template>
<script>
@@ -35,15 +35,6 @@ export default {
this.$emit("update:modelValue", value);
},
},
itemsMap() {
return this.items.reduce(
(acc, item) => ({
...acc,
[item.id]: item.label,
}),
{}
);
},
},
methods: {
clickItem(id) {

View File

@@ -2,6 +2,7 @@ import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import moment from "moment";
import vClickOutside from "v-click-outside";
import "./assets/sass/fonts.sass";
import "./assets/sass/tailwind.sass";
import "./assets/sass/variables.sass";
@@ -14,4 +15,4 @@ if (process.env.NODE_ENV === "development") {
moment.locale("ru");
createApp(App).use(router, moment).mount("#app");
createApp(App).use(router, vClickOutside, moment).mount("#app");

View File

@@ -15,17 +15,16 @@
.flex.flex-col(v-for="(item, key) in sectionInfo" class="gap-y-1.5")
span.title-section.font-semibold.text-xs(v-if="settings[section].options") {{settings[section].options[key]}}
span.title-section.font-semibold.text-xs(v-if="item.header") {{item.header}}
client-detail-input.text-sm.text-sm.w-max-fit(v-if="isChange" :style="{fontWeight:key === 'numba'&&600}" v-model:value="sectionInfo[key]" :width="settings[section].width")
client-detail-input.text-sm.text-sm.w-max-fit(v-if="section!=='docs' && isChange" :style="{fontWeight:key === 'numba'&&600}" v-model:value="sectionInfo[key]" :width="settings[section].width")
.copy.icon-copy.cursor-pointer(v-if="item.copy" @click="() => copyValue(item)")
.flex(v-if="settings[section].options && !isChange")
span.text-sm.w-fit(:style="{fontWeight:key === 'numba'&&600}") {{item}}
.copy.icon-copy.cursor-pointer.pl-4(v-if="key === 'numba'" @click="() => copyValue(item)")
.flex(v-if="item.value && !isChange")
span.text-sm.w-fit {{item.value}}
.flex.items-center(v-if="item.name")
.icon-cancel.cancel.cursor-pointer.pr-3.text-xsm(v-if="isChange" :id="item.name" @click="(e) => deleteDoc(e, section)")
.icon-files.cursor-pointer.pr-3.text-xl(:style="{color:settings.docsColor[item.type]}")
span.text-sm {{item.name}}
.flex(v-if="item.name && !isChange")
span.text-sm.w-fit {{item.title}}
.flex.items-center(v-if="item.title")
.icon-cancel.cancel.cursor-pointer.pr-3.text-xsm(v-if="isChange" :id="item.id" @click="(e) => deleteDoc(e)")
span.text-sm {{item.title}}
</template>
<script>

View File

@@ -1,8 +1,10 @@
<template lang="pug">
.w-full.h-fit.pt-4.flex.gap-x-4(class="px-[52px] pb-[30px]")
client-detail-info-section(v-model:section-info="dataDocument" section="pass")
.flex.flex-col.gap-y-2
.flex.flex-col
client-detail-info-section(:section-info="dataAddress" section="addresses")
.flex.flex-col
client-detail-info-section(:section-info="dataAttachments" section="docs" :save-new-doc="saveNewDoc" :delete-doc="deleteDoc")
</template>
<script>
@@ -13,6 +15,7 @@ export default {
props: {
dataDetail: Object,
dataAddress: Object,
dataAttachments: Array,
saveNewDoc: Function,
deleteDoc: Function,
dataDocument: Object,

View File

@@ -1,6 +1,6 @@
<template lang="pug">
.wrapper-table.relative.flex.flex-col.gap-y-8.px-6.py-6.h-full.w-full
clients-form-create(v-if="isOpenFormCreate" :close-form="closeFormCreateClient")
base-client-form-create.right-0(v-if="isOpenFormCreate" :close-form="closeFormCreateClient")
clients-table-hat(:is-open-actions="marked.length" :open-form-create="openFormCreateClient")
.flex.flex-col.h-full.gap-y-2.table-container
clients-table-header(:check="selectedCheck" :is-check="selectAll")
@@ -21,8 +21,8 @@ import ClientsTableHeader from "@/pages/clients/components/ClientsTableHeader";
import ClientsTableHat from "@/pages/clients/components/ClientsTableHat";
import ClientsTableRow from "@/pages/clients/components/ClientsTableRow";
import ClientsTableCheckbox from "@/pages/clients/components/ClientsTableCheckbox";
import ClientsFormCreate from "@/pages/clients/components/ClientsFormCreate";
import { fetchWrapper } from "@/shared/fetchWrapper";
import BaseClientFormCreate from "@/components/base/BaseClientFormCreate";
export default {
name: "ClientsTable",
components: {
@@ -30,7 +30,7 @@ export default {
ClientsTableRow,
ClientsTableHat,
ClientsTableHeader,
ClientsFormCreate,
BaseClientFormCreate,
},
data() {
return {

View File

@@ -14,7 +14,7 @@
.icon-ok.text-xsm(class="pt-[3px]")
.relative.dots-button.icon-dots.cursor-pointer.leading-6.text-center(v-show="!isOpenChange" :tabindex="1" @click="(e) => openPopup(e)" @blur="handleUnFocusPopup")
clients-action-popup(v-if="isOpenPopup" :open-change-data="openChangeData")
client-detail-info-wrapper(v-if="isOpenDetailInfo" :data-address="dataAddress" :data-detail="dataDetail" :data-document="dataIdentityDocument" :save-new-doc="saveNewDoc" :delete-doc="deleteDoc")
client-detail-info-wrapper(v-if="isOpenDetailInfo" :data-address="dataAddress" :data-detail="dataDetail" :data-attachments="dataAttachments" :data-document="dataIdentityDocument" :save-new-doc="saveNewDoc" :delete-doc="deleteDoc")
</template>
<script>
@@ -30,6 +30,7 @@ import ClientsActionPopup from "@/pages/clients/components/ClientsActionPopup";
import ClientsTableCheckbox from "@/pages/clients/components/ClientsTableCheckbox";
import ClientDetailInfoWrapper from "@/pages/clients/components/ClientDetailInfoWrapper";
import BaseButton from "@/components/base/BaseButton";
import { fetchWrapper } from "@/shared/fetchWrapper";
import { column } from "@/pages/clients/utils/tableConfig";
export default {
name: "ClientsTableRow",
@@ -51,10 +52,12 @@ export default {
return {
dataIdentityDocument: {},
dataAddress: {},
dataAttachments: [],
dataDetail: {},
isOpenDetailInfo: false,
isOpenPopup: false,
columnBody: column,
prioritySettings: column.find((el) => el.name === "priority"),
isOpenChange: false,
dataClient: {},
};
@@ -73,7 +76,9 @@ export default {
this.client.first_name || ""
} ${this.client.patronymic || ""}`,
age: this.client.birth_date || "",
priority: this.client.priority,
priority: this.prioritySettings.settings.find(
(el) => el.priority === this.client.priority
).text,
phone: {
id: this.client.contacts.find((el) => el.kind === "PHONE")?.id || "",
kind: "PHONE",
@@ -95,21 +100,11 @@ export default {
},
methods: {
postUpdateClient() {
fetch(
`http://45.84.227.122:8080/general/person/${this.client.id}/update/`,
{
method: "POST",
headers: {
Accept: "*/*",
"Content-Type": "application/json;charset=utf-8",
},
body: JSON.stringify({
fetchWrapper.post(`general/person/${this.client.id}/update/`, {
full_name: this.dataClient.fullName,
birth_date: this.dataClient.age,
priority: this.dataClient.priority,
}),
}
);
});
},
postContactsClient() {
let contacts = [...this.dataClient.contacts];
@@ -154,37 +149,21 @@ export default {
},
postCreateContact(contact) {
fetch("http://45.84.227.122:8080/general/contact/create/", {
method: "POST",
headers: {
Accept: "*/*",
"Content-Type": "application/json;charset=utf-8",
},
body: JSON.stringify({
fetchWrapper.post("general/contact/create/", {
kind: contact.kind,
username: contact.username,
person_id: this.client.id,
}),
});
},
postUpdateContact(contact) {
fetch(`http://45.84.227.122:8080/general/contact/${contact.id}/update/`, {
method: "POST",
headers: {
Accept: "*/*",
"Content-Type": "application/json;charset=utf-8",
},
body: JSON.stringify({
fetchWrapper.post(`general/contact/${contact.id}/update/`, {
kind: contact.kind,
username: contact.username,
person_id: this.client.id,
}),
});
},
postDeleteContact(contact) {
fetch(`http://45.84.227.122:8080/general/contact/${contact.id}/delete/`, {
method: "DELETE",
});
fetchWrapper.del(`general/contact/${contact.id}/delete/`);
},
addNetwork(network) {
this.dataClient.contacts.push(network);
@@ -208,14 +187,16 @@ export default {
this.isOpenChange = true;
},
fetchClientDetail(id) {
// eslint-disable-next-line
fetch(`http://45.84.227.122:8080/general/person/${id}/detail`).then((res) => res.json()).then((data) => this.saveClientDetail(data))
fetchWrapper
.get(`general/person/${id}/detail/`)
.then((data) => this.saveClientDetail(data));
},
saveClientDetail(data) {
this.saveIdentityDocument(
data.identity_documents.find((el) => el.kind === "Паспорт")
);
this.saveAddress(data.address[0]);
this.saveAttachments([...data.attachments]);
},
saveIdentityDocument(data) {
this.dataIdentityDocument = {
@@ -227,9 +208,12 @@ export default {
},
saveAddress(data) {
this.dataAddress = {
join_address: data?.join_address || "-",
join_adress: data?.join_adress || "-",
};
},
saveAttachments(data) {
this.dataAttachments = [...data];
},
openPopup(e) {
e.target.focus();
this.isOpenPopup = !this.isOpenPopup;
@@ -241,19 +225,12 @@ export default {
handleUnFocusPopup() {
this.isOpenPopup = false;
},
saveNewDoc(section, data) {
this.dataDetail[section] = [...this.dataDetail[section], ...data];
saveNewDoc(data) {
this.dataAttachments = [...this.dataDetail, ...data];
},
deleteDoc(e, section) {
if (section === "additional") {
this.dataDetail[section].forEach((el, index) => {
if (el.name === e.target.id) {
delete this.dataDetail[section][index].name;
}
});
}
this.dataDetail[section] = this.dataDetail[section].filter(
(el) => el.name !== e.target.id
deleteDoc(e) {
this.dataAttachments = this.dataAttachments.filter(
(el) => el.id !== e.target.id
);
},
},

View File

@@ -4,11 +4,10 @@
</template>
<script>
import ClientsFormCreate from "@/pages/clients/components/ClientsFormCreate";
import ClientsTable from "@/pages/clients/components/ClientsTable";
export default {
name: "ClientsWrapper",
components: { ClientsTable, ClientsFormCreate },
components: { ClientsTable },
data() {
return {
isOpenForm: false,

View File

@@ -25,7 +25,7 @@
base-input.input-info(v-model:value="addresses.apartment_number" placeholder="Номер квартиры")
.flex.flex-col(class="gap-y-1.5")
span.text-sm.font-semibold Индекс
base-input.input-info(v-model:value="addresses.index_of_address" placeholder="000000")
base-input.input-info(v-model:value="addresses.zip_code" placeholder="000000")
.px-4
base-button(@click="saveClient" :size="40")
span.font-semibold Создать клиента

View File

@@ -3,7 +3,7 @@
.grid.grid-cols-2.gap-x-4.gap-y-6.px-4
.flex.flex-col(class="gap-y-1.5")
span.text-sm Приоритет
base-select(:items="priorityList" placeholder="Приоритет клиента" v-model="basicInfo.priority")
base-select(:items="priorityList", placeholder="Приоритет клиента", v-model="basicInfo.priority")
.flex.flex-col(class="gap-y-1.5")
span.text-sm Дата рождения
span.obligatory *

View File

@@ -1,31 +1,25 @@
<template lang="pug">
.flex.box-border.px-4.items-center.w-full.gap-x-2(:style="{ minWidth : width + 'px' }")
.flex.gap-x-2.items-center(v-if="!isOpenChange")
.dot.w-2.h-2(:style="{ backgroundColor : settings.settings.find((el) => el.priority == value).color }")
span.text-sm(:style="{ color : settings.settings.find((el) => el.priority == value).color }") {{settings.settings.find((el) => el.priority == value).text}}
.flex.gap-x-2.text-sm
old-base-select(v-if="isOpenChange" :size-input="10" :option-data="getOption" :list-data="selectData" :style-border="true" :choose-option="choosePriority" disabled)
base-select(v-if="isOpenChange" :items="getPriorityList" v-model="getOption")
.dot.w-2.h-2(:style="{ backgroundColor : settings.settings.find((el) => el.text == value).color }")
span.text-sm(:style="{ color : settings.settings.find((el) => el.text == value).color }") {{value}}
.flex.gap-x-2.text-sm(class="w-[164px]")
base-select(v-if="isOpenChange", :items="getPriorityList", v-model="value")
</template>
<script>
import { column } from "@/pages/clients/utils/tableConfig";
import OldBaseSelect from "@/components/base/OldBaseSelect";
import BaseSelect from "@/components/base/BaseSelect";
export default {
name: "TableCellBodyPriority",
props: ["value", "width", "isOpenChange", "choosePriority"],
components: { OldBaseSelect, BaseSelect },
components: { BaseSelect },
data() {
return {
settings: column.find((el) => el.name === "priority"),
};
},
computed: {
getOption() {
return this.settings.settings.find((el) => el.priority == this.value)
.text;
},
getPriorityList() {
return this.settings.settings.map((el) => {
return { label: el.text, id: el.id };

View File

@@ -137,7 +137,7 @@ export const detail = {
addresses: {
title: "Адреса",
options: {
join_address: "Полный адрес",
join_adress: "Полный адрес",
},
width: 292,
},

View File

@@ -74,7 +74,6 @@ export default {
.then((result) => result.json())
.then((token) => {
localStorage.setItem("tokenAccess", token.access);
token.cookie("tokenRefresh", token.refresh, { httpOnly: true });
});
},
},

View File

@@ -1,6 +1,6 @@
function prepareUrl(url) {
if (url.startsWith("http")) return url;
return `http://45.84.227.122:8080/${url}`;
return `http://45.84.227.122:8080/api/${url}`;
}
function handleRequest(method, url, headers, attempts, body) {
@@ -63,7 +63,7 @@ function del(url, headers, attempts = 3) {
}
function post(url, body, headers, attempts = 3) {
return handleRequest("POST", url, headers, attempts, null, body);
return handleRequest("POST", url, headers, attempts, body);
}
function put(url, headers, body, attempts = 3) {