mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-20 17:54:30 +08:00
support clicking on map to set specified geographic location
This commit is contained in:
@@ -13,7 +13,8 @@ import { ref, computed, useTemplateRef } from 'vue';
|
|||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
|
||||||
import type { MapInstance, MapPosition } from '@/lib/map/base.ts';
|
import type { MapPosition } from '@/core/map.ts';
|
||||||
|
import type { MapInstance } from '@/lib/map/base.ts';
|
||||||
import { createMapInstance } from '@/lib/map/index.ts';
|
import { createMapInstance } from '@/lib/map/index.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -23,6 +24,10 @@ const props = defineProps<{
|
|||||||
geoLocation?: MapPosition;
|
geoLocation?: MapPosition;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'click', geoLocation: MapPosition): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
const { tt, getCurrentLanguageInfo } = useI18n();
|
const { tt, getCurrentLanguageInfo } = useI18n();
|
||||||
|
|
||||||
const mapContainer = useTemplateRef<HTMLElement>('mapContainer');
|
const mapContainer = useTemplateRef<HTMLElement>('mapContainer');
|
||||||
@@ -86,6 +91,9 @@ function initMapView(): void {
|
|||||||
text: {
|
text: {
|
||||||
zoomIn: tt('Zoom in'),
|
zoomIn: tt('Zoom in'),
|
||||||
zoomOut: tt('Zoom out'),
|
zoomOut: tt('Zoom out'),
|
||||||
|
},
|
||||||
|
onClick: (geoLocation: MapPosition) => {
|
||||||
|
emit('click', geoLocation);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -105,7 +113,18 @@ function initMapView(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setMarkerPosition(geoLocation?: MapPosition): void {
|
||||||
|
if (!mapInstance.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (geoLocation) {
|
||||||
|
mapInstance.value.setMapCenterMarker(geoLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
initMapView
|
initMapView,
|
||||||
|
setMarkerPosition
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,13 +3,16 @@
|
|||||||
:opened="show" @sheet:open="onSheetOpen" @sheet:closed="onSheetClosed">
|
:opened="show" @sheet:open="onSheetOpen" @sheet:closed="onSheetClosed">
|
||||||
<f7-toolbar>
|
<f7-toolbar>
|
||||||
<div class="swipe-handler"></div>
|
<div class="swipe-handler"></div>
|
||||||
<div class="left"></div>
|
<div class="left">
|
||||||
|
<f7-link :text="tt('Disable Click to Set Location')" @click="switchSetGeoLocationByClickMap(false)" v-if="isSupportGetGeoLocationByClick() && props.setGeoLocationByClickMap"></f7-link>
|
||||||
|
<f7-link :text="tt('Enable Click to Set Location')" @click="switchSetGeoLocationByClickMap(true)" v-if="isSupportGetGeoLocationByClick() && !props.setGeoLocationByClickMap"></f7-link>
|
||||||
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<f7-link :text="tt('Done')" @click="save"></f7-link>
|
<f7-link :text="tt('Done')" @click="save"></f7-link>
|
||||||
</div>
|
</div>
|
||||||
</f7-toolbar>
|
</f7-toolbar>
|
||||||
<f7-page-content class="no-margin-vertical no-padding-vertical">
|
<f7-page-content class="no-margin-vertical no-padding-vertical">
|
||||||
<map-view ref="map" height="400px" :geo-location="geoLocation">
|
<map-view ref="map" height="400px" :geo-location="geoLocation" @click="updateSpecifiedGeoLocation">
|
||||||
<template #error-title="{ mapSupported, mapDependencyLoaded }">
|
<template #error-title="{ mapSupported, mapDependencyLoaded }">
|
||||||
<div class="display-flex padding justify-content-space-between align-items-center">
|
<div class="display-flex padding justify-content-space-between align-items-center">
|
||||||
<div class="ebk-sheet-title" v-if="!mapSupported"><b>{{ tt('Unsupported Map Provider') }}</b></div>
|
<div class="ebk-sheet-title" v-if="!mapSupported"><b>{{ tt('Unsupported Map Provider') }}</b></div>
|
||||||
@@ -36,17 +39,21 @@ import MapView from '@/components/common/MapView.vue';
|
|||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
|
||||||
import type { MapPosition } from '@/lib/map/base.ts';
|
import type { MapPosition } from '@/core/map.ts';
|
||||||
|
|
||||||
|
import { isSupportGetGeoLocationByClick } from '@/lib/map/index.ts';
|
||||||
|
|
||||||
type MapViewType = InstanceType<typeof MapView>;
|
type MapViewType = InstanceType<typeof MapView>;
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue?: MapPosition;
|
modelValue?: MapPosition;
|
||||||
|
setGeoLocationByClickMap?: boolean;
|
||||||
show: boolean;
|
show: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', value: MapPosition | undefined): void;
|
(e: 'update:modelValue', value: MapPosition | undefined): void;
|
||||||
|
(e: 'update:setGeoLocationByClickMap', value: boolean): void;
|
||||||
(e: 'update:show', value: boolean): void;
|
(e: 'update:show', value: boolean): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@@ -63,6 +70,17 @@ const geoLocation = computed<MapPosition | undefined>({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updateSpecifiedGeoLocation(mapPosition: MapPosition): void {
|
||||||
|
if (isSupportGetGeoLocationByClick() && props.setGeoLocationByClickMap) {
|
||||||
|
geoLocation.value = mapPosition;
|
||||||
|
map.value?.setMarkerPosition(mapPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchSetGeoLocationByClickMap(value: boolean): void {
|
||||||
|
emit('update:setGeoLocationByClickMap', value);
|
||||||
|
}
|
||||||
|
|
||||||
function save(): void {
|
function save(): void {
|
||||||
emit('update:show', false);
|
emit('update:show', false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export interface MapPosition {
|
||||||
|
latitude: number;
|
||||||
|
longitude: number;
|
||||||
|
}
|
||||||
+15
-1
@@ -1,6 +1,7 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
|
import type { MapPosition } from '@/core/map.ts';
|
||||||
|
import type { MapProvider, MapInstance, MapInstanceInitOptions } from './base.ts';
|
||||||
|
|
||||||
import { asyncLoadAssets } from '@/lib/misc.ts';
|
import { asyncLoadAssets } from '@/lib/misc.ts';
|
||||||
import services from '@/lib/services.ts';
|
import services from '@/lib/services.ts';
|
||||||
@@ -18,6 +19,10 @@ export class AmapMapProvider implements MapProvider {
|
|||||||
return 'https://www.amap.com';
|
return 'https://www.amap.com';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isSupportGetGeoLocationByClick(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
public asyncLoadAssets(language?: string): Promise<unknown> {
|
public asyncLoadAssets(language?: string): Promise<unknown> {
|
||||||
if (AmapMapProvider.AMap) {
|
if (AmapMapProvider.AMap) {
|
||||||
@@ -86,6 +91,15 @@ export class AmapMapInstance implements MapInstance {
|
|||||||
});
|
});
|
||||||
amapInstance.addControl(amapToolbar);
|
amapInstance.addControl(amapToolbar);
|
||||||
|
|
||||||
|
amapInstance.on('click', function(e) {
|
||||||
|
if (options.onClick) {
|
||||||
|
options.onClick({
|
||||||
|
latitude: e.lnglat.lat,
|
||||||
|
longitude: e.lnglat.lng
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.amapInstance = amapInstance;
|
this.amapInstance = amapInstance;
|
||||||
this.amapToolbar = amapToolbar;
|
this.amapToolbar = amapToolbar;
|
||||||
this.inited = true;
|
this.inited = true;
|
||||||
|
|||||||
+15
-1
@@ -1,6 +1,7 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
|
import type { MapPosition } from '@/core/map.ts';
|
||||||
|
import type { MapProvider, MapInstance, MapInstanceInitOptions } from './base.ts';
|
||||||
|
|
||||||
import { asyncLoadAssets } from '@/lib/misc.ts';
|
import { asyncLoadAssets } from '@/lib/misc.ts';
|
||||||
import services from '@/lib/services.ts';
|
import services from '@/lib/services.ts';
|
||||||
@@ -17,6 +18,10 @@ export class BaiduMapProvider implements MapProvider {
|
|||||||
return 'https://map.baidu.com';
|
return 'https://map.baidu.com';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isSupportGetGeoLocationByClick(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
public asyncLoadAssets(language?: string): Promise<unknown> {
|
public asyncLoadAssets(language?: string): Promise<unknown> {
|
||||||
if (BaiduMapProvider.BMap) {
|
if (BaiduMapProvider.BMap) {
|
||||||
@@ -76,6 +81,15 @@ export class BaiduMapInstance implements MapInstance {
|
|||||||
baiduMapInstance.addControl(baiduMapNavigationControl);
|
baiduMapInstance.addControl(baiduMapNavigationControl);
|
||||||
baiduMapInstance.centerAndZoom(new BMap.Point(options.initCenter.longitude, options.initCenter.latitude), options.zoomLevel);
|
baiduMapInstance.centerAndZoom(new BMap.Point(options.initCenter.longitude, options.initCenter.latitude), options.zoomLevel);
|
||||||
|
|
||||||
|
baiduMapInstance.addEventListener('click', function(e) {
|
||||||
|
if (options.onClick) {
|
||||||
|
options.onClick({
|
||||||
|
latitude: e.point.lat,
|
||||||
|
longitude: e.point.lng
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.baiduMapInstance = baiduMapInstance;
|
this.baiduMapInstance = baiduMapInstance;
|
||||||
this.baiduMapConverter = new BMap.Convertor();
|
this.baiduMapConverter = new BMap.Convertor();
|
||||||
this.baiduMapNavigationControl = baiduMapNavigationControl;
|
this.baiduMapNavigationControl = baiduMapNavigationControl;
|
||||||
|
|||||||
+5
-6
@@ -1,5 +1,8 @@
|
|||||||
|
import type { MapPosition } from '@/core/map.ts';
|
||||||
|
|
||||||
export interface MapProvider {
|
export interface MapProvider {
|
||||||
getWebsite(): string;
|
getWebsite(): string;
|
||||||
|
isSupportGetGeoLocationByClick(): boolean;
|
||||||
asyncLoadAssets(language?: string): Promise<unknown>;
|
asyncLoadAssets(language?: string): Promise<unknown>;
|
||||||
createMapInstance(): MapInstance | null;
|
createMapInstance(): MapInstance | null;
|
||||||
}
|
}
|
||||||
@@ -22,10 +25,6 @@ export interface MapInstanceInitOptions {
|
|||||||
readonly text: {
|
readonly text: {
|
||||||
readonly zoomIn: string;
|
readonly zoomIn: string;
|
||||||
readonly zoomOut: string;
|
readonly zoomOut: string;
|
||||||
}
|
};
|
||||||
}
|
readonly onClick?: (position: MapPosition) => void;
|
||||||
|
|
||||||
export interface MapPosition {
|
|
||||||
latitude: number;
|
|
||||||
longitude: number;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
|
import type { MapPosition } from '@/core/map.ts';
|
||||||
|
import type { MapProvider, MapInstance, MapInstanceInitOptions } from './base.ts';
|
||||||
|
|
||||||
import { asyncLoadAssets } from '@/lib/misc.ts';
|
import { asyncLoadAssets } from '@/lib/misc.ts';
|
||||||
import services from '@/lib/services.ts';
|
import services from '@/lib/services.ts';
|
||||||
@@ -15,6 +16,10 @@ export class GoogleMapProvider implements MapProvider {
|
|||||||
return 'https://maps.google.com';
|
return 'https://maps.google.com';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isSupportGetGeoLocationByClick(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public asyncLoadAssets(language?: string): Promise<unknown> {
|
public asyncLoadAssets(language?: string): Promise<unknown> {
|
||||||
if (GoogleMapProvider.GoogleMap) {
|
if (GoogleMapProvider.GoogleMap) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
@@ -76,6 +81,16 @@ export class GoogleMapInstance implements MapInstance {
|
|||||||
position: GoogleMapProvider.ControlPosition.LEFT_TOP
|
position: GoogleMapProvider.ControlPosition.LEFT_TOP
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.googleMapInstance.addListener('click', function(e) {
|
||||||
|
if (options.onClick) {
|
||||||
|
options.onClick({
|
||||||
|
latitude: e.latLng.lat(),
|
||||||
|
longitude: e.latLng.lng()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.inited = true;
|
this.inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ export function getMapWebsite(): string {
|
|||||||
return mapProvider?.getWebsite() || '';
|
return mapProvider?.getWebsite() || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isSupportGetGeoLocationByClick(): boolean {
|
||||||
|
return mapProvider?.isSupportGetGeoLocationByClick() || false;
|
||||||
|
}
|
||||||
|
|
||||||
export function createMapInstance(): MapInstance | null {
|
export function createMapInstance(): MapInstance | null {
|
||||||
return mapProvider?.createMapInstance() || null;
|
return mapProvider?.createMapInstance() || null;
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-1
@@ -1,8 +1,10 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
import type { MapPosition } from '@/core/map.ts';
|
||||||
|
|
||||||
import { type LeafletTileSource, type LeafletTileSourceExtraParam, LEAFLET_TILE_SOURCES } from '@/consts/map.ts';
|
import { type LeafletTileSource, type LeafletTileSourceExtraParam, LEAFLET_TILE_SOURCES } from '@/consts/map.ts';
|
||||||
|
|
||||||
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
|
import type { MapProvider, MapInstance, MapInstanceInitOptions } from './base.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isMapDataFetchProxyEnabled,
|
isMapDataFetchProxyEnabled,
|
||||||
@@ -35,6 +37,10 @@ export class LeafletMapProvider implements MapProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isSupportGetGeoLocationByClick(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
public asyncLoadAssets(language?: string): Promise<unknown> {
|
public asyncLoadAssets(language?: string): Promise<unknown> {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
@@ -158,6 +164,15 @@ export class LeafletMapInstance implements MapInstance {
|
|||||||
this.leafletAttribution = attribution;
|
this.leafletAttribution = attribution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leafletInstance.addEventListener('click', function(e) {
|
||||||
|
if (options.onClick) {
|
||||||
|
options.onClick({
|
||||||
|
latitude: e.latlng.lat,
|
||||||
|
longitude: e.latlng.lng
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.leafletInstance = leafletInstance;
|
this.leafletInstance = leafletInstance;
|
||||||
this.leafletTileLayer = tileLayer;
|
this.leafletTileLayer = tileLayer;
|
||||||
this.leafletZoomControl = zoomControl;
|
this.leafletZoomControl = zoomControl;
|
||||||
|
|||||||
@@ -1639,6 +1639,9 @@
|
|||||||
"Location on Map": "Standort auf der Karte",
|
"Location on Map": "Standort auf der Karte",
|
||||||
"Update Geographic Location": "Geografischen Standort aktualisieren",
|
"Update Geographic Location": "Geografischen Standort aktualisieren",
|
||||||
"Clear Geographic Location": "Geografischen Standort löschen",
|
"Clear Geographic Location": "Geografischen Standort löschen",
|
||||||
|
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||||
|
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||||
|
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||||
"Unable to retrieve current position": "Aktuelle Position kann nicht abgerufen werden",
|
"Unable to retrieve current position": "Aktuelle Position kann nicht abgerufen werden",
|
||||||
"Cannot Initialize Map": "Karte kann nicht initialisiert werden",
|
"Cannot Initialize Map": "Karte kann nicht initialisiert werden",
|
||||||
"Unsupported Map Provider": "Nicht unterstützter Kartenanbieter",
|
"Unsupported Map Provider": "Nicht unterstützter Kartenanbieter",
|
||||||
|
|||||||
@@ -1639,6 +1639,9 @@
|
|||||||
"Location on Map": "Location on Map",
|
"Location on Map": "Location on Map",
|
||||||
"Update Geographic Location": "Update Geographic Location",
|
"Update Geographic Location": "Update Geographic Location",
|
||||||
"Clear Geographic Location": "Clear Geographic Location",
|
"Clear Geographic Location": "Clear Geographic Location",
|
||||||
|
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||||
|
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||||
|
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||||
"Unable to retrieve current position": "Unable to retrieve current position",
|
"Unable to retrieve current position": "Unable to retrieve current position",
|
||||||
"Cannot Initialize Map": "Cannot Initialize Map",
|
"Cannot Initialize Map": "Cannot Initialize Map",
|
||||||
"Unsupported Map Provider": "Unsupported Map Provider",
|
"Unsupported Map Provider": "Unsupported Map Provider",
|
||||||
|
|||||||
@@ -1638,6 +1638,9 @@
|
|||||||
"Location on Map": "Ubicación en el mapa",
|
"Location on Map": "Ubicación en el mapa",
|
||||||
"Update Geographic Location": "Actualizar ubicación geográfica",
|
"Update Geographic Location": "Actualizar ubicación geográfica",
|
||||||
"Clear Geographic Location": "Borrar ubicación geográfica",
|
"Clear Geographic Location": "Borrar ubicación geográfica",
|
||||||
|
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||||
|
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||||
|
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||||
"Unable to retrieve current position": "No se puede recuperar la posición actual",
|
"Unable to retrieve current position": "No se puede recuperar la posición actual",
|
||||||
"Cannot Initialize Map": "No se puede inicializar el mapa",
|
"Cannot Initialize Map": "No se puede inicializar el mapa",
|
||||||
"Unsupported Map Provider": "Proveedor de mapas no compatible",
|
"Unsupported Map Provider": "Proveedor de mapas no compatible",
|
||||||
|
|||||||
@@ -1639,6 +1639,9 @@
|
|||||||
"Location on Map": "Posizione sulla mappa",
|
"Location on Map": "Posizione sulla mappa",
|
||||||
"Update Geographic Location": "Aggiorna posizione geografica",
|
"Update Geographic Location": "Aggiorna posizione geografica",
|
||||||
"Clear Geographic Location": "Cancella posizione geografica",
|
"Clear Geographic Location": "Cancella posizione geografica",
|
||||||
|
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||||
|
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||||
|
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||||
"Unable to retrieve current position": "Impossibile recuperare la posizione corrente",
|
"Unable to retrieve current position": "Impossibile recuperare la posizione corrente",
|
||||||
"Cannot Initialize Map": "Impossibile inizializzare la mappa",
|
"Cannot Initialize Map": "Impossibile inizializzare la mappa",
|
||||||
"Unsupported Map Provider": "Fornitore mappa non supportato",
|
"Unsupported Map Provider": "Fornitore mappa non supportato",
|
||||||
|
|||||||
@@ -1639,6 +1639,9 @@
|
|||||||
"Location on Map": "マップ上の座標",
|
"Location on Map": "マップ上の座標",
|
||||||
"Update Geographic Location": "地理座標の更新",
|
"Update Geographic Location": "地理座標の更新",
|
||||||
"Clear Geographic Location": "地理座標を削除",
|
"Clear Geographic Location": "地理座標を削除",
|
||||||
|
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||||
|
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||||
|
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||||
"Unable to retrieve current position": "現在位置を取得できません",
|
"Unable to retrieve current position": "現在位置を取得できません",
|
||||||
"Cannot Initialize Map": "マップを初期化できません",
|
"Cannot Initialize Map": "マップを初期化できません",
|
||||||
"Unsupported Map Provider": "サポートされていないマッププロバイダーです",
|
"Unsupported Map Provider": "サポートされていないマッププロバイダーです",
|
||||||
|
|||||||
@@ -1639,6 +1639,9 @@
|
|||||||
"Location on Map": "Местоположение на карте",
|
"Location on Map": "Местоположение на карте",
|
||||||
"Update Geographic Location": "Обновить географическое местоположение",
|
"Update Geographic Location": "Обновить географическое местоположение",
|
||||||
"Clear Geographic Location": "Очистить географическое местоположение",
|
"Clear Geographic Location": "Очистить географическое местоположение",
|
||||||
|
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||||
|
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||||
|
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||||
"Unable to retrieve current position": "Не удалось получить текущее местоположение",
|
"Unable to retrieve current position": "Не удалось получить текущее местоположение",
|
||||||
"Cannot Initialize Map": "Не удалось инициализировать карту",
|
"Cannot Initialize Map": "Не удалось инициализировать карту",
|
||||||
"Unsupported Map Provider": "Неподдерживаемый поставщик карт",
|
"Unsupported Map Provider": "Неподдерживаемый поставщик карт",
|
||||||
|
|||||||
@@ -1639,6 +1639,9 @@
|
|||||||
"Location on Map": "Розташування на карті",
|
"Location on Map": "Розташування на карті",
|
||||||
"Update Geographic Location": "Оновити геолокацію",
|
"Update Geographic Location": "Оновити геолокацію",
|
||||||
"Clear Geographic Location": "Очистити геолокацію",
|
"Clear Geographic Location": "Очистити геолокацію",
|
||||||
|
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||||
|
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||||
|
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||||
"Unable to retrieve current position": "Не вдалося отримати поточне розташування",
|
"Unable to retrieve current position": "Не вдалося отримати поточне розташування",
|
||||||
"Cannot Initialize Map": "Не вдалося ініціалізувати карту",
|
"Cannot Initialize Map": "Не вдалося ініціалізувати карту",
|
||||||
"Unsupported Map Provider": "Непідтримуваний провайдер карт",
|
"Unsupported Map Provider": "Непідтримуваний провайдер карт",
|
||||||
|
|||||||
@@ -1639,6 +1639,9 @@
|
|||||||
"Location on Map": "Vị trí trên bản đồ",
|
"Location on Map": "Vị trí trên bản đồ",
|
||||||
"Update Geographic Location": "Cập nhật vị trí địa lý",
|
"Update Geographic Location": "Cập nhật vị trí địa lý",
|
||||||
"Clear Geographic Location": "Xóa vị trí địa lý",
|
"Clear Geographic Location": "Xóa vị trí địa lý",
|
||||||
|
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||||
|
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||||
|
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||||
"Unable to retrieve current position": "Không thể lấy vị trí hiện tại",
|
"Unable to retrieve current position": "Không thể lấy vị trí hiện tại",
|
||||||
"Cannot Initialize Map": "Không thể khởi tạo bản đồ",
|
"Cannot Initialize Map": "Không thể khởi tạo bản đồ",
|
||||||
"Unsupported Map Provider": "Nhà cung cấp bản đồ không được hỗ trợ",
|
"Unsupported Map Provider": "Nhà cung cấp bản đồ không được hỗ trợ",
|
||||||
|
|||||||
@@ -1639,6 +1639,9 @@
|
|||||||
"Location on Map": "地图上的位置",
|
"Location on Map": "地图上的位置",
|
||||||
"Update Geographic Location": "更新地理位置",
|
"Update Geographic Location": "更新地理位置",
|
||||||
"Clear Geographic Location": "清除地理位置",
|
"Clear Geographic Location": "清除地理位置",
|
||||||
|
"Click on Map to Set Geographic Location": "地图上点击设置地理位置",
|
||||||
|
"Enable Click to Set Location": "启用点击设置位置",
|
||||||
|
"Disable Click to Set Location": "禁用点击设置位置",
|
||||||
"Unable to retrieve current position": "无法获取当前地理位置",
|
"Unable to retrieve current position": "无法获取当前地理位置",
|
||||||
"Cannot Initialize Map": "无法初始化地图",
|
"Cannot Initialize Map": "无法初始化地图",
|
||||||
"Unsupported Map Provider": "不支持的地图提供方",
|
"Unsupported Map Provider": "不支持的地图提供方",
|
||||||
|
|||||||
@@ -1639,6 +1639,9 @@
|
|||||||
"Location on Map": "地圖上的位置",
|
"Location on Map": "地圖上的位置",
|
||||||
"Update Geographic Location": "更新地理位置",
|
"Update Geographic Location": "更新地理位置",
|
||||||
"Clear Geographic Location": "清除地理位置",
|
"Clear Geographic Location": "清除地理位置",
|
||||||
|
"Click on Map to Set Geographic Location": "地圖上點選設定地理位置",
|
||||||
|
"Enable Click to Set Location": "啟用點選設定位置",
|
||||||
|
"Disable Click to Set Location": "停用點選設定位置",
|
||||||
"Unable to retrieve current position": "無法取得目前位置",
|
"Unable to retrieve current position": "無法取得目前位置",
|
||||||
"Cannot Initialize Map": "無法初始化地圖",
|
"Cannot Initialize Map": "無法初始化地圖",
|
||||||
"Unsupported Map Provider": "不支援的地圖提供者",
|
"Unsupported Map Provider": "不支援的地圖提供者",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { PartialRecord } from '@/core/base.ts';
|
import type { PartialRecord } from '@/core/base.ts';
|
||||||
import type { YearMonth, StartEndTime } from '@/core/datetime.ts';
|
import type { YearMonth, StartEndTime } from '@/core/datetime.ts';
|
||||||
|
import type { MapPosition } from '@/core/map.ts';
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
|
|
||||||
import { Account, type AccountInfoResponse } from './account.ts';
|
import { Account, type AccountInfoResponse } from './account.ts';
|
||||||
@@ -72,6 +73,11 @@ export class Transaction implements TransactionInfoResponse {
|
|||||||
return this._geoLocation;
|
return this._geoLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public set geoLocation(value: MapPosition) {
|
||||||
|
this._geoLocation = TransactionGeoLocation.of(value);
|
||||||
|
}
|
||||||
|
|
||||||
public get categoryId(): string {
|
public get categoryId(): string {
|
||||||
return this.getCategoryId();
|
return this.getCategoryId();
|
||||||
}
|
}
|
||||||
@@ -404,8 +410,8 @@ export class TransactionGeoLocation implements TransactionGeoLocationRequest {
|
|||||||
return new TransactionGeoLocation(latitude, longitude);
|
return new TransactionGeoLocation(latitude, longitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static of(geoLocation: TransactionGeoLocationRequest): TransactionGeoLocation {
|
public static of(mapPosition: MapPosition): TransactionGeoLocation {
|
||||||
return new TransactionGeoLocation(geoLocation.latitude, geoLocation.longitude);
|
return new TransactionGeoLocation(mapPosition.latitude, mapPosition.longitude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,10 +502,7 @@ export interface TransactionListInMonthByPageRequest {
|
|||||||
readonly keyword: string;
|
readonly keyword: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TransactionGeoLocationResponse {
|
export type TransactionGeoLocationResponse = MapPosition;
|
||||||
readonly latitude: number;
|
|
||||||
readonly longitude: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TransactionInfoResponse {
|
export interface TransactionInfoResponse {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
|||||||
const submitting = ref<boolean>(false);
|
const submitting = ref<boolean>(false);
|
||||||
const uploadingPicture = ref<boolean>(false);
|
const uploadingPicture = ref<boolean>(false);
|
||||||
const geoLocationStatus = ref<GeoLocationStatus | null>(null);
|
const geoLocationStatus = ref<GeoLocationStatus | null>(null);
|
||||||
|
const setGeoLocationByClickMap = ref<boolean>(false);
|
||||||
|
|
||||||
const transaction = ref<Transaction | TransactionTemplate>(createNewTransactionModel(transactionDefaultType));
|
const transaction = ref<Transaction | TransactionTemplate>(createNewTransactionModel(transactionDefaultType));
|
||||||
|
|
||||||
@@ -378,6 +379,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
|||||||
submitting,
|
submitting,
|
||||||
uploadingPicture,
|
uploadingPicture,
|
||||||
geoLocationStatus,
|
geoLocationStatus,
|
||||||
|
setGeoLocationByClickMap,
|
||||||
transaction,
|
transaction,
|
||||||
// computed states
|
// computed states
|
||||||
currentTimezoneOffsetMinutes,
|
currentTimezoneOffsetMinutes,
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
<v-progress-circular indeterminate size="22" class="ml-2" v-if="loading"></v-progress-circular>
|
<v-progress-circular indeterminate size="22" class="ml-2" v-if="loading"></v-progress-circular>
|
||||||
</div>
|
</div>
|
||||||
<v-btn density="comfortable" color="default" variant="text" class="ml-2" :icon="true"
|
<v-btn density="comfortable" color="default" variant="text" class="ml-2" :icon="true"
|
||||||
:disabled="loading || submitting" v-if="mode !== TransactionEditPageMode.View">
|
:disabled="loading || submitting" v-if="mode !== TransactionEditPageMode.View && (activeTab === 'basicInfo' || (activeTab === 'map' && isSupportGetGeoLocationByClick()))">
|
||||||
<v-icon :icon="mdiDotsVertical" />
|
<v-icon :icon="mdiDotsVertical" />
|
||||||
<v-menu activator="parent">
|
<v-menu activator="parent">
|
||||||
<v-list>
|
<v-list v-if="activeTab === 'basicInfo'">
|
||||||
<v-list-item :prepend-icon="mdiSwapHorizontal"
|
<v-list-item :prepend-icon="mdiSwapHorizontal"
|
||||||
:title="tt('Swap Account')"
|
:title="tt('Swap Account')"
|
||||||
v-if="transaction.type === TransactionType.Transfer"
|
v-if="transaction.type === TransactionType.Transfer"
|
||||||
@@ -32,6 +32,19 @@
|
|||||||
:title="tt('Hide Amount')"
|
:title="tt('Hide Amount')"
|
||||||
v-if="!transaction.hideAmount" @click="transaction.hideAmount = true"></v-list-item>
|
v-if="!transaction.hideAmount" @click="transaction.hideAmount = true"></v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
|
<v-list v-if="activeTab === 'map'">
|
||||||
|
<v-list-item key="setGeoLocationByClickMap" value="setGeoLocationByClickMap"
|
||||||
|
:prepend-icon="mdiMapMarkerOutline"
|
||||||
|
:disabled="!transaction.geoLocation" v-if="isSupportGetGeoLocationByClick()">
|
||||||
|
<v-list-item-title class="cursor-pointer" @click="setGeoLocationByClickMap = !setGeoLocationByClickMap; geoMenuState = false">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<span>{{ tt('Click on Map to Set Geographic Location') }}</span>
|
||||||
|
<v-spacer/>
|
||||||
|
<v-icon :icon="mdiCheck" v-if="setGeoLocationByClickMap" />
|
||||||
|
</div>
|
||||||
|
</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
@@ -346,7 +359,7 @@
|
|||||||
<v-window-item value="map">
|
<v-window-item value="map">
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12" md="12">
|
<v-col cols="12" md="12">
|
||||||
<map-view ref="map" map-class="transaction-edit-map-view" :geo-location="transaction.geoLocation">
|
<map-view ref="map" map-class="transaction-edit-map-view" :geo-location="transaction.geoLocation" @click="updateSpecifiedGeoLocation">
|
||||||
<template #error-title="{ mapSupported, mapDependencyLoaded }">
|
<template #error-title="{ mapSupported, mapDependencyLoaded }">
|
||||||
<span class="text-subtitle-1" v-if="!mapSupported"><b>{{ tt('Unsupported Map Provider') }}</b></span>
|
<span class="text-subtitle-1" v-if="!mapSupported"><b>{{ tt('Unsupported Map Provider') }}</b></span>
|
||||||
<span class="text-subtitle-1" v-else-if="!mapDependencyLoaded"><b>{{ tt('Cannot Initialize Map') }}</b></span>
|
<span class="text-subtitle-1" v-else-if="!mapDependencyLoaded"><b>{{ tt('Cannot Initialize Map') }}</b></span>
|
||||||
@@ -463,6 +476,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
|||||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||||
|
|
||||||
|
import type { MapPosition } from '@/core/map.ts';
|
||||||
import { CategoryType } from '@/core/category.ts';
|
import { CategoryType } from '@/core/category.ts';
|
||||||
import { TransactionType, TransactionEditScopeType } from '@/core/transaction.ts';
|
import { TransactionType, TransactionEditScopeType } from '@/core/transaction.ts';
|
||||||
import { TemplateType, ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
import { TemplateType, ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
||||||
@@ -488,6 +502,9 @@ import {
|
|||||||
isTransactionPicturesEnabled,
|
isTransactionPicturesEnabled,
|
||||||
getMapProvider
|
getMapProvider
|
||||||
} from '@/lib/server_settings.ts';
|
} from '@/lib/server_settings.ts';
|
||||||
|
import {
|
||||||
|
isSupportGetGeoLocationByClick
|
||||||
|
} from '@/lib/map/index.ts';
|
||||||
import logger from '@/lib/logger.ts';
|
import logger from '@/lib/logger.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -495,6 +512,8 @@ import {
|
|||||||
mdiEyeOffOutline,
|
mdiEyeOffOutline,
|
||||||
mdiEyeOutline,
|
mdiEyeOutline,
|
||||||
mdiSwapHorizontal,
|
mdiSwapHorizontal,
|
||||||
|
mdiMapMarkerOutline,
|
||||||
|
mdiCheck,
|
||||||
mdiPound,
|
mdiPound,
|
||||||
mdiMenuDown,
|
mdiMenuDown,
|
||||||
mdiImagePlusOutline,
|
mdiImagePlusOutline,
|
||||||
@@ -537,6 +556,7 @@ const {
|
|||||||
submitting,
|
submitting,
|
||||||
uploadingPicture,
|
uploadingPicture,
|
||||||
geoLocationStatus,
|
geoLocationStatus,
|
||||||
|
setGeoLocationByClickMap,
|
||||||
transaction,
|
transaction,
|
||||||
defaultCurrency,
|
defaultCurrency,
|
||||||
defaultAccountId,
|
defaultAccountId,
|
||||||
@@ -671,6 +691,7 @@ function open(options: TransactionEditOptions): Promise<TransactionEditResponse
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
submitting.value = false;
|
submitting.value = false;
|
||||||
geoLocationStatus.value = null;
|
geoLocationStatus.value = null;
|
||||||
|
setGeoLocationByClickMap.value = false;
|
||||||
originalTransactionEditable.value = false;
|
originalTransactionEditable.value = false;
|
||||||
|
|
||||||
initCategoryId.value = options.categoryId;
|
initCategoryId.value = options.categoryId;
|
||||||
@@ -1044,6 +1065,13 @@ function updateGeoLocation(forceUpdate: boolean): void {
|
|||||||
geoLocationStatus.value = GeoLocationStatus.Getting;
|
geoLocationStatus.value = GeoLocationStatus.Getting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateSpecifiedGeoLocation(mapPosition: MapPosition): void {
|
||||||
|
if (isSupportGetGeoLocationByClick() && setGeoLocationByClickMap.value) {
|
||||||
|
transaction.value.setLatitudeAndLongitude(mapPosition.latitude, mapPosition.longitude);
|
||||||
|
map.value?.setMarkerPosition(transaction.value.geoLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function clearGeoLocation(): void {
|
function clearGeoLocation(): void {
|
||||||
geoMenuState.value = false;
|
geoMenuState.value = false;
|
||||||
geoLocationStatus.value = null;
|
geoLocationStatus.value = null;
|
||||||
|
|||||||
@@ -344,6 +344,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<map-sheet v-model="transaction.geoLocation"
|
<map-sheet v-model="transaction.geoLocation"
|
||||||
|
v-model:set-geo-location-by-click-map="setGeoLocationByClickMap"
|
||||||
v-model:show="showGeoLocationMapSheet">
|
v-model:show="showGeoLocationMapSheet">
|
||||||
</map-sheet>
|
</map-sheet>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
@@ -549,6 +550,7 @@ const {
|
|||||||
submitting,
|
submitting,
|
||||||
uploadingPicture,
|
uploadingPicture,
|
||||||
geoLocationStatus,
|
geoLocationStatus,
|
||||||
|
setGeoLocationByClickMap,
|
||||||
transaction,
|
transaction,
|
||||||
currentTimezoneOffsetMinutes,
|
currentTimezoneOffsetMinutes,
|
||||||
defaultCurrency,
|
defaultCurrency,
|
||||||
|
|||||||
Reference in New Issue
Block a user