|
@@ -353,13 +353,12 @@
|
|
<div class="process-edit-content">
|
|
<div class="process-edit-content">
|
|
<div>{{ step.name }}</div>
|
|
<div>{{ step.name }}</div>
|
|
<div class="process-edit-desc">{{ step.description }}</div>
|
|
<div class="process-edit-desc">{{ step.description }}</div>
|
|
- </div>
|
|
|
|
|
|
+ </div><!-- v-if="step.name=='AI视频'" -->
|
|
<div class="process-edit-btn">
|
|
<div class="process-edit-btn">
|
|
<el-button
|
|
<el-button
|
|
type="info"
|
|
type="info"
|
|
size="small"
|
|
size="small"
|
|
plain
|
|
plain
|
|
- v-if="step.name=='AI视频'"
|
|
|
|
@click="editAIVideo(step)"
|
|
@click="editAIVideo(step)"
|
|
>
|
|
>
|
|
修改
|
|
修改
|
|
@@ -1030,69 +1029,174 @@
|
|
<el-dialog
|
|
<el-dialog
|
|
title="资料收集"
|
|
title="资料收集"
|
|
v-model="showDataCollectionDialog"
|
|
v-model="showDataCollectionDialog"
|
|
- width="500px"
|
|
|
|
|
|
+ width="900px"
|
|
:close-on-click-modal="false"
|
|
:close-on-click-modal="false"
|
|
class="data-collection-dialog"
|
|
class="data-collection-dialog"
|
|
>
|
|
>
|
|
<div class="data-collection-form">
|
|
<div class="data-collection-form">
|
|
- <div class="question-list">
|
|
|
|
- <div v-for="(question, index) in questionTypes" :key="index" class="question-item">
|
|
|
|
- <!-- 问题标题栏 -->
|
|
|
|
- <div class="question-header">
|
|
|
|
- <div class="question-title">
|
|
|
|
- <span>{{ question.label }}</span>
|
|
|
|
- </div>
|
|
|
|
- <div class="question-type">
|
|
|
|
- <span>问答类</span>
|
|
|
|
- <el-icon><ArrowDown /></el-icon>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <!-- 问题内容区 -->
|
|
|
|
- <div class="question-content">
|
|
|
|
- <div class="user-answer">用户回答</div>
|
|
|
|
-
|
|
|
|
- <!-- 操作按钮区 -->
|
|
|
|
- <div class="question-actions">
|
|
|
|
- <div class="action-left">
|
|
|
|
- <el-switch v-model="question.isVisible" />
|
|
|
|
- <span class="action-text">{{ question.isVisible ? '显示' : '隐藏' }}</span>
|
|
|
|
|
|
+ <!-- 字段配置面板 -->
|
|
|
|
+ <div class="field-config-panel">
|
|
|
|
+ <div class="panel-header">
|
|
|
|
+ <h3>字段显示配置</h3>
|
|
|
|
+ <el-button type="primary" size="small" @click="saveFieldConfig">保存配置</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="field-config-list">
|
|
|
|
+ <!-- 基本信息部分 -->
|
|
|
|
+ <div class="section-title">基本信息</div>
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
+ <el-col :span="8" v-for="(field, key) in getBasicFields()" :key="key">
|
|
|
|
+ <div class="field-config-item">
|
|
|
|
+ <span class="field-label">
|
|
|
|
+ {{ field.label }}
|
|
|
|
+ <!-- <el-tag v-if="field.required" size="small" type="danger" class="required-tag">必填</el-tag> -->
|
|
|
|
+ </span>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ :content="field.required ? '必填项不可隐藏' : '切换显示/隐藏'"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
|
|
+ <el-switch
|
|
|
|
+ v-model="field.visible"
|
|
|
|
+ :disabled="field.required"
|
|
|
|
+ class="custom-switch"
|
|
|
|
+ />
|
|
|
|
+ </el-tooltip>
|
|
</div>
|
|
</div>
|
|
- <div class="action-right">
|
|
|
|
- <el-icon class="action-icon"><Document /></el-icon>
|
|
|
|
- <el-icon class="action-icon"><Delete /></el-icon>
|
|
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+
|
|
|
|
+ <!-- 家庭成员信息部分 -->
|
|
|
|
+ <div class="section-title">家庭成员信息</div>
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
+ <el-col :span="24">
|
|
|
|
+ <div class="field-config-item">
|
|
|
|
+ <span class="field-label">
|
|
|
|
+ {{ fieldConfig.family_member.label }}
|
|
|
|
+ <el-tag v-if="fieldConfig.family_member.visible" size="small" type="success">已启用</el-tag>
|
|
|
|
+ </span>
|
|
|
|
+ <el-switch v-model="fieldConfig.family_member.visible" class="custom-switch" />
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <!-- 设置区域 -->
|
|
|
|
- <div class="question-settings">
|
|
|
|
- <div class="setting-item">
|
|
|
|
- <span>开启评分</span>
|
|
|
|
- <el-switch v-model="question.enableScoring" />
|
|
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row :gutter="20" v-if="fieldConfig.family_member.visible">
|
|
|
|
+ <el-col :span="8" v-for="(field, key) in fieldConfig.family_member.fields" :key="key">
|
|
|
|
+ <div class="field-config-item sub-field">
|
|
|
|
+ <span class="field-label">
|
|
|
|
+ {{ field.label }}
|
|
|
|
+ <!-- <el-tag v-if="field.required" size="small" type="danger" class="required-tag">必填</el-tag> -->
|
|
|
|
+ </span>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ :content="field.required ? '必填项不可隐藏' : '切换显示/隐藏'"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
|
|
+ <el-switch
|
|
|
|
+ v-model="field.visible"
|
|
|
|
+ :disabled="field.required"
|
|
|
|
+ class="custom-switch"
|
|
|
|
+ />
|
|
|
|
+ </el-tooltip>
|
|
</div>
|
|
</div>
|
|
- <div class="setting-item">
|
|
|
|
- <span>必答</span>
|
|
|
|
- <el-switch v-model="question.isRequired" />
|
|
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+
|
|
|
|
+ <!-- 教育经历部分 -->
|
|
|
|
+ <div class="section-title">教育经历</div>
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
+ <el-col :span="24">
|
|
|
|
+ <div class="field-config-item">
|
|
|
|
+ <span class="field-label">
|
|
|
|
+ {{ fieldConfig.education.label }}
|
|
|
|
+ <el-tag v-if="fieldConfig.education.visible" size="small" type="success">已启用</el-tag>
|
|
|
|
+ </span>
|
|
|
|
+ <el-switch v-model="fieldConfig.education.visible" class="custom-switch" />
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row :gutter="20" v-if="fieldConfig.education.visible">
|
|
|
|
+ <el-col :span="8" v-for="(field, key) in fieldConfig.education.fields" :key="key">
|
|
|
|
+ <div class="field-config-item sub-field">
|
|
|
|
+ <span class="field-label">
|
|
|
|
+ {{ field.label }}
|
|
|
|
+ <!-- <el-tag v-if="field.required" size="small" type="danger" class="required-tag">必填</el-tag> -->
|
|
|
|
+ </span>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ :content="field.required ? '必填项不可隐藏' : '切换显示/隐藏'"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
|
|
+ <el-switch
|
|
|
|
+ v-model="field.visible"
|
|
|
|
+ :disabled="field.required"
|
|
|
|
+ class="custom-switch"
|
|
|
|
+ />
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+
|
|
|
|
+ <!-- 专业技能部分 -->
|
|
|
|
+ <div class="section-title">专业技能</div>
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
+ <el-col :span="8" v-for="(field, key) in getSkillFields()" :key="key">
|
|
|
|
+ <div class="field-config-item">
|
|
|
|
+ <span class="field-label">
|
|
|
|
+ {{ field.label }}
|
|
|
|
+ <!-- <el-tag v-if="field.required" size="small" type="danger" class="required-tag">必填</el-tag> -->
|
|
|
|
+ </span>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ :content="field.required ? '必填项不可隐藏' : '切换显示/隐藏'"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
|
|
+ <el-switch
|
|
|
|
+ v-model="field.visible"
|
|
|
|
+ :disabled="field.required"
|
|
|
|
+ class="custom-switch"
|
|
|
|
+ />
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+
|
|
|
|
+ <!-- 工作经历部分 -->
|
|
|
|
+ <div class="section-title">工作经历</div>
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
+ <el-col :span="24">
|
|
|
|
+ <div class="field-config-item">
|
|
|
|
+ <span class="field-label">
|
|
|
|
+ {{ fieldConfig.work_experience.label }}
|
|
|
|
+ <el-tag v-if="fieldConfig.work_experience.visible" size="small" type="success">已启用</el-tag>
|
|
|
|
+ </span>
|
|
|
|
+ <el-switch v-model="fieldConfig.work_experience.visible" class="custom-switch" />
|
|
|
|
+ </div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row :gutter="20" v-if="fieldConfig.work_experience.visible">
|
|
|
|
+ <el-col :span="8" v-for="(field, key) in fieldConfig.work_experience.fields" :key="key">
|
|
|
|
+ <div class="field-config-item sub-field">
|
|
|
|
+ <span class="field-label">
|
|
|
|
+ {{ field.label }}
|
|
|
|
+ <!-- <el-tag v-if="field.required" size="small" type="danger" class="required-tag">必填</el-tag> -->
|
|
|
|
+ </span>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ :content="field.required ? '必填项不可隐藏' : '切换显示/隐藏'"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
|
|
+ <el-switch
|
|
|
|
+ v-model="field.visible"
|
|
|
|
+ :disabled="field.required"
|
|
|
|
+ class="custom-switch"
|
|
|
|
+ />
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
- <!-- 添加问题按钮 -->
|
|
|
|
- <div class="add-question">
|
|
|
|
- <el-button type="primary" plain @click="handleAddQuestion">
|
|
|
|
- <el-icon><Plus /></el-icon>
|
|
|
|
- 添加问题
|
|
|
|
- </el-button>
|
|
|
|
- </div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<template #footer>
|
|
<template #footer>
|
|
<span class="dialog-footer">
|
|
<span class="dialog-footer">
|
|
<el-button @click="cancelDataCollection">取消</el-button>
|
|
<el-button @click="cancelDataCollection">取消</el-button>
|
|
<el-button type="primary" @click="confirmDataCollection">确认</el-button>
|
|
<el-button type="primary" @click="confirmDataCollection">确认</el-button>
|
|
- </span>
|
|
|
|
|
|
+ </span>
|
|
</template>
|
|
</template>
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
|
@@ -1112,8 +1216,8 @@
|
|
placeholder="请输入步骤名称"
|
|
placeholder="请输入步骤名称"
|
|
maxlength="30"
|
|
maxlength="30"
|
|
show-word-limit
|
|
show-word-limit
|
|
- />
|
|
|
|
- </div>
|
|
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
|
|
<!-- <div class="form-item">
|
|
<!-- <div class="form-item">
|
|
<div class="form-label">必填项</div>
|
|
<div class="form-label">必填项</div>
|
|
@@ -1154,7 +1258,7 @@
|
|
<span class="dialog-footer">
|
|
<span class="dialog-footer">
|
|
<el-button @click="cancelResumeCollection">取消</el-button>
|
|
<el-button @click="cancelResumeCollection">取消</el-button>
|
|
<el-button type="primary" @click="confirmResumeCollection">确认</el-button>
|
|
<el-button type="primary" @click="confirmResumeCollection">确认</el-button>
|
|
- </span>
|
|
|
|
|
|
+ </span>
|
|
</template>
|
|
</template>
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
|
@@ -1323,8 +1427,10 @@ import { ElMessage, ElMessageBox, ElDrawer } from 'element-plus';
|
|
import * as api from '../list/api';
|
|
import * as api from '../list/api';
|
|
import { Plus, Document, ArrowDown, Edit, Delete, InfoFilled, QuestionFilled, Search, Rank } from '@element-plus/icons-vue';
|
|
import { Plus, Document, ArrowDown, Edit, Delete, InfoFilled, QuestionFilled, Search, Rank } from '@element-plus/icons-vue';
|
|
import { GetList } from '../../questionBank/classList/api';
|
|
import { GetList } from '../../questionBank/classList/api';
|
|
-import { GetCompetencyList,GetQuestionList,GenerateQuestions,GetDraftList,SaveDraft,GetDigitalList } from './api';
|
|
|
|
|
|
+import { GetCompetencyList,GetQuestionList,GenerateQuestions,GetDraftList,SaveDraft,GetDigitalList,CreateConfig,GetConfig } from './api';
|
|
import draggable from 'vuedraggable';
|
|
import draggable from 'vuedraggable';
|
|
|
|
+import { updateFieldConfig } from './utils';
|
|
|
|
+import type { ProfileFieldsConfig } from './types';
|
|
|
|
|
|
// 添加 ChatQuestion 接口定义
|
|
// 添加 ChatQuestion 接口定义
|
|
interface ChatQuestion {
|
|
interface ChatQuestion {
|
|
@@ -1383,9 +1489,11 @@ const positionData = reactive({
|
|
// 招聘流程数据 - 修改为普通数组而非 ref 对象
|
|
// 招聘流程数据 - 修改为普通数组而非 ref 对象
|
|
const recruitmentProcess = reactive([
|
|
const recruitmentProcess = reactive([
|
|
{ id: 1, name: '待核验', description: '待核验', active: true },
|
|
{ id: 1, 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: 3, name: '已通过', description: '已通过', active: true },
|
|
{ id: 3, name: '已通过', description: '已通过', active: true },
|
|
- { id: 4, name: '已淘汰', description: '已淘汰', active: false }
|
|
|
|
|
|
+ { id: 4, name: '已淘汰', description: '已淘汰', active: false },
|
|
|
|
+
|
|
]);
|
|
]);
|
|
|
|
|
|
// 是否显示流程编辑对话框
|
|
// 是否显示流程编辑对话框
|
|
@@ -1398,8 +1506,8 @@ const processStepOptions = [
|
|
{ label: 'AI实时对话', value: 'ai_chat' },
|
|
{ label: 'AI实时对话', value: 'ai_chat' },
|
|
{ label: '资料收集', value: 'data_collection' },
|
|
{ label: '资料收集', value: 'data_collection' },
|
|
{ label: '简历收集', value: 'resume_collection' },
|
|
{ label: '简历收集', value: 'resume_collection' },
|
|
- { label: '代码测试', value: 'code_test' },
|
|
|
|
- { label: '打字测试', value: 'typing_test' }
|
|
|
|
|
|
+ /* { label: '代码测试', value: 'code_test' },
|
|
|
|
+ { label: '打字测试', value: 'typing_test' } */
|
|
];
|
|
];
|
|
|
|
|
|
// 当前选择的添加位置
|
|
// 当前选择的添加位置
|
|
@@ -1781,9 +1889,8 @@ const showStepOptions = (index: number, event: MouseEvent) => {
|
|
// 阻止事件冒泡
|
|
// 阻止事件冒泡
|
|
event.stopPropagation();
|
|
event.stopPropagation();
|
|
};
|
|
};
|
|
-
|
|
|
|
// 修改添加选定类型的步骤方法
|
|
// 修改添加选定类型的步骤方法
|
|
-const addSelectedStepType = (type: string, label: string) => {
|
|
|
|
|
|
+const addSelectedStepType = async (type: string, label: string) => {
|
|
if (type === 'ai_video') {
|
|
if (type === 'ai_video') {
|
|
showAIVideoDialog.value = true;
|
|
showAIVideoDialog.value = true;
|
|
showOptionsMenu.value = false;
|
|
showOptionsMenu.value = false;
|
|
@@ -1806,8 +1913,12 @@ const addSelectedStepType = (type: string, label: string) => {
|
|
|
|
|
|
// 添加资料收集类型的处理
|
|
// 添加资料收集类型的处理
|
|
if (type === 'data_collection') {
|
|
if (type === 'data_collection') {
|
|
- showDataCollectionDialog.value = true;
|
|
|
|
- showOptionsMenu.value = false;
|
|
|
|
|
|
+ const response = await GetConfig(route.query.id);
|
|
|
|
+ if (response && response.data) {
|
|
|
|
+ updateFieldConfig(fieldConfig, response.data.profile_fields_config as ProfileFieldsConfig);
|
|
|
|
+ showDataCollectionDialog.value = true;
|
|
|
|
+ showOptionsMenu.value = false;
|
|
|
|
+ }
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2086,10 +2197,10 @@ const cancelDataCollection = () => {
|
|
|
|
|
|
// 确认添加资料收集
|
|
// 确认添加资料收集
|
|
const confirmDataCollection = () => {
|
|
const confirmDataCollection = () => {
|
|
- if (dataCollectionForm.questions.length === 0) {
|
|
|
|
|
|
+ /* if (dataCollectionForm.questions.length === 0) {
|
|
ElMessage.warning('请至少选择一个问题');
|
|
ElMessage.warning('请至少选择一个问题');
|
|
return;
|
|
return;
|
|
- }
|
|
|
|
|
|
+ } */
|
|
|
|
|
|
// 创建新的资料收集步骤
|
|
// 创建新的资料收集步骤
|
|
const newStep = {
|
|
const newStep = {
|
|
@@ -2650,14 +2761,27 @@ const saveCompetency = async () => {
|
|
const currentEditingStep = ref<AIVideoStep | null>(null);
|
|
const currentEditingStep = ref<AIVideoStep | null>(null);
|
|
|
|
|
|
// 编辑AI视频
|
|
// 编辑AI视频
|
|
-const editAIVideo = (step: AIVideoStep) => {
|
|
|
|
- currentEditingStep.value = step;
|
|
|
|
- showAIVideoDialog.value = true;
|
|
|
|
- currentStep.value = 1;
|
|
|
|
- // 重置选项
|
|
|
|
- (Object.keys(aiVideoOptions) as Array<keyof typeof aiVideoOptions>).forEach(key => {
|
|
|
|
- aiVideoOptions[key] = false;
|
|
|
|
- });
|
|
|
|
|
|
+const editAIVideo = async (step: AIVideoStep) => {
|
|
|
|
+ // 添加资料收集类型的处理
|
|
|
|
+ if (step.name === '资料收集') {
|
|
|
|
+ const response = await GetConfig(route.query.id);
|
|
|
|
+ if (response && response.data) {
|
|
|
|
+ updateFieldConfig(fieldConfig, response.data.profile_fields_config as ProfileFieldsConfig);
|
|
|
|
+ showDataCollectionDialog.value = true;
|
|
|
|
+ showOptionsMenu.value = false;
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (step.name === 'AI视频') {
|
|
|
|
+ currentEditingStep.value = step;
|
|
|
|
+ showAIVideoDialog.value = true;
|
|
|
|
+ currentStep.value = 1;
|
|
|
|
+ // 重置选项
|
|
|
|
+ (Object.keys(aiVideoOptions) as Array<keyof typeof aiVideoOptions>).forEach(key => {
|
|
|
|
+ aiVideoOptions[key] = false;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
};
|
|
};
|
|
|
|
|
|
// 保存AI视频配置
|
|
// 保存AI视频配置
|
|
@@ -2915,6 +3039,211 @@ console.log(draftResponse);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+// 字段配置数据
|
|
|
|
+const fieldConfig = reactive({
|
|
|
|
+ // 基本信息
|
|
|
|
+ name: { visible: true, label: '姓名', required: true },
|
|
|
|
+ gender: { visible: true, label: '性别', required: true },
|
|
|
|
+ three_period: { visible: true, label: '是否为三期', required: true },
|
|
|
|
+ phone: { visible: true, label: '手机号', required: true },
|
|
|
|
+ id_card: { visible: true, label: '身份证号', required: true },
|
|
|
|
+ ethnicity: { visible: true, label: '民族', required: true },
|
|
|
|
+ height: { visible: true, label: '身高(cm)', required: false },
|
|
|
|
+ weight: { visible: true, label: '体重(kg)', required: false },
|
|
|
|
+ current_address: { visible: true, label: '现居住地址', required: true },
|
|
|
|
+ household_location: { visible: true, label: '户口所在地', required: false },
|
|
|
|
+ marital_status: { visible: true, label: '婚育状况', required: false },
|
|
|
|
+ expected_salary: { visible: true, label: '期望薪资(元/月)', required: false },
|
|
|
|
+
|
|
|
|
+ // 家庭成员信息
|
|
|
|
+ family_member: {
|
|
|
|
+ visible: true,
|
|
|
|
+ label: '家庭成员',
|
|
|
|
+ fields: {
|
|
|
|
+ relation: { visible: true, label: '称谓', required: true },
|
|
|
|
+ name: { visible: true, label: '姓名', required: true },
|
|
|
|
+ workplace_address: { visible: true, label: '工作单位/家庭地址', required: false },
|
|
|
|
+ position: { visible: true, label: '职务', required: false },
|
|
|
|
+ phone: { visible: true, label: '联系电话', required: true },
|
|
|
|
+ is_emergency_contact: { visible: true, label: '是否为紧急联系人', required: false }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 教育经历
|
|
|
|
+ education: {
|
|
|
|
+ visible: true,
|
|
|
|
+ label: '教育经历',
|
|
|
|
+ fields: {
|
|
|
|
+ start_time: { visible: true, label: '开始时间', required: true },
|
|
|
|
+ end_time: { visible: true, label: '结束时间', required: true },
|
|
|
|
+ school_name: { visible: true, label: '学校名称', required: true },
|
|
|
|
+ major: { visible: true, label: '专业', required: true },
|
|
|
|
+ degree: { visible: true, label: '学历', required: true }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 专业技能
|
|
|
|
+ skills: { visible: true, label: '专业技能', required: true },
|
|
|
|
+ training: { visible: true, label: '受过的培训', required: true },
|
|
|
|
+
|
|
|
|
+ // 工作经历
|
|
|
|
+ work_experience: {
|
|
|
|
+ visible: true,
|
|
|
|
+ label: '工作经历',
|
|
|
|
+ fields: {
|
|
|
|
+ start_time: { visible: true, label: '开始时间', required: true },
|
|
|
|
+ end_time: { visible: true, label: '结束时间', required: true },
|
|
|
|
+ company_name: { visible: true, label: '单位名称', required: true },
|
|
|
|
+ employee_count: { visible: true, label: '单位人数', required: true },
|
|
|
|
+ department: { visible: true, label: '任职部门', required: true },
|
|
|
|
+ position: { visible: true, label: '担任职务', required: true },
|
|
|
|
+ monthly_salary: { visible: true, label: '月总收入', required: true },
|
|
|
|
+ supervisor: { visible: true, label: '直接领导', required: true },
|
|
|
|
+ supervisor_phone: { visible: true, label: '领导电话', required: true }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+// 保存字段配置
|
|
|
|
+const saveFieldConfig = async () => {
|
|
|
|
+ try {
|
|
|
|
+ // 构建配置数据
|
|
|
|
+ const configData = {
|
|
|
|
+ position_id: route.query.id, // 职位ID
|
|
|
|
+ config_name: "咖啡师配置", // 配置名称
|
|
|
|
+ digital_human_id: 4, // 数字人ID
|
|
|
|
+
|
|
|
|
+ // 简历上传配置
|
|
|
|
+ require_resume_upload: true, // 是否要求上传简历
|
|
|
|
+ resume_file_types: ["pdf", "docx", "doc"], // 允许的文件类型
|
|
|
|
+ max_resume_size_mb: 10, // 最大文件大小(MB)
|
|
|
|
+
|
|
|
|
+ // 个人信息配置
|
|
|
|
+ require_basic_info: true, // 是否要求填写基本信息
|
|
|
|
+ profile_fields_config: {
|
|
|
|
+ name: { required: fieldConfig.name.required, visible: fieldConfig.name.visible },
|
|
|
|
+ phone: { required: fieldConfig.phone.required, visible: fieldConfig.phone.visible },
|
|
|
|
+ id_card: { required: fieldConfig.id_card.required, visible: fieldConfig.id_card.visible },
|
|
|
|
+ gender: { required: fieldConfig.gender.required, visible: fieldConfig.gender.visible },
|
|
|
|
+ birth_date: { required: false, visible: true },
|
|
|
|
+ political_status: { required: false, visible: true },
|
|
|
|
+ ethnicity: { required: fieldConfig.ethnicity.required, visible: fieldConfig.ethnicity.visible },
|
|
|
|
+ height: { required: fieldConfig.height.required, visible: fieldConfig.height.visible },
|
|
|
|
+ weight: { required: fieldConfig.weight.required, visible: fieldConfig.weight.visible },
|
|
|
|
+ marital_status: { required: fieldConfig.marital_status.required, visible: fieldConfig.marital_status.visible }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 教育信息配置
|
|
|
|
+ require_education_info: fieldConfig.education.visible, // 是否要求填写教育信息
|
|
|
|
+ education_fields_config: {
|
|
|
|
+ school_name: { required: fieldConfig.education.fields.school_name.required, visible: fieldConfig.education.fields.school_name.visible },
|
|
|
|
+ major: { required: fieldConfig.education.fields.major.required, visible: fieldConfig.education.fields.major.visible },
|
|
|
|
+ degree: { required: fieldConfig.education.fields.degree.required, visible: fieldConfig.education.fields.degree.visible },
|
|
|
|
+ start_date: { required: fieldConfig.education.fields.start_time.required, visible: fieldConfig.education.fields.start_time.visible },
|
|
|
|
+ end_date: { required: fieldConfig.education.fields.end_time.required, visible: fieldConfig.education.fields.end_time.visible }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 工作经验配置
|
|
|
|
+ require_work_experience: fieldConfig.work_experience.visible, // 是否要求填写工作经验
|
|
|
|
+ work_experience_fields_config: {
|
|
|
|
+ company_name: { required: fieldConfig.work_experience.fields.company_name.required, visible: fieldConfig.work_experience.fields.company_name.visible },
|
|
|
|
+ position: { required: fieldConfig.work_experience.fields.position.required, visible: fieldConfig.work_experience.fields.position.visible },
|
|
|
|
+ department: { required: fieldConfig.work_experience.fields.department.required, visible: fieldConfig.work_experience.fields.department.visible },
|
|
|
|
+ start_date: { required: fieldConfig.work_experience.fields.start_time.required, visible: fieldConfig.work_experience.fields.start_time.visible },
|
|
|
|
+ end_date: { required: fieldConfig.work_experience.fields.end_time.required, visible: fieldConfig.work_experience.fields.end_time.visible },
|
|
|
|
+ job_description: { required: true, visible: true },
|
|
|
|
+ achievements: { required: false, visible: true },
|
|
|
|
+ resignation_reason: { required: false, visible: true }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 家庭信息配置
|
|
|
|
+ require_family_info: fieldConfig.family_member.visible, // 是否要求填写家庭信息
|
|
|
|
+ family_fields_config: {
|
|
|
|
+ relation: { required: fieldConfig.family_member.fields.relation.required, visible: fieldConfig.family_member.fields.relation.visible },
|
|
|
|
+ name: { required: fieldConfig.family_member.fields.name.required, visible: fieldConfig.family_member.fields.name.visible },
|
|
|
|
+ workplace: { required: fieldConfig.family_member.fields.workplace_address.required, visible: fieldConfig.family_member.fields.workplace_address.visible },
|
|
|
|
+ position: { required: fieldConfig.family_member.fields.position.required, visible: fieldConfig.family_member.fields.position.visible },
|
|
|
|
+ phone: { required: fieldConfig.family_member.fields.phone.required, visible: fieldConfig.family_member.fields.phone.visible }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 培训经历配置
|
|
|
|
+ require_training_info: false,
|
|
|
|
+ training_fields_config: {
|
|
|
|
+ training_name: { required: true, visible: true },
|
|
|
|
+ institution: { required: true, visible: true },
|
|
|
|
+ start_date: { required: true, visible: true },
|
|
|
|
+ end_date: { required: false, visible: true },
|
|
|
|
+ certificate: { required: false, visible: true }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 姿态配置
|
|
|
|
+ enable_posture_check: true,
|
|
|
|
+ posture_check_config: {
|
|
|
|
+ required_photos: ["front", "side", "back"],
|
|
|
|
+ instructions: "请按照提示上传您的全身照片,确保光线充足,背景简洁"
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 面试配置
|
|
|
|
+ interview_duration_minutes: 45,
|
|
|
|
+ enable_video_recording: true,
|
|
|
|
+ enable_face_recognition: true,
|
|
|
|
+
|
|
|
|
+ // 评分配置
|
|
|
|
+ scoring_method: "hybrid",
|
|
|
|
+ auto_analysis_enabled: true,
|
|
|
|
+
|
|
|
|
+ // 其他配置
|
|
|
|
+ custom_welcome_message: "欢迎参加咖啡师岗位的面试,请放松心情,准备好开始面试吧!",
|
|
|
|
+ custom_instructions: "本次面试共有10个问题,每个问题有60秒的回答时间,请简洁明了地表达您的观点。",
|
|
|
|
+
|
|
|
|
+ notification_config: {
|
|
|
|
+ send_email: true,
|
|
|
|
+ send_sms: false,
|
|
|
|
+ notify_hr: true,
|
|
|
|
+ completion_message: "感谢您完成面试,我们将在3个工作日内给您回复。"
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ is_active: true,
|
|
|
|
+ is_template: false
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // 调用后端 API
|
|
|
|
+ await CreateConfig(configData);
|
|
|
|
+ ElMessage.success('配置保存成功');
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('保存配置失败:', error);
|
|
|
|
+ ElMessage.error('配置保存失败');
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+// 获取基本信息字段
|
|
|
|
+const getBasicFields = () => {
|
|
|
|
+ const basicFields = {
|
|
|
|
+ name: fieldConfig.name,
|
|
|
|
+ gender: fieldConfig.gender,
|
|
|
|
+ three_period: fieldConfig.three_period,
|
|
|
|
+ phone: fieldConfig.phone,
|
|
|
|
+ id_card: fieldConfig.id_card,
|
|
|
|
+ ethnicity: fieldConfig.ethnicity,
|
|
|
|
+ height: fieldConfig.height,
|
|
|
|
+ weight: fieldConfig.weight,
|
|
|
|
+ current_address: fieldConfig.current_address,
|
|
|
|
+ household_location: fieldConfig.household_location,
|
|
|
|
+ marital_status: fieldConfig.marital_status,
|
|
|
|
+ expected_salary: fieldConfig.expected_salary
|
|
|
|
+ };
|
|
|
|
+ return basicFields;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+// 获取专业技能字段
|
|
|
|
+const getSkillFields = () => {
|
|
|
|
+ const skillFields = {
|
|
|
|
+ skills: fieldConfig.skills,
|
|
|
|
+ training: fieldConfig.training
|
|
|
|
+ };
|
|
|
|
+ return skillFields;
|
|
|
|
+};
|
|
|
|
+
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
@@ -3005,4 +3334,85 @@ console.log(draftResponse);
|
|
margin-right: 8px;
|
|
margin-right: 8px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+.field-config-panel {
|
|
|
|
+ background: #fff;
|
|
|
|
+ border-radius: 8px;
|
|
|
|
+ padding: 24px;
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
|
+
|
|
|
|
+ .panel-header {
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ align-items: center;
|
|
|
|
+ margin-bottom: 24px;
|
|
|
|
+
|
|
|
|
+ h3 {
|
|
|
|
+ margin: 0;
|
|
|
|
+ font-size: 18px;
|
|
|
|
+ color: #303133;
|
|
|
|
+ font-weight: 600;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .section-title {
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ font-weight: 500;
|
|
|
|
+ color: #303133;
|
|
|
|
+ margin: 24px 0 16px;
|
|
|
|
+ padding-left: 10px;
|
|
|
|
+ border-left: 4px solid #0419a3;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .field-config-item {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ margin-bottom: 12px;
|
|
|
|
+ padding: 12px 16px;
|
|
|
|
+ background: #f5f7fa;
|
|
|
|
+ border-radius: 6px;
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
+
|
|
|
|
+ &:hover {
|
|
|
|
+ background: #eef1f6;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ &.sub-field {
|
|
|
|
+ background: #fff;
|
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
|
+ margin-left: 12px;
|
|
|
|
+
|
|
|
|
+ &:hover {
|
|
|
|
+ border-color: #0419a3;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .field-label {
|
|
|
|
+ flex: 1;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ color: #606266;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ gap: 8px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .required-tag {
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ padding: 0 6px;
|
|
|
|
+ height: 20px;
|
|
|
|
+ line-height: 18px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ :deep(.el-switch.is-checked .el-switch__core) {
|
|
|
|
+ border-color: #0419a3;
|
|
|
|
+ background-color: #0419a3;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.el-row {
|
|
|
|
+ margin-bottom: 12px;
|
|
|
|
+}
|
|
</style>
|
|
</style>
|