From e6c2d76238c43264dfcd8aeaee401afc6b522970 Mon Sep 17 00:00:00 2001 From: dlandy Date: Wed, 8 Apr 2026 17:56:12 +0800 Subject: [PATCH] update --- Dockerfile | 4 +- client/.env.development.example | 2 + client/index.html | 14 +- client/package-lock.json | 30 ++ client/package.json | 2 + client/public/favicon.ico | Bin 0 -> 23072 bytes client/public/favicon.png | Bin 0 -> 8974 bytes client/public/favicon.svg | 40 +++ client/public/local-fonts.css | 6 + client/src/App.vue | 51 ++- client/src/admin/AdminApp.vue | 167 +++++----- client/src/admin/admin.scss | 126 ++++++-- client/src/admin/api.js | 5 + .../src/admin/components/AccessModeDialog.vue | 10 +- client/src/admin/components/AdminKpiRow.vue | 4 +- .../admin/components/AdminOverviewSection.vue | 287 ++++++++++++----- .../admin/components/AdminToolsSection.vue | 4 +- .../src/admin/components/ToolFormDialog.vue | 20 +- client/src/admin/pages/AdminOverviewPage.vue | 36 +-- client/src/admin/router.js | 2 +- client/src/admin/stores/console.js | 51 +++ client/src/api.js | 47 +++ client/src/style.scss | 110 ++++++- client/src/utils/markdown.js | 72 +++++ client/vite.config.js | 27 +- docker/runtime-entrypoint.sh | 35 ++ docs/DOCKER_RUN_TOOLSSHOW.md | 12 +- server/.env.example | 2 +- server/src/app.module.ts | 2 + .../src/modules/access/access.controller.ts | 11 + server/src/modules/access/access.service.ts | 80 ++++- .../access/dto/track-tool-interaction.dto.ts | 25 ++ .../admin-overview.controller.ts | 18 ++ .../admin-overview/admin-overview.module.ts | 9 + .../admin-overview/admin-overview.service.ts | 300 ++++++++++++++++++ .../admin-tools/admin-tools.service.ts | 41 ++- .../admin-tools/dto/create-tool.dto.ts | 7 +- .../admin-tools/dto/update-access-mode.dto.ts | 8 +- .../modules/downloads/downloads.service.ts | 9 - .../modules/tools/dto/get-tools-query.dto.ts | 3 +- server/src/modules/tools/tools.service.ts | 17 +- 41 files changed, 1361 insertions(+), 335 deletions(-) create mode 100644 client/.env.development.example create mode 100644 client/public/favicon.ico create mode 100644 client/public/favicon.png create mode 100644 client/public/favicon.svg create mode 100644 client/public/local-fonts.css create mode 100644 client/src/utils/markdown.js create mode 100644 docker/runtime-entrypoint.sh create mode 100644 server/src/modules/access/dto/track-tool-interaction.dto.ts create mode 100644 server/src/modules/admin-overview/admin-overview.controller.ts create mode 100644 server/src/modules/admin-overview/admin-overview.module.ts create mode 100644 server/src/modules/admin-overview/admin-overview.service.ts diff --git a/Dockerfile b/Dockerfile index 6dffd53..10d8442 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,7 +28,9 @@ COPY --from=server-builder /build/server/dist ./dist COPY --from=server-builder /build/server/prisma ./prisma RUN npx prisma generate COPY --from=client-builder /build/client/dist ./public +COPY docker/runtime-entrypoint.sh /usr/local/bin/toolsshow-entrypoint +RUN chmod +x /usr/local/bin/toolsshow-entrypoint EXPOSE 3000 -CMD ["sh", "-c", "npx prisma migrate deploy && node dist/src/main.js"] +CMD ["toolsshow-entrypoint"] diff --git a/client/.env.development.example b/client/.env.development.example new file mode 100644 index 0000000..9291a1f --- /dev/null +++ b/client/.env.development.example @@ -0,0 +1,2 @@ +VITE_API_BASE=/api/v1 +VITE_API_PROXY_TARGET=http://localhost:3000 diff --git a/client/index.html b/client/index.html index f0ba583..e7aa875 100644 --- a/client/index.html +++ b/client/index.html @@ -3,16 +3,14 @@ - ToolsShow - Vue3 客户端 - - - + 资源导航站点 + + + +
- \ No newline at end of file + diff --git a/client/package-lock.json b/client/package-lock.json index fb95f55..b96aeca 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,7 +9,9 @@ "version": "1.0.0", "dependencies": { "axios": "^1.13.1", + "dompurify": "^3.3.3", "element-plus": "^2.11.7", + "marked": "^17.0.5", "pinia": "^2.3.1", "vue": "^3.5.22", "vue-router": "^4.6.3" @@ -1257,6 +1259,13 @@ "@types/lodash": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/web-bluetooth": { "version": "0.0.20", "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", @@ -1518,6 +1527,15 @@ "node": ">=8" } }, + "node_modules/dompurify": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-3.3.3.tgz", + "integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -1893,6 +1911,18 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/marked": { + "version": "17.0.5", + "resolved": "https://registry.npmmirror.com/marked/-/marked-17.0.5.tgz", + "integrity": "sha512-6hLvc0/JEbRjRgzI6wnT2P1XuM1/RrrDEX0kPt0N7jGm1133g6X7DlxFasUIx+72aKAr904GTxhSLDrd5DIlZg==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", diff --git a/client/package.json b/client/package.json index 3c2ef60..4e2fbec 100644 --- a/client/package.json +++ b/client/package.json @@ -10,7 +10,9 @@ }, "dependencies": { "axios": "^1.13.1", + "dompurify": "^3.3.3", "element-plus": "^2.11.7", + "marked": "^17.0.5", "pinia": "^2.3.1", "vue": "^3.5.22", "vue-router": "^4.6.3" diff --git a/client/public/favicon.ico b/client/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ba619418b6fc292b2db0f7958dff396971b00068 GIT binary patch literal 23072 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

=x6Nngxs1D>uqI4lS*oPRUpg~AoEO8hI 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/local-fonts.css b/client/public/local-fonts.css new file mode 100644 index 0000000..e491b28 --- /dev/null +++ b/client/public/local-fonts.css @@ -0,0 +1,6 @@ +:root { + --font-sans: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; + --font-display: "Avenir Next", "Trebuchet MS", "Segoe UI", "PingFang SC", sans-serif; + --font-admin-sans: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; + --font-admin-mono: "Cascadia Code", "Consolas", "SFMono-Regular", monospace; +} diff --git a/client/src/App.vue b/client/src/App.vue index e7542a8..0ec970c 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -3,18 +3,14 @@

- - + 资源导航