feat: ship OA drafts/badges, role dual-track, and test-env deploy tooling.

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>
This commit is contained in:
zlwuandCursor committed 2026-08-06 13:58:47 +08:00
1 parent 7af53fc344
commit de22678c87
56 files changed
+11861 -6082

No files matched your search

+48 -10
View File
@@ -1,14 +1,32 @@
import { fetchOaCcUnreadCount } from '@/api/oaApproval'
import { OA_MENU_CODE_CC, useOaMenuBadgeStore } from '@/store/modules/oa-menu-badge'
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 (code === OA_MENU_CODE_CC) return code
if (String(item.name || '') === 'OaApprovalCc') return OA_MENU_CODE_CC
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
}
@@ -29,11 +47,31 @@ export async function refreshOaMenuBadges() {
const menuStore = useMenuStore()
const badgeStore = useOaMenuBadgeStore()
const visibleCodes = collectVisibleOaMenuBadgeCodes(menuStore.menuList)
if (!visibleCodes.includes(OA_MENU_CODE_CC)) return
try {
const data = await fetchOaCcUnreadCount()
badgeStore.setBadge(OA_MENU_CODE_CC, data?.count ?? 0)
} catch {
badgeStore.setBadge(OA_MENU_CODE_CC, 0)
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)
}