From 4c88964473c108fa1145fa7709e933643edee414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Sun, 6 Sep 2026 10:41:47 +0800 Subject: [PATCH] =?UTF-8?q?task-283(=E5=90=8E=E5=8F=B0=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E6=94=B6=E5=B0=BE/=E5=8F=91=E5=B8=83):=20admin-vue=20=E5=90=8E?= =?UTF-8?q?=E5=8F=B0=E5=B7=A5=E7=A8=8B=E5=85=A5=E5=BA=93=20+=20Flask=20?= =?UTF-8?q?=E5=90=8E=E5=8F=B0=E6=95=B4=E4=BD=93=E9=80=80=E5=BD=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新后台 admin-frontend-vue 整工程入库(base=/admin-vue/、History 路由、Nginx 静态托管方案与 verify-dist 校验) - Java AdminConsoleController 改为入口重定向: /admin|/admin.html、/login|/login.html -> /admin-vue/; 删除 classpath:static 旧 admin.html/login.html 单页与 admin.js 副本 - Flask 后台整体退役: 删除 admin_api/auth/main 蓝图、web_source 页面、static 脚本与 admin 相关测试; app.py 收敛为仅注册 version_bp(/api/version、/api/version/latest, 供桌面端更新检查) - AdminApiGuardFilterTest 豁免样例路径 /admin.html -> /admin-vue/ --- admin-frontend-vue/.gitignore | 6 + admin-frontend-vue/README.md | 39 + admin-frontend-vue/index.html | 13 + .../public/assets}/logo.jpg | Bin admin-frontend-vue/src/App.vue | 7 + admin-frontend-vue/src/api/http.ts | 2 +- admin-frontend-vue/src/api/users-dto.ts | 2 +- admin-frontend-vue/src/layout/topbar-model.ts | 5 +- .../src/pages/account/GroupsPage.vue | 16 +- .../src/pages/account/MenusPage.vue | 18 +- .../src/pages/account/UsersPage.vue | 15 +- .../src/pages/asin/AsinInvalidPage.vue | 10 +- .../src/pages/asin/DedupeRegistryPage.vue | 19 +- .../src/pages/asin/QueryAsinPage.vue | 31 +- .../src/pages/asin/SkipPricePage.vue | 31 +- .../src/pages/login/LoginPage.vue | 333 + .../src/pages/records/history-dto.ts | 2 +- .../src/pages/shop/ShopKeysPage.vue | 11 +- .../src/pages/shop/ShopManagePage.vue | 17 +- .../src/pages/tasks/DuplicateCheckPage.vue | 10 +- .../pages/tasks/duplicate-console-model.ts | 132 + admin-frontend-vue/src/router/index.ts | 11 + .../src/router/menu-route-map.ts | 27 + admin-frontend-vue/src/router/routes.ts | 13 + .../src/stores/admin-session.ts | 6 +- admin-frontend-vue/src/styles/main.css | 12 +- admin-frontend-vue/src/vite-env.d.ts | 1 + .../tests/align-shop-columns.test.ts | 13 +- .../tests/duplicate-console.test.ts | 120 + .../live/task-180-public-version-live.test.ts | 49 + admin-frontend-vue/tests/task-10.test.ts | 2 +- admin-frontend-vue/tests/task-12.test.ts | 2 +- admin-frontend-vue/tests/task-16.test.ts | 2 +- admin-frontend-vue/tests/task-29.test.ts | 2 +- admin-frontend-vue/tests/task-36.test.ts | 2 +- admin-frontend-vue/tests/task-5.test.ts | 4 +- admin-frontend-vue/tests/task-8.test.ts | 2 +- admin-frontend-vue/tsconfig.node.json | 10 + admin-frontend-vue/vite.config.ts | 9 + .../controller/AdminConsoleController.java | 25 +- .../src/main/resources/static/admin.html | 6659 --------------- .../src/main/resources/static/login.html | 887 -- .../static/static/admin-interactions.js | 333 - .../src/main/resources/static/static/admin.js | 7206 ----------------- .../src/main/resources/static/static/bg.jpg | Bin 164259 -> 0 bytes .../resources/static/static/logo_thumb.png | Bin 6360 -> 0 bytes .../config/AdminApiGuardFilterTest.java | 2 +- .../service/ImageHistoryServiceTest.java | 42 + backend/ali_oss.py | 215 - backend/app.py | 27 +- backend/blueprints/admin_api.py | 4896 ----------- backend/blueprints/auth.py | 87 - backend/blueprints/main.py | 54 - backend/static/admin-interactions.js | 333 - backend/static/admin.js | 7206 ----------------- backend/static/bg.jpg | Bin 164259 -> 0 bytes backend/static/logo.jpg | Bin 10772 -> 0 bytes backend/static/logo_thumb.png | Bin 6360 -> 0 bytes backend/tests/test_admin_dedupe_total_data.py | 170 - backend/tests/test_admin_invalid_asin_data.py | 143 - .../tests/test_admin_proxy_internal_token.py | 111 - .../test_admin_shop_data_duplicate_check.py | 326 - backend/tests/test_admin_shop_data_groups.py | 226 - .../tests/test_python_java_http_contract.py | 117 - backend/utils/__init__.py | 2 +- backend/utils/auth.py | 113 - backend/utils/render.py | 22 - backend/utils/ssrf.py | 58 - backend/web_source/_admin_extracted.js | 2337 ------ backend/web_source/admin.html | 6659 --------------- backend/web_source/login.html | 862 -- 71 files changed, 974 insertions(+), 39150 deletions(-) create mode 100644 admin-frontend-vue/.gitignore create mode 100644 admin-frontend-vue/README.md create mode 100644 admin-frontend-vue/index.html rename {backend-java/src/main/resources/static/static => admin-frontend-vue/public/assets}/logo.jpg (100%) create mode 100644 admin-frontend-vue/src/App.vue create mode 100644 admin-frontend-vue/src/pages/login/LoginPage.vue create mode 100644 admin-frontend-vue/src/pages/tasks/duplicate-console-model.ts create mode 100644 admin-frontend-vue/src/router/menu-route-map.ts create mode 100644 admin-frontend-vue/src/vite-env.d.ts create mode 100644 admin-frontend-vue/tests/duplicate-console.test.ts create mode 100644 admin-frontend-vue/tests/live/task-180-public-version-live.test.ts create mode 100644 admin-frontend-vue/tsconfig.node.json delete mode 100644 backend-java/src/main/resources/static/admin.html delete mode 100644 backend-java/src/main/resources/static/login.html delete mode 100644 backend-java/src/main/resources/static/static/admin-interactions.js delete mode 100644 backend-java/src/main/resources/static/static/admin.js delete mode 100644 backend-java/src/main/resources/static/static/bg.jpg delete mode 100644 backend-java/src/main/resources/static/static/logo_thumb.png create mode 100644 backend-java/src/test/java/com/nanri/aiimage/modules/imagehistory/service/ImageHistoryServiceTest.java delete mode 100644 backend/ali_oss.py delete mode 100644 backend/blueprints/admin_api.py delete mode 100644 backend/blueprints/auth.py delete mode 100644 backend/blueprints/main.py delete mode 100644 backend/static/admin-interactions.js delete mode 100644 backend/static/admin.js delete mode 100644 backend/static/bg.jpg delete mode 100644 backend/static/logo.jpg delete mode 100644 backend/static/logo_thumb.png delete mode 100644 backend/tests/test_admin_dedupe_total_data.py delete mode 100644 backend/tests/test_admin_invalid_asin_data.py delete mode 100644 backend/tests/test_admin_proxy_internal_token.py delete mode 100644 backend/tests/test_admin_shop_data_duplicate_check.py delete mode 100644 backend/tests/test_admin_shop_data_groups.py delete mode 100644 backend/tests/test_python_java_http_contract.py delete mode 100644 backend/utils/auth.py delete mode 100644 backend/utils/render.py delete mode 100644 backend/utils/ssrf.py delete mode 100644 backend/web_source/_admin_extracted.js delete mode 100644 backend/web_source/admin.html delete mode 100644 backend/web_source/login.html diff --git a/admin-frontend-vue/.gitignore b/admin-frontend-vue/.gitignore new file mode 100644 index 00000000..b673f63c --- /dev/null +++ b/admin-frontend-vue/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +dist/ +.env* +!.env.example +test-results/ +vite-dev.log diff --git a/admin-frontend-vue/README.md b/admin-frontend-vue/README.md new file mode 100644 index 00000000..68526fdb --- /dev/null +++ b/admin-frontend-vue/README.md @@ -0,0 +1,39 @@ +# Admin Frontend Vue + +独立的后台管理前端工程,与客户端 `frontend-vue` 完全分离。 + +## 本地开发 + +```powershell +npm install +$env:VITE_API_TARGET = "http://127.0.0.1:18080" +npm run dev +``` + +开发入口:`http://localhost:5174/admin-vue/` + +## 构建 + +```powershell +npm run build +npm test +``` + +构建产物在 `dist/`,部署到 Nginx 的 `/admin-vue/` 根目录。该工程不写入客户端的 `new_web_source`,也不打进 Java JAR。 + +## 运行时契约 + +- 登录态:复用同源 Cookie/Session。 +- 当前用户:`GET /api/admin/current-user`。 +- 菜单树:`GET /api/admin/current-user/menus`,Java 返回树形菜单。 +- 退出登录:`POST /api/admin/logout`。 +- 前端路由:History 模式,基准路径 `/admin-vue/`。 +- 权限粒度:菜单/页面级,不定义按钮级权限。 + +## 首批页面 + +- `/admin-vue/account/users` +- `/admin-vue/account/menus` +- `/admin-vue/account/groups` + +当前首批页面已接入 Java 现有用户、菜单和数据权限分组 API;Java 菜单接口完成树形响应和 Flyway 菜单迁移后,路由权限守卫即可按最终菜单树工作。 diff --git a/admin-frontend-vue/index.html b/admin-frontend-vue/index.html new file mode 100644 index 00000000..9f5de7fe --- /dev/null +++ b/admin-frontend-vue/index.html @@ -0,0 +1,13 @@ + + + + + + + 数富AI - 后台管理 + + +
+ + + diff --git a/backend-java/src/main/resources/static/static/logo.jpg b/admin-frontend-vue/public/assets/logo.jpg similarity index 100% rename from backend-java/src/main/resources/static/static/logo.jpg rename to admin-frontend-vue/public/assets/logo.jpg diff --git a/admin-frontend-vue/src/App.vue b/admin-frontend-vue/src/App.vue new file mode 100644 index 00000000..a78fb6fd --- /dev/null +++ b/admin-frontend-vue/src/App.vue @@ -0,0 +1,7 @@ + + + diff --git a/admin-frontend-vue/src/api/http.ts b/admin-frontend-vue/src/api/http.ts index 92f21795..b2b836a4 100644 --- a/admin-frontend-vue/src/api/http.ts +++ b/admin-frontend-vue/src/api/http.ts @@ -14,7 +14,7 @@ function redirectToLogin(requestUrl?: string): void { // 已在登录页或失败请求即登录端点时不再跳转,避免登录页循环与吞掉登录失败反馈。 if (!shouldRedirectUnauthorized(window.location.pathname, requestUrl)) return const target = loginRedirectTarget(window.location) - window.location.assign(`/login?redirect=${target}`) + window.location.assign('/admin-vue/login?redirect=' + target) } http.interceptors.response.use( diff --git a/admin-frontend-vue/src/api/users-dto.ts b/admin-frontend-vue/src/api/users-dto.ts index ed572237..768cd1c1 100644 --- a/admin-frontend-vue/src/api/users-dto.ts +++ b/admin-frontend-vue/src/api/users-dto.ts @@ -1,7 +1,7 @@ /** 用户管理列表/分页 DTO(任务 41):纯逻辑,无框架依赖,与 Java AdminUserController 对齐。 */ import type { AdminUser } from '../types/admin' -export const USER_PAGE_DEFAULT_SIZE = 15 +export const USER_PAGE_DEFAULT_SIZE = 10 export const USER_PAGE_MIN_PAGE = 1 export const USER_PAGE_MAX_SIZE = 200 diff --git a/admin-frontend-vue/src/layout/topbar-model.ts b/admin-frontend-vue/src/layout/topbar-model.ts index 5b2ae3a5..965498cf 100644 --- a/admin-frontend-vue/src/layout/topbar-model.ts +++ b/admin-frontend-vue/src/layout/topbar-model.ts @@ -1,4 +1,5 @@ -import type { AdminUser } from '../types/admin' +import type { AdminUser } from '../types/admin.ts' +import { roleLabel } from '../types/admin.ts' /** 无 meta.title 时的壳层缺省标题。 */ export const ADMIN_DEFAULT_TITLE = '管理后台' @@ -18,5 +19,5 @@ export interface TopbarUserViewModel { /** 顶部栏用户模型:用户信息或未登录空态统一为可渲染视图模型。 */ export function topbarUserOf(user: AdminUser | null | undefined): TopbarUserViewModel { if (!user) return { username: '当前用户', role: '', hasUser: false } - return { username: user.username || '当前用户', role: user.role || '', hasUser: true } + return { username: user.username || '当前用户', role: roleLabel(user.role) || user.role || '', hasUser: true } } diff --git a/admin-frontend-vue/src/pages/account/GroupsPage.vue b/admin-frontend-vue/src/pages/account/GroupsPage.vue index 8f9cc5ad..789032d2 100644 --- a/admin-frontend-vue/src/pages/account/GroupsPage.vue +++ b/admin-frontend-vue/src/pages/account/GroupsPage.vue @@ -18,14 +18,19 @@ const isSuperAdmin = computed(() => session.isSuperAdmin) const currentUserId = computed(() => session.user?.id ?? null) // 客户端分页:全量拉取后按页切片展示。 const page = ref(1) -const pageSize = 10 +const pageSize = ref(10) const total = computed(() => rows.value.length) -const pagedRows = computed(() => rows.value.slice((page.value - 1) * pageSize, page.value * pageSize)) +const pagedRows = computed(() => rows.value.slice((page.value - 1) * pageSize.value, page.value * pageSize.value)) function changePage(p: number) { page.value = p } +function changeSize(size: number) { + pageSize.value = size + page.value = 1 +} + function canEditOf(group: ShopGroupItem): boolean { if (isSuperAdmin.value) return true return currentUserId.value != null && group.leaderUserId != null && currentUserId.value === group.leaderUserId @@ -75,7 +80,6 @@ onMounted(loadGroups)

数据权限分组

管理店铺数据访问分组和组员范围。组长不可更改,组员为普通账号。

- 新建分组 @@ -96,8 +100,10 @@ onMounted(loadGroups) +
+ 新建分组 +
- @@ -123,7 +129,7 @@ onMounted(loadGroups)
([]) // 客户端分页:列表展示统一带分页组件。 const page = ref(1) -const pageSize = 10 +const pageSize = ref(10) const total = computed(() => rows.value.length) -const pagedRows = computed(() => rows.value.slice((page.value - 1) * pageSize, page.value * pageSize)) +const pagedRows = computed(() => rows.value.slice((page.value - 1) * pageSize.value, page.value * pageSize.value)) function changePage(p: number) { page.value = p } + +function changeSize(size: number) { + pageSize.value = size + page.value = 1 +} const createVisible = ref(false) const saving = ref(false) const editingNode = ref(null) @@ -186,10 +191,12 @@ onMounted(loadMenus)

菜单管理

维护后台菜单树和页面路由。权限粒度仅到菜单/页面。

- 新增菜单 +
+ 新增菜单 +
- +
+ 新建用户 +
-