diff --git a/furniture-3d-system/src/app/intake/new-product-management/page.tsx b/furniture-3d-system/src/app/intake/new-product-management/page.tsx
index e431bb65..ced4b8c2 100644
--- a/furniture-3d-system/src/app/intake/new-product-management/page.tsx
+++ b/furniture-3d-system/src/app/intake/new-product-management/page.tsx
@@ -1,39 +1,5 @@
-import { requireSession } from "@/lib/server-session";
-import { OA_BOARD_DEFAULT_TRACKED_STATUSES } from "@/server/services/oa-board.constants";
-import {
- createEmptyOaBoardDashboard,
- oaBoardService,
-} from "@/server/services/oa-board.service";
-import NewProductManagementDashboard from "./NewProductManagementDashboard";
-
-export const dynamic = "force-dynamic";
+import { redirect } from 'next/navigation'
export default async function NewProductManagementPage() {
- await requireSession("/login");
-
- const result = await oaBoardService
- .getDashboard({
- overallStatus: [...OA_BOARD_DEFAULT_TRACKED_STATUSES],
- })
- .then((dashboard) => ({
- dashboard,
- loadErrorMessage: null as string | null,
- }))
- .catch((error) => {
- console.error("Failed to load new product management dashboard", error);
- return {
- dashboard: createEmptyOaBoardDashboard(),
- loadErrorMessage:
- error instanceof Error
- ? `新品管理数据读取失败:${error.message}`
- : "新品管理数据读取失败,请稍后重试。",
- };
- });
-
- return (
-
- );
+ redirect('/supply-chain/new-products/overview')
}
diff --git a/furniture-3d-system/src/app/supply-chain/components/supply-chain-tabs.tsx b/furniture-3d-system/src/app/supply-chain/components/supply-chain-tabs.tsx
index 8f5f1a37..587580a3 100644
--- a/furniture-3d-system/src/app/supply-chain/components/supply-chain-tabs.tsx
+++ b/furniture-3d-system/src/app/supply-chain/components/supply-chain-tabs.tsx
@@ -90,6 +90,7 @@ export const SUPPLY_CHAIN_ROUTE_TITLES: Record = {
'/supply-chain/database/product-archive': '产品全量档案',
'/supply-chain/database/category-config': '类目配置',
'/supply-chain/database/warehouse-config': '仓库配置',
+ '/supply-chain/new-products/overview': '新品经营总览',
'/supply-chain/new-products/unified-table': '新品开发进度总表',
'/supply-chain/new-products/sample-progress': '打样进度明细',
'/supply-chain/purchase/daily-affairs': '日常事项',
diff --git a/furniture-3d-system/src/app/supply-chain/config/supply-chain-menu.test.ts b/furniture-3d-system/src/app/supply-chain/config/supply-chain-menu.test.ts
index c5c4266f..77f099b6 100644
--- a/furniture-3d-system/src/app/supply-chain/config/supply-chain-menu.test.ts
+++ b/furniture-3d-system/src/app/supply-chain/config/supply-chain-menu.test.ts
@@ -6,6 +6,11 @@ describe('supply chain menu', () => {
expect(items).toEqual(
expect.arrayContaining([
+ expect.objectContaining({
+ label: '新品经营总览',
+ module: '新品管理',
+ route: '/supply-chain/new-products/overview',
+ }),
expect.objectContaining({
label: '新品开发进度总表',
module: '新品管理',
diff --git a/furniture-3d-system/src/app/supply-chain/config/supply-chain-menu.ts b/furniture-3d-system/src/app/supply-chain/config/supply-chain-menu.ts
index e2fdf5b2..c2b4157a 100644
--- a/furniture-3d-system/src/app/supply-chain/config/supply-chain-menu.ts
+++ b/furniture-3d-system/src/app/supply-chain/config/supply-chain-menu.ts
@@ -54,6 +54,11 @@ export const SUPPLY_CHAIN_MENU: SupplyChainMenuModule[] = [
label: '新品管理',
icon: 'PackagePlus',
sections: [
+ {
+ items: [
+ { label: '新品经营总览', route: '/supply-chain/new-products/overview', targetKey: 'newProductOverview' },
+ ],
+ },
{
title: '公共数据源',
items: [
diff --git a/furniture-3d-system/src/app/supply-chain/new-products/overview/page.tsx b/furniture-3d-system/src/app/supply-chain/new-products/overview/page.tsx
new file mode 100644
index 00000000..39845d5c
--- /dev/null
+++ b/furniture-3d-system/src/app/supply-chain/new-products/overview/page.tsx
@@ -0,0 +1,49 @@
+import { redirect } from 'next/navigation'
+import NewProductManagementDashboard from '@/app/intake/new-product-management/NewProductManagementDashboard'
+import { requireSession } from '@/lib/server-session'
+import { OA_BOARD_DEFAULT_TRACKED_STATUSES } from '@/server/services/oa-board.constants'
+import {
+ createEmptyOaBoardDashboard,
+ oaBoardService,
+} from '@/server/services/oa-board.service'
+import { supplyChainPermissionSettingsService } from '@/server/services/supply-chain-permission-settings.service'
+
+export const dynamic = 'force-dynamic'
+export const metadata = { title: '新品经营总览 · 供应链中心' }
+
+export default async function NewProductOverviewPage() {
+ const { authUser } = await requireSession('/login')
+ const access = await supplyChainPermissionSettingsService.getUserAccess(
+ authUser,
+ 'newProductOverview',
+ )
+ if (!access.view) redirect('/supply-chain')
+
+ const result = await oaBoardService
+ .getDashboard({
+ overallStatus: [...OA_BOARD_DEFAULT_TRACKED_STATUSES],
+ })
+ .then((dashboard) => ({
+ dashboard,
+ loadErrorMessage: null as string | null,
+ }))
+ .catch((error) => {
+ console.error('Failed to load supply chain new product overview', error)
+ return {
+ dashboard: createEmptyOaBoardDashboard(),
+ loadErrorMessage:
+ error instanceof Error
+ ? `新品管理数据读取失败:${error.message}`
+ : '新品管理数据读取失败,请稍后重试。',
+ }
+ })
+
+ return (
+
+
+
+ )
+}
diff --git a/furniture-3d-system/src/app/users/components/SupplyChainPermissionWorkspace.tsx b/furniture-3d-system/src/app/users/components/SupplyChainPermissionWorkspace.tsx
index 0c21195c..9e957d9f 100644
--- a/furniture-3d-system/src/app/users/components/SupplyChainPermissionWorkspace.tsx
+++ b/furniture-3d-system/src/app/users/components/SupplyChainPermissionWorkspace.tsx
@@ -22,6 +22,7 @@ const TARGET_ICONS: Record {
})
it('maps new product pages to their permission nodes', () => {
+ expect(
+ getSupplyChainPermissionTargetForPath('/supply-chain/new-products/overview'),
+ ).toBe('newProductOverview')
expect(
getSupplyChainPermissionTargetForPath('/supply-chain/new-products/unified-table'),
).toBe('newProductUnifiedTable')
diff --git a/furniture-3d-system/src/lib/supply-chain-permission-settings.ts b/furniture-3d-system/src/lib/supply-chain-permission-settings.ts
index fac5c1db..5a8b0a12 100644
--- a/furniture-3d-system/src/lib/supply-chain-permission-settings.ts
+++ b/furniture-3d-system/src/lib/supply-chain-permission-settings.ts
@@ -19,6 +19,7 @@ export type SupplyChainPermissionTargetKey =
| 'productArchive'
| 'categoryConfig'
| 'warehouseConfig'
+ | 'newProductOverview'
| 'newProductUnifiedTable'
| 'newProductSampleProgress'
| 'purchaseDailyAffairs'
@@ -67,6 +68,7 @@ export const SUPPLY_CHAIN_PERMISSION_TARGETS: SupplyChainPermissionTarget[] = [
{ key: 'productArchive', label: '产品全量档案', description: '商品、供应链和运营档案' },
{ key: 'categoryConfig', label: '类目配置', description: '产品全量档案类目维护' },
{ key: 'warehouseConfig', label: '仓库配置', description: '出入库仓库维护' },
+ { key: 'newProductOverview', label: '新品经营总览', description: '新品经营指标和阶段时效分析' },
{ key: 'newProductUnifiedTable', label: '新品开发进度总表', description: '新品流程公共数据源' },
{ key: 'newProductSampleProgress', label: '打样进度明细', description: '新品打样进度公共数据源' },
{ key: 'purchaseDailyAffairs', label: '日常事项', description: '采购日常协作' },
@@ -85,6 +87,7 @@ export const SUPPLY_CHAIN_PERMISSION_TARGET_ROUTES: Partial<
productArchive: '/supply-chain/database/product-archive',
categoryConfig: '/supply-chain/database/category-config',
warehouseConfig: '/supply-chain/database/warehouse-config',
+ newProductOverview: '/supply-chain/new-products/overview',
newProductUnifiedTable: '/supply-chain/new-products/unified-table',
newProductSampleProgress: '/supply-chain/new-products/sample-progress',
purchaseDailyAffairs: '/supply-chain/purchase/daily-affairs',
@@ -238,6 +241,7 @@ export function getSupplyChainPermissionTargetForPath(pathname: string) {
if (pathname === '/supply-chain/database/product-archive') return 'productArchive' as const
if (pathname === '/supply-chain/database/category-config') return 'categoryConfig' as const
if (pathname === '/supply-chain/database/warehouse-config') return 'warehouseConfig' as const
+ if (pathname === '/supply-chain/new-products/overview') return 'newProductOverview' as const
if (pathname === '/supply-chain/new-products/unified-table') return 'newProductUnifiedTable' as const
if (pathname === '/supply-chain/new-products/sample-progress') return 'newProductSampleProgress' as const
if (pathname === '/supply-chain/purchase/daily-affairs') return 'purchaseDailyAffairs' as const