-
-
-
-
-
-
diff --git a/src/main.ts b/src/main.ts
index abb382a..208f1de 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -10,11 +10,13 @@ import Ripple from "primevue/ripple";
import ToastService from 'primevue/toastservice'
import Tooltip from 'primevue/tooltip';
import { createPinia } from 'pinia';
+import ConfirmationService from 'primevue/confirmationservice';
const app = createApp(App);
app.use(router);
app.use(ToastService);
+app.use(ConfirmationService);
app.use(createPinia())
app.directive('ripple', Ripple);
app.directive('tooltip', Tooltip);
@@ -24,6 +26,7 @@ app.use(PrimeVue, {
}
});
+
app.config.globalProperties.$primevue.config.locale = {
firstDayOfWeek: 1, // Устанавливаем понедельник как первый день недели
dayNames: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"],
diff --git a/src/models/Budget.ts b/src/models/Budget.ts
index af601fe..dfcfb37 100644
--- a/src/models/Budget.ts
+++ b/src/models/Budget.ts
@@ -1,20 +1,27 @@
import {Transaction} from "@/models/Transaction";
-import {Category, CategorySetting} from "@/models/Category";
+import {Category} from "@/models/Category";
-export class BudgetInfo {
- budget: Budget
+export class Budget {
+ id: number
+ name: string
+ dateFrom: Date
+ dateTo: Date
+ createdAt: Date
plannedExpenses: [Transaction]
plannedIncomes: [Transaction]
+ categories: [BudgetCategory]
transactions: [Transaction]
- transactionCategoriesSums: []
- totalIncomes: number
- totalExpenses: number
- chartData: [[]]
- unplannedCategories: [BudgetCategory]
+ warns: [Warn]
}
-export class Budget {
+export class Warn {
+ id: string
+ severity: string
+ message: string
+}
+
+export class BudgetInfo {
id: number
name: string
dateFrom: Date
@@ -23,6 +30,8 @@ export class Budget {
}
export class BudgetCategory {
- category: Category;
- categorySetting: CategorySetting
+ category: Category
+ currentSpent: BigDecimal // отображает сумму потраченных на данный момент средств по категории
+ currentLimit: BigDecimal // отображает текущий лимит по категории
+ currentPlanned: BigDecimal // отображает текущую сумму запланированных расходов по категории
}
diff --git a/src/models/Transaction.ts b/src/models/Transaction.ts
index e0a436d..36ae3bc 100644
--- a/src/models/Transaction.ts
+++ b/src/models/Transaction.ts
@@ -1,23 +1,24 @@
import {Category} from "@/models/Category";
+import {User} from "@/models/User";
export class Transaction {
- id: number;
- transactionType: TransactionType;
+ id: String;
+ type: TransactionType;
+ user: User
category: Category;
comment: string;
date: Date;
amount: number
+ parentId: String
isDone: boolean;
}
-export class TransactionCategoriesSum{
+export class TransactionCategoriesSum {
category: Category;
sum: number
}
-
-
export class TransactionType {
code: string;
name: string;
diff --git a/src/services/axiosSetup.ts b/src/services/axiosSetup.ts
index 1bedd16..f3beb50 100644
--- a/src/services/axiosSetup.ts
+++ b/src/services/axiosSetup.ts
@@ -4,8 +4,8 @@ import { useRouter } from 'vue-router';
// Создаем экземпляр axios
const api = axios.create({
- baseURL: 'https://luminic.space/api/v1',
- // baseURL: 'http://localhost:8000/api/v1',
+ baseURL: 'https://luminic.space/api/',
+ // baseURL: 'http://localhost:8082/api',
});
// Устанавливаем токен из localStorage при каждом запуске
@@ -19,7 +19,7 @@ api.interceptors.response.use(
(response) => response,
(error) => {
- if (error.response && error.response.status === 401) {
+ if (error.response && error.response.status === 403) {
localStorage.removeItem('token');
const router = useRouter();
router.push('/login');
diff --git a/src/services/budgetsService.ts b/src/services/budgetsService.ts
index 5c61f9a..7d3b8a6 100644
--- a/src/services/budgetsService.ts
+++ b/src/services/budgetsService.ts
@@ -4,25 +4,32 @@ import {format} from "date-fns";
// Импортируете настроенный экземпляр axios
export const getBudgetInfos = async () => {
+ try {
- let response = await apiClient.get('/budgets/');
+
+ let response = await apiClient.get('/budgets');
let budgetInfos = response.data;
budgetInfos.forEach((budgetInfo: Budget) => {
budgetInfo.dateFrom = new Date(budgetInfo.dateFrom);
budgetInfo.dateTo = new Date(budgetInfo.dateTo);
- // budgetInfo.plannedExpenses.forEach(e => {
- // e.date = new Date(e.date)
- // })
- //
- // budgetInfo.plannedIncomes.forEach(e => {
- // e.date = new Date(e.date)
- // })
- //
- // budgetInfo.transactions.forEach(e => {
- // e.date = new Date(e.date)
- // })
+ budgetInfo.plannedExpenses?.forEach(e => {
+ e.date = new Date(e.date)
+ })
+
+ budgetInfo.plannedIncomes?.forEach(e => {
+ e.date = new Date(e.date)
+ })
+
+ budgetInfo.transactions?.forEach(e => {
+ e.date = new Date(e.date)
+ })
})
return budgetInfos
+ } catch (e) {
+ console.log(e)
+ throw e
+
+ }
}
export const getBudgetTransactions = async (budgetId, transactionType, categoryType) => {
@@ -66,18 +73,50 @@ export const getBudgetInfo = async (budget_id: number) => {
};
+
+export const getWarns = async (budgetId: string, hidden: Boolean = null) => {
+ let url = `/budgets/${budgetId}/warns`
+ if (hidden) {
+ url += `?hidden=${hidden}`
+ }
+ let warns = await apiClient.get(url);
+ return warns.data
+}
+
+export const hideWarnRequest = async (budgetId: string, warnId: string) => {
+ await apiClient.post(`/budgets/${budgetId}/warns/${warnId}/hide`);
+}
+
export const updateBudgetCategoryRequest = async (budget_id, category: BudgetCategory) => {
- await apiClient.put('/budgets/' + budget_id + '/category', category);
+ return await apiClient.post('/budgets/' + budget_id + '/categories/' + category.category.id + "/limit", {"limit": category.currentLimit}).then(i => i.data);
}
export const createBudget = async (budget: Budget, createRecurrent: Boolean) => {
- budget.dateFrom = format(budget.dateFrom, 'yyyy-MM-dd')
- budget.dateTo = format(budget.dateTo, 'yyyy-MM-dd')
- let data = {
- budget: budget,
- createRecurrent: createRecurrent
+
+ try {
+
+ let budgetToCreate = JSON.parse(JSON.stringify(budget));
+ budgetToCreate.dateFrom = format(budget.dateFrom, 'yyyy-MM-dd')
+ budgetToCreate.dateTo = format(budget.dateTo, 'yyyy-MM-dd')
+ let data = {
+ budget: budgetToCreate,
+ createRecurrent: createRecurrent
+ }
+ await apiClient.post('/budgets/', data);
+
+ } catch (e){
+ console.error(e)
+ throw e
+ }
+}
+
+
+export const deleteBudgetRequest = async (budgetId: string) => {
+ try {
+ // throw Error("test")
+ let response = await apiClient.delete(`/budgets/${budgetId}`);
+ } catch (error) {
+ console.log(error);
+ throw error;
}
- await apiClient.post('/budgets', data);
- budget.dateFrom = format(budget.dateFrom, 'dd.mm.yy')
- budget.dateTo = format(budget.dateTo, 'dd.mm.yy')
}
\ No newline at end of file
diff --git a/src/services/categoryService.ts b/src/services/categoryService.ts
index f75d7e4..be055fa 100644
--- a/src/services/categoryService.ts
+++ b/src/services/categoryService.ts
@@ -5,7 +5,7 @@ import {Category} from "@/models/Category"; // Импортируете нас
export const getCategories = async (type = null) => {
type = type ? type : ''
- return await apiClient.get('/categories/?type=' + type);
+ return await apiClient.get('/categories?type=' + type);
};
export const getCategoryTypes = async () => {
diff --git a/src/services/transactionService.ts b/src/services/transactionService.ts
index da7c97d..b747531 100644
--- a/src/services/transactionService.ts
+++ b/src/services/transactionService.ts
@@ -7,9 +7,10 @@ export const getTransaction = async (transactionId: int) => {
return await apiClient.post(`/transactions/${transactionId}`,);
}
-export const getTransactions = async (transaction_type = null, category_type = null, category_id = null, user_id = null, limit = null, offset = null) => {
+export const getTransactions = async (transaction_type = null, category_type = null, category_id = null, user_id = null, is_child = null, limit = null, offset = null) => {
const params = {};
+ console.log(is_child)
// Add the parameters to the params object if they are not null
if (transaction_type) {
params.transaction_type = transaction_type;
@@ -25,6 +26,9 @@ export const getTransactions = async (transaction_type = null, category_type = n
if (user_id) {
params.user_id = user_id
}
+ if (is_child!=null){
+ params.is_child = is_child
+ }
if (limit) {
params.limit = limit
}
@@ -33,22 +37,25 @@ export const getTransactions = async (transaction_type = null, category_type = n
}
// Use axios to make the GET request, passing the params as the second argument
- return await apiClient.get('/transactions/', {
+ return await apiClient.get('/transactions', {
params: params
});
}
export const createTransactionRequest = async (transaction: Transaction) => {
transaction.date = format(transaction.date, 'yyyy-MM-dd')
- let transactionResponse = await apiClient.post('/transactions', transaction);
- console.log(transaction.date)
+ let transactionResponse = await apiClient.post('/transactions', transaction);
+
transaction.date = new Date(transaction.date);
return transactionResponse.data
};
export const updateTransactionRequest = async (transaction: Transaction) => {
const id = transaction.id
- transaction.date = format(transaction.date, 'yyyy-MM-dd')
+ // console.log(transaction.isDone)
+ // transaction.date = transaction.date.setHours(0,0,0,0)
+ transaction.date = format(transaction.date, "yyyy-MM-dd")
+
const response = await apiClient.put(`/transactions/${id}`, transaction);
transaction = response.data
transaction.date = new Date(transaction.date);
@@ -56,15 +63,15 @@ export const updateTransactionRequest = async (transaction: Transaction) => {
return transaction
};
-export const setTransactionDoneRequest = async (transaction: Transaction) => {
- const id = transaction.id
- // transaction.date = format(transaction.date, 'yyyy-MM-dd')
- const response = await apiClient.put(`/transactions/${id}/done`, transaction);
- transaction = response.data
- transaction.date = new Date(transaction.date);
-
- return transaction
-};
+// export const setTransactionDoneRequest = async (transaction: Transaction) => {
+// const id = transaction.id
+// // transaction.date = format(transaction.date, 'yyyy-MM-dd')
+// const response = await apiClient.patch(`/transactions/${id}/set-done`, transaction);
+// // transaction = response.data
+// // transaction.date = new Date(transaction.date);
+//
+// // return transaction
+// };
export const deleteTransactionRequest = async (id: number) => {
return await apiClient.delete(`/transactions/${id}`);
@@ -74,7 +81,7 @@ export const getTransactionTypes = async () => {
return await apiClient.get('/transactions/types');
}
-export const getTransactionCategoriesSums = async () => {
+export const getTransactionCategoriesSums = async () => {
let response = await apiClient.get('/transactions/categories/_calc_sums');
return response.data;
}
\ No newline at end of file
diff --git a/src/services/userService.ts b/src/services/userService.ts
new file mode 100644
index 0000000..c9aacff
--- /dev/null
+++ b/src/services/userService.ts
@@ -0,0 +1,7 @@
+import apiClient from '@/services/axiosSetup';
+
+
+export const getUsers = async () => {
+ let users = await apiClient.get('/users/');
+ return users.data;
+}
\ No newline at end of file
diff --git a/src/stores/userStore.ts b/src/stores/userStore.ts
index 90aa70c..9fefb16 100644
--- a/src/stores/userStore.ts
+++ b/src/stores/userStore.ts
@@ -1,17 +1,20 @@
-import { defineStore } from 'pinia';
-import { ref } from 'vue';
+import {defineStore} from 'pinia';
+import {ref} from 'vue';
import apiClient from "@/services/axiosSetup";
+import {useRoute, useRouter} from "vue-router";
export const useUserStore = defineStore('user', () => {
const user = ref(null);
const loadingUser = ref(true);
+ const router = useRouter();
+ const route = useRoute();
async function fetchUserProfile() {
// Убираем проверку на `loadingUser`, чтобы не блокировать запрос
if (!user.value) {
loadingUser.value = true;
try {
- const response = await apiClient.get('/auth/users/me'); // запрос к API для получения данных пользователя
+ const response = await apiClient.get('/auth/me'); // запрос к API для получения данных пользователя
if (response.status !== 200) throw new Error('Ошибка загрузки данных пользователя');
user.value = response.data;
@@ -24,5 +27,29 @@ export const useUserStore = defineStore('user', () => {
}
}
- return { user, loadingUser, fetchUserProfile };
+ // Основная функция для логина
+ async function login( username, password, tg_id=null) {
+ try {
+ let response;
+ if (tg_id) {
+ response = await apiClient.post('/auth/token/tg', {tg_id: tg_id});
+ } else {
+ response = await apiClient.post('/auth/login', {
+ username: username,
+ password: password,
+ });
+ }
+
+ const token = response.data.token;
+ localStorage.setItem('token', token);
+ apiClient.defaults.headers.common['Authorization'] = `Bearer ${token}`;
+ await fetchUserProfile();
+ await router.push(route.query['back'] ? route.query['back'].toString() : '/');
+ } catch (error) {
+ console.error(error);
+ alert('Ошибка входа. Проверьте логин и пароль.');
+ }
+ };
+
+ return {user, loadingUser, fetchUserProfile, login};
});