mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-20 17:54:30 +08:00
support map provider and whether use map data proxy settings
This commit is contained in:
+5
-1
@@ -145,7 +145,11 @@ func startWebServer(c *cli.Context) error {
|
|||||||
proxyRoute := router.Group("/proxy")
|
proxyRoute := router.Group("/proxy")
|
||||||
proxyRoute.Use(bindMiddleware(middlewares.JWTAuthorizationByQueryString))
|
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")
|
apiRoute := router.Group("/api")
|
||||||
|
|||||||
@@ -110,6 +110,13 @@ enable_register = true
|
|||||||
# Set to true to allow users to export their data
|
# Set to true to allow users to export their data
|
||||||
enable_export = true
|
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]
|
||||||
# Exchange rates data source, supports the following types:
|
# Exchange rates data source, supports the following types:
|
||||||
# "euro_central_bank"
|
# "euro_central_bank"
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ var (
|
|||||||
ErrGettingLocalAddress = NewSystemError(SystemSubcategorySetting, 2, http.StatusInternalServerError, "failed to get local address")
|
ErrGettingLocalAddress = NewSystemError(SystemSubcategorySetting, 2, http.StatusInternalServerError, "failed to get local address")
|
||||||
ErrInvalidUuidMode = NewSystemError(SystemSubcategorySetting, 3, http.StatusInternalServerError, "invalid uuid mode")
|
ErrInvalidUuidMode = NewSystemError(SystemSubcategorySetting, 3, http.StatusInternalServerError, "invalid uuid mode")
|
||||||
ErrInvalidExchangeRatesDataSource = NewSystemError(SystemSubcategorySetting, 4, http.StatusInternalServerError, "invalid exchange rates data source")
|
ErrInvalidExchangeRatesDataSource = NewSystemError(SystemSubcategorySetting, 4, http.StatusInternalServerError, "invalid exchange rates data source")
|
||||||
|
ErrInvalidMapProvider = NewSystemError(SystemSubcategorySetting, 5, http.StatusInternalServerError, "invalid map provider")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ func ServerSettingsCookie(config *settings.Config) core.MiddlewareHandlerFunc {
|
|||||||
settingsArr := []string{
|
settingsArr := []string{
|
||||||
buildBooleanSetting("r", config.EnableUserRegister),
|
buildBooleanSetting("r", config.EnableUserRegister),
|
||||||
buildBooleanSetting("e", config.EnableDataExport),
|
buildBooleanSetting("e", config.EnableDataExport),
|
||||||
|
buildStringSetting("m", config.MapProvider),
|
||||||
|
buildBooleanSetting("mp", config.EnableMapDataFetchProxy),
|
||||||
}
|
}
|
||||||
|
|
||||||
bundledSettings := strings.Join(settingsArr, "_")
|
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 {
|
func buildBooleanSetting(key string, value bool) string {
|
||||||
if value {
|
if value {
|
||||||
return fmt.Sprintf("%s.1", key)
|
return fmt.Sprintf("%s.1", key)
|
||||||
|
|||||||
@@ -62,6 +62,11 @@ const (
|
|||||||
InternalUuidGeneratorType string = "internal"
|
InternalUuidGeneratorType string = "internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Map provider types
|
||||||
|
const (
|
||||||
|
OpenStreetMapProvider string = "openstreetmap"
|
||||||
|
)
|
||||||
|
|
||||||
// Exchange rates data source types
|
// Exchange rates data source types
|
||||||
const (
|
const (
|
||||||
EuroCentralBankDataSource string = "euro_central_bank"
|
EuroCentralBankDataSource string = "euro_central_bank"
|
||||||
@@ -169,6 +174,10 @@ type Config struct {
|
|||||||
// Data
|
// Data
|
||||||
EnableDataExport bool
|
EnableDataExport bool
|
||||||
|
|
||||||
|
// Map
|
||||||
|
MapProvider string
|
||||||
|
EnableMapDataFetchProxy bool
|
||||||
|
|
||||||
// Exchange Rates
|
// Exchange Rates
|
||||||
ExchangeRatesDataSource string
|
ExchangeRatesDataSource string
|
||||||
ExchangeRatesRequestTimeout uint32
|
ExchangeRatesRequestTimeout uint32
|
||||||
@@ -239,6 +248,12 @@ func LoadConfiguration(configFilePath string) (*Config, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = loadMapConfiguration(config, cfgFile, "map")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
err = loadExchangeRatesConfiguration(config, cfgFile, "exchange_rates")
|
err = loadExchangeRatesConfiguration(config, cfgFile, "exchange_rates")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -416,6 +431,17 @@ func loadDataConfiguration(config *Config, configFile *ini.File, sectionName str
|
|||||||
return nil
|
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 {
|
func loadExchangeRatesConfiguration(config *Config, configFile *ini.File, sectionName string) error {
|
||||||
if getConfigItemStringValue(configFile, sectionName, "data_source") == EuroCentralBankDataSource {
|
if getConfigItemStringValue(configFile, sectionName, "data_source") == EuroCentralBankDataSource {
|
||||||
config.ExchangeRatesDataSource = EuroCentralBankDataSource
|
config.ExchangeRatesDataSource = EuroCentralBankDataSource
|
||||||
|
|||||||
@@ -8,9 +8,20 @@
|
|||||||
<f7-link :text="$t('Done')" @click="save"></f7-link>
|
<f7-link :text="$t('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" v-if="knownMapProvider">
|
||||||
<div ref="map" style="height: 400px; width: 100%"></div>
|
<div ref="map" style="height: 400px; width: 100%"></div>
|
||||||
</f7-page-content>
|
</f7-page-content>
|
||||||
|
<f7-page-content class="no-margin-top no-padding-top" v-else-if="!knownMapProvider">
|
||||||
|
<div class="display-flex padding justify-content-space-between align-items-center">
|
||||||
|
<div style="font-size: 18px"><b>{{ $t('Unsupported Map Provider') }}</b></div>
|
||||||
|
</div>
|
||||||
|
<div class="padding-horizontal padding-bottom">
|
||||||
|
<p class="no-margin">{{ $t('Please refresh the page and try again. If the error is still displayed, make sure that server map settings are set correctly.') }}</p>
|
||||||
|
<div class="margin-top text-align-center">
|
||||||
|
<f7-link @click="close" :text="$t('Close')"></f7-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</f7-page-content>
|
||||||
</f7-sheet>
|
</f7-sheet>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -25,7 +36,14 @@ export default {
|
|||||||
'update:show'
|
'update:show'
|
||||||
],
|
],
|
||||||
data() {
|
data() {
|
||||||
|
let knownMapProvider = false;
|
||||||
|
|
||||||
|
if (this.$settings.getMapProvider() === 'openstreetmap') {
|
||||||
|
knownMapProvider = true;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
knownMapProvider: knownMapProvider,
|
||||||
leaflet: null,
|
leaflet: null,
|
||||||
tileLayer: null,
|
tileLayer: null,
|
||||||
zoomControl: null,
|
zoomControl: null,
|
||||||
@@ -61,60 +79,67 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.leaflet) {
|
if (this.knownMapProvider && this.$settings.getMapProvider() === 'openstreetmap') {
|
||||||
const mapContainer = this.$refs.map;
|
if (!this.leaflet) {
|
||||||
|
const mapContainer = this.$refs.map;
|
||||||
|
|
||||||
this.leaflet = this.$map.leaflet.map(mapContainer, {
|
this.leaflet = this.$map.leaflet.map(mapContainer, {
|
||||||
attributionControl: false,
|
attributionControl: false,
|
||||||
zoomControl: 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('© <a href="http://www.openstreetmap.org/copyright" class="external" target="_blank">OpenStreetMap</a>');
|
|
||||||
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.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);
|
this.tileLayer.addTo(this.leaflet);
|
||||||
} else {
|
|
||||||
this.marker.setLatLng(this.initCenter);
|
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('© <a href="http://www.openstreetmap.org/copyright" class="external" target="_blank">OpenStreetMap</a>');
|
||||||
|
this.attribution.addTo(this.leaflet);
|
||||||
|
|
||||||
|
isFirstInit = true;
|
||||||
}
|
}
|
||||||
} else if (centerChanged && this.zoomLevel <= 1) {
|
|
||||||
if (this.marker) {
|
if (isFirstInit || centerChanged) {
|
||||||
this.marker.remove();
|
this.leaflet.setView(this.initCenter, this.zoomLevel);
|
||||||
this.marker = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
onSheetClosed() {
|
||||||
|
|||||||
+13
-2
@@ -2,6 +2,7 @@ import axios from 'axios';
|
|||||||
|
|
||||||
import api from '../consts/api.js';
|
import api from '../consts/api.js';
|
||||||
import userState from './userstate.js';
|
import userState from './userstate.js';
|
||||||
|
import settings from './settings.js';
|
||||||
import utilities from './utilities/index.js';
|
import utilities from './utilities/index.js';
|
||||||
|
|
||||||
let needBlockRequest = false;
|
let needBlockRequest = false;
|
||||||
@@ -390,8 +391,18 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
generateOpenStreetMapTileImageUrl: () => {
|
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'
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -171,5 +171,7 @@ export default {
|
|||||||
setEnableAutoDarkMode: value => setOption('autoDarkMode', value),
|
setEnableAutoDarkMode: value => setOption('autoDarkMode', value),
|
||||||
isUserRegistrationEnabled: () => getServerSetting('r') === '1',
|
isUserRegistrationEnabled: () => getServerSetting('r') === '1',
|
||||||
isDataExportingEnabled: () => getServerSetting('e') === '1',
|
isDataExportingEnabled: () => getServerSetting('e') === '1',
|
||||||
|
getMapProvider: () => getServerSetting('m'),
|
||||||
|
isMapDataFetchProxyEnabled: () => getServerSetting('mp') === '1',
|
||||||
clearSettings: clearSettings
|
clearSettings: clearSettings
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -842,6 +842,8 @@ export default {
|
|||||||
'Update Geographic Location': 'Update Geographic Location',
|
'Update Geographic Location': 'Update Geographic Location',
|
||||||
'Clear Geographic Location': 'Clear Geographic Location',
|
'Clear Geographic Location': 'Clear Geographic Location',
|
||||||
'Unable to get current position': 'Unable to get current position',
|
'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',
|
'Tags': 'Tags',
|
||||||
'Your transaction description (optional)': 'Your transaction description (optional)',
|
'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?',
|
'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?',
|
||||||
|
|||||||
@@ -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': '不支持的地图提供方',
|
||||||
|
'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?': '您确定要保存这个金额为0的交易?',
|
'Are you sure you want to save this transaction whose amount is 0?': '您确定要保存这个金额为0的交易?',
|
||||||
|
|||||||
Reference in New Issue
Block a user