83 lines
2.8 KiB
TypeScript
83 lines
2.8 KiB
TypeScript
// @ts-nocheck
|
|
|
|
|
|
export const EMP_RE = /emp_[a-z0-9]+/i;
|
|
|
|
const CN_NUM_MAP = {
|
|
'一': 1, '二': 2, '三': 3, '四': 4, '五': 5,
|
|
'六': 6, '七': 7, '八': 8, '九': 9, '十': 10,
|
|
};
|
|
|
|
const INDEX_RE = /(?:第\s*|选\s*|选第\s*)?([一二三四五六七八九十\d]+)\s*[号个]?\s*/;
|
|
|
|
export function validateCandidateSelection(aiResponse, candidates) {
|
|
if (!aiResponse || typeof aiResponse !== 'string') {
|
|
return { valid: false, reason: 'NO_AI_RESPONSE' };
|
|
}
|
|
if (!Array.isArray(candidates) || candidates.length === 0) {
|
|
return { valid: false, reason: 'NO_CANDIDATES' };
|
|
}
|
|
|
|
|
|
const validIds = candidates
|
|
.map(c => (typeof c === 'string' ? c : c?.employeeId))
|
|
.filter(Boolean)
|
|
.map(id => id.toLowerCase());
|
|
|
|
|
|
const empMatch = aiResponse.match(EMP_RE);
|
|
if (empMatch) {
|
|
const empId = empMatch[0].toLowerCase();
|
|
if (validIds.includes(empId)) {
|
|
return { valid: true, employeeId: empId };
|
|
}
|
|
return {
|
|
valid: false,
|
|
reason: 'EMP_NOT_IN_CANDIDATES',
|
|
attempted: empId,
|
|
validIds,
|
|
};
|
|
}
|
|
|
|
|
|
const numMatch = aiResponse.match(INDEX_RE);
|
|
if (numMatch) {
|
|
const raw = numMatch[1];
|
|
const idx = /^\d+$/.test(raw)
|
|
? parseInt(raw, 10)
|
|
: CN_NUM_MAP[raw];
|
|
if (idx == null) {
|
|
return { valid: false, reason: 'UNRECOGNIZED_FORMAT' };
|
|
}
|
|
if (idx >= 1 && idx <= validIds.length) {
|
|
return { valid: true, employeeId: validIds[idx - 1] };
|
|
}
|
|
return {
|
|
valid: false,
|
|
reason: 'INDEX_OUT_OF_RANGE',
|
|
index: idx,
|
|
total: validIds.length,
|
|
};
|
|
}
|
|
|
|
return { valid: false, reason: 'UNRECOGNIZED_FORMAT' };
|
|
}
|
|
|
|
export function formatValidationFailure(result) {
|
|
if (!result || result.valid) return '';
|
|
switch (result.reason) {
|
|
case 'INDEX_OUT_OF_RANGE':
|
|
return `序号 ${result.index} 越界(共 ${result.total} 个候选)。请用户从 1-${result.total} 中选择,或在候选表里指出特征(如「乘务二组那个」)。`;
|
|
case 'EMP_NOT_IN_CANDIDATES':
|
|
return `引用的员工 ID「${result.attempted}」不在当前候选列表内。请用户从候选列表中重新选择(候选:${result.validIds?.join(', ')})。`;
|
|
case 'UNRECOGNIZED_FORMAT':
|
|
return `未识别用户的选择。请用户回复「序号」(如「1 号」),或直接说班组/岗位特征(如「乘务二组那个」)。`;
|
|
case 'NO_CANDIDATES':
|
|
return `当前没有候选列表,请用户先重新发起查询。`;
|
|
case 'NO_AI_RESPONSE':
|
|
return `AI 回复为空,无法识别选择。`;
|
|
default:
|
|
return `选择无效,请用户重新选择。`;
|
|
}
|
|
}
|