From 3c569061fe76ccb85956690a6c7c26c21d54a6e4 Mon Sep 17 00:00:00 2001 From: Crimson Date: Sat, 9 May 2026 01:59:49 +0500 Subject: [PATCH] =?UTF-8?q?fix27:=20=D0=BF=D0=BE=D0=BB=D0=BD=D1=8B=D0=B9?= =?UTF-8?q?=20production-=D1=84=D0=B8=D0=BA=D1=81=20dashboard/peer/i18n=20?= =?UTF-8?q?=D0=B1=D0=B5=D0=B7=20=D0=BB=D0=B5=D0=B3=D0=B0=D1=81=D0=B8-?= =?UTF-8?q?=D0=BA=D0=BE=D1=81=D1=82=D1=8B=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/frontend/package.json | 30 ++-- apps/frontend/pnpm-lock.yaml | 61 ++++++++ apps/frontend/src/api/peer/index.ts | 10 +- apps/frontend/src/lang/package/en.ts | 26 +++- apps/frontend/src/lang/package/ru.ts | 26 +++- apps/frontend/src/views/dashboard/index.vue | 149 +++++++++++++++++--- apps/frontend/src/views/login/index.vue | 6 +- apps/frontend/src/views/peer/list/index.vue | 41 +++++- apps/router/peer.go | 11 +- 9 files changed, 293 insertions(+), 67 deletions(-) diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 87cf581..4acab8e 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -12,20 +12,22 @@ "lint:prettier": "prettier --write \"**/*.{js,cjs,ts,json,tsx,css,less,scss,vue,html,md}\"", "lint:stylelint": "stylelint \"**/*.{css,scss,vue}\" --fix" }, - "dependencies": { - "@element-plus/icons-vue": "^1.0.0", - "@vueuse/core": "^9.1.1", - "axios": "^1.3.4", - "copy-to-clipboard": "^3.3.3", - "element-plus": "^2.3.1", - "nprogress": "^0.2.0", - "path-browserify": "^1.0.1", - "pinia": "^2.0.33", - "vue": "^3.2.45", - "vue-i18n": "9", - "vue-router": "^4.1.6", - "vuedraggable": "^4.1.0" - }, + "dependencies": { + "@element-plus/icons-vue": "^1.0.0", + "@vueuse/core": "^9.1.1", + "axios": "^1.3.4", + "copy-to-clipboard": "^3.3.3", + "echarts": "^5.5.1", + "element-plus": "^2.3.1", + "nprogress": "^0.2.0", + "path-browserify": "^1.0.1", + "pinia": "^2.0.33", + "vue": "^3.2.45", + "vue-echarts": "^7.0.3", + "vue-i18n": "9", + "vue-router": "^4.1.6", + "vuedraggable": "^4.1.0" + }, "devDependencies": { "@iconify-json/ep": "^1.1.8", "@types/nprogress": "^0.2.0", diff --git a/apps/frontend/pnpm-lock.yaml b/apps/frontend/pnpm-lock.yaml index 25a7e02..34a8690 100644 --- a/apps/frontend/pnpm-lock.yaml +++ b/apps/frontend/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: copy-to-clipboard: specifier: ^3.3.3 version: 3.3.3 + echarts: + specifier: ^5.5.1 + version: 5.6.0 element-plus: specifier: ^2.3.1 version: 2.3.1(vue@3.2.45) @@ -35,6 +38,9 @@ importers: vue: specifier: ^3.2.45 version: 3.2.45 + vue-echarts: + specifier: ^7.0.3 + version: 7.0.3(@vue/runtime-core@3.2.45)(echarts@5.6.0)(vue@3.2.45) vue-i18n: specifier: '9' version: 9.0.0(vue@3.2.45) @@ -1183,6 +1189,9 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + echarts@5.6.0: + resolution: {integrity: sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==} + electron-to-chromium@1.4.529: resolution: {integrity: sha512-6uyPyXTo8lkv8SWAmjKFbG42U073TXlzD4R8rW3EzuznhFS2olCIAfjjQtV2dV2ar/vRF55KUd3zQYnCB0dd3A==} @@ -2698,6 +2707,9 @@ packages: tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + tsutils@3.21.0: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -2868,6 +2880,17 @@ packages: terser: optional: true + vue-demi@0.13.11: + resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue-demi@0.14.6: resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} engines: {node: '>=12'} @@ -2879,6 +2902,16 @@ packages: '@vue/composition-api': optional: true + vue-echarts@7.0.3: + resolution: {integrity: sha512-/jSxNwOsw5+dYAUcwSfkLwKPuzTQ0Cepz1LxCOpj2QcHrrmUa/Ql0eQqMmc1rTPQVrh2JQ29n2dhq75ZcHvRDw==} + peerDependencies: + '@vue/runtime-core': ^3.0.0 + echarts: ^5.5.1 + vue: ^2.7.0 || ^3.1.1 + peerDependenciesMeta: + '@vue/runtime-core': + optional: true + vue-eslint-parser@9.3.1: resolution: {integrity: sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==} engines: {node: ^14.17.0 || >=16.0.0} @@ -2952,6 +2985,9 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + zrender@5.6.1: + resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==} + snapshots: '@aashutoshrathi/word-wrap@1.2.6': {} @@ -4155,6 +4191,11 @@ snapshots: duplexer@0.1.2: {} + echarts@5.6.0: + dependencies: + tslib: 2.3.0 + zrender: 5.6.1 + electron-to-chromium@1.4.529: {} element-plus@2.3.1(vue@3.2.45): @@ -5742,6 +5783,8 @@ snapshots: tslib@1.14.1: {} + tslib@2.3.0: {} + tsutils@3.21.0(typescript@4.9.3): dependencies: tslib: 1.14.1 @@ -5962,10 +6005,24 @@ snapshots: fsevents: 2.3.3 sass: 1.58.3 + vue-demi@0.13.11(vue@3.2.45): + dependencies: + vue: 3.2.45 + vue-demi@0.14.6(vue@3.2.45): dependencies: vue: 3.2.45 + vue-echarts@7.0.3(@vue/runtime-core@3.2.45)(echarts@5.6.0)(vue@3.2.45): + dependencies: + echarts: 5.6.0 + vue: 3.2.45 + vue-demi: 0.13.11(vue@3.2.45) + optionalDependencies: + '@vue/runtime-core': 3.2.45 + transitivePeerDependencies: + - '@vue/composition-api' + vue-eslint-parser@9.3.1(eslint@8.34.0): dependencies: debug: 4.3.4 @@ -6037,3 +6094,7 @@ snapshots: yargs-parser@20.2.9: {} yocto-queue@0.1.0: {} + + zrender@5.6.1: + dependencies: + tslib: 2.3.0 diff --git a/apps/frontend/src/api/peer/index.ts b/apps/frontend/src/api/peer/index.ts index c69d81a..8aaf67c 100644 --- a/apps/frontend/src/api/peer/index.ts +++ b/apps/frontend/src/api/peer/index.ts @@ -50,21 +50,21 @@ export function updatePeerApi(data: PeerUpdateDto): AxiosPromise { export function resetPeerTrafficApi(data: IdDto): AxiosPromise { return request({ url: `/peers/${data.id}/reset-traffic`, - method: "post", + method: "patch", }); } export function releaseKickPeerApi(data: IdDto): AxiosPromise { return request({ url: `/peers/${data.id}/release-kick`, - method: "post", + method: "patch", }); } export function kickPeerApi(id: number, data: KickPeerDto): AxiosPromise { return request({ url: `/peers/${id}/kick`, - method: "post", + method: "patch", data, }); } @@ -80,7 +80,7 @@ export function getPeerClientConfigApi( export function importPeerApi(data: FormData): AxiosPromise { return request({ - url: "/peers/import", + url: "/peer-import", method: "post", headers: { "Content-Type": "multipart/form-data", @@ -91,7 +91,7 @@ export function importPeerApi(data: FormData): AxiosPromise { export function exportPeerApi(): AxiosPromise { return request({ - url: "/peers/export", + url: "/peer-export", method: "post", responseType: "blob", }); diff --git a/apps/frontend/src/lang/package/en.ts b/apps/frontend/src/lang/package/en.ts index d832df1..3ffa0fb 100644 --- a/apps/frontend/src/lang/package/en.ts +++ b/apps/frontend/src/lang/package/en.ts @@ -20,6 +20,9 @@ export default { username: "Username", password: "Password", login: "Login", + capsLockOn: "Caps lock is On", + usernameFormatIncorrect: "Username format is incorrect", + passwordFormatIncorrect: "Password format is incorrect", }, dashboard: { stale: "Dashboard data is stale. Retrying automatically...", @@ -34,9 +37,19 @@ export default { todayDownload: "Today download", todayUpload: "Today upload", trafficChart: "Traffic & System Timeseries", + trafficSeriesChart: "Traffic: download/upload", + systemSeriesChart: "System: CPU/RAM", download: "Download", upload: "Upload", total: "Total", + security: { + hysteriaStopped: "Hysteria2 is stopped", + trafficApiUnavailable: "Traffic API is unavailable", + }, + error: { + trafficApiUnavailable: "Traffic API is unavailable", + collectorStale: "Collector data is stale", + }, }, admin: { changePasswordTitle: "Change password", @@ -93,8 +106,8 @@ export default { yearLater: "A year later", hourLater: "A hour later", dayLater: "A day later", - deleteConfirm: "Are you sure to delete the user \u300c{username}\u300d?", - resetTrafficConfirm: "Are you sure to reset traffic?", + deleteConfirm: "Are you sure to delete peer \u300c{username}\u300d?", + resetTrafficConfirm: "Are you sure to reset peer traffic?", invalid: "Invalid value", switchLanguageSuccess: "Language switched successfully", sizeChanged: "Interface size changed", @@ -116,7 +129,6 @@ export default { peer: { name: "Peer", remark: "Remark", - username: "Username", secret: "Secret", maxDevices: "Max devices", disabled: "Disabled", @@ -130,8 +142,6 @@ export default { clientQr: "Client QR", unlimited: "Unlimited", secretRotateConfirm: "Rotate peer secret? Existing client configurations will stop working until updated.", - pass: "Pass", - conPass: "ConPass", quota: "Quota", download: "Download", upload: "Upload", @@ -143,7 +153,6 @@ export default { online: "Online", offline: "Offline", device: "Online Devices", - role: "Role", unit: "Unit", loginAt: "Last login time", conAt: "Last connection time", @@ -153,6 +162,11 @@ export default { kickTip: "Force user to log off", releaseKick: "Release", releaseKickTip: "Remove offline status", + createdAt: "Created at", + bannedUntil: "Banned until", + totalTraffic: "Total traffic", + copyUri: "Copy URI", + more: "More", }, config: { huiWebPort: "HY2XS admin Web Port", diff --git a/apps/frontend/src/lang/package/ru.ts b/apps/frontend/src/lang/package/ru.ts index 1b9ce36..00b8be7 100644 --- a/apps/frontend/src/lang/package/ru.ts +++ b/apps/frontend/src/lang/package/ru.ts @@ -18,6 +18,9 @@ export default { username: "Логин", password: "Пароль", login: "Войти", + capsLockOn: "Caps Lock включён", + usernameFormatIncorrect: "Неверный формат логина", + passwordFormatIncorrect: "Неверный формат пароля", }, dashboard: { stale: "Данные дашборда устарели. Выполняется автоматическая повторная попытка...", @@ -32,9 +35,19 @@ export default { todayDownload: "Скачано за сегодня", todayUpload: "Отдано за сегодня", trafficChart: "Трафик и системные метрики", + trafficSeriesChart: "Трафик: download/upload", + systemSeriesChart: "Система: CPU/RAM", download: "Скачано", upload: "Отдано", total: "Всего", + security: { + hysteriaStopped: "Hysteria2 остановлена", + trafficApiUnavailable: "Traffic API недоступен", + }, + error: { + trafficApiUnavailable: "Traffic API недоступен", + collectorStale: "Данные коллектора устарели", + }, }, admin: { changePasswordTitle: "Смена пароля", @@ -89,8 +102,8 @@ export default { yearLater: "Через год", hourLater: "Через час", dayLater: "Через день", - deleteConfirm: "Вы уверены, что хотите удалить пользователя «{username}»?", - resetTrafficConfirm: "Сбросить трафик для пользователя?", + deleteConfirm: "Удалить пир «{username}»?", + resetTrafficConfirm: "Сбросить трафик для пира?", invalid: "Некорректное значение", switchLanguageSuccess: "Язык переключён", sizeChanged: "Размер интерфейса изменён", @@ -111,7 +124,6 @@ export default { peer: { name: "Пир", remark: "Комментарий", - username: "Логин", secret: "Секрет", maxDevices: "Лимит устройств", disabled: "Отключён", @@ -125,8 +137,6 @@ export default { clientQr: "QR клиента", unlimited: "Безлимит", secretRotateConfirm: "Сменить секрет пира? Текущие клиентские конфиги перестанут работать до обновления.", - pass: "Пароль входа", - conPass: "Пароль подключения", quota: "Квота", download: "Скачано", upload: "Отдано", @@ -138,7 +148,11 @@ export default { online: "Онлайн", offline: "Офлайн", device: "Устройства", - role: "Роль", + createdAt: "Создан", + bannedUntil: "Блокировка до", + totalTraffic: "Суммарный трафик", + copyUri: "Копировать URI", + more: "Ещё", unit: "Ед. изм.", loginAt: "Последний вход", conAt: "Последнее подключение", diff --git a/apps/frontend/src/views/dashboard/index.vue b/apps/frontend/src/views/dashboard/index.vue index 4994096..965f602 100644 --- a/apps/frontend/src/views/dashboard/index.vue +++ b/apps/frontend/src/views/dashboard/index.vue @@ -51,13 +51,10 @@ - - - - - - - +
+ + +
@@ -81,11 +78,24 @@