add total amount in home page

This commit is contained in:
MaysWind
2021-01-10 21:24:02 +08:00
parent a470752d42
commit a5474d0d65
15 changed files with 576 additions and 7 deletions
+21
View File
@@ -159,6 +159,27 @@ export default {
password
});
},
getTransactionOverview: ( { today, thisWeek, thisMonth, thisYear } ) => {
const queryParams = [];
if (today) {
queryParams.push(`today_${today.startTime}_${today.endTime}`);
}
if (thisWeek) {
queryParams.push(`thisWeek_${thisWeek.startTime}_${thisWeek.endTime}`);
}
if (thisMonth) {
queryParams.push(`thisMonth_${thisMonth.startTime}_${thisMonth.endTime}`);
}
if (thisYear) {
queryParams.push(`thisYear_${thisYear.startTime}_${thisYear.endTime}`);
}
return axios.get('v1/overviews/transaction.json' + (queryParams.length ? '?query=' + queryParams.join('|') : ''));
},
getAllAccounts: ({ visibleOnly }) => {
return axios.get('v1/accounts/list.json?visible_only=' + !!visibleOnly);
},
+9 -1
View File
@@ -10,7 +10,9 @@ export default {
'format': {
'date': {
'long': 'MM/DD/YYYY',
'yearMonth': 'YYYY-MM'
'year': 'YYYY',
'yearMonth': 'YYYY-M',
'monthDay': 'M/D'
},
'datetime': {
'long': 'MM/DD/YYYY HH:mm:ss',
@@ -362,6 +364,8 @@ export default {
'transaction tag name is empty': 'Transaction tag title is empty',
'transaction tag name already exists': 'Transaction tag title already exists',
'transaction tag is in use and cannot be deleted': 'Transaction tag is in use and it cannot be deleted',
'query items cannot be empty': 'There are no query items',
'query items too much': 'There are too many query items',
},
'parameter': {
'id': 'ID',
@@ -496,6 +500,10 @@ export default {
'Sign Up': 'Sign Up',
'Transaction List': 'Transaction List',
'Account List': 'Account List',
'This Week': 'This Week',
'This Month': 'This Month',
'This Year': 'This Year',
'Unable to get transaction overview': 'Unable to get transaction overview',
'Net assets': 'Net assets',
'Total assets': 'Total assets',
'Total liabilities': 'Total liabilities',
+9 -1
View File
@@ -10,7 +10,9 @@ export default {
'format': {
'date': {
'long': 'YYYY年MM月DD日',
'yearMonth': 'YYYY年MM月'
'year': 'YYYY年',
'yearMonth': 'YYYY年M月',
'monthDay': 'M月D日'
},
'datetime': {
'long': 'YYYY年MM月DD日 HH:mm:ss',
@@ -362,6 +364,8 @@ export default {
'transaction tag name is empty': '交易标签标题不能为空',
'transaction tag name already exists': '交易标签标题已经存在',
'transaction tag is in use and cannot be deleted': '交易标签正在被使用,无法删除',
'query items cannot be empty': '请求项目不能为空',
'query items too much': '请求项目过多',
},
'parameter': {
'id': 'ID',
@@ -496,6 +500,10 @@ export default {
'Sign Up': '注册',
'Transaction List': '交易列表',
'Account List': '账户列表',
'This Week': '本周',
'This Month': '本月',
'This Year': '今年',
'Unable to get transaction overview': '无法获取交易概要',
'Net assets': '净资产',
'Total assets': '总资产',
'Total liabilities': '总负债',
+18
View File
@@ -40,6 +40,9 @@ import {
UPDATE_TAG_VISIBILITY_IN_TRANSACTION_TAG_LIST,
REMOVE_TAG_FROM_TRANSACTION_TAG_LIST,
UPDATE_TRANSACTION_TAG_LIST_INVALID_STATE,
LOAD_TRANSACTION_OVERVIEW,
UPDATE_TRANSACTION_OVERVIEW_INVALID_STATE,
} from './mutations.js';
import {
@@ -79,6 +82,10 @@ import {
clearExchangeRatesFromLocalStorage,
} from './exchangeRates.js';
import {
loadTransactionOverview
} from './overview.js';
import {
loadAllAccounts,
getAccount,
@@ -154,6 +161,8 @@ const stores = {
allTransactionTags: [],
allTransactionTagsMap: {},
transactionTagListStateInvalid: true,
transactionOverview: {},
transactionOverviewStateInvalid: true,
},
getters: {
// user
@@ -706,6 +715,12 @@ const stores = {
[UPDATE_TRANSACTION_TAG_LIST_INVALID_STATE] (state, invalidState) {
state.transactionTagListStateInvalid = invalidState;
},
[LOAD_TRANSACTION_OVERVIEW] (state, transactionOverview) {
state.transactionOverview = transactionOverview;
},
[UPDATE_TRANSACTION_OVERVIEW_INVALID_STATE] (state, invalidState) {
state.transactionOverviewStateInvalid = invalidState;
},
},
actions: {
// user
@@ -734,6 +749,9 @@ const stores = {
// exchange rates
getLatestExchangeRates,
// overview
loadTransactionOverview,
// account
loadAllAccounts,
saveAccount,
+3
View File
@@ -36,3 +36,6 @@ export const CHANGE_TAG_DISPLAY_ORDER_IN_TRANSACTION_TAG_LIST = 'CHANGE_TAG_DISP
export const UPDATE_TAG_VISIBILITY_IN_TRANSACTION_TAG_LIST = 'UPDATE_TAG_VISIBILITY_IN_TRANSACTION_TAG_LIST';
export const REMOVE_TAG_FROM_TRANSACTION_TAG_LIST = 'REMOVE_TAG_FROM_TRANSACTION_TAG_LIST';
export const UPDATE_TRANSACTION_TAG_LIST_INVALID_STATE = 'UPDATE_TRANSACTION_TAG_LIST_INVALID_STATE';
export const LOAD_TRANSACTION_OVERVIEW = 'LOAD_TRANSACTION_OVERVIEW';
export const UPDATE_TRANSACTION_OVERVIEW_INVALID_STATE = 'UPDATE_TRANSACTION_OVERVIEW_INVALID_STATE';
+53
View File
@@ -0,0 +1,53 @@
import services from '../lib/services.js';
import logger from '../lib/logger.js';
import {
LOAD_TRANSACTION_OVERVIEW,
UPDATE_TRANSACTION_OVERVIEW_INVALID_STATE,
} from './mutations.js';
export function loadTransactionOverview(context, { dateRange, force }) {
if (!force && !context.state.transactionOverviewStateInvalid) {
return new Promise((resolve) => {
resolve(context.state.transactionOverview);
});
}
return new Promise((resolve, reject) => {
services.getTransactionOverview({
today: dateRange.today,
thisWeek: dateRange.thisWeek,
thisMonth: dateRange.thisMonth,
thisYear: dateRange.thisYear
}).then(response => {
const data = response.data;
if (!data || !data.success || !data.result) {
reject({ message: 'Unable to get transaction overview' });
return;
}
context.commit(LOAD_TRANSACTION_OVERVIEW, data.result);
if (context.state.transactionOverviewStateInvalid) {
context.commit(UPDATE_TRANSACTION_OVERVIEW_INVALID_STATE, false);
}
resolve(data.result);
}).catch(error => {
if (force) {
logger.error('failed to force load transaction overview', error);
} else {
logger.error('failed to load transaction overview', error);
}
if (error.response && error.response.data && error.response.data.errorMessage) {
reject({ error: error.response.data });
} else if (!error.processed) {
reject({ message: 'Unable to get transaction overview' });
} else {
reject(error);
}
});
});
}
+3
View File
@@ -14,6 +14,7 @@ import {
REMOVE_TRANSACTION_FROM_TRANSACTION_LIST,
UPDATE_TRANSACTION_LIST_INVALID_STATE,
UPDATE_ACCOUNT_LIST_INVALID_STATE,
UPDATE_TRANSACTION_OVERVIEW_INVALID_STATE,
} from './mutations.js';
const emptyTransactionResult = {
@@ -169,6 +170,7 @@ export function saveTransaction(context, { transaction, defaultCurrency }) {
}
context.commit(UPDATE_ACCOUNT_LIST_INVALID_STATE, true);
context.commit(UPDATE_TRANSACTION_OVERVIEW_INVALID_STATE, true);
resolve(data.result);
}).catch(error => {
@@ -216,6 +218,7 @@ export function deleteTransaction(context, { transaction, defaultCurrency, befor
}
context.commit(UPDATE_ACCOUNT_LIST_INVALID_STATE, true);
context.commit(UPDATE_TRANSACTION_OVERVIEW_INVALID_STATE, true);
resolve(data.result);
}).catch(error => {
+285 -5
View File
@@ -1,12 +1,184 @@
<template>
<f7-page>
<f7-page ptr @ptr:refresh="reload" @page:afterin="onPageAfterIn">
<f7-navbar>
<f7-nav-title :title="$t('global.app.title')"></f7-nav-title>
</f7-navbar>
<f7-list media-list class="skeleton-text">
<f7-list-item title="Placeholder"></f7-list-item>
</f7-list>
<f7-card class="skeleton-text" v-if="loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-item link="#" chevron-center>
<div slot="media">
<f7-icon f7="calendar_today"></f7-icon>
</div>
<div slot="title" class="no-padding">
<span>Today</span>
</div>
<div slot="footer" class="overview-transaction-footer">
<span>MM/DD/YYYY</span>
</div>
<div slot="after">
<div class="text-color-red">
<small>0.00 USD</small>
</div>
<div class="text-color-teal">
<small>0.00 USD</small>
</div>
</div>
</f7-list-item>
<f7-list-item link="#" chevron-center>
<div slot="media">
<f7-icon f7="calendar"></f7-icon>
</div>
<div slot="title" class="no-padding">
<span>This week</span>
</div>
<div slot="footer" class="overview-transaction-footer">
<span>MM/DD - MM/DD</span>
</div>
<div slot="after">
<div class="text-color-red">
<small>0.00 USD</small>
</div>
<div class="text-color-teal">
<small>0.00 USD</small>
</div>
</div>
</f7-list-item>
<f7-list-item link="#" chevron-center>
<div slot="media">
<f7-icon f7="calendar"></f7-icon>
</div>
<div slot="title" class="no-padding">
<span>This month</span>
</div>
<div slot="footer" class="overview-transaction-footer">
<span>MM/DD - MM/DD</span>
</div>
<div slot="after">
<div class="text-color-red">
<small>0.00 USD</small>
</div>
<div class="text-color-teal">
<small>0.00 USD</small>
</div>
</div>
</f7-list-item>
<f7-list-item link="#" chevron-center>
<div slot="media">
<f7-icon f7="square_stack_3d_up"></f7-icon>
</div>
<div slot="title" class="no-padding">
<span>This year</span>
</div>
<div slot="footer" class="overview-transaction-footer">
<span>YYYY</span>
</div>
<div slot="after">
<div class="text-color-red">
<small>0.00 USD</small>
</div>
<div class="text-color-teal">
<small>0.00 USD</small>
</div>
</div>
</f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
<f7-card v-else-if="!loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-item link="/transaction/list?dateType=1" chevron-center>
<div slot="media">
<f7-icon f7="calendar_today"></f7-icon>
</div>
<div slot="title" class="no-padding">
<span>{{ $t('Today' )}}</span>
</div>
<div slot="footer" class="overview-transaction-footer">
<span>{{ dateRange.today.startTime | moment($t('format.date.long')) }}</span>
</div>
<div slot="after">
<div class="text-color-red">
<small v-if="transactionOverview.today">{{ transactionOverview.today.incomeAmount | currency(defaultCurrency) }}</small>
</div>
<div class="text-color-teal">
<small v-if="transactionOverview.today">{{ transactionOverview.today.expenseAmount | currency(defaultCurrency) }}</small>
</div>
</div>
</f7-list-item>
<f7-list-item link="/transaction/list?dateType=5" chevron-center>
<div slot="media">
<f7-icon f7="calendar"></f7-icon>
</div>
<div slot="title" class="no-padding">
<span>{{ $t('This Week' )}}</span>
</div>
<div slot="footer" class="overview-transaction-footer">
<span>{{ dateRange.thisWeek.startTime | moment($t('format.date.monthDay')) }}</span>
<span>-</span>
<span>{{ dateRange.thisWeek.endTime | moment($t('format.date.monthDay')) }}</span>
</div>
<div slot="after">
<div class="text-color-red">
<small v-if="transactionOverview.thisWeek">{{ transactionOverview.thisWeek.incomeAmount | currency(defaultCurrency) }}</small>
</div>
<div class="text-color-teal">
<small v-if="transactionOverview.thisWeek">{{ transactionOverview.thisWeek.expenseAmount | currency(defaultCurrency) }}</small>
</div>
</div>
</f7-list-item>
<f7-list-item link="/transaction/list?dateType=7" chevron-center>
<div slot="media">
<f7-icon f7="calendar"></f7-icon>
</div>
<div slot="title" class="no-padding">
<span>{{ $t('This Month' )}}</span>
</div>
<div slot="footer" class="overview-transaction-footer">
<span>{{ dateRange.thisMonth.startTime | moment($t('format.date.monthDay')) }}</span>
<span>-</span>
<span>{{ dateRange.thisMonth.endTime | moment($t('format.date.monthDay')) }}</span>
</div>
<div slot="after">
<div class="text-color-red">
<small v-if="transactionOverview.thisMonth">{{ transactionOverview.thisMonth.incomeAmount | currency(defaultCurrency) }}</small>
</div>
<div class="text-color-teal">
<small v-if="transactionOverview.thisMonth">{{ transactionOverview.thisMonth.expenseAmount | currency(defaultCurrency) }}</small>
</div>
</div>
</f7-list-item>
<f7-list-item link="/transaction/list?dateType=9" chevron-center>
<div slot="media">
<f7-icon f7="square_stack_3d_up"></f7-icon>
</div>
<div slot="title" class="no-padding">
<span>{{ $t('This Year' )}}</span>
</div>
<div slot="footer" class="overview-transaction-footer">
<span>{{ dateRange.thisYear.startTime | moment($t('format.date.year')) }}</span>
</div>
<div slot="after">
<div class="text-color-red">
<small v-if="transactionOverview.thisYear">{{ transactionOverview.thisYear.incomeAmount | currency(defaultCurrency) }}</small>
</div>
<div class="text-color-teal">
<small v-if="transactionOverview.thisYear">{{ transactionOverview.thisYear.expenseAmount | currency(defaultCurrency) }}</small>
</div>
</div>
</f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
<f7-toolbar tabbar labels bottom>
<f7-link href="/transaction/list">
@@ -33,10 +205,118 @@
</template>
<script>
export default {}
export default {
data() {
const self = this;
return {
dateRange: self.getCurrentDateRange(),
loading: true
};
},
computed: {
transactionOverview() {
return this.$store.state.transactionOverview;
},
defaultCurrency() {
return this.$store.getters.currentUserDefaultCurrency || this.$t('default.currency');
}
},
created() {
const self = this;
self.loading = true;
self.$store.dispatch('loadTransactionOverview', {
dateRange: self.dateRange,
force: false
}).then(() => {
self.loading = false;
}).catch(error => {
self.loading = false;
if (!error.processed) {
self.$toast(error.message || error);
}
});
},
methods: {
onPageAfterIn() {
const newDateRange = this.getCurrentDateRange();
if (newDateRange.today.startTime !== this.dateRange.today.startTime ||
newDateRange.today.endTime !== this.dateRange.today.endTime) {
this.dateRange = newDateRange;
}
if (this.$store.state.transactionOverviewStateInvalid && !this.loading) {
this.reload(null);
}
},
reload(done) {
const self = this;
self.$store.dispatch('loadTransactionOverview', {
dateRange: self.dateRange,
force: true
}).then(() => {
if (done) {
done();
}
}).catch(error => {
if (done) {
done();
}
if (!error.processed) {
self.$toast(error.message || error);
}
});
},
getCurrentDateRange() {
const self = this;
return {
today: {
startTime: self.$utilities.getTodayFirstUnixTime(),
endTime: self.$utilities.getTodayLastUnixTime()
},
thisWeek: {
startTime: self.$utilities.getThisWeekFirstUnixTime(),
endTime: self.$utilities.getThisWeekLastUnixTime()
},
thisMonth: {
startTime: self.$utilities.getThisMonthFirstUnixTime(),
endTime: self.$utilities.getThisMonthLastUnixTime()
},
thisYear: {
startTime: self.$utilities.getThisYearFirstUnixTime(),
endTime: self.$utilities.getThisYearLastUnixTime()
}
};
}
}
}
</script>
<style>
.home-overview-card {
background-color: var(--f7-color-yellow);
height: 300px;
}
.theme-dark .home-overview-card {
background-color: var(--f7-theme-color);
}
.overview-transaction-footer {
padding-top: 2px;
}
.overview-transaction-footer > span {
margin-right: 4px;
}
.tabbar-labels i.lab-tarbar-big-icon {
font-size: 42px;
width: 42px;