增加正式员工同步过滤规则

This commit is contained in:
WuYongJie 2026-03-11 14:52:35 +08:00
parent 4ee77e8eff
commit a247fa69d3
3 changed files with 56 additions and 5 deletions

View File

@ -121,12 +121,18 @@ SQLSERVER_ENCRYPT=false
SQLSERVER_TRUST_CERT=true
HR_SYNC_ENABLED=false
HR_SYNC_SCHEDULE=03:00
HR_SYNC_ALLOWED_STATUS_VALUES=3
HR_SYNC_INACTIVE_STATUS_VALUES=5
HR_SYNC_EXCLUDED_DEPARTMENTS=供应商,快递公司,外部交流
HR_SYNC_EXCLUDED_NAME_KEYWORDS=
```
- `HR_SYNC_ENABLED=true` 时,后端会启动每日定时同步
- `HR_SYNC_SCHEDULE` 建议使用 `03:00`
- `HR_SYNC_ALLOWED_STATUS_VALUES` 用来限定“哪些源状态算正式员工”,当前建议 `3`
- `HR_SYNC_INACTIVE_STATUS_VALUES` 用来标记源系统里的非在职状态码
- `HR_SYNC_EXCLUDED_DEPARTMENTS` 用来排除供应商、快递公司等外部对象
- `HR_SYNC_EXCLUDED_NAME_KEYWORDS` 可选,用来额外排除名字特征
- 如果源库是较老版本 SQL Server,建议 `SQLSERVER_ENCRYPT=false`
## 当前线上资源

View File

@ -43,6 +43,14 @@ let schedulerStarted = false
let schedulerRunning = false
let lastSchedulerRunKey = ''
const getConfiguredSet = (value: string, defaultValue: string) =>
new Set(
(value || defaultValue)
.split(',')
.map((item) => item.trim())
.filter(Boolean)
)
const getSqlServerConfig = (): any => {
const server = process.env.SQLSERVER_HOST
const port = Number(process.env.SQLSERVER_PORT || '1433')
@ -106,11 +114,9 @@ const parseExtensionFlowerName = (extension: unknown) => {
}
const resolvePersonStatus = (active: unknown, employeeStatus: unknown): 'active' | 'inactive' => {
const inactiveStatusValues = new Set(
(process.env.HR_SYNC_INACTIVE_STATUS_VALUES || '5')
.split(',')
.map((item) => item.trim())
.filter(Boolean)
const inactiveStatusValues = getConfiguredSet(
process.env.HR_SYNC_INACTIVE_STATUS_VALUES || '',
'5'
)
const sourceStatus = safeTrim(employeeStatus)
@ -130,6 +136,41 @@ const resolvePersonStatus = (active: unknown, employeeStatus: unknown): 'active'
return 'active'
}
const isFormalEmployee = (person: SourcePerson) => {
const allowedStatusValues = getConfiguredSet(
process.env.HR_SYNC_ALLOWED_STATUS_VALUES || '',
'3'
)
const excludedDepartments = Array.from(
getConfiguredSet(
process.env.HR_SYNC_EXCLUDED_DEPARTMENTS || '',
'供应商,快递公司,外部交流'
)
)
const excludedNameKeywords = Array.from(
getConfiguredSet(
process.env.HR_SYNC_EXCLUDED_NAME_KEYWORDS || '',
''
)
)
if (!allowedStatusValues.has(person.sourceEmployeeStatus || '')) {
return false
}
const departmentName = person.departmentName || ''
if (excludedDepartments.some((keyword) => departmentName.includes(keyword))) {
return false
}
const text = `${person.nickname} ${person.realName}`.trim()
if (excludedNameKeywords.some((keyword) => text.includes(keyword))) {
return false
}
return person.status === 'active'
}
const getSourceDepartments = async (pool: any): Promise<SourceDepartment[]> => {
const result = await pool
.request()
@ -207,6 +248,7 @@ const getSourcePersons = async (pool: any): Promise<SourcePerson[]> => {
} satisfies SourcePerson
})
.filter((item: SourcePerson) => item.sourceUserId)
.filter((item: SourcePerson) => isFormalEmployee(item))
}
const syncDepartments = async (sourceDepartments: SourceDepartment[]) => {

View File

@ -45,7 +45,10 @@ services:
SQLSERVER_TRUST_CERT: ${SQLSERVER_TRUST_CERT:-true}
HR_SYNC_ENABLED: ${HR_SYNC_ENABLED:-false}
HR_SYNC_SCHEDULE: ${HR_SYNC_SCHEDULE:-03:00}
HR_SYNC_ALLOWED_STATUS_VALUES: ${HR_SYNC_ALLOWED_STATUS_VALUES:-3}
HR_SYNC_INACTIVE_STATUS_VALUES: ${HR_SYNC_INACTIVE_STATUS_VALUES:-5}
HR_SYNC_EXCLUDED_DEPARTMENTS: ${HR_SYNC_EXCLUDED_DEPARTMENTS:-供应商,快递公司,外部交流}
HR_SYNC_EXCLUDED_NAME_KEYWORDS: ${HR_SYNC_EXCLUDED_NAME_KEYWORDS:-}
depends_on:
mysql:
condition: service_healthy