فهرست منبع

✨ feat(tenant): add tenant configuration feature

- add Settings icon import from lucide-react
- add useNavigate hook for routing
- implement handleConfigTenant function to navigate to tenant config page
- add configuration button in tenant table with Settings icon
- update menu configuration to focus on tenant management features
- add route for tenant configuration page at /tenant/config/:id
yourname 1 ماه پیش
والد
کامیت
a828c61fe8
3فایلهای تغییر یافته به همراه50 افزوده شده و 150 حذف شده
  1. 18 1
      packages/tenant-management-ui/src/components/TenantsPage.tsx
  2. 15 147
      web/src/client/tenant/menu.tsx
  3. 17 2
      web/src/client/tenant/routes.tsx

+ 18 - 1
packages/tenant-management-ui/src/components/TenantsPage.tsx

@@ -1,7 +1,7 @@
 import React, { useState, useMemo, useCallback } from 'react';
 import { useQuery } from '@tanstack/react-query';
 import { format } from 'date-fns';
-import { Plus, Search, Edit, Trash2, Filter, X } from 'lucide-react';
+import { Plus, Search, Edit, Trash2, Filter, X, Settings } from 'lucide-react';
 import { tenantClientManager, tenantClient } from '../api/tenantClient';
 import type { InferRequestType, InferResponseType } from 'hono/client';
 import { Button } from '@d8d/shared-ui-components/components/ui/button';
@@ -23,6 +23,7 @@ import { toast } from 'sonner';
 import { CreateTenantDto, UpdateTenantDto } from '@d8d/tenant-module-mt/schemas';
 import { cn } from '../utils/cn';
 import { formatTenantStatus } from '../utils/formatTenantStatus';
+import { useNavigate } from 'react-router-dom';
 
 // 使用RPC方式提取类型
 type CreateTenantRequest = InferRequestType<typeof tenantClient.index.$post>['json'];
