@hkyhy/marsun-components-core 0.1.138 → 0.1.140
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/components/Iam/client.d.ts +3 -0
- package/dist/components/Iam/index.d.ts +1 -1
- package/dist/components/Iam/pages/IamUsersPage.d.ts +15 -1
- package/dist/components/Iam/pages/IamUsersPage.js +171 -162
- package/dist/components/Iam/pages/IamUsersPage.js.map +1 -1
- package/dist/components/Table/Table.d.ts +2 -2
- package/dist/components/Table/Table.js +75 -72
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Table/columnConfigUtils.d.ts +8 -0
- package/dist/components/Table/columnConfigUtils.js +130 -113
- package/dist/components/Table/columnConfigUtils.js.map +1 -1
- package/dist/components/Table/index.d.ts +1 -1
- package/dist/components/Tools/ActionTracking/CreateAction/CreateActionForm.d.ts +2 -0
- package/dist/components/Tools/ActionTracking/CreateAction/CreateActionForm.js +97 -83
- package/dist/components/Tools/ActionTracking/CreateAction/CreateActionForm.js.map +1 -1
- package/dist/components/Tools/ActionTracking/CreateAction/CreateActionModal.d.ts +2 -0
- package/dist/components/Tools/ActionTracking/CreateAction/CreateActionModal.js +111 -106
- package/dist/components/Tools/ActionTracking/CreateAction/CreateActionModal.js.map +1 -1
- package/dist/components/Tools/ActionTracking/CreateAction/types.d.ts +4 -0
- package/dist/components/Tools/Inbox/InboxBell/InboxBell.js +168 -155
- package/dist/components/Tools/Inbox/InboxBell/InboxBell.js.map +1 -1
- package/dist/components/Tools/Inbox/InboxBell/inboxItemActions.js +60 -46
- package/dist/components/Tools/Inbox/InboxBell/inboxItemActions.js.map +1 -1
- package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js +68 -60
- package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js.map +1 -1
- package/dist/index.js +478 -477
- package/dist/marsun-components-core.css +1 -1
- package/dist/styles/global.css +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InboxBell.js","sources":["../../../../../src/components/Tools/Inbox/InboxBell/InboxBell.tsx"],"sourcesContent":["import { Badge, Button, Checkbox, Drawer, Space, message, notification } from 'antd';\nimport classNames from 'classnames';\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type UIEvent,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { Empty } from '@/components/Empty';\nimport { Bell } from '@/components/Icons';\nimport { PageSpin } from '@/components/Layout';\nimport { SegmentedRadio } from '@/components/SegmentedRadio';\nimport { StateBar } from '@/components/StateBar';\nimport { SEMANTIC_COLORS, SemanticTag } from '@/components/Tag';\nimport { VirtualScrollbar } from '@/components/VirtualScrollbar';\nimport { sanitizeInboxHtml } from '../sanitizeInboxHtml';\nimport { INBOX_BADGE_REFRESH_EVENT } from '../requestInboxBadgeRefresh';\nimport { emphasizeQuoted } from './emphasizeQuoted';\nimport {\n filterInboxActionsForHost,\n isInboxButtonDriven,\n resolveInboxItemActions,\n type InboxItemActionKind,\n type InboxItemQuickAction,\n} from './inboxItemActions';\nimport {\n loadInboxToastPrefs,\n saveInboxToastPrefs,\n shouldToastForMessageType,\n type InboxToastPrefs,\n} from './toastPrefs';\nimport styles from './style.module.scss';\n\n/** SSE / 写后预览 toast 展示时长 */\nconst TOAST_DURATION_MS = 6_000;\n\nexport type InboxBellMessageType = 'alert' | 'action' | 'remind' | string;\n\nexport type InboxBellItem = {\n id: string;\n title?: string;\n /** 纯文本摘要(列表兼容) */\n summary?: string;\n /** 已渲染 HTML 正文;空则主摘要位回落 summary */\n bodyHtml?: string | null;\n read?: boolean;\n messageType?: InboxBellMessageType;\n href?: string;\n createdAt?: string;\n level?: string;\n /** 级别展示名(业务仓从已有维表/工具函数填;空则回落 level) */\n levelLabel?: string;\n /**\n * 级别 Tag 色:业务仓传入预警级别设置色(如 QA `ALERT_LEVEL_COLORS.*.accent`)。\n * 支持 SemanticColor 键或 `#hex`;core 不自造级别色表。\n */\n levelColor?: string;\n category?: string;\n scene?: string;\n eventKey?: string;\n categoryLabel?: string;\n alertId?: string | null;\n actionId?: string | null;\n claimed?: boolean;\n started?: boolean;\n /** 行动当前状态(enrich / contextJson);终态时底栏只保留查看任务 */\n actionStatus?: string;\n factory?: string;\n variety?: string;\n metric?: string;\n /** 业务日/月份(如 2026-07-31);预警深链 date 用 */\n month?: string;\n};\n\nexport type InboxBellListResult = {\n /** 分页列表(Marsun list-api 唯一数组名) */\n pageData: InboxBellItem[];\n total?: number;\n unreadTotal?: number;\n unreadByMessageType?: Partial<Record<string, number>>;\n};\n\nexport type InboxBellListParams = {\n unreadOnly?: boolean;\n readOnly?: boolean;\n messageType?: InboxBellMessageType;\n currentPage?: number;\n pageSize?: number;\n};\n\nexport type InboxBellProps = {\n /** 拉取站内信(业务注入;须带 JWT 身份,禁止无身份全表) */\n fetchInbox: (params: InboxBellListParams) => Promise<InboxBellListResult>;\n /** 标记已读 */\n markRead: (id: string) => Promise<void | InboxBellItem>;\n /**\n * 清空未读(本用户+租户+app 全部未读标已读)。不传则不展示按钮。\n * 成功后铃铛会刷新列表与角标。\n */\n markAllRead?: () => Promise<{ updated?: number } | void>;\n /** 点击条目:默认用 window.location / 业务 navigate */\n onNavigate?: (href: string, item: InboxBellItem) => void;\n /**\n * 轮询未读角标(ms)。默认 `0`(关定时);`>0` 才 setInterval。\n * 角标另由:挂载首刷、`locationKey`、focus/visibility、`requestInboxBadgeRefresh` 触发。\n */\n pollMs?: number;\n /**\n * 路由/页面身份;变化时刷新角标(如 React Router `location.pathname`)。\n * 整页加载靠挂载首刷,不必另传。\n */\n locationKey?: string | number;\n pageSize?: number;\n className?: string;\n /** Drawer 标题 */\n title?: string;\n /**\n * 同源 SSE 路径(默认 `/api/v1/msg-center/inbox/stream`)。\n * 传 `false` 关闭。须配合 `getAccessToken`(EventSource 用 `access_token` 查询参数传 JWT)。\n * 失败回落写后刷新 / 焦点刷新,不定时轮询冒充。\n */\n streamPath?: string | false;\n /** 返回当前 JWT;空则不开 SSE */\n getAccessToken?: () => string | null | undefined;\n /**\n * 卡片底栏动作(认领/去执行/查看等)。不传则底栏按钮一律走 onNavigate / href。\n * 业务仓拦截 claim_alert / start_action;铃铛不解析新建任务。\n */\n onItemAction?: (kind: InboxItemActionKind, item: InboxBellItem) => void | Promise<void>;\n};\n\nexport type InboxBellHandle = {\n refreshBadge: () => Promise<void>;\n};\n\nconst TYPE_TABS: Array<{ key: string; label: string }> = [\n { key: '', label: '全部' },\n { key: 'alert', label: '预警' },\n { key: 'action', label: '行动' },\n { key: 'remind', label: '提醒' },\n];\n\nconst TYPE_TAG_LABEL: Record<string, string> = {\n alert: '预警',\n action: '行动',\n remind: '提醒',\n};\n\nconst FOCUS_DEBOUNCE_MS = 300;\n/** SSE / 写后 / 外部刷角标合并窗口,避免扫描风暴打爆 inbox */\nconst BADGE_DEBOUNCE_MS = 1_500;\n/** 距底部小于该值时拉下一页 */\nconst LOAD_MORE_GAP_PX = 72;\n\nfunction messageTypeLabel(raw?: string): string {\n const key = String(raw || '')\n .trim()\n .toLowerCase();\n if (!key) return '';\n return TYPE_TAG_LABEL[key] || key;\n}\n\nfunction messageTypeSemanticColor(raw?: string): string {\n const key = String(raw || '')\n .trim()\n .toLowerCase();\n if (key === 'alert') return SEMANTIC_COLORS.DANGER;\n if (key === 'action') return SEMANTIC_COLORS.PRIMARY;\n if (key === 'remind') return SEMANTIC_COLORS.WARNING;\n return SEMANTIC_COLORS.DEFAULT;\n}\n\nfunction itemMetaLine(item: InboxBellItem): string {\n return [item.factory, item.variety, item.metric]\n .map((x) => String(x || '').trim())\n .filter(Boolean)\n .join(' · ');\n}\n\n/** 业务传入色;无则 DEFAULT(禁止在 core 造级别→色平行表) */\nfunction resolveLevelTagColor(raw?: string): string {\n const c = String(raw || '').trim();\n return c || SEMANTIC_COLORS.DEFAULT;\n}\n\ntype BadgePreview = {\n messageType?: string;\n title?: string;\n summary?: string;\n};\n\ntype LiveToast = {\n key: string;\n title: string;\n summary: string;\n messageType?: string;\n};\n\nfunction parseBadgePreview(raw: string): BadgePreview | null {\n try {\n const data = JSON.parse(raw) as Record<string, unknown>;\n if (!data || typeof data !== 'object') return null;\n const messageType = String(data.messageType || data.message_type || '').trim();\n const title = String(data.title || '').trim();\n const summary = String(data.summary || '').trim();\n if (!messageType && !title && !summary) return null;\n return {\n messageType: messageType || undefined,\n title: title || undefined,\n summary: summary || undefined,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * 通用站内信铃铛:列表 / 已读 / Tab / 角标 / 卡片底栏动作 / 可选 SSE toast。\n * 认领、去执行等业务动作由 `onItemAction` 注入;默认底栏按钮走 onNavigate / href。\n * 默认不定时轮询;有消息侧靠业务回调 / 路由 / 焦点 / 可选 SSE 再拉角标。\n */\nconst InboxBell = forwardRef<InboxBellHandle, InboxBellProps>(function InboxBell(\n {\n fetchInbox,\n markRead,\n markAllRead,\n onNavigate,\n pollMs = 0,\n locationKey,\n pageSize = 20,\n className,\n title = '站内信',\n streamPath = '/api/v1/msg-center/inbox/stream',\n getAccessToken,\n onItemAction,\n },\n ref,\n) {\n const [open, setOpen] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [items, setItems] = useState<InboxBellItem[]>([]);\n const [unreadTotal, setUnreadTotal] = useState(0);\n const [unreadByType, setUnreadByType] = useState<Partial<Record<string, number>>>({});\n const [messageType, setMessageType] = useState<string>('');\n const [readFilter, setReadFilter] = useState<'all' | 'unread' | 'read'>('all');\n const [toastPrefs, setToastPrefs] = useState<InboxToastPrefs>(() => loadInboxToastPrefs());\n const [loadingMore, setLoadingMore] = useState(false);\n const [clearingUnread, setClearingUnread] = useState(false);\n const [liveToast, setLiveToast] = useState<LiveToast | null>(null);\n const focusDebounceRef = useRef<number | null>(null);\n const badgeDebounceRef = useRef<number | null>(null);\n const pendingToastRef = useRef<BadgePreview | null>(null);\n const toastTimerRef = useRef<number | null>(null);\n const locationKeyPrimedRef = useRef(false);\n const toastPrefsRef = useRef(toastPrefs);\n toastPrefsRef.current = toastPrefs;\n const currentPageRef = useRef(1);\n const loadingMoreRef = useRef(false);\n const hasMoreRef = useRef(false);\n\n const listQuery = useMemo(\n () => ({\n messageType: messageType || undefined,\n unreadOnly: readFilter === 'unread' || undefined,\n readOnly: readFilter === 'read' || undefined,\n }),\n [messageType, readFilter],\n );\n\n const load = useCallback(async () => {\n setLoading(true);\n setError('');\n currentPageRef.current = 1;\n hasMoreRef.current = false;\n try {\n const res = await fetchInbox({\n currentPage: 1,\n pageSize,\n ...listQuery,\n });\n const page = res?.pageData || [];\n const total = typeof res?.total === 'number' ? res.total : page.length;\n setItems(page);\n hasMoreRef.current = page.length > 0 && page.length < total;\n setUnreadTotal(typeof res?.unreadTotal === 'number' ? res.unreadTotal : 0);\n setUnreadByType(res?.unreadByMessageType || {});\n } catch (e) {\n setItems([]);\n hasMoreRef.current = false;\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, [fetchInbox, pageSize, listQuery]);\n\n const loadMore = useCallback(async () => {\n if (loadingMoreRef.current || !hasMoreRef.current) return;\n loadingMoreRef.current = true;\n setLoadingMore(true);\n try {\n const next = currentPageRef.current + 1;\n const res = await fetchInbox({\n currentPage: next,\n pageSize,\n ...listQuery,\n });\n const page = res?.pageData || [];\n const total = typeof res?.total === 'number' ? res.total : 0;\n setItems((prev) => {\n const seen = new Set(prev.map((x) => x.id));\n const extra = page.filter((x) => x?.id && !seen.has(x.id));\n const merged = extra.length ? [...prev, ...extra] : prev;\n hasMoreRef.current =\n extra.length > 0 && (total > 0 ? merged.length < total : extra.length >= pageSize);\n return merged;\n });\n if (page.length) currentPageRef.current = next;\n if (typeof res?.unreadTotal === 'number') setUnreadTotal(res.unreadTotal);\n if (res?.unreadByMessageType) setUnreadByType(res.unreadByMessageType);\n } catch {\n hasMoreRef.current = false;\n } finally {\n loadingMoreRef.current = false;\n setLoadingMore(false);\n }\n }, [fetchInbox, pageSize, listQuery]);\n\n const onListScroll = useCallback(\n (e: UIEvent<HTMLDivElement>) => {\n const el = e.currentTarget;\n if (el.scrollHeight - el.scrollTop - el.clientHeight <= LOAD_MORE_GAP_PX) {\n void loadMore();\n }\n },\n [loadMore],\n );\n\n const refreshBadge = useCallback(async () => {\n try {\n // 与列表同 pageSize(禁硬编码 1);角标只消费 unread* 字段\n const res = await fetchInbox({ currentPage: 1, pageSize });\n setUnreadTotal(typeof res?.unreadTotal === 'number' ? res.unreadTotal : 0);\n setUnreadByType(res?.unreadByMessageType || {});\n } catch {\n /* 角标失败不打断 UI */\n }\n }, [fetchInbox, pageSize]);\n\n const dismissLiveToast = useCallback(() => {\n if (toastTimerRef.current != null) {\n window.clearTimeout(toastTimerRef.current);\n toastTimerRef.current = null;\n }\n setLiveToast(null);\n }, []);\n\n const openDrawerFromToast = useCallback(() => {\n dismissLiveToast();\n setOpen(true);\n }, [dismissLiveToast]);\n\n const flushPendingToast = useCallback(() => {\n const preview = pendingToastRef.current;\n pendingToastRef.current = null;\n if (!preview) return;\n if (!shouldToastForMessageType(toastPrefsRef.current, preview.messageType)) return;\n // 自渲染 toast:避免 antd 静态 notification 离场后残留透明可点壳\n if (toastTimerRef.current != null) {\n window.clearTimeout(toastTimerRef.current);\n toastTimerRef.current = null;\n }\n const toastKey = `inbox-badge-${preview.messageType || 'msg'}-${Date.now()}`;\n setLiveToast({\n key: toastKey,\n title: preview.title || '新站内信',\n summary: preview.summary || '',\n messageType: preview.messageType,\n });\n toastTimerRef.current = window.setTimeout(() => {\n toastTimerRef.current = null;\n setLiveToast(null);\n }, TOAST_DURATION_MS);\n }, []);\n\n /** 合并高频角标刷新(SSE 扫描风暴 / 写后 / 路由 / 焦点);有预览时立即 toast,角标仍防抖 */\n const scheduleBadgeRefresh = useCallback(\n (preview?: BadgePreview | null) => {\n if (preview) {\n pendingToastRef.current = preview;\n flushPendingToast();\n }\n if (badgeDebounceRef.current != null) {\n window.clearTimeout(badgeDebounceRef.current);\n }\n badgeDebounceRef.current = window.setTimeout(() => {\n badgeDebounceRef.current = null;\n void refreshBadge();\n }, BADGE_DEBOUNCE_MS);\n },\n [refreshBadge, flushPendingToast],\n );\n\n useImperativeHandle(ref, () => ({ refreshBadge }), [refreshBadge]);\n\n useEffect(() => {\n void refreshBadge();\n }, [refreshBadge]);\n\n useEffect(() => {\n if (locationKey === undefined) return;\n // 挂载首刷已由 refreshBadge effect 覆盖;仅后续路由变化再拉\n if (!locationKeyPrimedRef.current) {\n locationKeyPrimedRef.current = true;\n return;\n }\n scheduleBadgeRefresh();\n }, [locationKey, scheduleBadgeRefresh]);\n\n useEffect(() => {\n if (pollMs <= 0) return undefined;\n const t = window.setInterval(() => {\n void refreshBadge();\n }, pollMs);\n return () => window.clearInterval(t);\n }, [pollMs, refreshBadge]);\n\n useEffect(() => {\n const schedule = () => {\n if (focusDebounceRef.current != null) {\n window.clearTimeout(focusDebounceRef.current);\n }\n focusDebounceRef.current = window.setTimeout(() => {\n focusDebounceRef.current = null;\n scheduleBadgeRefresh();\n }, FOCUS_DEBOUNCE_MS);\n };\n\n const onVisibility = () => {\n if (document.visibilityState === 'visible') schedule();\n };\n\n window.addEventListener('focus', schedule);\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n window.removeEventListener('focus', schedule);\n document.removeEventListener('visibilitychange', onVisibility);\n if (focusDebounceRef.current != null) {\n window.clearTimeout(focusDebounceRef.current);\n focusDebounceRef.current = null;\n }\n };\n }, [scheduleBadgeRefresh]);\n\n useEffect(() => {\n const onExternal = (ev: Event) => {\n const detail = (ev as CustomEvent<{ preview?: BadgePreview | null }>).detail;\n scheduleBadgeRefresh(detail?.preview || undefined);\n };\n window.addEventListener(INBOX_BADGE_REFRESH_EVENT, onExternal);\n return () => window.removeEventListener(INBOX_BADGE_REFRESH_EVENT, onExternal);\n }, [scheduleBadgeRefresh]);\n\n useEffect(() => {\n // 清掉历史版本 ant notification 残留的透明可点壳\n notification.destroy();\n }, []);\n\n useEffect(() => {\n return () => {\n if (badgeDebounceRef.current != null) {\n window.clearTimeout(badgeDebounceRef.current);\n badgeDebounceRef.current = null;\n }\n if (toastTimerRef.current != null) {\n window.clearTimeout(toastTimerRef.current);\n toastTimerRef.current = null;\n }\n };\n }, []);\n\n useEffect(() => {\n if (streamPath === false) return undefined;\n if (typeof getAccessToken !== 'function') return undefined;\n if (typeof window === 'undefined' || typeof EventSource === 'undefined') return undefined;\n\n const base = String(streamPath || '/api/v1/msg-center/inbox/stream').trim();\n let closed = false;\n let es: EventSource | null = null;\n let retryTimer: number | null = null;\n let attempt = 0;\n\n const onBadge = (ev: Event) => {\n const msgEv = ev as MessageEvent;\n const preview = typeof msgEv?.data === 'string' ? parseBadgePreview(msgEv.data) : null;\n scheduleBadgeRefresh(preview);\n };\n\n const clearRetry = () => {\n if (retryTimer != null) {\n window.clearTimeout(retryTimer);\n retryTimer = null;\n }\n };\n\n const scheduleReconnect = () => {\n if (closed || retryTimer != null) return;\n const delay = Math.min(30_000, 1_000 * 2 ** Math.min(attempt, 5));\n attempt += 1;\n retryTimer = window.setTimeout(() => {\n retryTimer = null;\n connect();\n }, delay);\n };\n\n const connect = () => {\n if (closed) return;\n const token = String(getAccessToken() || '').trim();\n if (!token) {\n scheduleReconnect();\n return;\n }\n if (es) {\n es.removeEventListener('badge', onBadge);\n es.removeEventListener('inbox', onBadge);\n es.close();\n es = null;\n }\n const url = new URL(base, window.location.origin);\n url.searchParams.set('access_token', token);\n try {\n es = new EventSource(url.toString());\n } catch {\n scheduleReconnect();\n return;\n }\n es.addEventListener('badge', onBadge);\n es.addEventListener('inbox', onBadge);\n es.onopen = () => {\n attempt = 0;\n };\n // 受控退避重连(勿永久 close;否则站内信 toast 再也收不到)\n es.onerror = () => {\n if (closed) return;\n es?.close();\n es = null;\n scheduleReconnect();\n };\n };\n\n connect();\n\n return () => {\n closed = true;\n clearRetry();\n if (es) {\n es.removeEventListener('badge', onBadge);\n es.removeEventListener('inbox', onBadge);\n es.close();\n es = null;\n }\n };\n }, [streamPath, getAccessToken, scheduleBadgeRefresh]);\n\n useEffect(() => {\n if (open) void load();\n }, [open, load]);\n\n const typeTabOptions = useMemo(\n () =>\n TYPE_TABS.map((t) => {\n const n = t.key ? unreadByType[t.key] || 0 : unreadTotal;\n return {\n key: t.key || 'all',\n label: n > 0 ? `${t.label} (${n})` : t.label,\n };\n }),\n [unreadByType, unreadTotal],\n );\n\n const updateToastPref = (key: keyof InboxToastPrefs, checked: boolean) => {\n setToastPrefs((prev) => {\n const next = { ...prev, [key]: checked };\n saveInboxToastPrefs(next);\n return next;\n });\n };\n\n const handleOpenItem = async (item: InboxBellItem, opts?: { skipRead?: boolean }) => {\n if (!opts?.skipRead && !item.read) {\n try {\n await markRead(item.id);\n setItems((prev) => prev.map((x) => (x.id === item.id ? { ...x, read: true } : x)));\n setUnreadTotal((n) => Math.max(0, n - 1));\n } catch (e) {\n message.error(e instanceof Error ? e.message : '标记已读失败');\n return;\n }\n }\n const href = String(item.href || '').trim();\n if (!href) return;\n if (onNavigate) {\n onNavigate(href, item);\n setOpen(false);\n return;\n }\n if (href.startsWith('http://') || href.startsWith('https://')) {\n window.open(href, '_blank', 'noopener,noreferrer');\n } else {\n window.location.assign(href);\n }\n setOpen(false);\n };\n\n const runQuickAction = async (item: InboxBellItem, action: InboxItemQuickAction) => {\n if (action.disabled) return;\n if (onItemAction) {\n try {\n await onItemAction(action.kind, item);\n setOpen(false);\n void load();\n void refreshBadge();\n } catch (e) {\n message.error(e instanceof Error ? e.message : '操作失败');\n }\n return;\n }\n await handleOpenItem(item);\n };\n\n const handleClearUnread = async () => {\n if (!markAllRead || unreadTotal <= 0 || clearingUnread) return;\n setClearingUnread(true);\n try {\n const res = await markAllRead();\n const n = typeof res?.updated === 'number' ? res.updated : undefined;\n message.success(typeof n === 'number' ? `已清空 ${n} 条未读` : '已清空未读');\n await load();\n await refreshBadge();\n } catch (e) {\n message.error(e instanceof Error ? e.message : '清空未读失败');\n } finally {\n setClearingUnread(false);\n }\n };\n\n const toastTypeLabel = liveToast ? messageTypeLabel(liveToast.messageType) : '';\n\n return (\n <div className={classNames(styles.bellWrap, className)}>\n <Badge count={unreadTotal} size=\"small\" overflowCount={99} offset={[-4, 4]}>\n <Button\n type=\"text\"\n className={styles.bellBtn}\n icon={<Bell size={16} aria-hidden />}\n aria-label={unreadTotal > 0 ? `站内信,${unreadTotal} 条未读` : '站内信'}\n onClick={() => setOpen(true)}\n />\n </Badge>\n {liveToast && typeof document !== 'undefined'\n ? createPortal(\n <div className={styles.toastHost} data-testid=\"inbox-live-toast-host\">\n <div\n key={liveToast.key}\n className={classNames('marsun-inbox-toast', styles.toastNotice)}\n role=\"alert\"\n data-testid=\"inbox-live-toast\"\n onClick={openDrawerFromToast}\n >\n <button\n type=\"button\"\n className={styles.toastClose}\n aria-label=\"关闭\"\n onClick={(e) => {\n e.stopPropagation();\n dismissLiveToast();\n }}\n >\n ×\n </button>\n <div className={styles.toastHead}>\n <span className={styles.toastTitle}>{emphasizeQuoted(liveToast.title)}</span>\n {toastTypeLabel ? (\n <SemanticTag\n color={messageTypeSemanticColor(liveToast.messageType)}\n className={styles.typeTag}\n >\n {toastTypeLabel}\n </SemanticTag>\n ) : null}\n </div>\n <div className={styles.toastBody}>\n {liveToast.summary ? (\n <div className={styles.toastDesc}>{emphasizeQuoted(liveToast.summary)}</div>\n ) : null}\n <div className={styles.toastActions}>\n <Button\n type=\"primary\"\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n openDrawerFromToast();\n }}\n >\n 查看\n </Button>\n </div>\n </div>\n </div>\n </div>,\n document.body,\n )\n : null}\n <Drawer\n title={title}\n open={open}\n onClose={() => setOpen(false)}\n size={420}\n destroyOnClose={false}\n className={styles.drawer}\n styles={{\n header: { padding: '12px 16px' },\n body: { padding: '12px 16px' },\n }}\n >\n <StateBar\n className={styles.typeTabs}\n size=\"small\"\n activeKey={messageType || 'all'}\n onChange={(k) => setMessageType(k === 'all' ? '' : k)}\n stateOption={typeTabOptions}\n isInner\n />\n <div className={styles.filterRow}>\n <SegmentedRadio<'all' | 'unread' | 'read'>\n size=\"small\"\n value={readFilter}\n onChange={(v) => setReadFilter(v)}\n options={[\n { value: 'all', label: '全部' },\n { value: 'unread', label: '未读' },\n { value: 'read', label: '已读' },\n ]}\n />\n {markAllRead ? (\n <Button\n type=\"link\"\n size=\"small\"\n className={styles.clearUnreadBtn}\n data-testid=\"inbox-clear-unread\"\n loading={clearingUnread}\n disabled={unreadTotal <= 0 || clearingUnread}\n onClick={() => void handleClearUnread()}\n >\n 清空未读\n </Button>\n ) : null}\n </div>\n <div className={styles.toastPrefs} data-testid=\"inbox-toast-prefs\">\n <div className={styles.toastPrefsTitle}>消息提示</div>\n <p className={styles.toastPrefsHint}>本机浏览器偏好,非租户策略</p>\n <Space size={12} wrap>\n <Checkbox\n checked={toastPrefs.alert}\n onChange={(e) => updateToastPref('alert', e.target.checked)}\n >\n 预警弹出\n </Checkbox>\n <Checkbox\n checked={toastPrefs.action}\n onChange={(e) => updateToastPref('action', e.target.checked)}\n >\n 行动弹出\n </Checkbox>\n <Checkbox\n checked={toastPrefs.remind}\n onChange={(e) => updateToastPref('remind', e.target.checked)}\n >\n 提醒弹出\n </Checkbox>\n </Space>\n </div>\n {error ? <p className={styles.error}>{error}</p> : null}\n <div className={classNames('inbox-bell-list-pane', styles.listPane)}>\n <PageSpin spinning={loading && items.length === 0}>\n {!loading && !error && items.length === 0 ? (\n <Empty description=\"暂无站内信\" />\n ) : items.length === 0 ? null : (\n <VirtualScrollbar\n wrapperClassName={classNames('inbox-bell-list-scroll', styles.listScroll)}\n className={styles.listViewport}\n data-testid=\"inbox-bell-list-scroll\"\n onScroll={onListScroll}\n >\n <ul className={styles.list}>\n {items.map((item) => {\n const typeLabel = messageTypeLabel(item.messageType);\n const levelText = String(item.levelLabel || item.level || '').trim();\n const showLevel = Boolean(levelText);\n const safeHtml = sanitizeInboxHtml(item.bodyHtml);\n const actions = filterInboxActionsForHost(\n resolveInboxItemActions(item),\n Boolean(onItemAction),\n );\n const buttonDriven = isInboxButtonDriven(item);\n const meta = itemMetaLine(item);\n const showActions = Boolean(actions.primary);\n return (\n <li key={item.id}>\n <div\n className={classNames(\n styles.item,\n !item.read && styles.itemUnread,\n buttonDriven && styles.itemStatic,\n )}\n role={buttonDriven ? undefined : 'button'}\n tabIndex={buttonDriven ? undefined : 0}\n onClick={buttonDriven ? undefined : () => void handleOpenItem(item)}\n onKeyDown={\n buttonDriven\n ? undefined\n : (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n void handleOpenItem(item);\n }\n }\n }\n >\n <div className={styles.itemHeader}>\n <span className={styles.itemHeaderLeft}>\n <span className={styles.itemTitle} title={item.title || '(无标题)'}>\n {item.title || '(无标题)'}\n </span>\n {typeLabel ? (\n <SemanticTag\n color={messageTypeSemanticColor(item.messageType)}\n className={styles.typeTag}\n >\n {typeLabel}\n </SemanticTag>\n ) : null}\n </span>\n <span className={styles.itemTime}>{item.createdAt || ''}</span>\n </div>\n <div className={styles.itemBody}>\n {safeHtml ? (\n <div\n className={styles.itemBodyHtml}\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n ) : item.summary ? (\n <span className={styles.itemSummary}>\n {emphasizeQuoted(item.summary)}\n </span>\n ) : null}\n </div>\n {meta ? <span className={styles.itemMeta}>{meta}</span> : null}\n {showLevel ? (\n <div className={styles.itemFooterTags}>\n <SemanticTag\n color={resolveLevelTagColor(item.levelColor)}\n selected\n className={styles.typeTag}\n >\n {levelText}\n </SemanticTag>\n </div>\n ) : null}\n {showActions && actions.primary ? (\n <div\n className={styles.itemActions}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <Space size={8} wrap>\n <Button\n size=\"small\"\n type=\"primary\"\n onClick={() => void runQuickAction(item, actions.primary!)}\n >\n {actions.primary.label}\n </Button>\n {actions.secondary ? (\n <Button\n size=\"small\"\n type=\"link\"\n onClick={() => void runQuickAction(item, actions.secondary!)}\n >\n {actions.secondary.label}\n </Button>\n ) : null}\n </Space>\n </div>\n ) : null}\n </div>\n </li>\n );\n })}\n </ul>\n {loadingMore ? (\n <p className={classNames('inbox-bell-list-footer', styles.listFooter)}>加载中…</p>\n ) : null}\n </VirtualScrollbar>\n )}\n </PageSpin>\n </div>\n </Drawer>\n </div>\n );\n});\n\nexport default InboxBell;\nexport {\n DEFAULT_INBOX_TOAST_PREFS,\n loadInboxToastPrefs,\n saveInboxToastPrefs,\n shouldToastForMessageType,\n} from './toastPrefs';\nexport type { InboxToastPrefs } from './toastPrefs';\nexport {\n resolveInboxItemActions,\n resolveInboxSceneKey,\n filterInboxActionsForHost,\n normalizeInboxActions,\n inboxSceneLabel,\n isInboxButtonDriven,\n isTerminalActionStatus,\n} from './inboxItemActions';\nexport type {\n InboxItemActionKind,\n InboxItemQuickAction,\n InboxItemActionsResolved,\n} from './inboxItemActions';\n"],"names":["TOAST_DURATION_MS","TYPE_TABS","TYPE_TAG_LABEL","FOCUS_DEBOUNCE_MS","BADGE_DEBOUNCE_MS","LOAD_MORE_GAP_PX","messageTypeLabel","raw","key","messageTypeSemanticColor","SEMANTIC_COLORS","itemMetaLine","item","x","resolveLevelTagColor","parseBadgePreview","data","messageType","title","summary","InboxBell","forwardRef","fetchInbox","markRead","markAllRead","onNavigate","pollMs","locationKey","pageSize","className","streamPath","getAccessToken","onItemAction","ref","open","setOpen","useState","loading","setLoading","error","setError","items","setItems","unreadTotal","setUnreadTotal","unreadByType","setUnreadByType","setMessageType","readFilter","setReadFilter","toastPrefs","setToastPrefs","loadInboxToastPrefs","loadingMore","setLoadingMore","clearingUnread","setClearingUnread","liveToast","setLiveToast","focusDebounceRef","useRef","badgeDebounceRef","pendingToastRef","toastTimerRef","locationKeyPrimedRef","toastPrefsRef","currentPageRef","loadingMoreRef","hasMoreRef","listQuery","useMemo","load","useCallback","res","page","total","loadMore","next","prev","seen","extra","merged","onListScroll","el","refreshBadge","dismissLiveToast","openDrawerFromToast","flushPendingToast","preview","shouldToastForMessageType","toastKey","scheduleBadgeRefresh","useImperativeHandle","useEffect","t","schedule","onVisibility","onExternal","ev","detail","INBOX_BADGE_REFRESH_EVENT","notification","base","closed","es","retryTimer","attempt","onBadge","msgEv","clearRetry","scheduleReconnect","delay","connect","token","url","typeTabOptions","n","updateToastPref","checked","saveInboxToastPrefs","handleOpenItem","opts","e","message","href","runQuickAction","action","handleClearUnread","toastTypeLabel","classNames","styles","jsx","Badge","Button","Bell","createPortal","jsxs","emphasizeQuoted","SemanticTag","Drawer","StateBar","k","SegmentedRadio","v","Space","Checkbox","PageSpin","Empty","VirtualScrollbar","typeLabel","levelText","showLevel","safeHtml","sanitizeInboxHtml","actions","filterInboxActionsForHost","resolveInboxItemActions","buttonDriven","isInboxButtonDriven","meta","showActions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InboxBell.js","sources":["../../../../../src/components/Tools/Inbox/InboxBell/InboxBell.tsx"],"sourcesContent":["import { Badge, Button, Checkbox, Drawer, Space, message, notification } from 'antd';\nimport classNames from 'classnames';\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type UIEvent,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { Empty } from '@/components/Empty';\nimport { Bell } from '@/components/Icons';\nimport { PageSpin } from '@/components/Layout';\nimport { SegmentedRadio } from '@/components/SegmentedRadio';\nimport { StateBar } from '@/components/StateBar';\nimport { SEMANTIC_COLORS, SemanticTag } from '@/components/Tag';\nimport { VirtualScrollbar } from '@/components/VirtualScrollbar';\nimport { sanitizeInboxHtml } from '../sanitizeInboxHtml';\nimport { INBOX_BADGE_REFRESH_EVENT } from '../requestInboxBadgeRefresh';\nimport { emphasizeQuoted } from './emphasizeQuoted';\nimport {\n filterInboxActionsForHost,\n isInboxButtonDriven,\n resolveInboxItemActions,\n type InboxItemActionKind,\n type InboxItemQuickAction,\n} from './inboxItemActions';\nimport {\n loadInboxToastPrefs,\n saveInboxToastPrefs,\n shouldToastForMessageType,\n type InboxToastPrefs,\n} from './toastPrefs';\nimport styles from './style.module.scss';\n\n/** SSE / 写后预览 toast 展示时长 */\nconst TOAST_DURATION_MS = 6_000;\n\nexport type InboxBellMessageType = 'alert' | 'action' | 'remind' | string;\n\nexport type InboxBellItem = {\n id: string;\n title?: string;\n /** 纯文本摘要(列表兼容) */\n summary?: string;\n /** 已渲染 HTML 正文;空则主摘要位回落 summary */\n bodyHtml?: string | null;\n read?: boolean;\n messageType?: InboxBellMessageType;\n href?: string;\n createdAt?: string;\n level?: string;\n /** 级别展示名(业务仓从已有维表/工具函数填;空则回落 level) */\n levelLabel?: string;\n /**\n * 级别 Tag 色:业务仓传入预警级别设置色(如 QA `ALERT_LEVEL_COLORS.*.accent`)。\n * 支持 SemanticColor 键或 `#hex`;core 不自造级别色表。\n */\n levelColor?: string;\n category?: string;\n scene?: string;\n eventKey?: string;\n categoryLabel?: string;\n alertId?: string | null;\n actionId?: string | null;\n claimed?: boolean;\n started?: boolean;\n /** 行动当前状态(enrich / contextJson);终态时底栏只保留查看任务 */\n actionStatus?: string;\n factory?: string;\n variety?: string;\n metric?: string;\n /** 业务日/月份(如 2026-07-31);预警深链 date 用 */\n month?: string;\n};\n\nexport type InboxBellListResult = {\n /** 分页列表(Marsun list-api 唯一数组名) */\n pageData: InboxBellItem[];\n total?: number;\n unreadTotal?: number;\n unreadByMessageType?: Partial<Record<string, number>>;\n};\n\nexport type InboxBellListParams = {\n unreadOnly?: boolean;\n readOnly?: boolean;\n messageType?: InboxBellMessageType;\n currentPage?: number;\n pageSize?: number;\n};\n\nexport type InboxBellProps = {\n /** 拉取站内信(业务注入;须带 JWT 身份,禁止无身份全表) */\n fetchInbox: (params: InboxBellListParams) => Promise<InboxBellListResult>;\n /** 标记已读 */\n markRead: (id: string) => Promise<void | InboxBellItem>;\n /**\n * 清空未读(本用户+租户+app 全部未读标已读)。不传则不展示按钮。\n * 成功后铃铛会刷新列表与角标。\n */\n markAllRead?: () => Promise<{ updated?: number } | void>;\n /** 点击条目:默认用 window.location / 业务 navigate */\n onNavigate?: (href: string, item: InboxBellItem) => void;\n /**\n * 轮询未读角标(ms)。默认 `0`(关定时);`>0` 才 setInterval。\n * 角标另由:挂载首刷、`locationKey`、focus/visibility、`requestInboxBadgeRefresh` 触发。\n */\n pollMs?: number;\n /**\n * 路由/页面身份;变化时刷新角标(如 React Router `location.pathname`)。\n * 整页加载靠挂载首刷,不必另传。\n */\n locationKey?: string | number;\n pageSize?: number;\n className?: string;\n /** Drawer 标题 */\n title?: string;\n /**\n * 同源 SSE 路径(默认 `/api/v1/msg-center/inbox/stream`)。\n * 传 `false` 关闭。须配合 `getAccessToken`(EventSource 用 `access_token` 查询参数传 JWT)。\n * 失败回落写后刷新 / 焦点刷新,不定时轮询冒充。\n */\n streamPath?: string | false;\n /** 返回当前 JWT;空则不开 SSE */\n getAccessToken?: () => string | null | undefined;\n /**\n * 卡片底栏动作(认领/去执行/查看等)。不传则底栏按钮一律走 onNavigate / href。\n * 业务仓拦截 claim_alert / start_action;铃铛不解析新建任务。\n */\n onItemAction?: (kind: InboxItemActionKind, item: InboxBellItem) => void | Promise<void>;\n};\n\nexport type InboxBellHandle = {\n refreshBadge: () => Promise<void>;\n};\n\nconst TYPE_TABS: Array<{ key: string; label: string }> = [\n { key: '', label: '全部' },\n { key: 'alert', label: '预警' },\n { key: 'action', label: '行动' },\n { key: 'remind', label: '提醒' },\n];\n\nconst TYPE_TAG_LABEL: Record<string, string> = {\n alert: '预警',\n action: '行动',\n remind: '提醒',\n};\n\nconst FOCUS_DEBOUNCE_MS = 300;\n/** SSE / 写后 / 外部刷角标合并窗口,避免扫描风暴打爆 inbox */\nconst BADGE_DEBOUNCE_MS = 1_500;\n/** 距底部小于该值时拉下一页 */\nconst LOAD_MORE_GAP_PX = 72;\n\nfunction messageTypeLabel(raw?: string): string {\n const key = String(raw || '')\n .trim()\n .toLowerCase();\n if (!key) return '';\n return TYPE_TAG_LABEL[key] || key;\n}\n\nfunction messageTypeSemanticColor(raw?: string): string {\n const key = String(raw || '')\n .trim()\n .toLowerCase();\n if (key === 'alert') return SEMANTIC_COLORS.DANGER;\n if (key === 'action') return SEMANTIC_COLORS.PRIMARY;\n if (key === 'remind') return SEMANTIC_COLORS.WARNING;\n return SEMANTIC_COLORS.DEFAULT;\n}\n\nfunction itemMetaLine(item: InboxBellItem): string {\n return [item.factory, item.variety, item.metric]\n .map((x) => String(x || '').trim())\n .filter(Boolean)\n .join(' · ');\n}\n\n/** 业务传入色;无则 DEFAULT(禁止在 core 造级别→色平行表) */\nfunction resolveLevelTagColor(raw?: string): string {\n const c = String(raw || '').trim();\n return c || SEMANTIC_COLORS.DEFAULT;\n}\n\ntype BadgePreview = {\n messageType?: string;\n title?: string;\n summary?: string;\n};\n\ntype LiveToast = {\n key: string;\n title: string;\n summary: string;\n messageType?: string;\n};\n\nfunction parseBadgePreview(raw: string): BadgePreview | null {\n try {\n const data = JSON.parse(raw) as Record<string, unknown>;\n if (!data || typeof data !== 'object') return null;\n const messageType = String(data.messageType || data.message_type || '').trim();\n const title = String(data.title || '').trim();\n const summary = String(data.summary || '').trim();\n if (!messageType && !title && !summary) return null;\n return {\n messageType: messageType || undefined,\n title: title || undefined,\n summary: summary || undefined,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * 通用站内信铃铛:列表 / 已读 / Tab / 角标 / 卡片底栏动作 / 可选 SSE toast。\n * 认领、去执行等业务动作由 `onItemAction` 注入;默认底栏按钮走 onNavigate / href。\n * 默认不定时轮询;有消息侧靠业务回调 / 路由 / 焦点 / 可选 SSE 再拉角标。\n */\nconst InboxBell = forwardRef<InboxBellHandle, InboxBellProps>(function InboxBell(\n {\n fetchInbox,\n markRead,\n markAllRead,\n onNavigate,\n pollMs = 0,\n locationKey,\n pageSize = 20,\n className,\n title = '站内信',\n streamPath = '/api/v1/msg-center/inbox/stream',\n getAccessToken,\n onItemAction,\n },\n ref,\n) {\n const [open, setOpen] = useState(false);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState('');\n const [items, setItems] = useState<InboxBellItem[]>([]);\n const [unreadTotal, setUnreadTotal] = useState(0);\n const [unreadByType, setUnreadByType] = useState<Partial<Record<string, number>>>({});\n const [messageType, setMessageType] = useState<string>('');\n const [readFilter, setReadFilter] = useState<'all' | 'unread' | 'read'>('all');\n const [toastPrefs, setToastPrefs] = useState<InboxToastPrefs>(() => loadInboxToastPrefs());\n const [loadingMore, setLoadingMore] = useState(false);\n const [clearingUnread, setClearingUnread] = useState(false);\n const [liveToast, setLiveToast] = useState<LiveToast | null>(null);\n const focusDebounceRef = useRef<number | null>(null);\n const badgeDebounceRef = useRef<number | null>(null);\n const pendingToastRef = useRef<BadgePreview | null>(null);\n const toastTimerRef = useRef<number | null>(null);\n const locationKeyPrimedRef = useRef(false);\n const toastPrefsRef = useRef(toastPrefs);\n toastPrefsRef.current = toastPrefs;\n const currentPageRef = useRef(1);\n const loadingMoreRef = useRef(false);\n const hasMoreRef = useRef(false);\n\n const listQuery = useMemo(\n () => ({\n messageType: messageType || undefined,\n unreadOnly: readFilter === 'unread' || undefined,\n readOnly: readFilter === 'read' || undefined,\n }),\n [messageType, readFilter],\n );\n\n const load = useCallback(async () => {\n setLoading(true);\n setError('');\n currentPageRef.current = 1;\n hasMoreRef.current = false;\n try {\n const res = await fetchInbox({\n currentPage: 1,\n pageSize,\n ...listQuery,\n });\n const page = res?.pageData || [];\n const total = typeof res?.total === 'number' ? res.total : page.length;\n setItems(page);\n hasMoreRef.current = page.length > 0 && page.length < total;\n setUnreadTotal(typeof res?.unreadTotal === 'number' ? res.unreadTotal : 0);\n setUnreadByType(res?.unreadByMessageType || {});\n } catch (e) {\n setItems([]);\n hasMoreRef.current = false;\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setLoading(false);\n }\n }, [fetchInbox, pageSize, listQuery]);\n\n const loadMore = useCallback(async () => {\n if (loadingMoreRef.current || !hasMoreRef.current) return;\n loadingMoreRef.current = true;\n setLoadingMore(true);\n try {\n const next = currentPageRef.current + 1;\n const res = await fetchInbox({\n currentPage: next,\n pageSize,\n ...listQuery,\n });\n const page = res?.pageData || [];\n const total = typeof res?.total === 'number' ? res.total : 0;\n setItems((prev) => {\n const seen = new Set(prev.map((x) => x.id));\n const extra = page.filter((x) => x?.id && !seen.has(x.id));\n const merged = extra.length ? [...prev, ...extra] : prev;\n hasMoreRef.current =\n extra.length > 0 && (total > 0 ? merged.length < total : extra.length >= pageSize);\n return merged;\n });\n if (page.length) currentPageRef.current = next;\n if (typeof res?.unreadTotal === 'number') setUnreadTotal(res.unreadTotal);\n if (res?.unreadByMessageType) setUnreadByType(res.unreadByMessageType);\n } catch {\n hasMoreRef.current = false;\n } finally {\n loadingMoreRef.current = false;\n setLoadingMore(false);\n }\n }, [fetchInbox, pageSize, listQuery]);\n\n const onListScroll = useCallback(\n (e: UIEvent<HTMLDivElement>) => {\n const el = e.currentTarget;\n if (el.scrollHeight - el.scrollTop - el.clientHeight <= LOAD_MORE_GAP_PX) {\n void loadMore();\n }\n },\n [loadMore],\n );\n\n const refreshBadge = useCallback(async () => {\n try {\n // 与列表同 pageSize(禁硬编码 1);角标只消费 unread* 字段\n const res = await fetchInbox({ currentPage: 1, pageSize });\n setUnreadTotal(typeof res?.unreadTotal === 'number' ? res.unreadTotal : 0);\n setUnreadByType(res?.unreadByMessageType || {});\n } catch {\n /* 角标失败不打断 UI */\n }\n }, [fetchInbox, pageSize]);\n\n const dismissLiveToast = useCallback(() => {\n if (toastTimerRef.current != null) {\n window.clearTimeout(toastTimerRef.current);\n toastTimerRef.current = null;\n }\n setLiveToast(null);\n }, []);\n\n const openDrawerFromToast = useCallback(() => {\n dismissLiveToast();\n setOpen(true);\n }, [dismissLiveToast]);\n\n const flushPendingToast = useCallback(() => {\n const preview = pendingToastRef.current;\n pendingToastRef.current = null;\n if (!preview) return;\n if (!shouldToastForMessageType(toastPrefsRef.current, preview.messageType)) return;\n // 自渲染 toast:避免 antd 静态 notification 离场后残留透明可点壳\n if (toastTimerRef.current != null) {\n window.clearTimeout(toastTimerRef.current);\n toastTimerRef.current = null;\n }\n const toastKey = `inbox-badge-${preview.messageType || 'msg'}-${Date.now()}`;\n setLiveToast({\n key: toastKey,\n title: preview.title || '新站内信',\n summary: preview.summary || '',\n messageType: preview.messageType,\n });\n toastTimerRef.current = window.setTimeout(() => {\n toastTimerRef.current = null;\n setLiveToast(null);\n }, TOAST_DURATION_MS);\n }, []);\n\n /** 合并高频角标刷新(SSE 扫描风暴 / 写后 / 路由 / 焦点);有预览时立即 toast,角标仍防抖 */\n const scheduleBadgeRefresh = useCallback(\n (preview?: BadgePreview | null) => {\n if (preview) {\n pendingToastRef.current = preview;\n flushPendingToast();\n }\n if (badgeDebounceRef.current != null) {\n window.clearTimeout(badgeDebounceRef.current);\n }\n badgeDebounceRef.current = window.setTimeout(() => {\n badgeDebounceRef.current = null;\n void refreshBadge();\n }, BADGE_DEBOUNCE_MS);\n },\n [refreshBadge, flushPendingToast],\n );\n\n useImperativeHandle(ref, () => ({ refreshBadge }), [refreshBadge]);\n\n useEffect(() => {\n void refreshBadge();\n }, [refreshBadge]);\n\n useEffect(() => {\n if (locationKey === undefined) return;\n // 挂载首刷已由 refreshBadge effect 覆盖;仅后续路由变化再拉\n if (!locationKeyPrimedRef.current) {\n locationKeyPrimedRef.current = true;\n return;\n }\n scheduleBadgeRefresh();\n }, [locationKey, scheduleBadgeRefresh]);\n\n useEffect(() => {\n if (pollMs <= 0) return undefined;\n const t = window.setInterval(() => {\n void refreshBadge();\n }, pollMs);\n return () => window.clearInterval(t);\n }, [pollMs, refreshBadge]);\n\n useEffect(() => {\n const schedule = () => {\n if (focusDebounceRef.current != null) {\n window.clearTimeout(focusDebounceRef.current);\n }\n focusDebounceRef.current = window.setTimeout(() => {\n focusDebounceRef.current = null;\n scheduleBadgeRefresh();\n }, FOCUS_DEBOUNCE_MS);\n };\n\n const onVisibility = () => {\n if (document.visibilityState === 'visible') schedule();\n };\n\n window.addEventListener('focus', schedule);\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n window.removeEventListener('focus', schedule);\n document.removeEventListener('visibilitychange', onVisibility);\n if (focusDebounceRef.current != null) {\n window.clearTimeout(focusDebounceRef.current);\n focusDebounceRef.current = null;\n }\n };\n }, [scheduleBadgeRefresh]);\n\n useEffect(() => {\n const onExternal = (ev: Event) => {\n const detail = (ev as CustomEvent<{ preview?: BadgePreview | null }>).detail;\n scheduleBadgeRefresh(detail?.preview || undefined);\n };\n window.addEventListener(INBOX_BADGE_REFRESH_EVENT, onExternal);\n return () => window.removeEventListener(INBOX_BADGE_REFRESH_EVENT, onExternal);\n }, [scheduleBadgeRefresh]);\n\n useEffect(() => {\n // 清掉历史版本 ant notification 残留的透明可点壳\n notification.destroy();\n }, []);\n\n useEffect(() => {\n return () => {\n if (badgeDebounceRef.current != null) {\n window.clearTimeout(badgeDebounceRef.current);\n badgeDebounceRef.current = null;\n }\n if (toastTimerRef.current != null) {\n window.clearTimeout(toastTimerRef.current);\n toastTimerRef.current = null;\n }\n };\n }, []);\n\n useEffect(() => {\n if (streamPath === false) return undefined;\n if (typeof getAccessToken !== 'function') return undefined;\n if (typeof window === 'undefined' || typeof EventSource === 'undefined') return undefined;\n\n const base = String(streamPath || '/api/v1/msg-center/inbox/stream').trim();\n let closed = false;\n let es: EventSource | null = null;\n let retryTimer: number | null = null;\n let attempt = 0;\n\n const onBadge = (ev: Event) => {\n const msgEv = ev as MessageEvent;\n const preview = typeof msgEv?.data === 'string' ? parseBadgePreview(msgEv.data) : null;\n scheduleBadgeRefresh(preview);\n };\n\n const clearRetry = () => {\n if (retryTimer != null) {\n window.clearTimeout(retryTimer);\n retryTimer = null;\n }\n };\n\n const scheduleReconnect = () => {\n if (closed || retryTimer != null) return;\n const delay = Math.min(30_000, 1_000 * 2 ** Math.min(attempt, 5));\n attempt += 1;\n retryTimer = window.setTimeout(() => {\n retryTimer = null;\n connect();\n }, delay);\n };\n\n const connect = () => {\n if (closed) return;\n const token = String(getAccessToken() || '').trim();\n if (!token) {\n scheduleReconnect();\n return;\n }\n if (es) {\n es.removeEventListener('badge', onBadge);\n es.removeEventListener('inbox', onBadge);\n es.close();\n es = null;\n }\n const url = new URL(base, window.location.origin);\n url.searchParams.set('access_token', token);\n try {\n es = new EventSource(url.toString());\n } catch {\n scheduleReconnect();\n return;\n }\n es.addEventListener('badge', onBadge);\n es.addEventListener('inbox', onBadge);\n es.onopen = () => {\n attempt = 0;\n };\n // 受控退避重连(勿永久 close;否则站内信 toast 再也收不到)\n es.onerror = () => {\n if (closed) return;\n es?.close();\n es = null;\n scheduleReconnect();\n };\n };\n\n connect();\n\n return () => {\n closed = true;\n clearRetry();\n if (es) {\n es.removeEventListener('badge', onBadge);\n es.removeEventListener('inbox', onBadge);\n es.close();\n es = null;\n }\n };\n }, [streamPath, getAccessToken, scheduleBadgeRefresh]);\n\n useEffect(() => {\n if (open) void load();\n }, [open, load]);\n\n const typeTabOptions = useMemo(\n () =>\n TYPE_TABS.map((t) => {\n const n = t.key ? unreadByType[t.key] || 0 : unreadTotal;\n return {\n key: t.key || 'all',\n label: n > 0 ? `${t.label} (${n})` : t.label,\n };\n }),\n [unreadByType, unreadTotal],\n );\n\n const updateToastPref = (key: keyof InboxToastPrefs, checked: boolean) => {\n setToastPrefs((prev) => {\n const next = { ...prev, [key]: checked };\n saveInboxToastPrefs(next);\n return next;\n });\n };\n\n const handleOpenItem = async (item: InboxBellItem, opts?: { skipRead?: boolean }) => {\n if (!opts?.skipRead && !item.read) {\n try {\n await markRead(item.id);\n setItems((prev) => prev.map((x) => (x.id === item.id ? { ...x, read: true } : x)));\n setUnreadTotal((n) => Math.max(0, n - 1));\n } catch (e) {\n message.error(e instanceof Error ? e.message : '标记已读失败');\n return;\n }\n }\n const href = String(item.href || '').trim();\n if (!href) return;\n if (onNavigate) {\n onNavigate(href, item);\n setOpen(false);\n return;\n }\n if (href.startsWith('http://') || href.startsWith('https://')) {\n window.open(href, '_blank', 'noopener,noreferrer');\n } else {\n window.location.assign(href);\n }\n setOpen(false);\n };\n\n const runQuickAction = async (item: InboxBellItem, action: InboxItemQuickAction) => {\n if (action.disabled) return;\n if (onItemAction) {\n try {\n await onItemAction(action.kind, item);\n setOpen(false);\n void load();\n void refreshBadge();\n } catch (e) {\n message.error(e instanceof Error ? e.message : '操作失败');\n }\n return;\n }\n await handleOpenItem(item);\n };\n\n const handleClearUnread = async () => {\n if (!markAllRead || unreadTotal <= 0 || clearingUnread) return;\n setClearingUnread(true);\n try {\n const res = await markAllRead();\n const n = typeof res?.updated === 'number' ? res.updated : undefined;\n message.success(typeof n === 'number' ? `已清空 ${n} 条未读` : '已清空未读');\n await load();\n await refreshBadge();\n } catch (e) {\n message.error(e instanceof Error ? e.message : '清空未读失败');\n } finally {\n setClearingUnread(false);\n }\n };\n\n const toastTypeLabel = liveToast ? messageTypeLabel(liveToast.messageType) : '';\n\n return (\n <div className={classNames(styles.bellWrap, className)}>\n <Badge count={unreadTotal} size=\"small\" overflowCount={99} offset={[-4, 4]}>\n <Button\n type=\"text\"\n className={styles.bellBtn}\n icon={<Bell size={16} aria-hidden />}\n aria-label={unreadTotal > 0 ? `站内信,${unreadTotal} 条未读` : '站内信'}\n onClick={() => setOpen(true)}\n />\n </Badge>\n {liveToast && typeof document !== 'undefined'\n ? createPortal(\n <div className={styles.toastHost} data-testid=\"inbox-live-toast-host\">\n <div\n key={liveToast.key}\n className={classNames(\n 'marsun-inbox-toast',\n styles.toastNotice,\n liveToast.messageType === 'alert' && styles.accentAlert,\n liveToast.messageType === 'action' && styles.accentAction,\n liveToast.messageType === 'remind' && styles.accentRemind,\n )}\n role=\"alert\"\n data-testid=\"inbox-live-toast\"\n onClick={openDrawerFromToast}\n >\n <button\n type=\"button\"\n className={styles.toastClose}\n aria-label=\"关闭\"\n onClick={(e) => {\n e.stopPropagation();\n dismissLiveToast();\n }}\n >\n ×\n </button>\n <div className={styles.toastHead}>\n <span className={styles.toastTitle}>{emphasizeQuoted(liveToast.title)}</span>\n {toastTypeLabel ? (\n <SemanticTag\n color={messageTypeSemanticColor(liveToast.messageType)}\n className={styles.typeTag}\n >\n {toastTypeLabel}\n </SemanticTag>\n ) : null}\n </div>\n <div className={styles.toastBody}>\n {liveToast.summary ? (\n <div className={styles.toastDesc}>{emphasizeQuoted(liveToast.summary)}</div>\n ) : null}\n <div className={styles.toastActions}>\n <Button\n type=\"primary\"\n size=\"small\"\n onClick={(e) => {\n e.stopPropagation();\n openDrawerFromToast();\n }}\n >\n 查看\n </Button>\n </div>\n </div>\n </div>\n </div>,\n document.body,\n )\n : null}\n <Drawer\n title={title}\n open={open}\n onClose={() => setOpen(false)}\n size={420}\n destroyOnClose={false}\n className={styles.drawer}\n styles={{\n header: { padding: '12px 16px' },\n body: { padding: '12px 16px' },\n }}\n >\n <StateBar\n className={styles.typeTabs}\n size=\"small\"\n activeKey={messageType || 'all'}\n onChange={(k) => setMessageType(k === 'all' ? '' : k)}\n stateOption={typeTabOptions}\n isInner\n />\n <div className={styles.filterRow}>\n <SegmentedRadio<'all' | 'unread' | 'read'>\n size=\"small\"\n value={readFilter}\n onChange={(v) => setReadFilter(v)}\n options={[\n { value: 'all', label: '全部' },\n { value: 'unread', label: '未读' },\n { value: 'read', label: '已读' },\n ]}\n />\n {markAllRead ? (\n <Button\n type=\"link\"\n size=\"small\"\n className={styles.clearUnreadBtn}\n data-testid=\"inbox-clear-unread\"\n loading={clearingUnread}\n disabled={unreadTotal <= 0 || clearingUnread}\n onClick={() => void handleClearUnread()}\n >\n 清空未读\n </Button>\n ) : null}\n </div>\n <div className={styles.toastPrefs} data-testid=\"inbox-toast-prefs\">\n <div className={styles.toastPrefsTitle}>消息提示</div>\n <p className={styles.toastPrefsHint}>本机浏览器偏好,非租户策略</p>\n <Space size={12} wrap>\n <Checkbox\n checked={toastPrefs.alert}\n onChange={(e) => updateToastPref('alert', e.target.checked)}\n >\n 预警弹出\n </Checkbox>\n <Checkbox\n checked={toastPrefs.action}\n onChange={(e) => updateToastPref('action', e.target.checked)}\n >\n 行动弹出\n </Checkbox>\n <Checkbox\n checked={toastPrefs.remind}\n onChange={(e) => updateToastPref('remind', e.target.checked)}\n >\n 提醒弹出\n </Checkbox>\n </Space>\n </div>\n {error ? <p className={styles.error}>{error}</p> : null}\n <div className={classNames('inbox-bell-list-pane', styles.listPane)}>\n <PageSpin spinning={loading && items.length === 0}>\n {!loading && !error && items.length === 0 ? (\n <Empty description=\"暂无站内信\" />\n ) : items.length === 0 ? null : (\n <VirtualScrollbar\n wrapperClassName={classNames('inbox-bell-list-scroll', styles.listScroll)}\n className={styles.listViewport}\n data-testid=\"inbox-bell-list-scroll\"\n onScroll={onListScroll}\n >\n <ul className={styles.list}>\n {items.map((item) => {\n const typeLabel = messageTypeLabel(item.messageType);\n const levelText = String(item.levelLabel || item.level || '').trim();\n const showLevel = Boolean(levelText);\n const safeHtml = sanitizeInboxHtml(item.bodyHtml);\n const actions = filterInboxActionsForHost(\n resolveInboxItemActions(item),\n Boolean(onItemAction),\n );\n const buttonDriven = isInboxButtonDriven(item);\n const meta = itemMetaLine(item);\n const showActions = Boolean(actions.primary);\n return (\n <li key={item.id}>\n <div\n className={classNames(\n styles.item,\n !item.read && styles.itemUnread,\n buttonDriven && styles.itemStatic,\n item.messageType === 'alert' && styles.accentAlert,\n item.messageType === 'action' && styles.accentAction,\n item.messageType === 'remind' && styles.accentRemind,\n )}\n style={\n item.levelColor\n ? ({\n ['--inbox-accent' as string]: item.levelColor,\n } as CSSProperties)\n : undefined\n }\n role={buttonDriven ? undefined : 'button'}\n tabIndex={buttonDriven ? undefined : 0}\n onClick={buttonDriven ? undefined : () => void handleOpenItem(item)}\n onKeyDown={\n buttonDriven\n ? undefined\n : (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n void handleOpenItem(item);\n }\n }\n }\n >\n <div className={styles.itemRibbon} aria-hidden />\n <div className={styles.itemHeader}>\n <span className={styles.itemHeaderLeft}>\n {typeLabel ? (\n <SemanticTag\n color={messageTypeSemanticColor(item.messageType)}\n className={styles.typeTag}\n >\n {typeLabel}\n </SemanticTag>\n ) : null}\n <span className={styles.itemTitle} title={item.title || '(无标题)'}>\n {item.title || '(无标题)'}\n </span>\n </span>\n <span className={styles.itemTime}>{item.createdAt || ''}</span>\n </div>\n <div className={styles.itemBody}>\n {safeHtml ? (\n <div\n className={styles.itemBodyHtml}\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n ) : item.summary ? (\n <span className={styles.itemSummary}>\n {emphasizeQuoted(item.summary)}\n </span>\n ) : null}\n </div>\n {meta ? <span className={styles.itemMeta}>{meta}</span> : null}\n {showLevel ? (\n <div className={styles.itemFooterTags}>\n <SemanticTag\n color={resolveLevelTagColor(item.levelColor)}\n selected\n className={styles.typeTag}\n >\n {levelText}\n </SemanticTag>\n </div>\n ) : null}\n {showActions && actions.primary ? (\n <div\n className={styles.itemActions}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <Space size={8} wrap>\n <Button\n size=\"small\"\n type=\"primary\"\n onClick={() => void runQuickAction(item, actions.primary!)}\n >\n {actions.primary.label}\n </Button>\n {actions.secondary ? (\n <Button\n size=\"small\"\n type=\"link\"\n onClick={() => void runQuickAction(item, actions.secondary!)}\n >\n {actions.secondary.label}\n </Button>\n ) : null}\n </Space>\n </div>\n ) : null}\n </div>\n </li>\n );\n })}\n </ul>\n {loadingMore ? (\n <p className={classNames('inbox-bell-list-footer', styles.listFooter)}>加载中…</p>\n ) : null}\n </VirtualScrollbar>\n )}\n </PageSpin>\n </div>\n </Drawer>\n </div>\n );\n});\n\nexport default InboxBell;\nexport {\n DEFAULT_INBOX_TOAST_PREFS,\n loadInboxToastPrefs,\n saveInboxToastPrefs,\n shouldToastForMessageType,\n} from './toastPrefs';\nexport type { InboxToastPrefs } from './toastPrefs';\nexport {\n resolveInboxItemActions,\n resolveInboxSceneKey,\n filterInboxActionsForHost,\n normalizeInboxActions,\n inboxSceneLabel,\n isInboxButtonDriven,\n isTerminalActionStatus,\n} from './inboxItemActions';\nexport type {\n InboxItemActionKind,\n InboxItemQuickAction,\n InboxItemActionsResolved,\n} from './inboxItemActions';\n"],"names":["TOAST_DURATION_MS","TYPE_TABS","TYPE_TAG_LABEL","FOCUS_DEBOUNCE_MS","BADGE_DEBOUNCE_MS","LOAD_MORE_GAP_PX","messageTypeLabel","raw","key","messageTypeSemanticColor","SEMANTIC_COLORS","itemMetaLine","item","x","resolveLevelTagColor","parseBadgePreview","data","messageType","title","summary","InboxBell","forwardRef","fetchInbox","markRead","markAllRead","onNavigate","pollMs","locationKey","pageSize","className","streamPath","getAccessToken","onItemAction","ref","open","setOpen","useState","loading","setLoading","error","setError","items","setItems","unreadTotal","setUnreadTotal","unreadByType","setUnreadByType","setMessageType","readFilter","setReadFilter","toastPrefs","setToastPrefs","loadInboxToastPrefs","loadingMore","setLoadingMore","clearingUnread","setClearingUnread","liveToast","setLiveToast","focusDebounceRef","useRef","badgeDebounceRef","pendingToastRef","toastTimerRef","locationKeyPrimedRef","toastPrefsRef","currentPageRef","loadingMoreRef","hasMoreRef","listQuery","useMemo","load","useCallback","res","page","total","loadMore","next","prev","seen","extra","merged","onListScroll","el","refreshBadge","dismissLiveToast","openDrawerFromToast","flushPendingToast","preview","shouldToastForMessageType","toastKey","scheduleBadgeRefresh","useImperativeHandle","useEffect","t","schedule","onVisibility","onExternal","ev","detail","INBOX_BADGE_REFRESH_EVENT","notification","base","closed","es","retryTimer","attempt","onBadge","msgEv","clearRetry","scheduleReconnect","delay","connect","token","url","typeTabOptions","n","updateToastPref","checked","saveInboxToastPrefs","handleOpenItem","opts","e","message","href","runQuickAction","action","handleClearUnread","toastTypeLabel","classNames","styles","jsx","Badge","Button","Bell","createPortal","jsxs","emphasizeQuoted","SemanticTag","Drawer","StateBar","k","SegmentedRadio","v","Space","Checkbox","PageSpin","Empty","VirtualScrollbar","typeLabel","levelText","showLevel","safeHtml","sanitizeInboxHtml","actions","filterInboxActionsForHost","resolveInboxItemActions","buttonDriven","isInboxButtonDriven","meta","showActions"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const d = {
|
|
2
2
|
inspect_alert: "巡检预警",
|
|
3
3
|
claim_due: "认领到期",
|
|
4
4
|
claim_overdue: "认领到期",
|
|
@@ -6,91 +6,105 @@ const l = {
|
|
|
6
6
|
action_overdue: "行动超期",
|
|
7
7
|
action_assigned: "任务分配",
|
|
8
8
|
action_assigned_ack: "分配确认",
|
|
9
|
+
action_unassigned: "任务改派",
|
|
10
|
+
action_updated: "任务编辑",
|
|
9
11
|
action_status_changed: "状态变更",
|
|
10
12
|
action_claimed: "任务认领",
|
|
11
13
|
action_followed: "任务跟进",
|
|
14
|
+
action_approval_pending: "待审批",
|
|
15
|
+
action_approved: "已批准",
|
|
16
|
+
action_rejected: "已驳回",
|
|
17
|
+
action_approval_passed_ack: "审批回执",
|
|
18
|
+
action_approval_rejected_ack: "驳回回执",
|
|
12
19
|
l3_parallel: "L3并行"
|
|
13
|
-
},
|
|
20
|
+
}, l = {
|
|
14
21
|
"alert.inspect": "inspect_alert",
|
|
15
22
|
"remind.claim_due": "claim_due",
|
|
16
23
|
"action.overdue": "action_overdue",
|
|
17
24
|
"action.assigned": "action_assigned",
|
|
18
25
|
"action.assigned_ack": "action_assigned_ack",
|
|
26
|
+
"action.unassigned": "action_unassigned",
|
|
27
|
+
"action.updated": "action_updated",
|
|
19
28
|
"action.status_changed": "action_status_changed",
|
|
20
29
|
"action.status": "action_status_changed",
|
|
21
30
|
"action.due_soon": "action_overdue",
|
|
22
31
|
"action.claimed": "action_claimed",
|
|
23
|
-
"action.followed": "action_followed"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
"action.followed": "action_followed",
|
|
33
|
+
"action.approval_pending": "action_approval_pending",
|
|
34
|
+
"action.approved": "action_approved",
|
|
35
|
+
"action.rejected": "action_rejected",
|
|
36
|
+
"action.approval_passed_ack": "action_approval_passed_ack",
|
|
37
|
+
"action.approval_rejected_ack": "action_approval_rejected_ack"
|
|
38
|
+
}, p = /* @__PURE__ */ new Set(["done", "reviewed", "cancelled", "closed", "rejected"]);
|
|
39
|
+
function f(e) {
|
|
40
|
+
const a = String(e || "").trim().toLowerCase();
|
|
41
|
+
if (!a) return "";
|
|
42
|
+
if (d[a]) return a;
|
|
43
|
+
if (l[a]) return l[a];
|
|
44
|
+
const i = a.replace(/\./g, "_");
|
|
45
|
+
return d[i] ? i : a;
|
|
32
46
|
}
|
|
33
|
-
function
|
|
34
|
-
return !!(e &&
|
|
47
|
+
function m(e) {
|
|
48
|
+
return !!(e && d[e]);
|
|
35
49
|
}
|
|
36
50
|
function s(e) {
|
|
37
|
-
const
|
|
38
|
-
for (const
|
|
39
|
-
if (
|
|
40
|
-
return
|
|
51
|
+
const a = [e.eventKey, e.scene, e.category].map((i) => f(i));
|
|
52
|
+
for (const i of a)
|
|
53
|
+
if (m(i)) return i;
|
|
54
|
+
return a.find(Boolean) || "";
|
|
41
55
|
}
|
|
42
|
-
function
|
|
43
|
-
const
|
|
44
|
-
return
|
|
56
|
+
function y(e) {
|
|
57
|
+
const a = s(e);
|
|
58
|
+
return a && d[a] || "";
|
|
45
59
|
}
|
|
46
|
-
function
|
|
47
|
-
const
|
|
48
|
-
return
|
|
60
|
+
function b(e) {
|
|
61
|
+
const a = s(e);
|
|
62
|
+
return a === "claim_due" || a === "claim_overdue" || a === "action_overdue" || a === "action_assigned" || a === "action_assigned_ack" || a === "action_unassigned" || a === "action_updated" || a === "action_status_changed" || a === "action_claimed" || a === "action_followed" || a === "inspect_alert";
|
|
49
63
|
}
|
|
50
64
|
function _(e) {
|
|
51
65
|
return String(e || "").trim().toLowerCase();
|
|
52
66
|
}
|
|
53
|
-
function
|
|
54
|
-
return
|
|
67
|
+
function v(e) {
|
|
68
|
+
return p.has(_(e));
|
|
55
69
|
}
|
|
56
|
-
function
|
|
57
|
-
return String(e.messageType || "").trim().toLowerCase() === "action" ? !0 :
|
|
70
|
+
function k(e, a) {
|
|
71
|
+
return String(e.messageType || "").trim().toLowerCase() === "action" ? !0 : a.startsWith("action_") || a === "action_overdue" || a === "action_assigned" || a === "action_assigned_ack" || a === "action_status_changed" || a === "action_claimed" || a === "action_followed";
|
|
58
72
|
}
|
|
59
|
-
function c(e,
|
|
60
|
-
return
|
|
73
|
+
function c(e, a) {
|
|
74
|
+
return a ? { primary: { kind: "view_task", label: "查看任务" } } : String(e.href || "").trim() ? { primary: { kind: "view_href", label: "查看" } } : { primary: { kind: "open_actions", label: "查看任务" } };
|
|
61
75
|
}
|
|
62
76
|
function w(e) {
|
|
63
|
-
const
|
|
64
|
-
return
|
|
77
|
+
const a = s(e), i = String(e.actionId || "").trim(), t = String(e.alertId || "").trim(), n = _(e.actionStatus), r = v(n), o = !!e.started || r || n === "in_progress" || a === "action_followed" || a === "action_claimed", u = !!e.claimed || !!i || a === "action_claimed";
|
|
78
|
+
return a === "claim_due" || a === "claim_overdue" ? u ? i ? { primary: { kind: "view_task", label: "查看任务" } } : { primary: { kind: "view_alert", label: "查看预警" } } : { primary: { kind: "claim_alert", label: "去认领" } } : a === "action_claimed" || a === "action_followed" || a === "action_unassigned" || a === "action_updated" || a === "action_assigned_ack" ? c(e, i) : a === "action_status_changed" ? n === "draft" && i ? { primary: { kind: "view_task", label: "去批准创建" } } : c(e, i) : a === "action_approval_pending" ? i ? { primary: { kind: "view_task", label: "去批准创建" } } : c(e, i) : a === "action_approved" || a === "action_rejected" || a === "action_approval_passed_ack" || a === "action_approval_rejected_ack" ? c(e, i) : a === "action_overdue" || a === "action_assigned" ? r || o ? c(e, i) : i ? { primary: { kind: "start_action", label: "去执行" } } : String(e.href || "").trim() ? { primary: { kind: "view_href", label: "查看" } } : {} : a === "dispose_escalation" ? i ? {
|
|
65
79
|
primary: { kind: "view_task", label: "查看任务" },
|
|
66
|
-
secondary:
|
|
80
|
+
secondary: t ? { kind: "view_alert", label: "查看预警" } : void 0
|
|
67
81
|
} : {
|
|
68
82
|
primary: { kind: "view_alert", label: "查看预警" },
|
|
69
83
|
secondary: { kind: "open_actions", label: "去任务跟踪" }
|
|
70
|
-
} :
|
|
84
|
+
} : a.startsWith("rca") || a === "rca_approved" ? { primary: { kind: "view_rca", label: "查看根因" } } : a === "inspect_alert" || a === "l3_parallel" ? i ? {
|
|
71
85
|
primary: { kind: "view_alert", label: "查看预警" },
|
|
72
86
|
secondary: { kind: "view_task", label: "查看任务" }
|
|
73
|
-
} : { primary: { kind: "view_alert", label: "查看预警" } } :
|
|
87
|
+
} : { primary: { kind: "view_alert", label: "查看预警" } } : k(e, a) ? r || o || a === "action_claimed" ? c(e, i) : i ? { primary: { kind: "start_action", label: "去执行" } } : c(e, i) : t ? i ? {
|
|
74
88
|
primary: { kind: "view_alert", label: "查看预警" },
|
|
75
89
|
secondary: { kind: "view_task", label: "查看任务" }
|
|
76
|
-
} : { primary: { kind: "view_alert", label: "查看预警" } } :
|
|
90
|
+
} : { primary: { kind: "view_alert", label: "查看预警" } } : i ? r || o ? { primary: { kind: "view_task", label: "查看任务" } } : { primary: { kind: "start_action", label: "去执行" } } : String(e.href || "").trim() ? { primary: { kind: "view_href", label: "查看" } } : {};
|
|
77
91
|
}
|
|
78
|
-
function
|
|
79
|
-
const
|
|
80
|
-
let
|
|
81
|
-
return !
|
|
92
|
+
function g(e) {
|
|
93
|
+
const a = (n) => n && !n.disabled ? { ...n, disabled: void 0 } : void 0;
|
|
94
|
+
let i = a(e.primary), t = a(e.secondary);
|
|
95
|
+
return !i && t && (i = t, t = void 0), i && t && i.kind === t.kind && (t = void 0), { primary: i, secondary: t };
|
|
82
96
|
}
|
|
83
|
-
function S(e,
|
|
84
|
-
const
|
|
85
|
-
let n =
|
|
97
|
+
function S(e, a) {
|
|
98
|
+
const i = g(e), t = (o) => o && o.kind === "create_task" ? void 0 : o;
|
|
99
|
+
let n = t(i.primary), r = t(i.secondary);
|
|
86
100
|
return !n && r && (n = r, r = void 0), { primary: n, secondary: r };
|
|
87
101
|
}
|
|
88
102
|
export {
|
|
89
103
|
S as filterInboxActionsForHost,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
104
|
+
y as inboxSceneLabel,
|
|
105
|
+
b as isInboxButtonDriven,
|
|
106
|
+
v as isTerminalActionStatus,
|
|
107
|
+
g as normalizeInboxActions,
|
|
94
108
|
w as resolveInboxItemActions,
|
|
95
109
|
s as resolveInboxSceneKey
|
|
96
110
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inboxItemActions.js","sources":["../../../../../src/components/Tools/Inbox/InboxBell/inboxItemActions.ts"],"sourcesContent":["export type InboxItemActionKind =\n | 'view_alert'\n | 'claim_alert'\n | 'start_action'\n | 'view_task'\n /** @deprecated 铃铛永不解析;保留类型以免破对外联合 */\n | 'create_task'\n | 'open_actions'\n | 'view_rca'\n | 'view_href';\n\nexport type InboxItemQuickAction = {\n kind: InboxItemActionKind;\n label: string;\n /** 解析中间态用;渲染前会被 normalize 丢掉,禁止灰显占位 */\n disabled?: boolean;\n};\n\nexport type InboxItemActionsResolved = {\n primary?: InboxItemQuickAction;\n secondary?: InboxItemQuickAction;\n};\n\nexport type InboxItemActionSource = {\n category?: string | null;\n scene?: string | null;\n eventKey?: string | null;\n messageType?: string | null;\n alertId?: string | null;\n actionId?: string | null;\n claimed?: boolean;\n started?: boolean;\n /** 行动项当前状态:approved/in_progress/done/reviewed/cancelled 等 */\n actionStatus?: string | null;\n href?: string | null;\n};\n\nconst SCENE_LABEL: Record<string, string> = {\n inspect_alert: '巡检预警',\n claim_due: '认领到期',\n claim_overdue: '认领到期',\n dispose_escalation: '处置升级',\n action_overdue: '行动超期',\n action_assigned: '任务分配',\n action_assigned_ack: '分配确认',\n action_status_changed: '状态变更',\n action_claimed: '任务认领',\n action_followed: '任务跟进',\n l3_parallel: 'L3并行',\n};\n\nconst SCENE_ALIAS: Record<string, string> = {\n 'alert.inspect': 'inspect_alert',\n 'remind.claim_due': 'claim_due',\n 'action.overdue': 'action_overdue',\n 'action.assigned': 'action_assigned',\n 'action.assigned_ack': 'action_assigned_ack',\n 'action.status_changed': 'action_status_changed',\n 'action.status': 'action_status_changed',\n 'action.due_soon': 'action_overdue',\n 'action.claimed': 'action_claimed',\n 'action.followed': 'action_followed',\n};\n\nconst TERMINAL_STATUS = new Set(['done', 'reviewed', 'cancelled', 'closed']);\n\nfunction canonScene(raw?: string | null): string {\n const c = String(raw || '')\n .trim()\n .toLowerCase();\n if (!c) return '';\n if (SCENE_LABEL[c]) return c;\n if (SCENE_ALIAS[c]) return SCENE_ALIAS[c];\n const underscored = c.replace(/\\./g, '_');\n if (SCENE_LABEL[underscored]) return underscored;\n return c;\n}\n\n/** 是否已映射到 SCENE_LABEL 已知键(非原样回落的未知串) */\nfunction isKnownSceneKey(key: string): boolean {\n return Boolean(key && SCENE_LABEL[key]);\n}\n\n/**\n * 场景键:优先能映射到已知场景的 eventKey → scene → category;\n * 避免脏 category 压过正确 eventKey(如 action.status_changed)。\n */\nexport function resolveInboxSceneKey(item: InboxItemActionSource): string {\n const candidates = [item.eventKey, item.scene, item.category].map((x) => canonScene(x));\n for (const c of candidates) {\n if (isKnownSceneKey(c)) return c;\n }\n return candidates.find(Boolean) || '';\n}\n\nexport function inboxSceneLabel(item: InboxItemActionSource): string {\n const key = resolveInboxSceneKey(item);\n if (!key) return '';\n return SCENE_LABEL[key] || '';\n}\n\nexport function isInboxButtonDriven(item: InboxItemActionSource): boolean {\n const c = resolveInboxSceneKey(item);\n return (\n c === 'claim_due' ||\n c === 'claim_overdue' ||\n c === 'action_overdue' ||\n c === 'action_assigned' ||\n c === 'action_assigned_ack' ||\n c === 'action_status_changed' ||\n c === 'action_claimed' ||\n c === 'action_followed' ||\n c === 'inspect_alert'\n );\n}\n\nfunction normStatus(raw?: string | null): string {\n return String(raw || '')\n .trim()\n .toLowerCase();\n}\n\nexport function isTerminalActionStatus(status?: string | null): boolean {\n return TERMINAL_STATUS.has(normStatus(status));\n}\n\nfunction isActionMessage(n: InboxItemActionSource, scene: string): boolean {\n const mt = String(n.messageType || '')\n .trim()\n .toLowerCase();\n if (mt === 'action') return true;\n return (\n scene.startsWith('action_') ||\n scene === 'action_overdue' ||\n scene === 'action_assigned' ||\n scene === 'action_assigned_ack' ||\n scene === 'action_status_changed' ||\n scene === 'action_claimed' ||\n scene === 'action_followed'\n );\n}\n\nfunction viewTaskOrHref(n: InboxItemActionSource, actionId: string): InboxItemActionsResolved {\n if (actionId) return { primary: { kind: 'view_task', label: '查看任务' } };\n if (String(n.href || '').trim()) return { primary: { kind: 'view_href', label: '查看' } };\n return { primary: { kind: 'open_actions', label: '查看任务' } };\n}\n\n/**\n * 解析卡片底栏动作。\n * 约定:禁用态不返回(由 normalize 再保险);终态任务只给「查看任务」;永不解析新建任务。\n */\nexport function resolveInboxItemActions(n: InboxItemActionSource): InboxItemActionsResolved {\n const c = resolveInboxSceneKey(n);\n const actionId = String(n.actionId || '').trim();\n const alertId = String(n.alertId || '').trim();\n const status = normStatus(n.actionStatus);\n const terminal = isTerminalActionStatus(status);\n const started =\n Boolean(n.started) ||\n terminal ||\n status === 'in_progress' ||\n c === 'action_followed' ||\n c === 'action_claimed';\n const claimed = Boolean(n.claimed) || Boolean(actionId) || c === 'action_claimed';\n\n if (c === 'claim_due' || c === 'claim_overdue') {\n if (claimed) {\n return actionId\n ? { primary: { kind: 'view_task', label: '查看任务' } }\n : { primary: { kind: 'view_alert', label: '查看预警' } };\n }\n return { primary: { kind: 'claim_alert', label: '去认领' } };\n }\n\n // 已认领 / 已跟进 / 状态变更 / 分配人确认:只看任务(勿落「去执行」「查看预警」)\n if (\n c === 'action_claimed' ||\n c === 'action_followed' ||\n c === 'action_status_changed' ||\n c === 'action_assigned_ack'\n ) {\n return viewTaskOrHref(n, actionId);\n }\n\n if (c === 'action_overdue' || c === 'action_assigned') {\n if (terminal || started) {\n return viewTaskOrHref(n, actionId);\n }\n if (!actionId) {\n return String(n.href || '').trim() ? { primary: { kind: 'view_href', label: '查看' } } : {};\n }\n return { primary: { kind: 'start_action', label: '去执行' } };\n }\n\n if (c === 'dispose_escalation') {\n if (actionId) {\n return {\n primary: { kind: 'view_task', label: '查看任务' },\n secondary: alertId ? { kind: 'view_alert', label: '查看预警' } : undefined,\n };\n }\n return {\n primary: { kind: 'view_alert', label: '查看预警' },\n secondary: { kind: 'open_actions', label: '去任务跟踪' },\n };\n }\n\n if (c.startsWith('rca') || c === 'rca_approved') {\n return { primary: { kind: 'view_rca', label: '查看根因' } };\n }\n\n if (c === 'inspect_alert' || c === 'l3_parallel') {\n if (actionId) {\n return {\n primary: { kind: 'view_alert', label: '查看预警' },\n secondary: { kind: 'view_task', label: '查看任务' },\n };\n }\n return { primary: { kind: 'view_alert', label: '查看预警' } };\n }\n\n // 行动类消息(含历史 category 空):优先任务,禁止误用「查看预警」\n if (isActionMessage(n, c)) {\n if (terminal || started || c === 'action_claimed') {\n return viewTaskOrHref(n, actionId);\n }\n if (actionId) {\n return { primary: { kind: 'start_action', label: '去执行' } };\n }\n return viewTaskOrHref(n, actionId);\n }\n\n if (alertId) {\n if (actionId) {\n return {\n primary: { kind: 'view_alert', label: '查看预警' },\n secondary: { kind: 'view_task', label: '查看任务' },\n };\n }\n return { primary: { kind: 'view_alert', label: '查看预警' } };\n }\n\n if (actionId) {\n if (terminal || started) return { primary: { kind: 'view_task', label: '查看任务' } };\n return { primary: { kind: 'start_action', label: '去执行' } };\n }\n\n if (String(n.href || '').trim()) {\n return { primary: { kind: 'view_href', label: '查看' } };\n }\n\n return {};\n}\n\n/** 去掉 disabled;主按钮空时把次按钮升格;统一主/次语义 */\nexport function normalizeInboxActions(\n resolved: InboxItemActionsResolved,\n): InboxItemActionsResolved {\n const usable = (a?: InboxItemQuickAction) =>\n a && !a.disabled ? { ...a, disabled: undefined } : undefined;\n let primary = usable(resolved.primary);\n let secondary = usable(resolved.secondary);\n if (!primary && secondary) {\n primary = secondary;\n secondary = undefined;\n }\n if (primary && secondary && primary.kind === secondary.kind) {\n secondary = undefined;\n }\n return { primary, secondary };\n}\n\n/** 铃铛永不展示「新建任务」(解析路径已停产;此处再防御) */\nexport function filterInboxActionsForHost(\n resolved: InboxItemActionsResolved,\n _hasItemAction: boolean,\n): InboxItemActionsResolved {\n const base = normalizeInboxActions(resolved);\n const dropCreate = (a?: InboxItemQuickAction) => (a && a.kind === 'create_task' ? undefined : a);\n let primary = dropCreate(base.primary);\n let secondary = dropCreate(base.secondary);\n if (!primary && secondary) {\n primary = secondary;\n secondary = undefined;\n }\n return { primary, secondary };\n}\n"],"names":["SCENE_LABEL","SCENE_ALIAS","TERMINAL_STATUS","canonScene","raw","c","underscored","isKnownSceneKey","key","resolveInboxSceneKey","item","candidates","x","inboxSceneLabel","isInboxButtonDriven","normStatus","isTerminalActionStatus","status","isActionMessage","n","scene","viewTaskOrHref","actionId","resolveInboxItemActions","alertId","terminal","started","claimed","normalizeInboxActions","resolved","usable","a","primary","secondary","filterInboxActionsForHost","_hasItemAction","base","dropCreate"],"mappings":"AAqCA,MAAMA,IAAsC;AAAA,EAC1C,eAAe;AAAA,EACf,WAAW;AAAA,EACX,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,aAAa;AACf,GAEMC,IAAsC;AAAA,EAC1C,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,mBAAmB;AACrB,GAEMC,wBAAsB,IAAI,CAAC,QAAQ,YAAY,aAAa,QAAQ,CAAC;AAE3E,SAASC,EAAWC,GAA6B;AAC/C,QAAMC,IAAI,OAAOD,KAAO,EAAE,EACvB,KAAA,EACA,YAAA;AACH,MAAI,CAACC,EAAG,QAAO;AACf,MAAIL,EAAYK,CAAC,EAAG,QAAOA;AAC3B,MAAIJ,EAAYI,CAAC,EAAG,QAAOJ,EAAYI,CAAC;AACxC,QAAMC,IAAcD,EAAE,QAAQ,OAAO,GAAG;AACxC,SAAIL,EAAYM,CAAW,IAAUA,IAC9BD;AACT;AAGA,SAASE,EAAgBC,GAAsB;AAC7C,SAAO,GAAQA,KAAOR,EAAYQ,CAAG;AACvC;AAMO,SAASC,EAAqBC,GAAqC;AACxE,QAAMC,IAAa,CAACD,EAAK,UAAUA,EAAK,OAAOA,EAAK,QAAQ,EAAE,IAAI,CAACE,MAAMT,EAAWS,CAAC,CAAC;AACtF,aAAWP,KAAKM;AACd,QAAIJ,EAAgBF,CAAC,EAAG,QAAOA;AAEjC,SAAOM,EAAW,KAAK,OAAO,KAAK;AACrC;AAEO,SAASE,EAAgBH,GAAqC;AACnE,QAAMF,IAAMC,EAAqBC,CAAI;AACrC,SAAKF,KACER,EAAYQ,CAAG,KAAK;AAC7B;AAEO,SAASM,EAAoBJ,GAAsC;AACxE,QAAML,IAAII,EAAqBC,CAAI;AACnC,SACEL,MAAM,eACNA,MAAM,mBACNA,MAAM,oBACNA,MAAM,qBACNA,MAAM,yBACNA,MAAM,2BACNA,MAAM,oBACNA,MAAM,qBACNA,MAAM;AAEV;AAEA,SAASU,EAAWX,GAA6B;AAC/C,SAAO,OAAOA,KAAO,EAAE,EACpB,KAAA,EACA,YAAA;AACL;AAEO,SAASY,EAAuBC,GAAiC;AACtE,SAAOf,EAAgB,IAAIa,EAAWE,CAAM,CAAC;AAC/C;AAEA,SAASC,EAAgBC,GAA0BC,GAAwB;AAIzE,SAHW,OAAOD,EAAE,eAAe,EAAE,EAClC,KAAA,EACA,YAAA,MACQ,WAAiB,KAE1BC,EAAM,WAAW,SAAS,KAC1BA,MAAU,oBACVA,MAAU,qBACVA,MAAU,yBACVA,MAAU,2BACVA,MAAU,oBACVA,MAAU;AAEd;AAEA,SAASC,EAAeF,GAA0BG,GAA4C;AAC5F,SAAIA,IAAiB,EAAE,SAAS,EAAE,MAAM,aAAa,OAAO,SAAO,IAC/D,OAAOH,EAAE,QAAQ,EAAE,EAAE,KAAA,IAAe,EAAE,SAAS,EAAE,MAAM,aAAa,OAAO,OAAK,IAC7E,EAAE,SAAS,EAAE,MAAM,gBAAgB,OAAO,SAAO;AAC1D;AAMO,SAASI,EAAwBJ,GAAoD;AAC1F,QAAMd,IAAII,EAAqBU,CAAC,GAC1BG,IAAW,OAAOH,EAAE,YAAY,EAAE,EAAE,KAAA,GACpCK,IAAU,OAAOL,EAAE,WAAW,EAAE,EAAE,KAAA,GAClCF,IAASF,EAAWI,EAAE,YAAY,GAClCM,IAAWT,EAAuBC,CAAM,GACxCS,IACJ,EAAQP,EAAE,WACVM,KACAR,MAAW,iBACXZ,MAAM,qBACNA,MAAM,kBACFsB,IAAU,EAAQR,EAAE,WAAY,EAAQG,KAAajB,MAAM;AAEjE,SAAIA,MAAM,eAAeA,MAAM,kBACzBsB,IACKL,IACH,EAAE,SAAS,EAAE,MAAM,aAAa,OAAO,OAAA,EAAO,IAC9C,EAAE,SAAS,EAAE,MAAM,cAAc,OAAO,SAAO,IAE9C,EAAE,SAAS,EAAE,MAAM,eAAe,OAAO,QAAM,IAKtDjB,MAAM,oBACNA,MAAM,qBACNA,MAAM,2BACNA,MAAM,wBAECgB,EAAeF,GAAGG,CAAQ,IAG/BjB,MAAM,oBAAoBA,MAAM,oBAC9BoB,KAAYC,IACPL,EAAeF,GAAGG,CAAQ,IAE9BA,IAGE,EAAE,SAAS,EAAE,MAAM,gBAAgB,OAAO,QAAM,IAF9C,OAAOH,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,OAAO,KAAA,EAAK,IAAM,CAAA,IAKvFd,MAAM,uBACJiB,IACK;AAAA,IACL,SAAS,EAAE,MAAM,aAAa,OAAO,OAAA;AAAA,IACrC,WAAWE,IAAU,EAAE,MAAM,cAAc,OAAO,WAAW;AAAA,EAAA,IAG1D;AAAA,IACL,SAAS,EAAE,MAAM,cAAc,OAAO,OAAA;AAAA,IACtC,WAAW,EAAE,MAAM,gBAAgB,OAAO,QAAA;AAAA,EAAQ,IAIlDnB,EAAE,WAAW,KAAK,KAAKA,MAAM,iBACxB,EAAE,SAAS,EAAE,MAAM,YAAY,OAAO,SAAO,IAGlDA,MAAM,mBAAmBA,MAAM,gBAC7BiB,IACK;AAAA,IACL,SAAS,EAAE,MAAM,cAAc,OAAO,OAAA;AAAA,IACtC,WAAW,EAAE,MAAM,aAAa,OAAO,OAAA;AAAA,EAAO,IAG3C,EAAE,SAAS,EAAE,MAAM,cAAc,OAAO,SAAO,IAIpDJ,EAAgBC,GAAGd,CAAC,IAClBoB,KAAYC,KAAWrB,MAAM,mBACxBgB,EAAeF,GAAGG,CAAQ,IAE/BA,IACK,EAAE,SAAS,EAAE,MAAM,gBAAgB,OAAO,QAAM,IAElDD,EAAeF,GAAGG,CAAQ,IAG/BE,IACEF,IACK;AAAA,IACL,SAAS,EAAE,MAAM,cAAc,OAAO,OAAA;AAAA,IACtC,WAAW,EAAE,MAAM,aAAa,OAAO,OAAA;AAAA,EAAO,IAG3C,EAAE,SAAS,EAAE,MAAM,cAAc,OAAO,SAAO,IAGpDA,IACEG,KAAYC,IAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,OAAO,SAAO,IACvE,EAAE,SAAS,EAAE,MAAM,gBAAgB,OAAO,QAAM,IAGrD,OAAOP,EAAE,QAAQ,EAAE,EAAE,SAChB,EAAE,SAAS,EAAE,MAAM,aAAa,OAAO,OAAK,IAG9C,CAAA;AACT;AAGO,SAASS,EACdC,GAC0B;AAC1B,QAAMC,IAAS,CAACC,MACdA,KAAK,CAACA,EAAE,WAAW,EAAE,GAAGA,GAAG,UAAU,OAAA,IAAc;AACrD,MAAIC,IAAUF,EAAOD,EAAS,OAAO,GACjCI,IAAYH,EAAOD,EAAS,SAAS;AACzC,SAAI,CAACG,KAAWC,MACdD,IAAUC,GACVA,IAAY,SAEVD,KAAWC,KAAaD,EAAQ,SAASC,EAAU,SACrDA,IAAY,SAEP,EAAE,SAAAD,GAAS,WAAAC,EAAA;AACpB;AAGO,SAASC,EACdL,GACAM,GAC0B;AAC1B,QAAMC,IAAOR,EAAsBC,CAAQ,GACrCQ,IAAa,CAACN,MAA8BA,KAAKA,EAAE,SAAS,gBAAgB,SAAYA;AAC9F,MAAIC,IAAUK,EAAWD,EAAK,OAAO,GACjCH,IAAYI,EAAWD,EAAK,SAAS;AACzC,SAAI,CAACJ,KAAWC,MACdD,IAAUC,GACVA,IAAY,SAEP,EAAE,SAAAD,GAAS,WAAAC,EAAA;AACpB;"}
|
|
1
|
+
{"version":3,"file":"inboxItemActions.js","sources":["../../../../../src/components/Tools/Inbox/InboxBell/inboxItemActions.ts"],"sourcesContent":["export type InboxItemActionKind =\n | 'view_alert'\n | 'claim_alert'\n | 'start_action'\n | 'view_task'\n /** @deprecated 铃铛永不解析;保留类型以免破对外联合 */\n | 'create_task'\n | 'open_actions'\n | 'view_rca'\n | 'view_href';\n\nexport type InboxItemQuickAction = {\n kind: InboxItemActionKind;\n label: string;\n /** 解析中间态用;渲染前会被 normalize 丢掉,禁止灰显占位 */\n disabled?: boolean;\n};\n\nexport type InboxItemActionsResolved = {\n primary?: InboxItemQuickAction;\n secondary?: InboxItemQuickAction;\n};\n\nexport type InboxItemActionSource = {\n category?: string | null;\n scene?: string | null;\n eventKey?: string | null;\n messageType?: string | null;\n alertId?: string | null;\n actionId?: string | null;\n claimed?: boolean;\n started?: boolean;\n /** 行动项当前状态:approved/in_progress/done/reviewed/cancelled 等 */\n actionStatus?: string | null;\n href?: string | null;\n};\n\nconst SCENE_LABEL: Record<string, string> = {\n inspect_alert: '巡检预警',\n claim_due: '认领到期',\n claim_overdue: '认领到期',\n dispose_escalation: '处置升级',\n action_overdue: '行动超期',\n action_assigned: '任务分配',\n action_assigned_ack: '分配确认',\n action_unassigned: '任务改派',\n action_updated: '任务编辑',\n action_status_changed: '状态变更',\n action_claimed: '任务认领',\n action_followed: '任务跟进',\n action_approval_pending: '待审批',\n action_approved: '已批准',\n action_rejected: '已驳回',\n action_approval_passed_ack: '审批回执',\n action_approval_rejected_ack: '驳回回执',\n l3_parallel: 'L3并行',\n};\n\nconst SCENE_ALIAS: Record<string, string> = {\n 'alert.inspect': 'inspect_alert',\n 'remind.claim_due': 'claim_due',\n 'action.overdue': 'action_overdue',\n 'action.assigned': 'action_assigned',\n 'action.assigned_ack': 'action_assigned_ack',\n 'action.unassigned': 'action_unassigned',\n 'action.updated': 'action_updated',\n 'action.status_changed': 'action_status_changed',\n 'action.status': 'action_status_changed',\n 'action.due_soon': 'action_overdue',\n 'action.claimed': 'action_claimed',\n 'action.followed': 'action_followed',\n 'action.approval_pending': 'action_approval_pending',\n 'action.approved': 'action_approved',\n 'action.rejected': 'action_rejected',\n 'action.approval_passed_ack': 'action_approval_passed_ack',\n 'action.approval_rejected_ack': 'action_approval_rejected_ack',\n};\n\n/** rejected = 审批驳回终态;禁再展示「去执行 / 已执行」 */\nconst TERMINAL_STATUS = new Set(['done', 'reviewed', 'cancelled', 'closed', 'rejected']);\n\nfunction canonScene(raw?: string | null): string {\n const c = String(raw || '')\n .trim()\n .toLowerCase();\n if (!c) return '';\n if (SCENE_LABEL[c]) return c;\n if (SCENE_ALIAS[c]) return SCENE_ALIAS[c];\n const underscored = c.replace(/\\./g, '_');\n if (SCENE_LABEL[underscored]) return underscored;\n return c;\n}\n\n/** 是否已映射到 SCENE_LABEL 已知键(非原样回落的未知串) */\nfunction isKnownSceneKey(key: string): boolean {\n return Boolean(key && SCENE_LABEL[key]);\n}\n\n/**\n * 场景键:优先能映射到已知场景的 eventKey → scene → category;\n * 避免脏 category 压过正确 eventKey(如 action.status_changed)。\n */\nexport function resolveInboxSceneKey(item: InboxItemActionSource): string {\n const candidates = [item.eventKey, item.scene, item.category].map((x) => canonScene(x));\n for (const c of candidates) {\n if (isKnownSceneKey(c)) return c;\n }\n return candidates.find(Boolean) || '';\n}\n\nexport function inboxSceneLabel(item: InboxItemActionSource): string {\n const key = resolveInboxSceneKey(item);\n if (!key) return '';\n return SCENE_LABEL[key] || '';\n}\n\nexport function isInboxButtonDriven(item: InboxItemActionSource): boolean {\n const c = resolveInboxSceneKey(item);\n return (\n c === 'claim_due' ||\n c === 'claim_overdue' ||\n c === 'action_overdue' ||\n c === 'action_assigned' ||\n c === 'action_assigned_ack' ||\n c === 'action_unassigned' ||\n c === 'action_updated' ||\n c === 'action_status_changed' ||\n c === 'action_claimed' ||\n c === 'action_followed' ||\n c === 'inspect_alert'\n );\n}\n\nfunction normStatus(raw?: string | null): string {\n return String(raw || '')\n .trim()\n .toLowerCase();\n}\n\nexport function isTerminalActionStatus(status?: string | null): boolean {\n return TERMINAL_STATUS.has(normStatus(status));\n}\n\nfunction isActionMessage(n: InboxItemActionSource, scene: string): boolean {\n const mt = String(n.messageType || '')\n .trim()\n .toLowerCase();\n if (mt === 'action') return true;\n return (\n scene.startsWith('action_') ||\n scene === 'action_overdue' ||\n scene === 'action_assigned' ||\n scene === 'action_assigned_ack' ||\n scene === 'action_status_changed' ||\n scene === 'action_claimed' ||\n scene === 'action_followed'\n );\n}\n\nfunction viewTaskOrHref(n: InboxItemActionSource, actionId: string): InboxItemActionsResolved {\n if (actionId) return { primary: { kind: 'view_task', label: '查看任务' } };\n if (String(n.href || '').trim()) return { primary: { kind: 'view_href', label: '查看' } };\n return { primary: { kind: 'open_actions', label: '查看任务' } };\n}\n\n/**\n * 解析卡片底栏动作。\n * 约定:禁用态不返回(由 normalize 再保险);终态任务只给「查看任务」;永不解析新建任务。\n */\nexport function resolveInboxItemActions(n: InboxItemActionSource): InboxItemActionsResolved {\n const c = resolveInboxSceneKey(n);\n const actionId = String(n.actionId || '').trim();\n const alertId = String(n.alertId || '').trim();\n const status = normStatus(n.actionStatus);\n const terminal = isTerminalActionStatus(status);\n const started =\n Boolean(n.started) ||\n terminal ||\n status === 'in_progress' ||\n c === 'action_followed' ||\n c === 'action_claimed';\n const claimed = Boolean(n.claimed) || Boolean(actionId) || c === 'action_claimed';\n\n if (c === 'claim_due' || c === 'claim_overdue') {\n if (claimed) {\n return actionId\n ? { primary: { kind: 'view_task', label: '查看任务' } }\n : { primary: { kind: 'view_alert', label: '查看预警' } };\n }\n return { primary: { kind: 'claim_alert', label: '去认领' } };\n }\n\n // 已认领 / 已跟进 / 改派 / 编辑 / 分配人确认:只看任务(勿落「去执行」「查看预警」)\n if (\n c === 'action_claimed' ||\n c === 'action_followed' ||\n c === 'action_unassigned' ||\n c === 'action_updated' ||\n c === 'action_assigned_ack'\n ) {\n return viewTaskOrHref(n, actionId);\n }\n\n // 创建待批:引导批准创建(status=draft);其它状态变更仅查看\n if (c === 'action_status_changed') {\n if (status === 'draft' && actionId) {\n return { primary: { kind: 'view_task', label: '去批准创建' } };\n }\n return viewTaskOrHref(n, actionId);\n }\n\n // 审批链路:待审 → 去批准创建;已批/驳回/回执 → 只看任务(禁「去执行」「已执行」)\n if (c === 'action_approval_pending') {\n if (actionId) return { primary: { kind: 'view_task', label: '去批准创建' } };\n return viewTaskOrHref(n, actionId);\n }\n if (\n c === 'action_approved' ||\n c === 'action_rejected' ||\n c === 'action_approval_passed_ack' ||\n c === 'action_approval_rejected_ack'\n ) {\n return viewTaskOrHref(n, actionId);\n }\n\n if (c === 'action_overdue' || c === 'action_assigned') {\n if (terminal || started) {\n return viewTaskOrHref(n, actionId);\n }\n if (!actionId) {\n return String(n.href || '').trim() ? { primary: { kind: 'view_href', label: '查看' } } : {};\n }\n return { primary: { kind: 'start_action', label: '去执行' } };\n }\n\n if (c === 'dispose_escalation') {\n if (actionId) {\n return {\n primary: { kind: 'view_task', label: '查看任务' },\n secondary: alertId ? { kind: 'view_alert', label: '查看预警' } : undefined,\n };\n }\n return {\n primary: { kind: 'view_alert', label: '查看预警' },\n secondary: { kind: 'open_actions', label: '去任务跟踪' },\n };\n }\n\n if (c.startsWith('rca') || c === 'rca_approved') {\n return { primary: { kind: 'view_rca', label: '查看根因' } };\n }\n\n if (c === 'inspect_alert' || c === 'l3_parallel') {\n if (actionId) {\n return {\n primary: { kind: 'view_alert', label: '查看预警' },\n secondary: { kind: 'view_task', label: '查看任务' },\n };\n }\n return { primary: { kind: 'view_alert', label: '查看预警' } };\n }\n\n // 行动类消息(含历史 category 空):优先任务,禁止误用「查看预警」\n if (isActionMessage(n, c)) {\n if (terminal || started || c === 'action_claimed') {\n return viewTaskOrHref(n, actionId);\n }\n if (actionId) {\n return { primary: { kind: 'start_action', label: '去执行' } };\n }\n return viewTaskOrHref(n, actionId);\n }\n\n if (alertId) {\n if (actionId) {\n return {\n primary: { kind: 'view_alert', label: '查看预警' },\n secondary: { kind: 'view_task', label: '查看任务' },\n };\n }\n return { primary: { kind: 'view_alert', label: '查看预警' } };\n }\n\n if (actionId) {\n if (terminal || started) return { primary: { kind: 'view_task', label: '查看任务' } };\n return { primary: { kind: 'start_action', label: '去执行' } };\n }\n\n if (String(n.href || '').trim()) {\n return { primary: { kind: 'view_href', label: '查看' } };\n }\n\n return {};\n}\n\n/** 去掉 disabled;主按钮空时把次按钮升格;统一主/次语义 */\nexport function normalizeInboxActions(\n resolved: InboxItemActionsResolved,\n): InboxItemActionsResolved {\n const usable = (a?: InboxItemQuickAction) =>\n a && !a.disabled ? { ...a, disabled: undefined } : undefined;\n let primary = usable(resolved.primary);\n let secondary = usable(resolved.secondary);\n if (!primary && secondary) {\n primary = secondary;\n secondary = undefined;\n }\n if (primary && secondary && primary.kind === secondary.kind) {\n secondary = undefined;\n }\n return { primary, secondary };\n}\n\n/** 铃铛永不展示「新建任务」(解析路径已停产;此处再防御) */\nexport function filterInboxActionsForHost(\n resolved: InboxItemActionsResolved,\n _hasItemAction: boolean,\n): InboxItemActionsResolved {\n const base = normalizeInboxActions(resolved);\n const dropCreate = (a?: InboxItemQuickAction) => (a && a.kind === 'create_task' ? undefined : a);\n let primary = dropCreate(base.primary);\n let secondary = dropCreate(base.secondary);\n if (!primary && secondary) {\n primary = secondary;\n secondary = undefined;\n }\n return { primary, secondary };\n}\n"],"names":["SCENE_LABEL","SCENE_ALIAS","TERMINAL_STATUS","canonScene","raw","c","underscored","isKnownSceneKey","key","resolveInboxSceneKey","item","candidates","x","inboxSceneLabel","isInboxButtonDriven","normStatus","isTerminalActionStatus","status","isActionMessage","n","scene","viewTaskOrHref","actionId","resolveInboxItemActions","alertId","terminal","started","claimed","normalizeInboxActions","resolved","usable","a","primary","secondary","filterInboxActionsForHost","_hasItemAction","base","dropCreate"],"mappings":"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"}
|