70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
export const DINGTALK_APPROVAL_NO_MAX_LENGTH = 64
|
|
|
|
function isLeapYear(year: number): boolean {
|
|
return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)
|
|
}
|
|
|
|
function getDaysInMonth(year: number, month: number): number {
|
|
if (month === 2) {
|
|
return isLeapYear(year) ? 29 : 28
|
|
}
|
|
|
|
return [4, 6, 9, 11].includes(month) ? 30 : 31
|
|
}
|
|
|
|
function hasValidDatePrefix(value: string): boolean {
|
|
const year = Number.parseInt(value.slice(0, 4), 10)
|
|
const month = Number.parseInt(value.slice(4, 6), 10)
|
|
const day = Number.parseInt(value.slice(6, 8), 10)
|
|
|
|
if (year < 1000 || year > 9999 || month < 1 || month > 12 || day < 1) {
|
|
return false
|
|
}
|
|
|
|
return day <= getDaysInMonth(year, month)
|
|
}
|
|
|
|
export function normalizeDingtalkApprovalNo(
|
|
value: string | null | undefined,
|
|
): string | null {
|
|
if (typeof value !== 'string') {
|
|
return null
|
|
}
|
|
|
|
const normalized = value.trim()
|
|
return normalized || null
|
|
}
|
|
|
|
export function getDingtalkApprovalNoError(
|
|
value: string | null | undefined,
|
|
): string | null {
|
|
const normalized = normalizeDingtalkApprovalNo(value)
|
|
if (!normalized) {
|
|
return null
|
|
}
|
|
|
|
if (!/^\d+$/.test(normalized)) {
|
|
return '钉钉审批编号只能输入数字'
|
|
}
|
|
|
|
if (normalized.length < 9) {
|
|
return '钉钉审批编号需包含8位日期和后续编号'
|
|
}
|
|
|
|
if (normalized.length > DINGTALK_APPROVAL_NO_MAX_LENGTH) {
|
|
return `钉钉审批编号不能超过${DINGTALK_APPROVAL_NO_MAX_LENGTH}位`
|
|
}
|
|
|
|
if (!hasValidDatePrefix(normalized)) {
|
|
return '钉钉审批编号前8位不是有效日期'
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
export function validateDingtalkApprovalNo(
|
|
value: string | null | undefined,
|
|
): boolean {
|
|
return getDingtalkApprovalNoError(value) === null
|
|
}
|