117 lines
3.5 KiB
TypeScript
117 lines
3.5 KiB
TypeScript
export type OpenBorrowAssetPreview = {
|
||
equipmentId?: number | null
|
||
borrowRecordId?: number | null
|
||
personId?: number | null
|
||
equipmentCode: string
|
||
equipmentName: string
|
||
}
|
||
|
||
type HrSyncPersonDisplayNameSource = {
|
||
nickname?: string | null
|
||
realName?: string | null
|
||
}
|
||
|
||
const safeTrim = (value: unknown) => {
|
||
if (value === null || value === undefined) {
|
||
return null
|
||
}
|
||
|
||
const text = String(value).trim()
|
||
return text ? text : null
|
||
}
|
||
|
||
const getConfiguredSet = (value: string, defaultValue: string) =>
|
||
new Set(
|
||
((value && value.trim() ? value : defaultValue) || '')
|
||
.split(',')
|
||
.map((item) => item.trim())
|
||
.filter(Boolean)
|
||
)
|
||
|
||
const getInactiveStatusValues = () =>
|
||
getConfiguredSet(process.env.HR_SYNC_INACTIVE_STATUS_VALUES || '', '5')
|
||
|
||
const getInactiveStatusKeywords = () =>
|
||
Array.from(
|
||
getConfiguredSet(
|
||
process.env.HR_SYNC_INACTIVE_STATUS_KEYWORDS || '',
|
||
'离职,停用,停职,离岗,辞职,注销,禁用,失效,inactive,disabled,left'
|
||
)
|
||
).map((keyword) => keyword.toLowerCase())
|
||
|
||
export const resolveSourcePersonStatus = (employeeStatus: unknown): 'active' | 'inactive' => {
|
||
const inactiveStatusValues = getInactiveStatusValues()
|
||
const sourceStatus =
|
||
employeeStatus === null || employeeStatus === undefined ? null : String(employeeStatus).trim()
|
||
|
||
if (sourceStatus && inactiveStatusValues.has(sourceStatus)) {
|
||
return 'inactive'
|
||
}
|
||
|
||
if (sourceStatus) {
|
||
const normalizedStatus = sourceStatus.toLowerCase()
|
||
const inactiveStatusKeywords = getInactiveStatusKeywords()
|
||
if (inactiveStatusKeywords.some((keyword) => normalizedStatus.includes(keyword))) {
|
||
return 'inactive'
|
||
}
|
||
}
|
||
|
||
return 'active'
|
||
}
|
||
|
||
export const shouldUseSourceDepartmentBinding = (employeeStatus: unknown) =>
|
||
resolveSourcePersonStatus(employeeStatus) === 'active'
|
||
|
||
export const formatBorrowedAssetSummary = (assets: OpenBorrowAssetPreview[], limit = 3) => {
|
||
if (assets.length === 0) {
|
||
return '暂无待处理资产'
|
||
}
|
||
|
||
const summary = assets
|
||
.slice(0, limit)
|
||
.map((asset) => `${asset.equipmentCode} / ${asset.equipmentName}`)
|
||
.join('、')
|
||
|
||
return assets.length > limit ? `${summary} 等 ${assets.length} 项` : summary
|
||
}
|
||
|
||
export const resolveHrSyncPersonDisplayName = (person: HrSyncPersonDisplayNameSource) =>
|
||
safeTrim(person.nickname) || safeTrim(person.realName) || '未命名'
|
||
|
||
const extractBorrowedAssetSummary = (detail: string) => {
|
||
const matched = detail.match(/名下(?:待处理)?资产:([^。]+)/)
|
||
return matched?.[1]?.trim() || null
|
||
}
|
||
|
||
const extractStructuredBorrowedAssets = (afterSnapshot?: Record<string, any> | null) => {
|
||
if (!afterSnapshot || !Array.isArray(afterSnapshot.assets)) {
|
||
return []
|
||
}
|
||
|
||
return afterSnapshot.assets
|
||
.map((asset: Record<string, any>) => ({
|
||
equipmentCode: safeTrim(asset?.equipmentCode) || '',
|
||
equipmentName: safeTrim(asset?.equipmentName) || ''
|
||
}))
|
||
.filter((asset) => asset.equipmentCode && asset.equipmentName)
|
||
}
|
||
|
||
export const buildHrSyncPreviewLine = (change: {
|
||
changeType: string
|
||
title: string
|
||
detail: string
|
||
afterSnapshot?: Record<string, any> | null
|
||
}) => {
|
||
if (change.changeType !== 'person_deactivated' && change.changeType !== 'person_position_changed') {
|
||
return change.title
|
||
}
|
||
|
||
const structuredAssets = extractStructuredBorrowedAssets(change.afterSnapshot)
|
||
const assetSummary =
|
||
structuredAssets.length > 0
|
||
? formatBorrowedAssetSummary(structuredAssets)
|
||
: extractBorrowedAssetSummary(change.detail)
|
||
|
||
return assetSummary ? `${change.title}(名下资产:${assetSummary})` : change.title
|
||
}
|