|
@@ -0,0 +1,376 @@
|
|
|
|
+<template>
|
|
|
|
+ <el-drawer
|
|
|
|
+ title="AI视频"
|
|
|
|
+ v-model="modelValue"
|
|
|
|
+ direction="rtl"
|
|
|
|
+ size="60%"
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
+ class="ai-video-drawer"
|
|
|
|
+ :destroy-on-close="false"
|
|
|
|
+ @close="handleClose"
|
|
|
|
+ >
|
|
|
|
+ <!-- 步骤指示器 -->
|
|
|
|
+ <div class="ai-video-steps">
|
|
|
|
+ <div class="step-item" :class="{ 'active': currentStep === 1 }" @click="jumpToStep(1)">
|
|
|
|
+ <div class="step-number">1</div>
|
|
|
|
+ <div class="step-title">考察能力</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="step-line" :class="{ 'active-line': currentStep >= 2 }"></div>
|
|
|
|
+ <div class="step-item" :class="{ 'active': currentStep === 2 }" @click="jumpToStep(2)">
|
|
|
|
+ <div class="step-number">2</div>
|
|
|
|
+ <div class="step-title">面试题目</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="step-line" :class="{ 'active-line': currentStep >= 3 }"></div>
|
|
|
|
+ <div class="step-item" :class="{ 'active': currentStep === 3 }" @click="jumpToStep(3)">
|
|
|
|
+ <div class="step-number">3</div>
|
|
|
|
+ <div class="step-title">系统设置</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 步骤1:考察能力 -->
|
|
|
|
+ <div v-if="currentStep === 1" class="ai-video-content">
|
|
|
|
+ <div class="ai-video-options">
|
|
|
|
+ <p class="option-tip">下面是奇才智能算法推荐的胜任力考核维度,请结合您的需求增删,确认后点击「下一步」出题</p>
|
|
|
|
+
|
|
|
|
+ <div class="new-feature-tip">
|
|
|
|
+ <span class="new-tag">NEW</span>
|
|
|
|
+ AI根据岗位信息生成的能力,创建完步骤后,会自动将选择的新智能能力加入到该职位的考察能力列表中。
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="ability-options">
|
|
|
|
+ <el-checkbox v-model="aiVideoOptions.qualityControl" label="质量控制">
|
|
|
|
+ <div class="ability-label">质量控制</div>
|
|
|
|
+ </el-checkbox>
|
|
|
|
+
|
|
|
|
+ <el-checkbox v-model="aiVideoOptions.teamwork" label="团队协作">
|
|
|
|
+ <div class="ability-label">团队协作</div>
|
|
|
|
+ </el-checkbox>
|
|
|
|
+
|
|
|
|
+ <el-checkbox v-model="aiVideoOptions.problemSolving" label="问题解决">
|
|
|
|
+ <div class="ability-label">问题解决</div>
|
|
|
|
+ </el-checkbox>
|
|
|
|
+
|
|
|
|
+ <el-checkbox v-model="aiVideoOptions.dataAnalysis" label="问题分析">
|
|
|
|
+ <div class="ability-label">问题分析</div>
|
|
|
|
+ </el-checkbox>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 步骤2:面试题目 -->
|
|
|
|
+ <div v-if="currentStep === 2" class="ai-video-content">
|
|
|
|
+ <div class="interview-settings">
|
|
|
|
+ <div class="interview-header">
|
|
|
|
+ <div class="interview-duration">
|
|
|
|
+ <span>预计面试时长: </span>
|
|
|
|
+ <span class="duration-value">0秒</span>
|
|
|
|
+ <span class="duration-tip">拖动试题卡片可改变试题顺序</span>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="interview-actions">
|
|
|
|
+ <el-button type="primary" plain class="import-btn">
|
|
|
|
+ <el-icon><Document /></el-icon>
|
|
|
|
+ 导入题目
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button type="success" plain class="custom-btn">
|
|
|
|
+ <el-icon><Plus /></el-icon>
|
|
|
|
+ 自定义题目
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="interview-mode">
|
|
|
|
+ <span>面试问答方式: </span>
|
|
|
|
+ <span class="mode-value">传统读题模式</span>
|
|
|
|
+ <el-button type="primary" plain size="small" class="customize-btn">定制面试间</el-button>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="interview-questions-container">
|
|
|
|
+ <div class="no-questions" v-if="!chatQuestions.length">
|
|
|
|
+ <p>暂无题目</p>
|
|
|
|
+ <p class="ai-tip">点击"AI自动组题"按钮</p>
|
|
|
|
+ <p class="ai-tip">可根据您选择的能力类型一键组题</p>
|
|
|
|
+ <el-button type="success" class="auto-generate-btn">AI自动组题</el-button>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="question-list" v-else>
|
|
|
|
+ <div v-for="(question, index) in chatQuestions" :key="index" class="question-card">
|
|
|
|
+ <div class="question-header">
|
|
|
|
+ <div class="question-title">
|
|
|
|
+ <span class="question-number">题目{{ index + 1 }}</span>
|
|
|
|
+ <span>{{ question.title }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="question-actions">
|
|
|
|
+ <div class="weight-control">
|
|
|
|
+ <span class="weight-label">权重占比:</span>
|
|
|
|
+ <el-input-number
|
|
|
|
+ v-model="question.weight"
|
|
|
|
+ :min="0"
|
|
|
|
+ :max="100"
|
|
|
|
+ :step="1"
|
|
|
|
+ size="small"
|
|
|
|
+ controls-position="right"
|
|
|
|
+ >
|
|
|
|
+ <template #suffix>%</template>
|
|
|
|
+ </el-input-number>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="answer-limit">
|
|
|
|
+ <span class="answer-label">最多回答次数</span>
|
|
|
|
+ <el-select v-model="question.maxAnswers" size="small" placeholder="请选择">
|
|
|
|
+ <el-option label="1次" :value="1" />
|
|
|
|
+ <el-option label="2次" :value="2" />
|
|
|
|
+ <el-option label="3次" :value="3" />
|
|
|
|
+ </el-select>
|
|
|
|
+ </div>
|
|
|
|
+ <el-button type="text" @click="editQuestion(index)">
|
|
|
|
+ <el-icon><Edit /></el-icon>
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button type="text" @click="deleteQuestion(index)">
|
|
|
|
+ <el-icon><Delete /></el-icon>
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="question-info">
|
|
|
|
+ <div class="info-item">
|
|
|
|
+ <span class="info-label">考察能力:</span>
|
|
|
|
+ <span>{{ question.ability }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="info-item">
|
|
|
|
+ <span class="info-label">面试内容:</span>
|
|
|
|
+ <span>{{ question.content }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="info-item">
|
|
|
|
+ <span class="info-label">对话目标:</span>
|
|
|
|
+ <span>{{ question.target }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="multi-dimension-questions">
|
|
|
|
+ <div class="dimension-title">多维度能力测评题</div>
|
|
|
|
+ <div class="dimension-list">
|
|
|
|
+ <div v-for="ability in selectedAbilities" :key="ability.value" class="dimension-item">
|
|
|
|
+ <div class="dimension-header">
|
|
|
|
+ <span>{{ ability.label }}</span>
|
|
|
|
+ <span class="new-tag" v-if="ability.isNew">NEW</span>
|
|
|
|
+ <el-icon class="expand-icon"><ArrowDown /></el-icon>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 步骤3:系统设置 -->
|
|
|
|
+ <div v-if="currentStep === 3" class="ai-video-content">
|
|
|
|
+ <div class="system-settings">
|
|
|
|
+ <!-- 排名区间设置 -->
|
|
|
|
+ <div class="setting-section">
|
|
|
|
+ <div class="section-header">排名区间设置</div>
|
|
|
|
+ <div class="rank-settings">
|
|
|
|
+ <div class="rank-range">
|
|
|
|
+ <span>排名前</span>
|
|
|
|
+ <div class="range-inputs">
|
|
|
|
+ <el-input v-model="rankSettings.min" size="small" class="percent-input">
|
|
|
|
+ <template #suffix>%</template>
|
|
|
|
+ </el-input>
|
|
|
|
+ <span>-</span>
|
|
|
|
+ <el-input v-model="rankSettings.max" size="small" class="percent-input">
|
|
|
|
+ <template #suffix>%</template>
|
|
|
|
+ </el-input>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="score-display">
|
|
|
|
+ <span>分数</span>
|
|
|
|
+ <div class="score-range">{{ rankSettings.minScore }} - {{ rankSettings.maxScore }} 分</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <el-button type="primary" plain class="add-rank-btn">
|
|
|
|
+ <el-icon><Plus /></el-icon>
|
|
|
|
+ 添加排名区间
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- AI视频有效期 -->
|
|
|
|
+ <div class="setting-section">
|
|
|
|
+ <div class="section-header">AI视频有效期</div>
|
|
|
|
+ <div class="validity-setting">
|
|
|
|
+ <el-switch v-model="validityEnabled" />
|
|
|
|
+ <span class="validity-label">开启AI视频有效期</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="validity-tip">暂未设置,设置后候选人超过有效期则不可进入</div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- AI模型版本 -->
|
|
|
|
+ <div class="setting-section">
|
|
|
|
+ <div class="section-header">AI模型版本</div>
|
|
|
|
+ <el-select v-model="aiModelVersion" placeholder="请选择" class="model-select">
|
|
|
|
+ <el-option label="标准版" value="standard"></el-option>
|
|
|
|
+ </el-select>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <!-- 评分AI -->
|
|
|
|
+ <div class="setting-section">
|
|
|
|
+ <div class="section-header">评分AI</div>
|
|
|
|
+ <!-- 评分AI设置内容 -->
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <template #footer>
|
|
|
|
+ <div class="drawer-footer">
|
|
|
|
+ <el-button v-if="currentStep > 1" @click="prevStep">上一步</el-button>
|
|
|
|
+ <el-button @click="handleCancel">取消</el-button>
|
|
|
|
+ <el-button v-if="currentStep < 3" type="primary" @click="nextStep">下一步</el-button>
|
|
|
|
+ <el-button v-else type="success" @click="handleFinish">新增</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-drawer>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script setup lang="ts">
|
|
|
|
+import { ref, defineProps, defineEmits } from 'vue'
|
|
|
|
+import { Document, Plus, Edit, Delete, ArrowDown } from '@element-plus/icons-vue'
|
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
|
+
|
|
|
|
+const props = defineProps({
|
|
|
|
+ modelValue: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ required: true
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const emit = defineEmits(['update:modelValue', 'cancel', 'finish'])
|
|
|
|
+
|
|
|
|
+// 当前步骤
|
|
|
|
+const currentStep = ref(1)
|
|
|
|
+
|
|
|
|
+// AI视频选项
|
|
|
|
+const aiVideoOptions = ref({
|
|
|
|
+ qualityControl: false,
|
|
|
|
+ teamwork: false,
|
|
|
|
+ problemSolving: false,
|
|
|
|
+ dataAnalysis: false
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+// 面试题目
|
|
|
|
+const chatQuestions = ref([])
|
|
|
|
+
|
|
|
|
+// 选中的能力
|
|
|
|
+const selectedAbilities = ref([])
|
|
|
|
+
|
|
|
|
+// 排名设置
|
|
|
|
+const rankSettings = ref({
|
|
|
|
+ min: '',
|
|
|
|
+ max: '',
|
|
|
|
+ minScore: 0,
|
|
|
|
+ maxScore: 100
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+// AI视频有效期开关
|
|
|
|
+const validityEnabled = ref(false)
|
|
|
|
+
|
|
|
|
+// AI模型版本
|
|
|
|
+const aiModelVersion = ref('standard')
|
|
|
|
+
|
|
|
|
+// 方法
|
|
|
|
+const jumpToStep = (step: number) => {
|
|
|
|
+ if (step <= currentStep.value) {
|
|
|
|
+ currentStep.value = step
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const prevStep = () => {
|
|
|
|
+ if (currentStep.value > 1) {
|
|
|
|
+ currentStep.value--
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const nextStep = () => {
|
|
|
|
+ if (currentStep.value < 3) {
|
|
|
|
+ currentStep.value++
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const editQuestion = (index: number) => {
|
|
|
|
+ // 实现编辑题目的逻辑
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const deleteQuestion = (index: number) => {
|
|
|
|
+ chatQuestions.value.splice(index, 1)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const handleClose = () => {
|
|
|
|
+ emit('update:modelValue', false)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const handleCancel = () => {
|
|
|
|
+ emit('cancel')
|
|
|
|
+ handleClose()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const handleFinish = () => {
|
|
|
|
+ emit('finish', {
|
|
|
|
+ aiVideoOptions: aiVideoOptions.value,
|
|
|
|
+ chatQuestions: chatQuestions.value,
|
|
|
|
+ rankSettings: rankSettings.value,
|
|
|
|
+ validityEnabled: validityEnabled.value,
|
|
|
|
+ aiModelVersion: aiModelVersion.value
|
|
|
|
+ })
|
|
|
|
+ handleClose()
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style scoped>
|
|
|
|
+.ai-video-drawer {
|
|
|
|
+ /* 保持原有样式 */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.ai-video-steps {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ margin-bottom: 30px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.step-item {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ align-items: center;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.step-number {
|
|
|
|
+ width: 30px;
|
|
|
|
+ height: 30px;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ background-color: #eee;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.step-item.active .step-number {
|
|
|
|
+ background-color: #409EFF;
|
|
|
|
+ color: white;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.step-line {
|
|
|
|
+ width: 100px;
|
|
|
|
+ height: 2px;
|
|
|
|
+ background-color: #eee;
|
|
|
|
+ margin: 0 20px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.step-line.active-line {
|
|
|
|
+ background-color: #409EFF;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* 其他样式保持不变 */
|
|
|
|
+</style>
|