From 8cf7bf859b826c95a3df90a4d36a3b90505d7f81 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sun, 4 Jun 2023 14:39:20 +0800 Subject: [PATCH] support map provider and whether use map data proxy settings --- cmd/webserver.go | 6 +- conf/ezbookkeeping.ini | 7 ++ pkg/errs/setting.go | 1 + pkg/middlewares/server_settings_cookie.go | 6 ++ pkg/settings/setting.go | 26 +++++ src/components/mobile/MapSheet.vue | 125 +++++++++++++--------- src/lib/services.js | 15 ++- src/lib/settings.js | 2 + src/locales/en.js | 2 + src/locales/zh_Hans.js | 2 + 10 files changed, 139 insertions(+), 53 deletions(-) diff --git a/cmd/webserver.go b/cmd/webserver.go index 7d0b9eea..d7a29321 100644 --- a/cmd/webserver.go +++ b/cmd/webserver.go @@ -145,7 +145,11 @@ func startWebServer(c *cli.Context) error { proxyRoute := router.Group("/proxy") proxyRoute.Use(bindMiddleware(middlewares.JWTAuthorizationByQueryString)) { - proxyRoute.GET("/openstreetmap/tile/:zoomLevel/:coordinateX/:fileName", bindProxy(api.MapImages.OpenStreetMapTileImageProxyHandler)) + if config.EnableMapDataFetchProxy { + if config.MapProvider == settings.OpenStreetMapProvider { + proxyRoute.GET("/openstreetmap/tile/:zoomLevel/:coordinateX/:fileName", bindProxy(api.MapImages.OpenStreetMapTileImageProxyHandler)) + } + } } apiRoute := router.Group("/api") diff --git a/conf/ezbookkeeping.ini b/conf/ezbookkeeping.ini index b7f2c9ad..cf8f9e4c 100644 --- a/conf/ezbookkeeping.ini +++ b/conf/ezbookkeeping.ini @@ -110,6 +110,13 @@ enable_register = true # Set to true to allow users to export their data enable_export = true +[map] +# Map provider, supports `openstreetmap` +map_provider = openstreetmap + +# Set to true to use the ezbookkeeping server to proxy map data requests, for "openstreetmap" +map_data_fetch_proxy = false + [exchange_rates] # Exchange rates data source, supports the following types: # "euro_central_bank" diff --git a/pkg/errs/setting.go b/pkg/errs/setting.go index 1be135a5..f6684271 100644 --- a/pkg/errs/setting.go +++ b/pkg/errs/setting.go @@ -9,4 +9,5 @@ var ( ErrGettingLocalAddress = NewSystemError(SystemSubcategorySetting, 2, http.StatusInternalServerError, "failed to get local address") ErrInvalidUuidMode = NewSystemError(SystemSubcategorySetting, 3, http.StatusInternalServerError, "invalid uuid mode") ErrInvalidExchangeRatesDataSource = NewSystemError(SystemSubcategorySetting, 4, http.StatusInternalServerError, "invalid exchange rates data source") + ErrInvalidMapProvider = NewSystemError(SystemSubcategorySetting, 5, http.StatusInternalServerError, "invalid map provider") ) diff --git a/pkg/middlewares/server_settings_cookie.go b/pkg/middlewares/server_settings_cookie.go index d78a88da..61582533 100644 --- a/pkg/middlewares/server_settings_cookie.go +++ b/pkg/middlewares/server_settings_cookie.go @@ -16,6 +16,8 @@ func ServerSettingsCookie(config *settings.Config) core.MiddlewareHandlerFunc { settingsArr := []string{ buildBooleanSetting("r", config.EnableUserRegister), buildBooleanSetting("e", config.EnableDataExport), + buildStringSetting("m", config.MapProvider), + buildBooleanSetting("mp", config.EnableMapDataFetchProxy), } bundledSettings := strings.Join(settingsArr, "_") @@ -25,6 +27,10 @@ func ServerSettingsCookie(config *settings.Config) core.MiddlewareHandlerFunc { } } +func buildStringSetting(key string, value string) string { + return fmt.Sprintf("%s.%s", key, strings.Replace(value, ".", "-", -1)) +} + func buildBooleanSetting(key string, value bool) string { if value { return fmt.Sprintf("%s.1", key) diff --git a/pkg/settings/setting.go b/pkg/settings/setting.go index 442291e1..415fb007 100644 --- a/pkg/settings/setting.go +++ b/pkg/settings/setting.go @@ -62,6 +62,11 @@ const ( InternalUuidGeneratorType string = "internal" ) +// Map provider types +const ( + OpenStreetMapProvider string = "openstreetmap" +) + // Exchange rates data source types const ( EuroCentralBankDataSource string = "euro_central_bank" @@ -169,6 +174,10 @@ type Config struct { // Data EnableDataExport bool + // Map + MapProvider string + EnableMapDataFetchProxy bool + // Exchange Rates ExchangeRatesDataSource string ExchangeRatesRequestTimeout uint32 @@ -239,6 +248,12 @@ func LoadConfiguration(configFilePath string) (*Config, error) { return nil, err } + err = loadMapConfiguration(config, cfgFile, "map") + + if err != nil { + return nil, err + } + err = loadExchangeRatesConfiguration(config, cfgFile, "exchange_rates") if err != nil { @@ -416,6 +431,17 @@ func loadDataConfiguration(config *Config, configFile *ini.File, sectionName str return nil } +func loadMapConfiguration(config *Config, configFile *ini.File, sectionName string) error { + if getConfigItemStringValue(configFile, sectionName, "map_provider") == OpenStreetMapProvider { + config.MapProvider = OpenStreetMapProvider + } else { + return errs.ErrInvalidMapProvider + } + + config.EnableMapDataFetchProxy = getConfigItemBoolValue(configFile, sectionName, "map_data_fetch_proxy", false) + + return nil +} func loadExchangeRatesConfiguration(config *Config, configFile *ini.File, sectionName string) error { if getConfigItemStringValue(configFile, sectionName, "data_source") == EuroCentralBankDataSource { config.ExchangeRatesDataSource = EuroCentralBankDataSource diff --git a/src/components/mobile/MapSheet.vue b/src/components/mobile/MapSheet.vue index 227ae1b3..df7645ec 100644 --- a/src/components/mobile/MapSheet.vue +++ b/src/components/mobile/MapSheet.vue @@ -8,9 +8,20 @@ - +
+ +
+
{{ $t('Unsupported Map Provider') }}
+
+
+

{{ $t('Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.') }}

+
+ +
+
+
@@ -25,7 +36,14 @@ export default { 'update:show' ], data() { + let knownMapProvider = false; + + if (this.$settings.getMapProvider() === 'openstreetmap') { + knownMapProvider = true; + } + return { + knownMapProvider: knownMapProvider, leaflet: null, tileLayer: null, zoomControl: null, @@ -61,60 +79,67 @@ export default { } } - if (!this.leaflet) { - const mapContainer = this.$refs.map; + if (this.knownMapProvider && this.$settings.getMapProvider() === 'openstreetmap') { + if (!this.leaflet) { + const mapContainer = this.$refs.map; - this.leaflet = this.$map.leaflet.map(mapContainer, { - attributionControl: false, - zoomControl: false - }); - - this.tileLayer = this.$map.leaflet.tileLayer(this.$map.generateOpenStreetMapTileImageUrl(), { - maxZoom: 19 - }); - this.tileLayer.addTo(this.leaflet); - - this.zoomControl = this.$map.leaflet.control.zoom({ - zoomInTitle: this.$t('Zoom in'), - zoomOutTitle: this.$t('Zoom out'), - }); - this.zoomControl.addTo(this.leaflet); - - this.attribution = this.$map.leaflet.control.attribution({ - prefix: false - }); - this.attribution.addAttribution('© OpenStreetMap'); - this.attribution.addTo(this.leaflet); - - isFirstInit = true; - } - - if (isFirstInit || centerChanged) { - this.leaflet.setView(this.initCenter, this.zoomLevel); - } - - if (centerChanged && this.zoomLevel > 1) { - if (!this.marker) { - const markerIcon = this.$map.leaflet.icon({ - iconUrl: 'img/map-marker-icon.png', - iconRetinaUrl: 'img/map-marker-icon-2x.png', - iconSize: [25, 32], - iconAnchor: [12, 32], - shadowUrl: 'img/map-marker-shadow.png', - shadowSize: [41, 32] + this.leaflet = this.$map.leaflet.map(mapContainer, { + attributionControl: false, + zoomControl: false }); - this.marker = this.$map.leaflet.marker(this.initCenter, { - icon: markerIcon + + const mapTileImageUrl = this.$map.generateOpenStreetMapTileImageUrl(); + + this.tileLayer = this.$map.leaflet.tileLayer(mapTileImageUrl.url, { + subdomains: mapTileImageUrl.subDomains, + maxZoom: 19 }); - this.marker.addTo(this.leaflet); - } else { - this.marker.setLatLng(this.initCenter); + this.tileLayer.addTo(this.leaflet); + + this.zoomControl = this.$map.leaflet.control.zoom({ + zoomInTitle: this.$t('Zoom in'), + zoomOutTitle: this.$t('Zoom out'), + }); + this.zoomControl.addTo(this.leaflet); + + this.attribution = this.$map.leaflet.control.attribution({ + prefix: false + }); + this.attribution.addAttribution('© OpenStreetMap'); + this.attribution.addTo(this.leaflet); + + isFirstInit = true; } - } else if (centerChanged && this.zoomLevel <= 1) { - if (this.marker) { - this.marker.remove(); - this.marker = null; + + if (isFirstInit || centerChanged) { + this.leaflet.setView(this.initCenter, this.zoomLevel); } + + if (centerChanged && this.zoomLevel > 1) { + if (!this.marker) { + const markerIcon = this.$map.leaflet.icon({ + iconUrl: 'img/map-marker-icon.png', + iconRetinaUrl: 'img/map-marker-icon-2x.png', + iconSize: [25, 32], + iconAnchor: [12, 32], + shadowUrl: 'img/map-marker-shadow.png', + shadowSize: [41, 32] + }); + this.marker = this.$map.leaflet.marker(this.initCenter, { + icon: markerIcon + }); + this.marker.addTo(this.leaflet); + } else { + this.marker.setLatLng(this.initCenter); + } + } else if (centerChanged && this.zoomLevel <= 1) { + if (this.marker) { + this.marker.remove(); + this.marker = null; + } + } + } else { + this.knownMapProvider = false; } }, onSheetClosed() { diff --git a/src/lib/services.js b/src/lib/services.js index 727c581a..f531e802 100644 --- a/src/lib/services.js +++ b/src/lib/services.js @@ -2,6 +2,7 @@ import axios from 'axios'; import api from '../consts/api.js'; import userState from './userstate.js'; +import settings from './settings.js'; import utilities from './utilities/index.js'; let needBlockRequest = false; @@ -390,8 +391,18 @@ export default { }); }, generateOpenStreetMapTileImageUrl: () => { - const token = userState.getToken(); + if (settings.isMapDataFetchProxyEnabled()) { + const token = userState.getToken(); - return api.baseProxyUrlPath + '/openstreetmap/tile/{z}/{x}/{y}.png?token=' + token; + return { + url: api.baseProxyUrlPath + '/openstreetmap/tile/{z}/{x}/{y}.png?token=' + token, + subDomains: '' + }; + } else { + return { + url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', + subDomains: 'abc' + }; + } }, }; diff --git a/src/lib/settings.js b/src/lib/settings.js index 935b9042..c4e78e5d 100644 --- a/src/lib/settings.js +++ b/src/lib/settings.js @@ -171,5 +171,7 @@ export default { setEnableAutoDarkMode: value => setOption('autoDarkMode', value), isUserRegistrationEnabled: () => getServerSetting('r') === '1', isDataExportingEnabled: () => getServerSetting('e') === '1', + getMapProvider: () => getServerSetting('m'), + isMapDataFetchProxyEnabled: () => getServerSetting('mp') === '1', clearSettings: clearSettings }; diff --git a/src/locales/en.js b/src/locales/en.js index c12aa4ab..f637580b 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -842,6 +842,8 @@ export default { 'Update Geographic Location': 'Update Geographic Location', 'Clear Geographic Location': 'Clear Geographic Location', 'Unable to get current position': 'Unable to get current position', + 'Unsupported Map Provider': 'Unsupported Map Provider', + 'Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.': 'Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.', '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?', diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js index 7fd10480..4ae0f943 100644 --- a/src/locales/zh_Hans.js +++ b/src/locales/zh_Hans.js @@ -842,6 +842,8 @@ export default { 'Update Geographic Location': '更新地理位置', 'Clear Geographic Location': '清除地理位置', 'Unable to get current position': '无法获取当前地理位置', + 'Unsupported Map Provider': '不支持的地图提供方', + 'Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.': '请刷新页面并重试。如果仍然显示错误,请确保正确设置了服务器地图设置。', 'Tags': '标签', 'Your transaction description (optional)': '你的交易描述 (可选)', 'Are you sure you want to save this transaction whose amount is 0?': '您确定要保存这个金额为0的交易?',