Add approval instance drafts with menu badges, dual-track user/role read model and role bound names, form-designer outline docs, and bare-metal test deploy scripts. Ignore local test-server credential file. Co-authored-by: Cursor <cursoragent@cursor.com>
78 lines
2.6 KiB
TypeScript
78 lines
2.6 KiB
TypeScript
import {
|
|
fetchOaCcUnreadCount,
|
|
fetchOaInstanceDraftCount,
|
|
fetchOaPendingTaskCount
|
|
} from '@/api/oaApproval'
|
|
import {
|
|
OA_MENU_CODE_CC,
|
|
OA_MENU_CODE_DRAFTS,
|
|
OA_MENU_CODE_PENDING,
|
|
useOaMenuBadgeStore
|
|
} from '@/store/modules/oa-menu-badge'
|
|
import { useMenuStore } from '@/store/modules/menu'
|
|
import type { AppRouteRecord } from '@/types/router'
|
|
|
|
const OA_BADGE_CODES = new Set([OA_MENU_CODE_CC, OA_MENU_CODE_DRAFTS, OA_MENU_CODE_PENDING])
|
|
|
|
export function resolveOaMenuBadgeCode(item: AppRouteRecord): string | undefined {
|
|
const code = (item.meta.menuCode || '').trim()
|
|
if (OA_BADGE_CODES.has(code)) return code
|
|
const name = String(item.name || '')
|
|
if (name === 'OaApprovalCc') return OA_MENU_CODE_CC
|
|
if (name === 'OaApprovalDrafts') return OA_MENU_CODE_DRAFTS
|
|
if (name === 'OaApprovalPending') return OA_MENU_CODE_PENDING
|
|
// path 兜底仅限 oa: 菜单,避免命中旧工作流 pending
|
|
if (!code.startsWith('oa:')) return undefined
|
|
const path = String(item.path || '')
|
|
if (path.endsWith('/cc') || path === 'cc') return OA_MENU_CODE_CC
|
|
if (path.endsWith('/drafts') || path === 'drafts') return OA_MENU_CODE_DRAFTS
|
|
if (path.endsWith('/pending') || path === 'pending') return OA_MENU_CODE_PENDING
|
|
return undefined
|
|
}
|
|
|
|
export function collectVisibleOaMenuBadgeCodes(menuList: AppRouteRecord[]): string[] {
|
|
const codes = new Set<string>()
|
|
const walk = (items: AppRouteRecord[]) => {
|
|
for (const item of items) {
|
|
const code = resolveOaMenuBadgeCode(item)
|
|
if (code) codes.add(code)
|
|
if (item.children?.length) walk(item.children)
|
|
}
|
|
}
|
|
walk(menuList || [])
|
|
return [...codes]
|
|
}
|
|
|
|
export async function refreshOaMenuBadges() {
|
|
const menuStore = useMenuStore()
|
|
const badgeStore = useOaMenuBadgeStore()
|
|
const visibleCodes = collectVisibleOaMenuBadgeCodes(menuStore.menuList)
|
|
if (!visibleCodes.length) return
|
|
|
|
const jobs: Promise<void>[] = []
|
|
|
|
if (visibleCodes.includes(OA_MENU_CODE_CC)) {
|
|
jobs.push(
|
|
fetchOaCcUnreadCount()
|
|
.then((data) => badgeStore.setBadge(OA_MENU_CODE_CC, data?.count ?? 0))
|
|
.catch(() => badgeStore.setBadge(OA_MENU_CODE_CC, 0))
|
|
)
|
|
}
|
|
if (visibleCodes.includes(OA_MENU_CODE_DRAFTS)) {
|
|
jobs.push(
|
|
fetchOaInstanceDraftCount()
|
|
.then((data) => badgeStore.setBadge(OA_MENU_CODE_DRAFTS, data?.count ?? 0))
|
|
.catch(() => badgeStore.setBadge(OA_MENU_CODE_DRAFTS, 0))
|
|
)
|
|
}
|
|
if (visibleCodes.includes(OA_MENU_CODE_PENDING)) {
|
|
jobs.push(
|
|
fetchOaPendingTaskCount()
|
|
.then((data) => badgeStore.setBadge(OA_MENU_CODE_PENDING, data?.count ?? 0))
|
|
.catch(() => badgeStore.setBadge(OA_MENU_CODE_PENDING, 0))
|
|
)
|
|
}
|
|
|
|
await Promise.all(jobs)
|
|
}
|