From ee64909811dd38c11a546fb418660421a608fff2 Mon Sep 17 00:00:00 2001 From: shunli Date: Tue, 5 May 2026 19:51:55 +0800 Subject: [PATCH] =?UTF-8?q?R89=20A4-A5=20=E7=A7=BB=E5=8A=A8=E5=AF=BC?= =?UTF-8?q?=E8=88=AA=E4=B8=8E=E5=B7=A5=E4=BD=9C=E5=8F=B0=E9=87=8D=E6=8E=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/mobile/MobileBottomNav.tsx | 2 + client/src/components/navigation/Topbar.tsx | 2 +- client/src/features/mobile/navigation.ts | 2 +- client/src/layouts/AppShellLayout.tsx | 6 +- client/src/pages/MobileMePage.tsx | 74 +++++++++++++++++-- client/src/pages/MobilePortalPage.tsx | 53 ++++++++++--- 6 files changed, 116 insertions(+), 23 deletions(-) diff --git a/client/src/components/mobile/MobileBottomNav.tsx b/client/src/components/mobile/MobileBottomNav.tsx index 0f050d31..d026b240 100644 --- a/client/src/components/mobile/MobileBottomNav.tsx +++ b/client/src/components/mobile/MobileBottomNav.tsx @@ -44,6 +44,7 @@ export function MobileBottomNav() { - +
diff --git a/client/src/features/mobile/navigation.ts b/client/src/features/mobile/navigation.ts index 94508e86..432d209a 100644 --- a/client/src/features/mobile/navigation.ts +++ b/client/src/features/mobile/navigation.ts @@ -30,6 +30,6 @@ export type MobileNavItem = { export const MOBILE_NAV_ITEMS: MobileNavItem[] = [ { key: "home", to: "/mobile", label: "首页", icon: "home" }, { key: "approvals", to: "/mobile/approvals", label: "审批", icon: "fact_check", anyOf: MOBILE_APPROVAL_PERMISSIONS }, - { key: "capture", to: "/mobile/capture", label: "拍照", icon: "photo_camera", anyOf: MOBILE_CAPTURE_PERMISSIONS }, + { key: "capture", to: "/mobile/capture", label: "票据", icon: "receipt_long", anyOf: MOBILE_CAPTURE_PERMISSIONS }, { key: "me", to: "/mobile/me", label: "我的", icon: "person" }, ]; diff --git a/client/src/layouts/AppShellLayout.tsx b/client/src/layouts/AppShellLayout.tsx index 6282f364..87ca44e2 100644 --- a/client/src/layouts/AppShellLayout.tsx +++ b/client/src/layouts/AppShellLayout.tsx @@ -30,9 +30,11 @@ export function AppShellLayout() {
- +
+ +
-
+
diff --git a/client/src/pages/MobileMePage.tsx b/client/src/pages/MobileMePage.tsx index 7ea2b4ef..608ad10b 100644 --- a/client/src/pages/MobileMePage.tsx +++ b/client/src/pages/MobileMePage.tsx @@ -6,6 +6,7 @@ import { fetchEmployeeProfile } from "../api/employees"; import { mapApiErrorMessage } from "../api/errorMessages"; import { isApiError } from "../api/types"; import { useAuth } from "../auth/AuthContext"; +import { hasAnyPermission } from "../auth/permissions"; import { EmployeeAvatar } from "../components/common/EmployeeAvatar"; import { PageHeader } from "../components/common/PageHeader"; import { PageScaffold } from "../components/patterns/PageScaffold"; @@ -22,8 +23,39 @@ function resolveErrorMessage(error: unknown) { return "请求失败,请稍后重试。"; } +function MobileActionLink({ + to, + label, + description, + icon, +}: { + to: string; + label: string; + description: string; + icon: string; +}) { + return ( + + + {icon} + + + {label} + {description} + + + ); +} + export function MobileMePage() { - const { me, refreshMe } = useAuth(); + const { me, permissions, refreshMe, logout } = useAuth(); + const canAccessApprovals = hasAnyPermission(permissions, ["expense.approve", "leave.approve", "procurement.approve", "travel.approve"]); + const canAccessAdmin = hasAnyPermission(permissions, ["*", "system.settings", "system.users", "report.dashboard.view"]); + const canAccessAssets = hasAnyPermission(permissions, ["asset.view_own", "asset.view_all", "asset.manage", "asset.transfer", "asset.inventory"]); + const canAccessProjects = hasAnyPermission(permissions, ["project.view_own", "project.view_all", "project.manage"]); const profileQuery = useQuery({ enabled: Boolean(me?.id), @@ -49,7 +81,7 @@ export function MobileMePage() { @@ -70,14 +102,36 @@ export function MobileMePage() { ) : null} - - {me?.id ? ( - - ) : null} + +
+ + {me?.id ? ( + + ) : null} +
+ +
+ + + + {canAccessApprovals ? : null} + {canAccessAssets ? : null} + {canAccessProjects ? : null} +
+
+ + {canAccessAdmin ? ( + +
+ + + +
+
+ ) : null} + + +
); } diff --git a/client/src/pages/MobilePortalPage.tsx b/client/src/pages/MobilePortalPage.tsx index 52941e6e..75d2d354 100644 --- a/client/src/pages/MobilePortalPage.tsx +++ b/client/src/pages/MobilePortalPage.tsx @@ -315,14 +315,45 @@ export function MobilePortalPage() { const teamStatusItems = teamStatusQuery.data ?? []; const pendingTasks = pendingCountQuery.data?.items ?? []; const notifications = notificationsQuery.data?.items ?? []; + const pendingApprovalCount = canAccessApprovals ? pendingCountQuery.data?.total ?? 0 : 0; + const unreadNotificationCount = notifications.filter((item) => !item.readAt).length; return ( +
+
+
+
今日重点
+
移动端只保留高频动作,低频模块放到“我的”。
+
+ 0 ? "badge-warning" : "badge-success"}> + {pendingApprovalCount > 0 ? `${pendingApprovalCount} 条待审批` : "暂无审批待办"} + +
+ +
+
+
{pendingApprovalCount}
+
审批待办
+
+
+
{unreadNotificationCount}
+
未读通知
+
+
+ +
+ + + +
+
+ {!attendanceFeatureDisabled ? (
@@ -524,15 +555,15 @@ export function MobilePortalPage() { )}
-
-
快捷入口
-
- - - - -
-
+ {(canAccessLeave || canAccessAssetScan) ? ( +
+
其他快捷入口
+
+ + +
+
+ ) : null}