MIF7 移动信息架构整改收口
这个提交包含在:
@@ -1,4 +1,4 @@
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import { useLocation, useNavigate, useSearchParams } from "react-router-dom";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import { fetchNotifications, markAllNotificationsRead, markNotificationRead, type NotificationItem } from "../api/notifications";
|
||||
@@ -16,7 +16,7 @@ const PAGE_SIZE = 20;
|
||||
|
||||
const NOTIFICATION_TYPE_OPTIONS = [
|
||||
{ label: "全部", value: "" },
|
||||
{ label: "审批待办", value: "workflow.task_assigned,workflow.task_reminded,workflow.task_overdue" },
|
||||
{ label: "审批事件", value: "workflow.task_assigned,workflow.task_reminded,workflow.task_overdue" },
|
||||
{ label: "报销", value: "reimbursement.approved,reimbursement.rejected,reimbursement.returned,reimbursement.paid" },
|
||||
{ label: "请假", value: "leave.approved,leave.rejected" },
|
||||
{ label: "采购", value: "purchase_request.approved,purchase_request.rejected" },
|
||||
@@ -36,10 +36,23 @@ function formatTime(value: string) {
|
||||
return value.slice(0, 19).replace("T", " ");
|
||||
}
|
||||
|
||||
function notificationTypeLabel(type: string) {
|
||||
if (type.startsWith("workflow.")) return "审批事件";
|
||||
if (type.startsWith("reimbursement.")) return "报销事件";
|
||||
if (type.startsWith("leave.")) return "请假事件";
|
||||
if (type.startsWith("purchase_request.")) return "采购事件";
|
||||
if (type.startsWith("travel_request.")) return "差旅事件";
|
||||
if (type.startsWith("asset.")) return "资产事件";
|
||||
if (type.startsWith("inventory_check.")) return "盘点事件";
|
||||
return "系统事件";
|
||||
}
|
||||
|
||||
export function MobileNotificationsPage() {
|
||||
const queryClient = useQueryClient();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const currentMobileSource = `${location.pathname}${location.search}`;
|
||||
|
||||
const unreadOnlyRaw = searchParams.get("unreadOnly") ?? "0";
|
||||
const unreadOnly = unreadOnlyRaw === "1" || unreadOnlyRaw === "true";
|
||||
@@ -84,7 +97,7 @@ export function MobileNotificationsPage() {
|
||||
if (!item.readAt) {
|
||||
await markReadMutation.mutateAsync(item.id);
|
||||
}
|
||||
navigate(targetLink);
|
||||
navigate(targetLink, { state: { from: currentMobileSource } });
|
||||
} catch (error) {
|
||||
toast.error(resolveErrorMessage(error));
|
||||
}
|
||||
@@ -193,6 +206,7 @@ export function MobileNotificationsPage() {
|
||||
>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs font-medium text-primary">{notificationTypeLabel(item.type)}</div>
|
||||
<div className="text-sm font-semibold text-zinc-900">{item.title}</div>
|
||||
{item.body ? <div className="mt-1 text-xs leading-5 text-zinc-500">{item.body}</div> : null}
|
||||
</div>
|
||||
@@ -202,7 +216,7 @@ export function MobileNotificationsPage() {
|
||||
</div>
|
||||
|
||||
<div className="mt-3 text-xs text-zinc-500">{formatTime(item.createdAt)}</div>
|
||||
<div className="mt-3 text-xs text-primary">{targetLink ? "查看详情" : "暂无直达详情"}</div>
|
||||
<div className="mt-3 text-xs text-primary">{targetLink ? "直达详情" : "暂无直达详情"}</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
|
||||
在新工单中引用
屏蔽一个用户