mirror of
https://github.com/setube/ogame-vue-ts.git
synced 2026-05-12 07:55:11 +08:00
feat: 支持Android端导出到Documents并多语言提示
Android端数据导出改为直接保存至Documents目录,导出成功后弹出带路径的多语言提示。引入@capacitor/status-bar与@capawesome/capacitor-file-picker依赖,主入口设置原生状态栏颜色与样式。各语言包补充导出成功带路径提示文案。
This commit is contained in:
@@ -40,4 +40,6 @@
|
|||||||
<!-- Permissions -->
|
<!-- Permissions -->
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
"@capacitor/core": "^8.0.0",
|
"@capacitor/core": "^8.0.0",
|
||||||
"@capacitor/filesystem": "^8.0.0",
|
"@capacitor/filesystem": "^8.0.0",
|
||||||
"@capacitor/share": "^8.0.0",
|
"@capacitor/share": "^8.0.0",
|
||||||
|
"@capacitor/status-bar": "^8.0.0",
|
||||||
|
"@capawesome/capacitor-file-picker": "^8.0.0",
|
||||||
"@tailwindcss/vite": "^4.1.17",
|
"@tailwindcss/vite": "^4.1.17",
|
||||||
"@tanstack/vue-table": "^8.21.3",
|
"@tanstack/vue-table": "^8.21.3",
|
||||||
"@vueuse/core": "^14.1.0",
|
"@vueuse/core": "^14.1.0",
|
||||||
|
|||||||
32
pnpm-lock.yaml
generated
32
pnpm-lock.yaml
generated
@@ -29,6 +29,12 @@ importers:
|
|||||||
'@capacitor/share':
|
'@capacitor/share':
|
||||||
specifier: ^8.0.0
|
specifier: ^8.0.0
|
||||||
version: 8.0.0(@capacitor/core@8.0.0)
|
version: 8.0.0(@capacitor/core@8.0.0)
|
||||||
|
'@capacitor/status-bar':
|
||||||
|
specifier: ^8.0.0
|
||||||
|
version: 8.0.0(@capacitor/core@8.0.0)
|
||||||
|
'@capawesome/capacitor-file-picker':
|
||||||
|
specifier: ^8.0.0
|
||||||
|
version: 8.0.0(@capacitor/core@8.0.0)
|
||||||
'@tailwindcss/vite':
|
'@tailwindcss/vite':
|
||||||
specifier: ^4.1.17
|
specifier: ^4.1.17
|
||||||
version: 4.1.17(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1))
|
version: 4.1.17(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1))
|
||||||
@@ -682,9 +688,19 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@capacitor/core': '>=8.0.0'
|
'@capacitor/core': '>=8.0.0'
|
||||||
|
|
||||||
|
'@capacitor/status-bar@8.0.0':
|
||||||
|
resolution: {integrity: sha512-aIj3bc7z8lfPgOen8HlrBrkfnxpFnh21OCx6jCUx4Mvv+B6eEkUQ49b32DOddgVfr+igRHLX2SYi7duqIsNDXg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@capacitor/core': '>=8.0.0'
|
||||||
|
|
||||||
'@capacitor/synapse@1.0.4':
|
'@capacitor/synapse@1.0.4':
|
||||||
resolution: {integrity: sha512-/C1FUo8/OkKuAT4nCIu/34ny9siNHr9qtFezu4kxm6GY1wNFxrCFWjfYx5C1tUhVGz3fxBABegupkpjXvjCHrw==}
|
resolution: {integrity: sha512-/C1FUo8/OkKuAT4nCIu/34ny9siNHr9qtFezu4kxm6GY1wNFxrCFWjfYx5C1tUhVGz3fxBABegupkpjXvjCHrw==}
|
||||||
|
|
||||||
|
'@capawesome/capacitor-file-picker@8.0.0':
|
||||||
|
resolution: {integrity: sha512-eA39o8phSRcA78tnmQT6T2h73pljt5g+TcxI3xdR1hlWG7nlGLM2fDfiAaQ/2IASI4TA+s+NGBW1TdOXbwQiOw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@capacitor/core': '>=8.0.0'
|
||||||
|
|
||||||
'@csstools/cascade-layer-name-parser@2.0.5':
|
'@csstools/cascade-layer-name-parser@2.0.5':
|
||||||
resolution: {integrity: sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==}
|
resolution: {integrity: sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -995,8 +1011,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==}
|
resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
'@electron/node-gyp@https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2':
|
'@electron/node-gyp@git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2':
|
||||||
resolution: {tarball: https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2}
|
resolution: {commit: 06b29aafb7708acef8b3669835c8a7857ebc92d2, repo: https://github.com/electron/node-gyp.git, type: git}
|
||||||
version: 10.2.0-electron.1
|
version: 10.2.0-electron.1
|
||||||
engines: {node: '>=12.13.0'}
|
engines: {node: '>=12.13.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -5143,8 +5159,16 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@capacitor/core': 8.0.0
|
'@capacitor/core': 8.0.0
|
||||||
|
|
||||||
|
'@capacitor/status-bar@8.0.0(@capacitor/core@8.0.0)':
|
||||||
|
dependencies:
|
||||||
|
'@capacitor/core': 8.0.0
|
||||||
|
|
||||||
'@capacitor/synapse@1.0.4': {}
|
'@capacitor/synapse@1.0.4': {}
|
||||||
|
|
||||||
|
'@capawesome/capacitor-file-picker@8.0.0(@capacitor/core@8.0.0)':
|
||||||
|
dependencies:
|
||||||
|
'@capacitor/core': 8.0.0
|
||||||
|
|
||||||
'@csstools/cascade-layer-name-parser@2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
|
'@csstools/cascade-layer-name-parser@2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
|
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
|
||||||
@@ -5480,7 +5504,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@electron/node-gyp@https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2':
|
'@electron/node-gyp@git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2':
|
||||||
dependencies:
|
dependencies:
|
||||||
env-paths: 2.2.1
|
env-paths: 2.2.1
|
||||||
exponential-backoff: 3.1.3
|
exponential-backoff: 3.1.3
|
||||||
@@ -5517,7 +5541,7 @@ snapshots:
|
|||||||
|
|
||||||
'@electron/rebuild@3.7.0':
|
'@electron/rebuild@3.7.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@electron/node-gyp': https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2
|
'@electron/node-gyp': git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2
|
||||||
'@malept/cross-spawn-promise': 2.0.0
|
'@malept/cross-spawn-promise': 2.0.0
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
debug: 4.4.3
|
debug: 4.4.3
|
||||||
|
|||||||
@@ -850,6 +850,7 @@ export default {
|
|||||||
export: 'Exportieren',
|
export: 'Exportieren',
|
||||||
exporting: 'Exportieren...',
|
exporting: 'Exportieren...',
|
||||||
exportSuccess: 'Export erfolgreich',
|
exportSuccess: 'Export erfolgreich',
|
||||||
|
exportSuccessWithPath: 'Export erfolgreich, Datei gespeichert unter: {path}',
|
||||||
exportFailed: 'Export fehlgeschlagen, bitte erneut versuchen',
|
exportFailed: 'Export fehlgeschlagen, bitte erneut versuchen',
|
||||||
importData: 'Daten importieren',
|
importData: 'Daten importieren',
|
||||||
importDataDesc: 'Spielfortschritt aus JSON-Datei wiederherstellen',
|
importDataDesc: 'Spielfortschritt aus JSON-Datei wiederherstellen',
|
||||||
|
|||||||
@@ -886,6 +886,7 @@ export default {
|
|||||||
export: 'Export',
|
export: 'Export',
|
||||||
exporting: 'Exporting...',
|
exporting: 'Exporting...',
|
||||||
exportSuccess: 'Export successful',
|
exportSuccess: 'Export successful',
|
||||||
|
exportSuccessWithPath: 'Export successful, file saved to: {path}',
|
||||||
exportFailed: 'Export failed, please try again',
|
exportFailed: 'Export failed, please try again',
|
||||||
importData: 'Import Data',
|
importData: 'Import Data',
|
||||||
importDataDesc: 'Restore game progress from JSON file',
|
importDataDesc: 'Restore game progress from JSON file',
|
||||||
|
|||||||
@@ -844,6 +844,7 @@ export default {
|
|||||||
export: 'エクスポート',
|
export: 'エクスポート',
|
||||||
exporting: 'エクスポート中...',
|
exporting: 'エクスポート中...',
|
||||||
exportSuccess: 'エクスポート成功',
|
exportSuccess: 'エクスポート成功',
|
||||||
|
exportSuccessWithPath: 'エクスポート成功、ファイルの保存先:{path}',
|
||||||
exportFailed: 'エクスポートに失敗しました。もう一度お試しください',
|
exportFailed: 'エクスポートに失敗しました。もう一度お試しください',
|
||||||
importData: 'データインポート',
|
importData: 'データインポート',
|
||||||
importDataDesc: 'JSONファイルからゲームの進行状況を復元',
|
importDataDesc: 'JSONファイルからゲームの進行状況を復元',
|
||||||
|
|||||||
@@ -845,6 +845,7 @@ export default {
|
|||||||
export: '내보내기',
|
export: '내보내기',
|
||||||
exporting: '내보내는 중...',
|
exporting: '내보내는 중...',
|
||||||
exportSuccess: '내보내기 성공',
|
exportSuccess: '내보내기 성공',
|
||||||
|
exportSuccessWithPath: '내보내기 성공, 파일 저장 위치: {path}',
|
||||||
exportFailed: '내보내기 실패, 다시 시도해주세요',
|
exportFailed: '내보내기 실패, 다시 시도해주세요',
|
||||||
importData: '데이터 가져오기',
|
importData: '데이터 가져오기',
|
||||||
importDataDesc: 'JSON 파일에서 게임 진행 상황 복원',
|
importDataDesc: 'JSON 파일에서 게임 진행 상황 복원',
|
||||||
|
|||||||
@@ -851,6 +851,7 @@ export default {
|
|||||||
export: 'Экспорт',
|
export: 'Экспорт',
|
||||||
exporting: 'Экспорт...',
|
exporting: 'Экспорт...',
|
||||||
exportSuccess: 'Экспорт успешен',
|
exportSuccess: 'Экспорт успешен',
|
||||||
|
exportSuccessWithPath: 'Экспорт успешен, файл сохранен в: {path}',
|
||||||
exportFailed: 'Экспорт не удался, попробуйте еще раз',
|
exportFailed: 'Экспорт не удался, попробуйте еще раз',
|
||||||
importData: 'Импорт данных',
|
importData: 'Импорт данных',
|
||||||
importDataDesc: 'Восстановить прогресс игры из JSON файла',
|
importDataDesc: 'Восстановить прогресс игры из JSON файла',
|
||||||
|
|||||||
@@ -873,6 +873,7 @@ export default {
|
|||||||
export: '导出',
|
export: '导出',
|
||||||
exporting: '导出中...',
|
exporting: '导出中...',
|
||||||
exportSuccess: '导出成功',
|
exportSuccess: '导出成功',
|
||||||
|
exportSuccessWithPath: '导出成功,文件已保存到:{path}',
|
||||||
exportFailed: '导出失败,请重试',
|
exportFailed: '导出失败,请重试',
|
||||||
importData: '导入数据',
|
importData: '导入数据',
|
||||||
importDataDesc: '从JSON文件恢复游戏进度',
|
importDataDesc: '从JSON文件恢复游戏进度',
|
||||||
|
|||||||
@@ -846,6 +846,7 @@ export default {
|
|||||||
export: '匯出',
|
export: '匯出',
|
||||||
exporting: '匯出中...',
|
exporting: '匯出中...',
|
||||||
exportSuccess: '匯出成功',
|
exportSuccess: '匯出成功',
|
||||||
|
exportSuccessWithPath: '匯出成功,檔案已儲存到:{path}',
|
||||||
exportFailed: '匯出失敗,請重試',
|
exportFailed: '匯出失敗,請重試',
|
||||||
importData: '匯入資料',
|
importData: '匯入資料',
|
||||||
importDataDesc: '從JSON檔案恢復遊戲進度',
|
importDataDesc: '從JSON檔案恢復遊戲進度',
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||||
|
import { Capacitor } from '@capacitor/core'
|
||||||
|
import { StatusBar, Style } from '@capacitor/status-bar'
|
||||||
import './style.css'
|
import './style.css'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
|
||||||
|
// Android 设置状态栏
|
||||||
|
if (Capacitor.isNativePlatform()) {
|
||||||
|
StatusBar.setBackgroundColor({ color: '#1a1a2e' })
|
||||||
|
StatusBar.setStyle({ style: Style.Dark })
|
||||||
|
StatusBar.setOverlaysWebView({ overlay: false })
|
||||||
|
}
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
const pinia = createPinia()
|
const pinia = createPinia()
|
||||||
|
|
||||||
|
|||||||
@@ -334,8 +334,7 @@
|
|||||||
import { saveAs } from 'file-saver'
|
import { saveAs } from 'file-saver'
|
||||||
import { toast } from 'vue-sonner'
|
import { toast } from 'vue-sonner'
|
||||||
import { Capacitor } from '@capacitor/core'
|
import { Capacitor } from '@capacitor/core'
|
||||||
import { Filesystem, Directory } from '@capacitor/filesystem'
|
import { Filesystem, Directory, Encoding } from '@capacitor/filesystem'
|
||||||
import { Share } from '@capacitor/share'
|
|
||||||
import pkg from '../../package.json'
|
import pkg from '../../package.json'
|
||||||
import { checkLatestVersion, canCheckVersion } from '@/utils/versionCheck'
|
import { checkLatestVersion, canCheckVersion } from '@/utils/versionCheck'
|
||||||
import type { VersionInfo } from '@/utils/versionCheck'
|
import type { VersionInfo } from '@/utils/versionCheck'
|
||||||
@@ -527,20 +526,16 @@
|
|||||||
const fileName = `${pkg.name}-${new Date().toISOString().slice(0, 10)}-${Date.now()}.json`
|
const fileName = `${pkg.name}-${new Date().toISOString().slice(0, 10)}-${Date.now()}.json`
|
||||||
const jsonString = JSON.stringify(exportData, null, 2)
|
const jsonString = JSON.stringify(exportData, null, 2)
|
||||||
|
|
||||||
// Android 使用 Capacitor Filesystem + Share
|
// Android 保存到 Documents 目录
|
||||||
if (Capacitor.isNativePlatform()) {
|
if (Capacitor.isNativePlatform()) {
|
||||||
// 写入文件到缓存目录
|
|
||||||
const result = await Filesystem.writeFile({
|
const result = await Filesystem.writeFile({
|
||||||
path: fileName,
|
path: fileName,
|
||||||
data: jsonString,
|
data: jsonString,
|
||||||
directory: Directory.Cache
|
directory: Directory.Documents,
|
||||||
})
|
encoding: Encoding.UTF8
|
||||||
// 分享文件让用户选择保存位置
|
|
||||||
await Share.share({
|
|
||||||
title: t('settings.exportData'),
|
|
||||||
url: result.uri,
|
|
||||||
dialogTitle: t('settings.exportData')
|
|
||||||
})
|
})
|
||||||
|
toast.success(t('settings.exportSuccessWithPath', { path: result.uri }))
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
// Web 使用 file-saver
|
// Web 使用 file-saver
|
||||||
saveAs(new Blob([jsonString], { type: 'application/json' }), fileName)
|
saveAs(new Blob([jsonString], { type: 'application/json' }), fileName)
|
||||||
|
|||||||
Reference in New Issue
Block a user