+ prediction
This commit is contained in:
@@ -16,7 +16,7 @@ import {
|
|||||||
updateTransactionRequest,
|
updateTransactionRequest,
|
||||||
deleteTransactionRequest, getTransactions
|
deleteTransactionRequest, getTransactions
|
||||||
} from "@/services/transactionService";
|
} from "@/services/transactionService";
|
||||||
import {getCategories, getCategoryTypes} from "@/services/categoryService";
|
import {getCategories, getCategoriesPredict, getCategoryTypes} from "@/services/categoryService";
|
||||||
import {useToast} from "primevue/usetoast";
|
import {useToast} from "primevue/usetoast";
|
||||||
import LoadingView from "@/components/LoadingView.vue";
|
import LoadingView from "@/components/LoadingView.vue";
|
||||||
import BudgetTransactionView from "@/components/budgets/BudgetTransactionView.vue";
|
import BudgetTransactionView from "@/components/budgets/BudgetTransactionView.vue";
|
||||||
@@ -53,9 +53,13 @@ const categoryTypeChanged = () => {
|
|||||||
editedTransaction.value.category = selectedCategoryType.value.code == "EXPENSE" ? expenseCategories.value[0] : incomeCategories.value[0];
|
editedTransaction.value.category = selectedCategoryType.value.code == "EXPENSE" ? expenseCategories.value[0] : incomeCategories.value[0];
|
||||||
|
|
||||||
}
|
}
|
||||||
const selectCategory = (category) => {
|
|
||||||
|
const isSelectedFromPredict = ref<boolean>();
|
||||||
|
|
||||||
|
const selectCategory = (category, fromPredict: boolean) => {
|
||||||
isCategorySelectorOpened.value = false;
|
isCategorySelectorOpened.value = false;
|
||||||
editedTransaction.value.category = category;
|
editedTransaction.value.category = category;
|
||||||
|
isSelectedFromPredict.value = fromPredict;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -70,6 +74,7 @@ const selectedTransactionType = ref<TransactionType | null>(null);
|
|||||||
const selectedCategory = ref<Category | null>(null);
|
const selectedCategory = ref<Category | null>(null);
|
||||||
|
|
||||||
const entireCategories = ref<Category[]>([]);
|
const entireCategories = ref<Category[]>([]);
|
||||||
|
const predictedCategories = ref<Category[]>([]);
|
||||||
const expenseCategories = ref<Category[]>([]);
|
const expenseCategories = ref<Category[]>([]);
|
||||||
const incomeCategories = ref<Category[]>([]);
|
const incomeCategories = ref<Category[]>([]);
|
||||||
const categoryTypes = ref<CategoryType[]>([]);
|
const categoryTypes = ref<CategoryType[]>([]);
|
||||||
@@ -231,7 +236,18 @@ const createTransaction = async (): Promise<void> => {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const predictionsLoading = ref(false);
|
||||||
|
const anotherCategories = ref([]);
|
||||||
|
const fetchPredictions = async () => {
|
||||||
|
if (editedTransaction.value?.comment) {
|
||||||
|
predictedCategories.value = await getCategoriesPredict(editedTransaction.value?.comment);
|
||||||
|
} else {
|
||||||
|
predictedCategories.value = []
|
||||||
|
}
|
||||||
|
predictedCategories.value.forEach((predictedCategory) => {
|
||||||
|
anotherCategories.value.push(entireCategories.value.find(category => predictedCategory.id != category.id));
|
||||||
|
})
|
||||||
|
}
|
||||||
const transactionsUpdatedEmit = async () => {
|
const transactionsUpdatedEmit = async () => {
|
||||||
await getTransactions('INSTANT', 'EXPENSE', null, user.value.id, false, 3).then(transactionsResponse => transactions.value = transactionsResponse.data);
|
await getTransactions('INSTANT', 'EXPENSE', null, user.value.id, false, 3).then(transactionsResponse => transactions.value = transactionsResponse.data);
|
||||||
|
|
||||||
@@ -286,7 +302,7 @@ const deleteTransaction = async () => {
|
|||||||
|
|
||||||
// Сброс формы
|
// Сброс формы
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
|
predictedCategories.value = []
|
||||||
// editedTransaction.value.date = new Date();
|
// editedTransaction.value.date = new Date();
|
||||||
editedTransaction.value.amount = null;
|
editedTransaction.value.amount = null;
|
||||||
editedTransaction.value.comment = '';
|
editedTransaction.value.comment = '';
|
||||||
@@ -387,26 +403,7 @@ onMounted(async () => {
|
|||||||
aria-labelledby="basic"
|
aria-labelledby="basic"
|
||||||
@change="categoryTypeChanged" class="justify-center"/>
|
@change="categoryTypeChanged" class="justify-center"/>
|
||||||
</div>
|
</div>
|
||||||
<button class="border border-gray-300 rounded-lg w-full z-40"
|
|
||||||
@click="isCategorySelectorOpened = !isCategorySelectorOpened">
|
|
||||||
<div class="flex flex-row items-center pe-4 py-2 ">
|
|
||||||
<div class="flex flex-row justify-between w-full gap-4 px-4 items-center">
|
|
||||||
<p class="text-3xl font-bold text-gray-700 dark:text-gray-400">{{
|
|
||||||
editedTransaction.category.icon
|
|
||||||
}}</p>
|
|
||||||
<div class="flex flex-col items-start justify-items-start justify-around w-full">
|
|
||||||
<p class="font-bold text-start line-clamp-1">{{ editedTransaction.category.name }}</p>
|
|
||||||
<p class="font-light line-clamp-1 items-start text-start">{{
|
|
||||||
editedTransaction.category.description
|
|
||||||
}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span :class="{'rotate-90': isCategorySelectorOpened}"
|
|
||||||
class="pi pi-angle-right transition-transform duration-300 text-5xl"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Анимированное открытие списка категорий -->
|
<!-- Анимированное открытие списка категорий -->
|
||||||
@@ -417,7 +414,7 @@ onMounted(async () => {
|
|||||||
<button
|
<button
|
||||||
v-for="category in editedTransaction.category.type.code == 'EXPENSE' ? expenseCategories : incomeCategories"
|
v-for="category in editedTransaction.category.type.code == 'EXPENSE' ? expenseCategories : incomeCategories"
|
||||||
:key="category.id" class="border rounded-lg mx-2 mb-2"
|
:key="category.id" class="border rounded-lg mx-2 mb-2"
|
||||||
@click="selectCategory(category)">
|
@click="selectCategory(category, false)">
|
||||||
<div class="flex flex-row justify-between w-full px-2">
|
<div class="flex flex-row justify-between w-full px-2">
|
||||||
<p class="text-4xl font-bold text-gray-700 dark:text-gray-400">{{ category.icon }}</p>
|
<p class="text-4xl font-bold text-gray-700 dark:text-gray-400">{{ category.icon }}</p>
|
||||||
<div class="flex flex-col items-start justify-items-start justify-around w-full">
|
<div class="flex flex-col items-start justify-items-start justify-around w-full">
|
||||||
@@ -460,10 +457,57 @@ onMounted(async () => {
|
|||||||
v-model="editedTransaction.comment"
|
v-model="editedTransaction.comment"
|
||||||
@focus="keyboardOpen=true"
|
@focus="keyboardOpen=true"
|
||||||
@blur="keyboardOpen=false"
|
@blur="keyboardOpen=false"
|
||||||
|
@change="fetchPredictions"
|
||||||
/>
|
/>
|
||||||
</FloatLabel>
|
</FloatLabel>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-2">
|
||||||
|
|
||||||
|
<button v-for="category in predictedCategories" class="border-2 border-gray-300 rounded-lg w-full z-40"
|
||||||
|
:class="isSelectedFromPredict && editedTransaction.category.id == category.id ? 'border-5 border-emerald-400' : ''"
|
||||||
|
@click="selectCategory(category, true)">
|
||||||
|
<div class="flex flex-row items-center pe-4 py-2 ">
|
||||||
|
<div class="flex flex-row justify-between w-full gap-4 px-4 items-center">
|
||||||
|
<p class="text-3xl font-bold text-gray-700 dark:text-gray-400">{{
|
||||||
|
category.icon
|
||||||
|
}}</p>
|
||||||
|
<div class="flex flex-col items-start justify-items-start justify-around w-full">
|
||||||
|
<p class="font-bold text-start line-clamp-1">{{ category.name }}</p>
|
||||||
|
<p class="font-light line-clamp-1 items-start text-start">{{
|
||||||
|
category.description
|
||||||
|
}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span :class="{'rotate-90': isCategorySelectorOpened}"
|
||||||
|
class="pi pi-angle-right transition-transform duration-300 text-5xl"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<button v-if="predictedCategories.length>0"
|
||||||
|
:class="!isSelectedFromPredict ? 'border-5 border-emerald-400' : 'border-5 border-gray-300'"
|
||||||
|
class="border-2 rounded-lg w-full z-40 outline-2"
|
||||||
|
@click="isCategorySelectorOpened = !isCategorySelectorOpened">
|
||||||
|
<div class="flex flex-row items-center pe-4 py-2 ">
|
||||||
|
<div class="flex flex-row justify-between w-full gap-4 px-4 items-center">
|
||||||
|
<p class="text-3xl font-bold text-gray-700 dark:text-gray-400">{{
|
||||||
|
!isSelectedFromPredict ? editedTransaction.category.icon : anotherCategories[0].icon
|
||||||
|
}}</p>
|
||||||
|
<div class="flex flex-col items-start justify-items-start justify-around w-full">
|
||||||
|
<p class="font-bold text-start line-clamp-1">{{ !isSelectedFromPredict ? editedTransaction.category.name : anotherCategories[0].name }}</p>
|
||||||
|
<p class="font-light text-xs line-clamp-1 items-start text-start">Нажмите чтобы выбрать другую категорию</p>
|
||||||
|
<!-- <p class="font-light line-clamp-1 items-start text-start">Нажмите чтобы выбрать другую категорию</p>-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span :class="{'rotate-90': isCategorySelectorOpened}"
|
||||||
|
class="pi pi-angle-right transition-transform duration-300 text-5xl"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<!-- <span v-else >Введите комментарий и категории появится</span>-->
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Date Picker -->
|
<!-- Date Picker -->
|
||||||
<div class="field col-12 gap-0">
|
<div class="field col-12 gap-0">
|
||||||
|
|||||||
@@ -15,6 +15,16 @@ export const getCategories = async (type = null) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getCategoriesPredict = async (comment:string) => {
|
||||||
|
const spaceStore = await useSpaceStore();
|
||||||
|
return await apiClient.get(`/spaces/${spaceStore.space?.id}/category-predict?comment=${comment}&cloud=0`)
|
||||||
|
.then(res => res.data)
|
||||||
|
.catch(err => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export const getCategoryTypes = async () => {
|
export const getCategoryTypes = async () => {
|
||||||
const spaceStore = useSpaceStore();
|
const spaceStore = useSpaceStore();
|
||||||
return await apiClient.get(`/spaces/${spaceStore.space?.id}/categories/types`);
|
return await apiClient.get(`/spaces/${spaceStore.space?.id}/categories/types`);
|
||||||
@@ -42,7 +52,9 @@ export const deleteCategoryRequest = async (id: string) => {
|
|||||||
const spaceStore = useSpaceStore();
|
const spaceStore = useSpaceStore();
|
||||||
return await apiClient.delete(`/spaces/${spaceStore.space?.id}/categories/${id}`)
|
return await apiClient.delete(`/spaces/${spaceStore.space?.id}/categories/${id}`)
|
||||||
.then(res => res.data)
|
.then(res => res.data)
|
||||||
.catch(err => {throw err})
|
.catch(err => {
|
||||||
|
throw err
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getCategoriesSumsRequest = async (spaceId: string) => {
|
export const getCategoriesSumsRequest = async (spaceId: string) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user