From 72c3bed203a47a7786a1c89d3051dcd8f125270b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Sat, 12 Apr 2025 22:10:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9D=E5=A7=8B=E5=8C=96=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/embed/locales/en_US/backend.mo | Bin 692 -> 0 bytes pkg/embed/locales/en_US/cli.mo | 3 -- pkg/embed/locales/en_US/web.mo | 3 -- pkg/embed/locales/zh_CN/cli.mo | 4 -- pkg/embed/locales/zh_CN/web.mo | 4 -- pkg/embed/locales/zh_TW/cli.mo | 4 -- pkg/embed/locales/zh_TW/web.mo | 4 -- web/gettext.config.js | 7 +++ web/package.json | 7 ++- web/pnpm-lock.yaml | 84 +++++++++++++++++++++++++++++ web/src/main.ts | 7 +-- web/src/utils/gettext/index.ts | 16 ++++++ web/src/utils/index.ts | 1 + 13 files changed, 117 insertions(+), 27 deletions(-) delete mode 100644 pkg/embed/locales/en_US/backend.mo delete mode 100644 pkg/embed/locales/en_US/cli.mo delete mode 100644 pkg/embed/locales/en_US/web.mo delete mode 100644 pkg/embed/locales/zh_CN/cli.mo delete mode 100644 pkg/embed/locales/zh_CN/web.mo delete mode 100644 pkg/embed/locales/zh_TW/cli.mo delete mode 100644 pkg/embed/locales/zh_TW/web.mo create mode 100644 web/gettext.config.js create mode 100644 web/src/utils/gettext/index.ts diff --git a/pkg/embed/locales/en_US/backend.mo b/pkg/embed/locales/en_US/backend.mo deleted file mode 100644 index 0530ef0df0d00354664d5f7656cc7b3dda0df282..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 692 zcmd<>^vlZgoGT#WQ#_IJxZJYqbGbU7SDsE zH5*@p#4Arh#hGTMb{<>X)p>qVr{k&XYh0hpb$y@9t{t~gefbudN6RzTWJSzgyXsS2 z*PTUK*;S{N=CLg=y*>xZW`8vGH4~#Do23|&#bE{$lO~IAf(nV3IakKby|%jR*wW5j zx7Mq_SSPl;EMj@%wY60TR?JFUUUvB2TJ<@L%AFQf-YdF3mn&l4yxYuz3KJE+oUpj4 zUL>}Bo3_-Z=}V`ch%53~-UPPYE_!uVV8*&^^<~kkv!cyFWaL+aW|q)bZ@N0aUeHqC z`tq&6R@~M%x&LNHb(Je-?Uvj2I{pJ#+;7|Rjo()bm1~q~KKQs}t?tSPJ6Fh6l?uhA zFR$9RcF~@MMb|fOEm*ynJ!#Ib7roDQ*RIaYDqk9-_2S@-<#xN2D^Gjy@B8z*SDb5? zL7C?1tO~s>_IYz5>LZp`|D4rT|8f%ly_wtR{)>{y3SaYg+nk9n?=I^O2dh8Y72d&r zcN@f<((u)rwA3NyL!9CJY?)AnYS#&WOY!wxCsxccTU(uL_T10(dhYfwtim!+914%G z-1;0GP&Zc0J0P=7`yNW<{(4dPTBiyuUIdHuWiyisS0^nhez7Q^XzOdi%HxanJ_p6D z=gYV37AtRQOHEUIowaBFqU{>9X5HI#VtM1ryQR-z>>o?34m9{U_PI9n864o{Rp_&A z@sKDvloh_bbk(DcE0glJtv>lnyLIK=X_^m8SI2G8Qk%K*?uPHHJ)djLy|7|l`JAoK nou;WT-*(`Lhl+=-5ub_Yoz|6ayN<0{`ZBdhe9k1z2VmO)B{FL* diff --git a/pkg/embed/locales/en_US/cli.mo b/pkg/embed/locales/en_US/cli.mo deleted file mode 100644 index 677059b3..00000000 --- a/pkg/embed/locales/en_US/cli.mo +++ /dev/null @@ -1,3 +0,0 @@ ->[jQhk'[j[6[jY0U슉*'O*^mZw!j_*'Nw(v)-๨zu\gz`ױpb-ijw\*ا>#yH -0v)jx.jpbX{ޙZjWbW -0v)ŊWݶ>#yHuW*'ijw-๨Mx%O9Ȩ6{m6N5mw \ No newline at end of file diff --git a/pkg/embed/locales/en_US/web.mo b/pkg/embed/locales/en_US/web.mo deleted file mode 100644 index a601acd0..00000000 --- a/pkg/embed/locales/en_US/web.mo +++ /dev/null @@ -1,3 +0,0 @@ ->[jQhk'[j[6[jY0U슉*'O*^mZw!j_*'Nw(v)-๨zu\gz`ױpb-ijw\*ا>#yH -0v)jx.jpbX{ޙZjWW -0v)ŊWݸ>#yHuW*'ijw-๨Mx%O9Ȩ6{m6N5mw \ No newline at end of file diff --git a/pkg/embed/locales/zh_CN/cli.mo b/pkg/embed/locales/zh_CN/cli.mo deleted file mode 100644 index ba0da4f5..00000000 --- a/pkg/embed/locales/zh_CN/cli.mo +++ /dev/null @@ -1,4 +0,0 @@ ->[jQhk'[j[5[j] z"}t -z{Sʗ{VZǭ -z{S}ĝx#ykjZW -0v)Ϯr:E®rڞ ®qbj)H?zfwhq^%-\*ا)^ ?v-!^Ȩޔy7(bJ)'yE*' ^MӍu] \ No newline at end of file diff --git a/pkg/embed/locales/zh_CN/web.mo b/pkg/embed/locales/zh_CN/web.mo deleted file mode 100644 index b22539c0..00000000 --- a/pkg/embed/locales/zh_CN/web.mo +++ /dev/null @@ -1,4 +0,0 @@ ->[jQhk'[j[5[j] z"}t -z{Sʗ{VZǭ -z{S}ĝx#ykjZW -0v)Ϯr:E®rڞ ®qbj)H?zfwhq^n-\*ا)^ ?v-!^Ȩޔy7(bJ)'yE*' ^MӍu] \ No newline at end of file diff --git a/pkg/embed/locales/zh_TW/cli.mo b/pkg/embed/locales/zh_TW/cli.mo deleted file mode 100644 index e3d82147..00000000 --- a/pkg/embed/locales/zh_TW/cli.mo +++ /dev/null @@ -1,4 +0,0 @@ ->[jQhk'[j[5[j] z"}t -z{Sʗ{VZǭ -z{S}ĝx#ykjZW -0v)Ϯr:E®rڞ Me®qbj)H?zfwhq^%-\*ا)^ ?v-!^Ȩޔy7(bNبO9Ȩ6{m6N5mw \ No newline at end of file diff --git a/pkg/embed/locales/zh_TW/web.mo b/pkg/embed/locales/zh_TW/web.mo deleted file mode 100644 index 3f2fd092..00000000 --- a/pkg/embed/locales/zh_TW/web.mo +++ /dev/null @@ -1,4 +0,0 @@ ->[jQhk'[j[5[j] z"}t -z{Sʗ{VZǭ -z{S}ĝx#ykjZW -0v)Ϯr:E®rڞ Me®qbj)H?zfwhq^n-\*ا)^ ?v-!^Ȩޔy7(bNبO9Ȩ6{m6N5mw \ No newline at end of file diff --git a/web/gettext.config.js b/web/gettext.config.js new file mode 100644 index 00000000..613d9257 --- /dev/null +++ b/web/gettext.config.js @@ -0,0 +1,7 @@ +module.exports = { + output: { + path: './src/locales', + potPath: './frontend.pot', + locales: ['en', 'zh_CN', 'zh_TW'] + } +} diff --git a/web/package.json b/web/package.json index e9c67534..fe9ed94e 100644 --- a/web/package.json +++ b/web/package.json @@ -20,7 +20,9 @@ "lint-only": "eslint . --fix", "format": "prettier --write src/", "copy": "cpx \"dist/**/*\" \"../pkg/embed/frontend\" -C", - "gen-auto-import": "tsx gen-auto-import.ts" + "gen-auto-import": "tsx gen-auto-import.ts", + "gettext:extract": "vue-gettext-extract", + "gettext:compile": "vue-gettext-compile" }, "dependencies": { "@alova/adapter-xhr": "^2.1.1", @@ -52,7 +54,8 @@ "vue": "^3.5.13", "vue-echarts": "^7.0.3", "vue-i18n": "^11.0.1", - "vue-router": "^4.5.0" + "vue-router": "^4.5.0", + "vue3-gettext": "4.0.0-alpha.8" }, "devDependencies": { "@iconify/json": "^2.2.290", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index d691eaa6..1efdfe9c 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -98,6 +98,9 @@ importers: vue-router: specifier: ^4.5.0 version: 4.5.0(vue@3.5.13(typescript@5.8.3)) + vue3-gettext: + specifier: 4.0.0-alpha.8 + version: 4.0.0-alpha.8(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.3)) devDependencies: '@iconify/json': specifier: ^2.2.290 @@ -1434,6 +1437,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + array-back@6.2.2: + resolution: {integrity: sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==} + engines: {node: '>=12.17'} + array-buffer-byte-length@1.0.2: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} @@ -1538,6 +1545,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -1569,6 +1580,15 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + command-line-args@6.0.1: + resolution: {integrity: sha512-Jr3eByUjqyK0qd8W0SGFW1nZwqCaNCtbXjRo2cRJC1OYxWl3MZ5t1US3jq+cO4sPavqgw4l9BMGX0CBe+trepg==} + engines: {node: '>=12.20'} + peerDependencies: + '@75lb/nature': latest + peerDependenciesMeta: + '@75lb/nature': + optional: true + commander@13.1.0: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} @@ -1985,6 +2005,15 @@ packages: find-index@0.1.1: resolution: {integrity: sha512-uJ5vWrfBKMcE6y2Z8834dwEZj9mNGxYa3t3I53OwFeuZ8D9oc2E5zcsrkuhX6h4iYrjhiv0T3szQmxlAV9uxDg==} + find-replace@5.0.2: + resolution: {integrity: sha512-Y45BAiE3mz2QsrN2fb5QEtO4qb44NcS7en/0y9PEVsg351HsLeVclP8QPMH79Le9sH3rs5RSwJu99W0WPZO43Q==} + engines: {node: '>=14'} + peerDependencies: + '@75lb/nature': latest + peerDependenciesMeta: + '@75lb/nature': + optional: true + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -2399,6 +2428,10 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} @@ -2417,6 +2450,9 @@ packages: lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -2763,6 +2799,9 @@ packages: pkg-types@2.1.0: resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} + pofile@1.1.4: + resolution: {integrity: sha512-r6Q21sKsY1AjTVVjOuU02VYKVNQGJNQHjTIvs4dEbeuuYfxgYk/DGD2mqqq4RDaVkwdSq0VEtmQUOPe/wH8X3g==} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -3143,6 +3182,10 @@ packages: engines: {node: '>=14.17'} hasBin: true + typical@7.3.0: + resolution: {integrity: sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==} + engines: {node: '>=12.17'} + uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} @@ -3424,6 +3467,14 @@ packages: peerDependencies: typescript: '>=5.0.0' + vue3-gettext@4.0.0-alpha.8: + resolution: {integrity: sha512-kz8hdgg0LuweeAUDFFH+L9GghfJ46CkmbyVY86xOm/eYi9/pUi5lWtpzDH25B80peUeoNF/uQdcli0wWaajS8g==} + engines: {node: '>= 20.0.0'} + hasBin: true + peerDependencies: + '@vue/compiler-sfc': '>=3.0.0' + vue: '>=3.0.0' + vue@3.5.13: resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} peerDependencies: @@ -5009,6 +5060,8 @@ snapshots: argparse@2.0.1: {} + array-back@6.2.2: {} + array-buffer-byte-length@1.0.2: dependencies: call-bound: 1.0.4 @@ -5125,6 +5178,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.4.1: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -5169,6 +5224,13 @@ snapshots: colorette@2.0.20: {} + command-line-args@6.0.1: + dependencies: + array-back: 6.2.2 + find-replace: 5.0.2 + lodash.camelcase: 4.3.0 + typical: 7.3.0 + commander@13.1.0: {} commander@2.20.3: {} @@ -5673,6 +5735,8 @@ snapshots: find-index@0.1.1: {} + find-replace@5.0.2: {} + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -6075,6 +6139,8 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lilconfig@3.1.3: {} + linkify-it@5.0.0: dependencies: uc.micro: 2.1.0 @@ -6093,6 +6159,8 @@ snapshots: lodash-es@4.17.21: {} + lodash.camelcase@4.3.0: {} + lodash.merge@4.6.2: {} lodash@4.17.21: {} @@ -6442,6 +6510,8 @@ snapshots: exsolve: 1.0.4 pathe: 2.0.3 + pofile@1.1.4: {} + possible-typed-array-names@1.1.0: {} postcss-selector-parser@6.1.2: @@ -6881,6 +6951,8 @@ snapshots: typescript@5.8.3: {} + typical@7.3.0: {} + uc.micro@2.1.0: {} ufo@1.5.4: {} @@ -7201,6 +7273,18 @@ snapshots: '@vue/language-core': 2.2.8(typescript@5.8.3) typescript: 5.8.3 + vue3-gettext@4.0.0-alpha.8(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.3)): + dependencies: + '@vue/compiler-sfc': 3.5.13 + chalk: 5.4.1 + command-line-args: 6.0.1 + glob: 11.0.1 + lilconfig: 3.1.3 + pofile: 1.1.4 + vue: 3.5.13(typescript@5.8.3) + transitivePeerDependencies: + - '@75lb/nature' + vue@3.5.13(typescript@5.8.3): dependencies: '@vue/compiler-dom': 3.5.13 diff --git a/web/src/main.ts b/web/src/main.ts index d96baabc..b4ff1b94 100644 --- a/web/src/main.ts +++ b/web/src/main.ts @@ -7,9 +7,9 @@ import { createApp } from 'vue' import App from './App.vue' import { setupI18n } from '@/i18n/i18n' -import { setupRouter } from './router' -import { setupStore, useThemeStore } from './store' -import { setupNaiveDiscreteApi } from './utils' +import { setupRouter } from '@/router' +import { setupStore, useThemeStore } from '@/store' +import { setupGettext, setupNaiveDiscreteApi } from '@/utils' import { install as VueMonacoEditorPlugin } from '@guolao/vue-monaco-editor' @@ -30,6 +30,7 @@ async function setupApp() { await setupStore(app) await setupNaiveDiscreteApi() await setupPanel().then(() => { + setupGettext(app) setupI18n(app) }) await setupRouter(app) diff --git a/web/src/utils/gettext/index.ts b/web/src/utils/gettext/index.ts new file mode 100644 index 00000000..8eb61e04 --- /dev/null +++ b/web/src/utils/gettext/index.ts @@ -0,0 +1,16 @@ +import type { App } from 'vue' +import { createGettext } from 'vue3-gettext' + +let gettext: ReturnType + +export function setupGettext(app: App) { + gettext = createGettext({ + availableLanguages: { + en: 'English', + zh_CN: '简体中文', + zh_TW: '繁體中文' + }, + defaultLanguage: 'zh_CN' + }) + app.use(gettext) +} diff --git a/web/src/utils/index.ts b/web/src/utils/index.ts index 9ae0b5ee..de8d05d6 100644 --- a/web/src/utils/index.ts +++ b/web/src/utils/index.ts @@ -1,5 +1,6 @@ export * from './auth' export * from './common' export * from './file' +export * from './gettext' export * from './http' export * from './storage'