|
@@ -448,9 +448,10 @@
|
|
<!-- 步骤1:考察能力 -->
|
|
<!-- 步骤1:考察能力 -->
|
|
<div v-if="currentStep === 1" class="ai-video-content">
|
|
<div v-if="currentStep === 1" class="ai-video-content">
|
|
<div class="ai-video-options">
|
|
<div class="ai-video-options">
|
|
- <p class="option-tip">下面是奇才智能算法推荐的胜任力考核维度,请结合您的需求增删,确认后点击「下一步」出题</p>
|
|
|
|
|
|
+ <p class="option-tip">AI根据岗位信息生成的能力,创建完步骤后,会自动将选择的新智能能力加入到该职位的考察能力列表中。</p>
|
|
|
|
|
|
<!-- <div class="new-feature-tip">
|
|
<!-- <div class="new-feature-tip">
|
|
|
|
+ 下面是奇才智能算法推荐的胜任力考核维度,请结合您的需求增删,确认后点击「下一步」出题
|
|
<span class="new-tag">NEW</span>
|
|
<span class="new-tag">NEW</span>
|
|
AI根据岗位信息生成的能力,创建完步骤后,会自动将选择的新智能能力加入到该职位的考察能力列表中。
|
|
AI根据岗位信息生成的能力,创建完步骤后,会自动将选择的新智能能力加入到该职位的考察能力列表中。
|
|
</div> -->
|
|
</div> -->
|
|
@@ -534,6 +535,27 @@
|
|
|
|
|
|
<!-- 添加得分题和色盲题开关 -->
|
|
<!-- 添加得分题和色盲题开关 -->
|
|
<div class="question-switches">
|
|
<div class="question-switches">
|
|
|
|
+ <!-- 添加题目数量控制 -->
|
|
|
|
+ <div class="switch-item">
|
|
|
|
+ <span class="switch-label">开放题数量</span>
|
|
|
|
+ <el-input-number
|
|
|
|
+ v-model="questionCountSettings.openQuestionsCount"
|
|
|
|
+ :min="1"
|
|
|
|
+ :max="20"
|
|
|
|
+ size="small"
|
|
|
|
+ @change="handleQuestionCountChange"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="switch-item">
|
|
|
|
+ <span class="switch-label">选择题数量</span>
|
|
|
|
+ <el-input-number
|
|
|
|
+ v-model="questionCountSettings.choiceQuestionsCount"
|
|
|
|
+ :min="1"
|
|
|
|
+ :max="20"
|
|
|
|
+ size="small"
|
|
|
|
+ @change="handleQuestionCountChange"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
<div class="switch-item">
|
|
<div class="switch-item">
|
|
<span class="switch-label">得分题</span>
|
|
<span class="switch-label">得分题</span>
|
|
<el-switch
|
|
<el-switch
|
|
@@ -748,8 +770,9 @@
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>追问风格: <el-select v-model="settings.interruptionMode" placeholder="请选择">
|
|
<div>追问风格: <el-select v-model="settings.interruptionMode" placeholder="请选择">
|
|
- <el-option label="从上一问重新作答" value="previous" />
|
|
|
|
- <el-option label="从当前问题作答" value="current" />
|
|
|
|
|
|
+ <el-option label="温和" value="1" />
|
|
|
|
+ <el-option label="严厉" value="2" />
|
|
|
|
+ <el-option label="严谨" value="3" />
|
|
</el-select></div>
|
|
</el-select></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -1593,8 +1616,9 @@
|
|
<div class="setting-info">
|
|
<div class="setting-info">
|
|
<span class="setting-name">复习面试</span>
|
|
<span class="setting-name">复习面试</span>
|
|
<p class="setting-desc">选取后,将允许面试者进行重复面试</p>
|
|
<p class="setting-desc">选取后,将允许面试者进行重复面试</p>
|
|
|
|
+ <el-switch v-model="interviewSettings.reviewInterview" />
|
|
</div>
|
|
</div>
|
|
- <el-switch v-model="interviewSettings.reviewInterview" />
|
|
|
|
|
|
+
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="setting-item">
|
|
<div class="setting-item">
|
|
@@ -1784,9 +1808,9 @@ const positionData = reactive({
|
|
|
|
|
|
// 招聘流程数据 - 修改为普通数组而非 ref 对象
|
|
// 招聘流程数据 - 修改为普通数组而非 ref 对象
|
|
const recruitmentProcess = reactive([
|
|
const recruitmentProcess = reactive([
|
|
- { id: 1, name: '待核验', description: '待核验', active: true },
|
|
|
|
{ id: 5, name: '资料收集', description: '资料收集', active: true },
|
|
{ id: 5, name: '资料收集', description: '资料收集', active: true },
|
|
{ id: 2, name: 'AI视频', description: 'AI视频', active: true },
|
|
{ id: 2, name: 'AI视频', description: 'AI视频', active: true },
|
|
|
|
+ { id: 1, name: '待核验', description: '待核验', active: true },
|
|
{ id: 3, name: '已通过', description: '已通过', active: true },
|
|
{ id: 3, name: '已通过', description: '已通过', active: true },
|
|
{ id: 4, name: '已淘汰', description: '已淘汰', active: false },
|
|
{ id: 4, name: '已淘汰', description: '已淘汰', active: false },
|
|
|
|
|
|
@@ -3942,90 +3966,6 @@ console.log(selectedQuestions.value);
|
|
ElMessage.success(`已添加${selectedQuestions.value.length}个题目`);
|
|
ElMessage.success(`已添加${selectedQuestions.value.length}个题目`);
|
|
};
|
|
};
|
|
|
|
|
|
-/* AI自动组题 */
|
|
|
|
-const handleAutoGenerate = async () => {
|
|
|
|
- console.log('AI自动组题');
|
|
|
|
-
|
|
|
|
- // 如果已经在轮询中,先取消之前的轮询
|
|
|
|
- if (pollingController) {
|
|
|
|
- cancelPolling();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 设置loading状态
|
|
|
|
- autoGenerateLoading.value = true;
|
|
|
|
-
|
|
|
|
- try {
|
|
|
|
- // 从已选择的能力标签中获取ID列表
|
|
|
|
- const competencyTagIds = selectedDimensions.value.map(dimension => {
|
|
|
|
- const tag = competencyTags.value.find(tag => tag.name === dimension.name);
|
|
|
|
- return tag ? tag.id : null;
|
|
|
|
- }).filter(id => id !== null);
|
|
|
|
-
|
|
|
|
- if (competencyTagIds.length === 0) {
|
|
|
|
- ElMessage.warning('请至少选择一个能力标签');
|
|
|
|
- autoGenerateLoading.value = false; // 如果验证失败,需要手动关闭loading
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- const params = {
|
|
|
|
- position_id: route.query.id,
|
|
|
|
- competency_tag_ids: competencyTagIds,
|
|
|
|
- open_questions_count: 2, // 开放题数量,默认2个
|
|
|
|
- choice_questions_count: 2, // 选择题数量,默认2个
|
|
|
|
- auto_save: true, // 自动保存到数据库
|
|
|
|
- tenant_id: 1 // 租户ID,这里写死为1,实际应该从系统配置或用户信息中获取
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- // 调用生成题目的接口
|
|
|
|
- const response = await GenerateQuestions(params);
|
|
|
|
-
|
|
|
|
- if (response && response.data) {
|
|
|
|
- // 生成成功后,使用轮询获取最新生成的题目
|
|
|
|
- const draftResponse = await pollForDraftList({
|
|
|
|
- tenant_id: 1,
|
|
|
|
- position_id: route.query.id as string
|
|
|
|
- });
|
|
|
|
- console.log(draftResponse);
|
|
|
|
-
|
|
|
|
- // 检查轮询是否被取消
|
|
|
|
- if (draftResponse === null) {
|
|
|
|
- console.log('轮询被取消,停止处理');
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (draftResponse && draftResponse.data && draftResponse.data.dataList) {
|
|
|
|
- // 将获取到的题目格式化并添加到 chatQuestions 列表中
|
|
|
|
- const formattedQuestions = draftResponse.data.dataList.map((question: any) => ({
|
|
|
|
- id: question.id || Date.now(),
|
|
|
|
- title: question.question || question.title,
|
|
|
|
- ability: question.ability || '未设置',
|
|
|
|
- content: question.content || question.question,
|
|
|
|
- target: question.target || '未设置',
|
|
|
|
- competency_tags: question.competency_tags || [],
|
|
|
|
- question_form_name: question.question_form_name,
|
|
|
|
- scoring_reference: question.scoring_reference,
|
|
|
|
- question_form: question.question_form,
|
|
|
|
- weight: 100,
|
|
|
|
- maxAnswers: 1,
|
|
|
|
- source: 'ai_generated' as const // 标识为AI生成的题目
|
|
|
|
- }));
|
|
|
|
-
|
|
|
|
- // 清空现有题目并添加新生成的题目
|
|
|
|
- chatQuestions.value = formattedQuestions;
|
|
|
|
- ElMessage.success(`已成功生成${formattedQuestions.length}个面试题目`);
|
|
|
|
- } else {
|
|
|
|
- ElMessage.warning('AI生成题目中,请稍后再试');
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error('AI自动组题失败:', error);
|
|
|
|
- ElMessage.error('AI自动组题失败,请重试');
|
|
|
|
- } finally {
|
|
|
|
- // 无论成功或失败都要关闭loading状态
|
|
|
|
- autoGenerateLoading.value = false;
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
// 字段配置数据
|
|
// 字段配置数据
|
|
const fieldConfig = reactive({
|
|
const fieldConfig = reactive({
|
|
// 基本信息
|
|
// 基本信息
|
|
@@ -4435,6 +4375,93 @@ const saveDisclaimer = () => {
|
|
ElMessage.success('免责声明内容已更新');
|
|
ElMessage.success('免责声明内容已更新');
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+// 题目数量设置
|
|
|
|
+const questionCountSettings = reactive({
|
|
|
|
+ openQuestionsCount: 5,
|
|
|
|
+ choiceQuestionsCount: 10
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+// 处理题目数量变化
|
|
|
|
+const handleQuestionCountChange = () => {
|
|
|
|
+ // 这里可以添加其他逻辑,比如保存到本地存储等
|
|
|
|
+ console.log('题目数量已更新:', questionCountSettings);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+// 修改自动生成题目的方法
|
|
|
|
+const handleAutoGenerate = async () => {
|
|
|
|
+ try {
|
|
|
|
+ autoGenerateLoading.value = true;
|
|
|
|
+
|
|
|
|
+ // 获取选中的能力标签ID
|
|
|
|
+ const competencyTagIds = selectedDimensions.value.map(dimension => {
|
|
|
|
+ const tag = competencyTags.value.find(tag => tag.name === dimension.name);
|
|
|
|
+ return tag ? tag.id : null;
|
|
|
|
+ }).filter(id => id !== null);
|
|
|
|
+
|
|
|
|
+ if (competencyTagIds.length === 0) {
|
|
|
|
+ ElMessage.warning('请先选择能力标签');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const params = {
|
|
|
|
+ position_id: route.query.id,
|
|
|
|
+ competency_tag_ids: competencyTagIds,
|
|
|
|
+ open_questions_count: questionCountSettings.openQuestionsCount, // 使用设置的开放题数量
|
|
|
|
+ choice_questions_count: questionCountSettings.choiceQuestionsCount, // 使用设置的选择题数量
|
|
|
|
+ auto_save: true,
|
|
|
|
+ tenant_id: 1
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // 调用生成题目的接口
|
|
|
|
+ const response = await GenerateQuestions(params);
|
|
|
|
+
|
|
|
|
+ if (response && response.data) {
|
|
|
|
+ // 生成成功后,使用轮询获取最新生成的题目
|
|
|
|
+ const draftResponse = await pollForDraftList({
|
|
|
|
+ tenant_id: 1,
|
|
|
|
+ position_id: route.query.id as string
|
|
|
|
+ });
|
|
|
|
+ console.log(draftResponse);
|
|
|
|
+
|
|
|
|
+ // 检查轮询是否被取消
|
|
|
|
+ if (draftResponse === null) {
|
|
|
|
+ console.log('轮询被取消,停止处理');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (draftResponse && draftResponse.data && draftResponse.data.dataList) {
|
|
|
|
+ // 将获取到的题目格式化并添加到 chatQuestions 列表中
|
|
|
|
+ const formattedQuestions = draftResponse.data.dataList.map((question: any) => ({
|
|
|
|
+ id: question.id || Date.now(),
|
|
|
|
+ title: question.question || question.title,
|
|
|
|
+ ability: question.ability || '未设置',
|
|
|
|
+ content: question.content || question.question,
|
|
|
|
+ target: question.target || '未设置',
|
|
|
|
+ competency_tags: question.competency_tags || [],
|
|
|
|
+ question_form_name: question.question_form_name,
|
|
|
|
+ scoring_reference: question.scoring_reference,
|
|
|
|
+ question_form: question.question_form,
|
|
|
|
+ weight: 100,
|
|
|
|
+ maxAnswers: 1,
|
|
|
|
+ source: 'ai_generated' as const // 标识为AI生成的题目
|
|
|
|
+ }));
|
|
|
|
+
|
|
|
|
+ // 清空现有题目并添加新生成的题目
|
|
|
|
+ chatQuestions.value = formattedQuestions;
|
|
|
|
+ ElMessage.success(`已成功生成${formattedQuestions.length}个面试题目`);
|
|
|
|
+ } else {
|
|
|
|
+ ElMessage.warning('AI生成题目中,请稍后再试');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('AI自动组题失败:', error);
|
|
|
|
+ ElMessage.error('AI自动组题失败,请重试');
|
|
|
|
+ } finally {
|
|
|
|
+ // 无论成功或失败都要关闭loading状态
|
|
|
|
+ autoGenerateLoading.value = false;
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
@@ -4741,14 +4768,8 @@ const saveDisclaimer = () => {
|
|
white-space: nowrap;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
|
|
|
|
- :deep(.el-switch.is-checked .el-switch__core) {
|
|
|
|
- border-color: #0419a3;
|
|
|
|
- background-color: #0419a3;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- :deep(.el-switch__core) {
|
|
|
|
- border-color: #dcdfe6;
|
|
|
|
- background-color: #dcdfe6;
|
|
|
|
|
|
+ .el-input-number {
|
|
|
|
+ width: 100px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -4824,7 +4845,7 @@ const saveDisclaimer = () => {
|
|
}
|
|
}
|
|
|
|
|
|
.setting-desc {
|
|
.setting-desc {
|
|
- width: 70%;
|
|
|
|
|
|
+ width: 66%;
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
color: #909399;
|
|
color: #909399;
|
|
margin: 0;
|
|
margin: 0;
|
|
@@ -4847,7 +4868,7 @@ const saveDisclaimer = () => {
|
|
|
|
|
|
.setting-desc-container {
|
|
.setting-desc-container {
|
|
display: flex;
|
|
display: flex;
|
|
- align-items: flex-start;
|
|
|
|
|
|
+ align-items: center;
|
|
gap: 8px;
|
|
gap: 8px;
|
|
flex: 1;
|
|
flex: 1;
|
|
|
|
|