@@ -37,6 +38,7 @@ type CreateTenantFormData = CreateTenantRequest;
 type UpdateTenantFormData = UpdateTenantRequest;
 
 export const TenantsPage = () => {
+  const navigate = useNavigate();
   const [searchParams, setSearchParams] = useState({
     page: 1,
     limit: 10,
@@ -202,6 +204,11 @@ export const TenantsPage = () => {
     setIsModalOpen(true);
   };
 
+  // 跳转到租户配置页面
+  const handleConfigTenant = (tenantId: number) => {
+    navigate(`/tenant/config/${tenantId}`);
+  };
+
   // 处理创建表单提交
   const handleCreateSubmit = async (data: CreateTenantFormData) => {
     try {
@@ -475,10 +482,19 @@ export const TenantsPage = () => {
                         </TableCell>
                         <TableCell className="text-right">
                           <div className="flex justify-end gap-2">
+                            <Button
+                              variant="ghost"
+                              size="icon"
+                              onClick={() => handleConfigTenant(tenant.id)}
+                              title="配置"
+                            >
+                              <Settings className="h-4 w-4" />
+                            </Button>
                             <Button
                               variant="ghost"
                               size="icon"
                               onClick={() => handleEditTenant(tenant)}
+                              title="编辑"
                             >
                               <Edit className="h-4 w-4" />
                             </Button>
@@ -486,6 +502,7 @@ export const TenantsPage = () => {
                               variant="ghost"
                               size="icon"
                               onClick={() => handleDeleteTenant(tenant.id)}
+                              title="删除"
                             >
                               <Trash2 className="h-4 w-4" />
                             </Button>

+ 15 - 147
web/src/client/tenant/menu.tsx

@@ -1,23 +1,13 @@
 import React from 'react';
-import { useNavigate } from 'react-router';
+import { useNavigate } from 'react-router-dom';
 import { useAuth } from '@d8d/tenant-management-ui';
 import {
-  Users,
   Settings,
   User,
   LogOut,
   BarChart3,
   LayoutDashboard,
-  File,
-  Megaphone,
-  Tag,
-  Package,
-  Truck,
-  Building,
-  UserCheck,
-  CreditCard,
-  TrendingUp,
-  MapPin
+  Building
 } from 'lucide-react';
 
 export interface MenuItem {
@@ -81,149 +71,27 @@ export const useMenu = () => {
   const { logout: handleLogout } = useAuth();
   const [collapsed, setCollapsed] = React.useState(false);
 
-  // 基础菜单项配置
+  // 基础菜单项配置 - 租户管理专用
   const menuItems: MenuItem[] = [
     {
       key: 'dashboard',
-      label: '控制台',
+      label: '租户控制台',
       icon: <LayoutDashboard className="h-4 w-4" />,
-      path: '/admin/dashboard'
+      path: '/tenant/dashboard'
     },
     {
-      key: 'users',
-      label: '用户管理',
-      icon: <Users className="h-4 w-4" />,
-      path: '/admin/users',
-      permission: 'user:manage'
-    },
-    {
-      key: 'files',
-      label: '文件管理',
-      icon: <File className="h-4 w-4" />,
-      path: '/admin/files',
-      permission: 'file:manage'
+      key: 'tenants',
+      label: '租户管理',
+      icon: <Building className="h-4 w-4" />,
+      path: '/tenant/tenants',
+      permission: 'tenant:manage'
     },
     {
       key: 'analytics',
-      label: '数据分析',
+      label: '租户数据',
       icon: <BarChart3 className="h-4 w-4" />,
-      path: '/admin/analytics',
-      permission: 'analytics:view'
-    },
-    {
-      key: 'advertisements',
-      label: '广告管理',
-      icon: <Megaphone className="h-4 w-4" />,
-      permission: 'advertisement:manage',
-      children: [
-        {
-          key: 'advertisements-list',
-          label: '广告列表',
-          path: '/admin/advertisements',
-          permission: 'advertisement:manage'
-        },
-        {
-          key: 'advertisement-types',
-          label: '广告类型',
-          path: '/admin/advertisement-types',
-          permission: 'advertisement:manage'
-        }
-      ]
-    },
-    {
-      key: 'goods',
-      label: '商品管理',
-      icon: <Package className="h-4 w-4" />,
-      permission: 'goods:manage',
-      children: [
-        {
-          key: 'goods-list',
-          label: '商品列表',
-          path: '/admin/goods',
-          permission: 'goods:manage'
-        },
-        {
-          key: 'goods-categories',
-          label: '商品分类',
-          path: '/admin/goods-categories',
-          permission: 'goods:manage'
-        },
-        {
-          key: 'express-companies',
-          label: '快递公司',
-          path: '/admin/express-companies',
-          permission: 'goods:manage'
-        },
-      ]
-    },
-    {
-      key: 'orders',
-      label: '订单管理',
-      icon: <Truck className="h-4 w-4" />,
-      permission: 'order:manage',
-      children: [
-        {
-          key: 'orders-list',
-          label: '订单列表',
-          path: '/admin/orders',
-          permission: 'order:manage'
-        }
-      ]
-    },
-    {
-      key: 'suppliers',
-      label: '供应商管理',
-      icon: <Building className="h-4 w-4" />,
-      path: '/admin/suppliers',
-      permission: 'supplier:manage'
-    },
-    {
-      key: 'merchants',
-      label: '商户管理',
-      icon: <Building className="h-4 w-4" />,
-      path: '/admin/merchants',
-      permission: 'merchant:manage'
-    },
-    {
-      key: 'agents',
-      label: '代理商管理',
-      icon: <UserCheck className="h-4 w-4" />,
-      path: '/admin/agents',
-      permission: 'agent:manage'
-    },
-    {
-      key: 'delivery-addresses',
-      label: '收货地址',
-      icon: <MapPin className="h-4 w-4" />,
-      path: '/admin/delivery-addresses',
-      permission: 'user:manage'
-    },
-    {
-      key: 'cards',
-      label: '卡券管理',
-      icon: <CreditCard className="h-4 w-4" />,
-      permission: 'card:manage',
-      children: [
-        {
-          key: 'user-cards',
-          label: '用户卡管理',
-          path: '/admin/user-cards',
-          permission: 'card:manage'
-        },
-        {
-          key: 'user-card-balance-records',
-          label: '余额记录',
-          path: '/admin/user-card-balance-records',
-          permission: 'card:manage'
-        }
-      ]
-    },
-    {
-      key: 'settings',
-      label: '系统设置',
-      icon: <Settings className="h-4 w-4" />,
-      path: '/admin/settings',
-      permission: 'settings:manage'
+      path: '/tenant/analytics',
+      permission: 'tenant:analytics'
     },
   ];
 
@@ -233,13 +101,13 @@ export const useMenu = () => {
       key: 'profile',
       label: '个人资料',
       icon: <User className="mr-2 h-4 w-4" />,
-      onClick: () => navigate('/admin/profile')
+      onClick: () => navigate('/tenant/profile')
     },
     {
       key: 'settings',
       label: '账户设置',
       icon: <Settings className="mr-2 h-4 w-4" />,
-      onClick: () => navigate('/admin/account-settings')
+      onClick: () => navigate('/tenant/account-settings')
     },
     {
       type: 'separator',

+ 17 - 2
web/src/client/tenant/routes.tsx

@@ -1,4 +1,4 @@
-import { createBrowserRouter, Navigate } from 'react-router';
+import { createBrowserRouter, Navigate } from 'react-router-dom';
 import { ProtectedRoute } from './components/ProtectedRoute';
 import { MainLayout } from './layouts/MainLayout';
 import { ErrorPage } from './components/ErrorPage';
@@ -43,10 +43,25 @@ export const router = createBrowserRouter([
         errorElement: <ErrorPage />
       },
       {
-        path: 'tenant-config',
+        path: 'config/:id',
         element: <TenantConfigPage />,
         errorElement: <ErrorPage />
       },
+      // {
+      //   path: 'analytics',
+      //   element: <DashboardPage />, // 暂时使用DashboardPage,后续可替换为专门的AnalyticsPage
+      //   errorElement: <ErrorPage />
+      // },
+      // {
+      //   path: 'profile',
+      //   element: <DashboardPage />, // 暂时使用DashboardPage,后续可替换为专门的ProfilePage
+      //   errorElement: <ErrorPage />
+      // },
+      // {
+      //   path: 'account-settings',
+      //   element: <DashboardPage />, // 暂时使用DashboardPage,后续可替换为专门的AccountSettingsPage
+      //   errorElement: <ErrorPage />
+      // },
       {
         path: '*',
         element: <NotFoundPage />,