support storing geo location in transaction

This commit is contained in:
MaysWind
2023-04-28 21:22:12 +08:00
parent 1ac968f63c
commit e71ffd1a77
9 changed files with 207 additions and 30 deletions
+4 -2
View File
@@ -266,7 +266,7 @@ export default {
getTransaction: ({ id }) => {
return axios.get(`v1/transactions/get.json?id=${id}&trim_account=true&trim_category=true&trim_tag=true`);
},
addTransaction: ({ type, categoryId, time, sourceAccountId, destinationAccountId, sourceAmount, destinationAmount, hideAmount, tagIds, comment, utcOffset }) => {
addTransaction: ({ type, categoryId, time, sourceAccountId, destinationAccountId, sourceAmount, destinationAmount, hideAmount, tagIds, comment, geoLocation, utcOffset }) => {
return axios.post('v1/transactions/add.json', {
type,
categoryId,
@@ -278,10 +278,11 @@ export default {
hideAmount,
tagIds,
comment,
geoLocation,
utcOffset
});
},
modifyTransaction: ({ id, type, categoryId, time, sourceAccountId, destinationAccountId, sourceAmount, destinationAmount, hideAmount, tagIds, comment, utcOffset }) => {
modifyTransaction: ({ id, type, categoryId, time, sourceAccountId, destinationAccountId, sourceAmount, destinationAmount, hideAmount, tagIds, comment, geoLocation, utcOffset }) => {
return axios.post('v1/transactions/modify.json', {
id,
type,
@@ -294,6 +295,7 @@ export default {
hideAmount,
tagIds,
comment,
geoLocation,
utcOffset
});
},
+3
View File
@@ -13,6 +13,7 @@ const defaultSettings = {
applicationLock: false,
applicationLockWebAuthn: false,
autoUpdateExchangeRatesData: true,
autoGetCurrentGeoLocation: false,
thousandsSeparator: true,
currencyDisplayMode: currencyConstants.defaultCurrencyDisplayMode,
showAmountInHomePage: true,
@@ -140,6 +141,8 @@ export default {
setEnableApplicationLockWebAuthn: value => setOption('applicationLockWebAuthn', value),
isAutoUpdateExchangeRatesData: () => getOption('autoUpdateExchangeRatesData'),
setAutoUpdateExchangeRatesData: value => setOption('autoUpdateExchangeRatesData', value),
isAutoGetCurrentGeoLocation: () => getOption('autoGetCurrentGeoLocation'),
setAutoGetCurrentGeoLocation: value => setOption('autoGetCurrentGeoLocation', value),
isEnableThousandsSeparator: () => getOption('thousandsSeparator'),
setEnableThousandsSeparator: value => setOption('thousandsSeparator', value),
getCurrencyDisplayMode: () => getOption('currencyDisplayMode'),
+7
View File
@@ -830,6 +830,12 @@ export default {
'Destination Account': 'Destination Account',
'Transaction Time': 'Transaction Time',
'Transaction Time Zone': 'Transaction Time Zone',
'Geographic Location': 'Geographic Location',
'No Location': 'No Location',
'Getting Location...': 'Getting Location...',
'Update Geographic Location': 'Update Geographic Location',
'Clear Geographic Location': 'Clear Geographic Location',
'Unable to get current position': 'Unable to get current position',
'Tags': 'Tags',
'Your transaction description (optional)': 'Your transaction description (optional)',
'Are you sure you want to save this transaction whose amount is 0?': 'Are you sure you want to save this transaction whose amount is 0?',
@@ -881,6 +887,7 @@ export default {
'Timezone': 'Timezone',
'System Default': 'System Default',
'Auto Update Exchange Rates Data': 'Auto Update Exchange Rates Data',
'Auto Get Current Geographic Location': 'Auto Get Current Geographic Location',
'Enable Thousands Separator': 'Enable Thousands Separator',
'Currency Display Mode': 'Currency Display Mode',
'Currency Code': 'Currency Code',
+7
View File
@@ -830,6 +830,12 @@ export default {
'Destination Account': '目标账户',
'Transaction Time': '交易时间',
'Transaction Time Zone': '交易时区',
'Geographic Location': '地理位置',
'No Location': '没有位置',
'Getting Location...': '正在获取位置...',
'Update Geographic Location': '更新地理位置',
'Clear Geographic Location': '清除地理位置',
'Unable to get current position': '无法获取当前地理位置',
'Tags': '标签',
'Your transaction description (optional)': '你的交易描述 (可选)',
'Are you sure you want to save this transaction whose amount is 0?': '您确定要保存这个金额为0的交易?',
@@ -881,6 +887,7 @@ export default {
'Timezone': '时区',
'System Default': '系统默认',
'Auto Update Exchange Rates Data': '自动更新汇率数据',
'Auto Get Current Geographic Location': '自动获取当前地理位置',
'Enable Thousands Separator': '启用千位分隔符',
'Currency Display Mode': '货币显示模式',
'Currency Code': '货币代码',
+13
View File
@@ -46,6 +46,11 @@
<f7-toggle :checked="isAutoUpdateExchangeRatesData" @toggle:change="isAutoUpdateExchangeRatesData = $event"></f7-toggle>
</f7-list-item>
<f7-list-item>
<span>{{ $t('Auto Get Current Geographic Location') }}</span>
<f7-toggle :checked="isAutoGetCurrentGeoLocation" @toggle:change="isAutoGetCurrentGeoLocation = $event"></f7-toggle>
</f7-list-item>
<f7-list-item>
<span>{{ $t('Enable Thousands Separator') }}</span>
<f7-toggle :checked="isEnableThousandsSeparator" @toggle:change="isEnableThousandsSeparator = $event"></f7-toggle>
@@ -149,6 +154,14 @@ export default {
this.$settings.setAutoUpdateExchangeRatesData(value);
}
},
isAutoGetCurrentGeoLocation: {
get: function () {
return this.$settings.isAutoGetCurrentGeoLocation();
},
set: function (value) {
this.$settings.setAutoGetCurrentGeoLocation(value);
}
},
isEnableThousandsSeparator: {
get: function () {
return this.$settings.isEnableThousandsSeparator();
+94 -1
View File
@@ -27,6 +27,7 @@
<f7-list-item class="list-item-with-header-and-title" header="Account" title="Account Name"></f7-list-item>
<f7-list-input label="Transaction Time" placeholder="YYYY/MM/DD HH:mm"></f7-list-input>
<f7-list-item :no-chevron="mode === 'view'" class="list-item-with-header-and-title list-item-title-hide-overflow" header="Transaction Time Zone" title="(UTC XX:XX) System Default" link="#"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-title-hide-overflow" header="Geographic Location" title="No Location" link="#"></f7-list-item>
<f7-list-item header="Tags">
<template #footer>
<f7-block class="margin-top-half no-padding no-margin">
@@ -236,6 +237,20 @@
</template>
</f7-list-item>
<f7-list-item
link="#" no-chevron
class="list-item-with-header-and-title list-item-title-hide-overflow"
:header="$t('Geographic Location')"
@click="showGeoLocationActionSheet = true"
>
<template #title>
<f7-block class="list-item-custom-title no-padding no-margin">
<span v-if="transaction.geoLocation">{{ `(${transaction.geoLocation.longitude}, ${transaction.geoLocation.latitude})` }}</span>
<span v-else-if="!transaction.geoLocation">{{ geoLocationStatusInfo }}</span>
</f7-block>
</template>
</f7-list-item>
<f7-list-item
link="#" no-chevron
:header="$t('Tags')"
@@ -275,6 +290,16 @@
></f7-list-input>
</f7-list>
<f7-actions close-by-outside-click close-on-escape :opened="showGeoLocationActionSheet" @actions:closed="showGeoLocationActionSheet = false">
<f7-actions-group>
<f7-actions-button v-if="mode !== 'view'" @click="updateGeoLocation(true)">{{ $t('Update Geographic Location') }}</f7-actions-button>
<f7-actions-button v-if="mode !== 'view'" @click="clearGeoLocation">{{ $t('Clear Geographic Location') }}</f7-actions-button>
</f7-actions-group>
<f7-actions-group>
<f7-actions-button bold close>{{ $t('Cancel') }}</f7-actions-button>
</f7-actions-group>
</f7-actions>
<f7-actions close-by-outside-click close-on-escape :opened="showMoreActionSheet" @actions:closed="showMoreActionSheet = false">
<f7-actions-group>
<f7-actions-button v-if="transaction.hideAmount" @click="transaction.hideAmount = false">{{ $t('Show Amount') }}</f7-actions-button>
@@ -330,12 +355,16 @@ export default {
destinationAmount: 0,
hideAmount: false,
tagIds: [],
comment: ''
comment: '',
geoLocation: null
},
loading: true,
loadingError: null,
geoLocationStatus: null,
submitting: false,
isSupportGeoLocation: !!navigator.geolocation,
showAccountBalance: self.$settings.isShowAccountBalance(),
showGeoLocationActionSheet: false,
showMoreActionSheet: false,
showSourceAmountSheet: false,
showDestinationAmountSheet: false,
@@ -507,6 +536,15 @@ export default {
destinationAmountFontSize() {
return this.getFontSizeByAmount(this.transaction.destinationAmount);
},
geoLocationStatusInfo() {
if (this.geoLocationStatus === 'success') {
return '';
} else if (this.geoLocationStatus === 'getting') {
return this.$t('Getting Location...');
} else {
return this.$t('No Location');
}
},
inputIsEmpty() {
return !!this.inputEmptyProblemMessage;
},
@@ -711,6 +749,10 @@ export default {
self.transaction.hideAmount = transaction.hideAmount;
self.transaction.tagIds = transaction.tagIds || [];
self.transaction.comment = transaction.comment;
if (self.mode === 'edit' || self.mode === 'view') {
self.transaction.geoLocation = transaction.geoLocation;
}
}
self.loading = false;
@@ -728,6 +770,11 @@ export default {
methods: {
onPageAfterIn() {
this.$routeBackOnError(this.f7router, 'loadingError');
if (this.$settings.isAutoGetCurrentGeoLocation() && this.mode === 'add'
&& !this.geoLocationStatus && !this.transaction.geoLocation) {
this.updateGeoLocation(false);
}
},
save() {
const self = this;
@@ -747,6 +794,7 @@ export default {
hideAmount: self.transaction.hideAmount,
tagIds: self.transaction.tagIds,
comment: self.transaction.comment,
geoLocation: self.transaction.geoLocation,
utcOffset: self.transaction.utcOffset
};
@@ -803,6 +851,51 @@ export default {
doSubmit();
}
},
updateGeoLocation(forceUpdate) {
const self = this;
if (!self.isSupportGeoLocation) {
self.$logger.warn('this browser does not support geo location');
if (forceUpdate) {
self.$toast('Unable to get current position');
}
return;
}
navigator.geolocation.getCurrentPosition(function (position) {
if (!position || !position.coords) {
self.$logger.error('current position is null');
self.geoLocationStatus = 'error';
if (forceUpdate) {
self.$toast('Unable to get current position');
}
return;
}
self.geoLocationStatus = 'success';
self.transaction.geoLocation = {
latitude: position.coords.latitude,
longitude: position.coords.longitude
};
}, function (err) {
self.$logger.error('cannot get current position', err);
self.geoLocationStatus = 'error';
if (forceUpdate) {
self.$toast('Unable to get current position');
}
});
self.geoLocationStatus = 'getting';
},
clearGeoLocation() {
this.geoLocationStatus = null;
this.transaction.geoLocation = null;
},
isCategoryIdAvailable(categories, categoryId) {
if (!categories || !categories.length) {
return false;