Browse Source

🔒 feat(auth): 添加登录保护和访问控制

- 为WordPreview页面添加登录检查和未登录状态提示
- 修改首页按钮文本,引导用户联系管理员获取访问权限
- 使用ProtectedRoute组件保护/word-preview路由,限制未登录访问
- 添加未登录状态UI,包含管理员联系方式和登录引导

📝 docs(ui): 更新用户引导文本

- 修改首页"免费开始使用"按钮文本为联系管理员指引
- 在未登录页面添加管理员微信联系方式
- 优化未登录状态提示信息,明确说明访问要求
yourname 3 months ago
parent
commit
4ea3825a28

+ 1 - 1
src/client/home/pages/HomePage.tsx

@@ -443,7 +443,7 @@ export default function HomePage() {
             onClick={() => navigate('/word-preview')}
           >
             <Shield className="h-5 w-5 mr-2" />
-            免费开始使用(5份以内3次免费体验)
+            请跟管理联系 微信 andree123654
           </Button>
         </div>
       </div>

+ 62 - 1
src/client/home/pages/WordPreview.tsx

@@ -13,7 +13,7 @@ import {
   FileText, Upload, Download, Eye, FileWarning, FileSpreadsheet,
   RefreshCw, CheckCircle, AlertCircle, DownloadCloud, Image, Package,
   X, ZoomIn, ZoomOut, ChevronLeft, ChevronRight, Settings,
-  CheckSquare, Square, Archive, CheckCheck
+  CheckSquare, Square, Archive, CheckCheck, User, MessageCircle
 } from 'lucide-react';
 import { toast } from 'sonner';
 import WordViewer from '@/client/home/components/WordViewer';
@@ -25,6 +25,8 @@ import {
   DialogHeader,
   DialogTitle,
 } from '@/client/components/ui/dialog';
+import { useAuth } from '@/client/home/hooks/AuthProvider';
+import { useNavigate } from 'react-router-dom';
 
 interface WordFile {
   id: string;
@@ -60,6 +62,8 @@ interface ProcessingResult {
 }
 
 export default function WordPreview() {
+  const { isAuthenticated, isLoading: authLoading } = useAuth();
+  const navigate = useNavigate();
   const [selectedWordFile, setSelectedWordFile] = useState<File | null>(null);
   const [selectedExcelFile, setSelectedExcelFile] = useState<File | null>(null);
   const [imageZipFile, setImageZipFile] = useState<File | null>(null);
@@ -915,6 +919,63 @@ export default function WordPreview() {
     return Object.values(imagePreviewUrls).reduce((total, folder) => total + Object.keys(folder).length, 0);
   };
 
+  // 如果未登录,显示提示信息
+  if (!isAuthenticated && !authLoading) {
+    return (
+      <div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-slate-50 to-slate-100 px-4 py-12">
+        <Card className="w-full max-w-md border-0 shadow-xl">
+          <CardHeader className="space-y-1 text-center">
+            <div className="mx-auto bg-red-100 p-3 rounded-full">
+              <User className="h-8 w-8 text-red-600" />
+            </div>
+            <CardTitle className="text-2xl font-bold">需要登录</CardTitle>
+            <CardDescription>
+              只有登录用户才能访问文档处理功能
+            </CardDescription>
+          </CardHeader>
+          <CardContent className="space-y-4">
+            <Alert variant="destructive">
+              <AlertCircle className="h-4 w-4" />
+              <AlertDescription>
+                请跟管理员联系获取账号密码
+              </AlertDescription>
+            </Alert>
+            
+            <div className="bg-blue-50 p-4 rounded-lg">
+              <div className="flex items-center justify-center space-x-2">
+                <MessageCircle className="h-5 w-5 text-blue-600" />
+                <span className="font-medium text-blue-800">管理员微信:</span>
+                <span className="text-lg font-bold text-blue-900">andree123654</span>
+              </div>
+              <p className="text-sm text-blue-700 mt-2 text-center">
+                添加管理员微信获取账号密码
+              </p>
+            </div>
+            
+            <Button
+              className="w-full"
+              onClick={() => navigate('/login')}
+            >
+              前往登录页面
+            </Button>
+          </CardContent>
+        </Card>
+      </div>
+    );
+  }
+
+  // 如果正在检查认证状态,显示加载中
+  if (authLoading) {
+    return (
+      <div className="flex justify-center items-center min-h-screen">
+        <div className="text-center">
+          <RefreshCw className="h-8 w-8 animate-spin mx-auto mb-4" />
+          <p>正在检查登录状态...</p>
+        </div>
+      </div>
+    );
+  }
+
   return (
     <div className="space-y-6">
       <div>

+ 5 - 1
src/client/home/routes.tsx

@@ -21,7 +21,11 @@ export const router = createBrowserRouter([
   },
   {
     path: '/word-preview',
-    element: <WordPreview />
+    element: (
+      <ProtectedRoute>
+        <WordPreview />
+      </ProtectedRoute>
+    )
   },
   {
     path: '/login',