set geo location data order when import transaction

This commit is contained in:
MaysWind
2025-06-15 22:59:21 +08:00
parent 4336d1ed1a
commit 9090c5c223
21 changed files with 133 additions and 55 deletions
+2 -1
View File
@@ -447,7 +447,7 @@ export default {
timeout: DEFAULT_UPLOAD_API_TIMEOUT
} as ApiRequestConfig);
},
parseImportTransaction: ({ fileType, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, tagSeparator }: { fileType: string, fileEncoding?: string, importFile: File, columnMapping?: Record<number, number>, transactionTypeMapping?: Record<string, TransactionType>, hasHeaderLine?: boolean, timeFormat?: string, timezoneFormat?: string, amountDecimalSeparator?: string, amountDigitGroupingSymbol?: string, geoSeparator?: string, tagSeparator?: string }): ApiResponsePromise<ImportTransactionResponsePageWrapper> => {
parseImportTransaction: ({ fileType, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, geoOrder, tagSeparator }: { fileType: string, fileEncoding?: string, importFile: File, columnMapping?: Record<number, number>, transactionTypeMapping?: Record<string, TransactionType>, hasHeaderLine?: boolean, timeFormat?: string, timezoneFormat?: string, amountDecimalSeparator?: string, amountDigitGroupingSymbol?: string, geoSeparator?: string, geoOrder?: string, tagSeparator?: string }): ApiResponsePromise<ImportTransactionResponsePageWrapper> => {
let textualColumnMapping: string | undefined = undefined;
let textualTransactionTypeMapping: string | undefined = undefined;
let textualHasHeaderLine: string | undefined = undefined;
@@ -476,6 +476,7 @@ export default {
amountDecimalSeparator: amountDecimalSeparator,
amountDigitGroupingSymbol: amountDigitGroupingSymbol,
geoSeparator: geoSeparator,
geoOrder: geoOrder,
tagSeparator: tagSeparator
}, {
timeout: DEFAULT_UPLOAD_API_TIMEOUT
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "Gleiche Zeit wie Standardzeitzone",
"Transaction Type": "Transaction Type",
"Geographic Location": "Geografischer Standort",
"Longitude": "Longitude",
"Latitude": "Latitude",
"No Location": "Kein Standort",
"Getting Location...": "Standort wird ermittelt...",
"Show on the map": "Auf der Karte anzeigen",
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "Same time as default timezone",
"Transaction Type": "Transaction Type",
"Geographic Location": "Geographic Location",
"Longitude": "Longitude",
"Latitude": "Latitude",
"No Location": "No Location",
"Getting Location...": "Getting Location...",
"Show on the map": "Show on the map",
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "Misma hora que la zona horaria predeterminada",
"Transaction Type": "Transaction Type",
"Geographic Location": "Ubicación geográfica",
"Longitude": "Longitude",
"Latitude": "Latitude",
"No Location": "Sin ubicación",
"Getting Location...": "Obteniendo ubicación...",
"Show on the map": "Mostrar en el mapa",
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "Stessa ora del fuso orario predefinito",
"Transaction Type": "Tipo di transazione",
"Geographic Location": "Posizione geografica",
"Longitude": "Longitude",
"Latitude": "Latitude",
"No Location": "Nessuna posizione",
"Getting Location...": "Recupero posizione...",
"Show on the map": "Mostra sulla mappa",
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "デフォルトのタイムゾーンと同じ時間",
"Transaction Type": "取引タイプ",
"Geographic Location": "地理座標",
"Longitude": "Longitude",
"Latitude": "Latitude",
"No Location": "座標はありません",
"Getting Location...": "座標を取得中...",
"Show on the map": "マップに表示",
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "То же время, что и в часовом поясе по умолчанию",
"Transaction Type": "Transaction Type",
"Geographic Location": "Географическое местоположение",
"Longitude": "Longitude",
"Latitude": "Latitude",
"No Location": "Нет местоположения",
"Getting Location...": "Получение местоположения...",
"Show on the map": "Показать на карте",
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "Той самий час, що й у часовому поясі за замовчуванням",
"Transaction Type": "Тип транзакції",
"Geographic Location": "Географічне розташування",
"Longitude": "Longitude",
"Latitude": "Latitude",
"No Location": "Немає розташування",
"Getting Location...": "Отримання розташування...",
"Show on the map": "Показати на карті",
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "Cùng thời gian với múi giờ mặc định",
"Transaction Type": "Transaction Type",
"Geographic Location": "Vị trí địa lý",
"Longitude": "Longitude",
"Latitude": "Latitude",
"No Location": "Không có vị trí",
"Getting Location...": "Đang lấy vị trí...",
"Show on the map": "Hiển thị trên bản đồ",
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "与默认时区时间相同",
"Transaction Type": "交易类型",
"Geographic Location": "地理位置",
"Longitude": "经度",
"Latitude": "纬度",
"No Location": "没有位置",
"Getting Location...": "正在获取位置...",
"Show on the map": "在地图上显示",
+2
View File
@@ -1657,6 +1657,8 @@
"Same time as default timezone": "與預設時區時間相同",
"Transaction Type": "交易類型",
"Geographic Location": "地理位置",
"Longitude": "經度",
"Latitude": "緯度",
"No Location": "沒有位置",
"Getting Location...": "正在取得位置...",
"Show on the map": "在地圖上顯示",
+2 -2
View File
@@ -1129,9 +1129,9 @@ export const useTransactionsStore = defineStore('transactions', () => {
});
}
function parseImportTransaction({ fileType, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, tagSeparator }: { fileType: string, fileEncoding?: string, importFile: File, columnMapping?: Record<number, number>, transactionTypeMapping?: Record<string, TransactionType>, hasHeaderLine?: boolean, timeFormat?: string, timezoneFormat?: string, amountDecimalSeparator?: string, amountDigitGroupingSymbol?: string, geoSeparator?: string, tagSeparator?: string }): Promise<ImportTransactionResponsePageWrapper> {
function parseImportTransaction({ fileType, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, geoOrder, tagSeparator }: { fileType: string, fileEncoding?: string, importFile: File, columnMapping?: Record<number, number>, transactionTypeMapping?: Record<string, TransactionType>, hasHeaderLine?: boolean, timeFormat?: string, timezoneFormat?: string, amountDecimalSeparator?: string, amountDigitGroupingSymbol?: string, geoSeparator?: string, geoOrder?: string, tagSeparator?: string }): Promise<ImportTransactionResponsePageWrapper> {
return new Promise((resolve, reject) => {
services.parseImportTransaction({ fileType, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, tagSeparator }).then(response => {
services.parseImportTransaction({ fileType, fileEncoding, importFile, columnMapping, transactionTypeMapping, hasHeaderLine, timeFormat, timezoneFormat, amountDecimalSeparator, amountDigitGroupingSymbol, geoSeparator, geoOrder, tagSeparator }).then(response => {
const data = response.data;
if (!data || !data.success || !data.result) {
@@ -424,16 +424,33 @@
<v-btn class="ml-2" color="secondary" density="compact" variant="outlined"
v-if="parsedFileDataColumnMapping && isNumber(parsedFileDataColumnMapping[ImportTransactionColumnType.GeographicLocation.type])">
<span>{{ tt('Geographic Location Separator') }}</span>
<span class="ml-1" v-if="parsedFileGeoLocationSeparator">({{ parsedFileGeoLocationSeparator }})</span>
<v-menu eager activator="parent" location="bottom" max-height="500">
<v-list>
<v-list-item :key="separator.value"
:append-icon="parsedFileGeoLocationSeparator === separator.value ? mdiCheck : undefined"
v-for="separator in allSeparators"
@click="parsedFileGeoLocationSeparator = separator.value">
<v-list-item-title class="cursor-pointer">
{{ separator.name }} ({{separator.value}})
</v-list-item-title>
<span class="ml-1" v-if="parsedFileGeoLocationSeparator">({{ parsedFileGeoLocationOrder === 'latlon' ? `${tt('Latitude')}${parsedFileGeoLocationSeparator}${tt('Longitude')}` : `${tt('Longitude')}${parsedFileGeoLocationSeparator}${tt('Latitude')}` }})</span>
<v-menu eager activator="parent" location="bottom" max-height="500"
:close-on-content-click="false">
<v-list class="pa-0">
<v-list-item class="pa-0">
<v-table class="transaction-types-popup-menu">
<tbody>
<tr :key="separator.value"
v-for="separator in allSeparators">
<td>{{ separator.name }} ({{separator.value}})</td>
<td>
<v-btn-toggle class="transaction-types-toggle" density="compact" variant="outlined"
mandatory="force" divided
v-model="parsedFileGeoLocationOrder"
v-if="parsedFileGeoLocationSeparator === separator.value">
<v-btn value="latlon">{{ `${tt('Latitude')}${separator.value}${tt('Longitude')}` }}</v-btn>
<v-btn value="lonlat">{{ `${tt('Longitude')}${separator.value}${tt('Latitude')}` }}</v-btn>
</v-btn-toggle>
<v-btn-group class="transaction-types-toggle" density="compact" variant="outlined"
divided v-if="parsedFileGeoLocationSeparator !== separator.value">
<v-btn @click="parsedFileGeoLocationSeparator = separator.value; parsedFileGeoLocationOrder = 'latlon'">{{ `${tt('Latitude')}${separator.value}${tt('Longitude')}` }}</v-btn>
<v-btn @click="parsedFileGeoLocationSeparator = separator.value; parsedFileGeoLocationOrder = 'lonlat'">{{ `${tt('Longitude')}${separator.value}${tt('Latitude')}` }}</v-btn>
</v-btn-group>
</td>
</tr>
</tbody>
</v-table>
</v-list-item>
</v-list>
</v-menu>
@@ -986,6 +1003,7 @@ const parsedFileTimeFormat = ref<string>('');
const parsedFileTimezoneFormat = ref<string>('');
const parsedFileAmountFormat = ref<string>('');
const parsedFileGeoLocationSeparator = ref<string>(' ');
const parsedFileGeoLocationOrder = ref<string>('lonlat');
const parsedFileTagSeparator = ref<string>(';');
const importTransactions = ref<ImportTransaction[] | undefined>(undefined);
const editingTransaction = ref<ImportTransaction | null>(null);
@@ -1943,6 +1961,7 @@ function open(): Promise<void> {
parsedFileTimezoneFormat.value = '';
parsedFileAmountFormat.value = '';
parsedFileGeoLocationSeparator.value = ' ';
parsedFileGeoLocationOrder.value = 'lonlat';
parsedFileTagSeparator.value = ';';
importTransactions.value = undefined;
editingTransaction.value = null;
@@ -2088,6 +2107,7 @@ function parseData(): void {
let amountDecimalSeparator: string | undefined = undefined;
let amountDigitGroupingSymbol: string | undefined = undefined;
let geoLocationSeparator: string | undefined = undefined;
let geoLocationOrder: string | undefined = undefined;
let tagSeparator: string | undefined = undefined;
if (isDsvFileType) {
@@ -2098,6 +2118,7 @@ function parseData(): void {
timezoneFormat = parsedFileTimezoneFormat.value;
amountFormat = parsedFileAmountFormat.value;
geoLocationSeparator = parsedFileGeoLocationSeparator.value;
geoLocationOrder = parsedFileGeoLocationOrder.value;
tagSeparator = parsedFileTagSeparator.value;
if (!columnMapping
@@ -2159,6 +2180,7 @@ function parseData(): void {
amountDecimalSeparator: amountDecimalSeparator,
amountDigitGroupingSymbol: amountDigitGroupingSymbol,
geoSeparator: geoLocationSeparator,
geoOrder: geoLocationOrder,
tagSeparator: tagSeparator
}).then(response => {
const parsedTransactions: ImportTransaction[] = [];