yangg 4 meses atrás
pai
commit
a6e61ae6a9

+ 1 - 1
.env.development

@@ -6,7 +6,7 @@ ENV = 'development'
 # 本地环境接口地址 121.36.251.245
 
 
-VITE_API_URL = 'http://192.168.100.101:8083'
+VITE_API_URL = 'http://192.168.100.187:8083'
 # VITE_API_URL = 'https://backend.qicai321.com'
 VITE_API_WX_URL='https://api.weixin.qq.com/'
 VITE_API_URL_MINLONG='http://117.185.80.170:7861'

+ 1 - 1
src/layout/navBars/tagsView/tagsView.vue

@@ -18,7 +18,7 @@
 					"
 				>
 					<i class="iconfont icon-webicon318 layout-navbars-tagsview-ul-li-iconfont" v-if="isActive(v)"></i>
-					<SvgIcon :name="v.meta.icon" v-if="!isActive(v) && getThemeConfig.isTagsviewIcon" class="pr5" />
+					<!-- <SvgIcon :name="v.meta.icon" v-if="!isActive(v) && getThemeConfig.isTagsviewIcon" class="pr5" /> -->
 					<span>{{ setTagsViewNameI18n(v) }}</span>
 					<template v-if="isActive(v)">
 						<SvgIcon

+ 2 - 2
src/theme/element.scss

@@ -90,7 +90,7 @@
 }
 .el-menu-item,
 .el-sub-menu__title {
-	color: rgba(var(--dark), 1);//var(--next-bg-menuBarColor);
+	color: #595959;//color: rgba(var(--dark), 1);//var(--next-bg-menuBarColor);
 	margin: 0 0 0 10px;
 }
 // 修复点击左侧菜单折叠再展开时,宽度不跟随问题
@@ -128,7 +128,7 @@
 	color: #000 !important;
 }
 .el-sub-menu.is-active.is-opened .el-sub-menu__title {
-	background-color: unset !important;
+	//background-color: unset !important;
 }
 // 子级菜单背景颜色
 // .el-menu--inline {

+ 1 - 1
src/theme/mixins/index.scss

@@ -4,7 +4,7 @@
 	font-size: 14px !important;
 	display: inline-block;
 	vertical-align: middle;
-	margin-right: 5px;
+	/* margin-right: 5px; */
 	width: 24px;
 	text-align: center;
 	justify-content: center;

+ 1 - 1
src/views/position/create/index.vue

@@ -172,7 +172,7 @@
           <el-select v-model="formData.job_type" placeholder="请选择职位状态">
             <el-option label="未发布" :value="0" />
             <el-option label="已发布" :value="1" />
-            <el-option label="已结束" :value="2" />
+            <!-- <el-option label="已结束" :value="2" /> -->
           </el-select>
         </el-form-item>
         

+ 19 - 3
src/views/position/detail/api.ts

@@ -21,7 +21,7 @@ export function GetQuestionList(query: PageQuery) {
 
 export function GenerateQuestions(obj: AddReq) {
 	return request({
-		url: '/api/admin/interview/questions/generate',
+		url: '/api/system/interview_question/ai_generated',
 		method: 'post',
 		data: {...obj,tenant_id:1},
         timeout: 0
@@ -105,15 +105,31 @@ export function GetOpeningSpeech(obj: AddReq) {
 	  timeout: 0
 	});
   }
+/* 批量绑定 */
+export function BatchBind(obj: AddReq) {
+	return request({
+		url: 'api/system/job/add_question',
+		method: 'post',
+		data: {...obj,tenant_id:"1"},
+	});
+}
+/* 批量取消绑定 */
+export function BatchUnbind(obj: AddReq) {
+	return request({
+		url: '/api/system/job/batch_delete_questions',
+		method: 'post',
+		data: {...obj,tenant_id:"1"},
+	});
+}
 
-export function GetPermission(query: UserPageQuery) {
+/* export function GetPermission(query: UserPageQuery) {
     return request({
         url: '/api/system/competency/list',
         method: 'get',
         params: {...query,tenant_id:1},
     });
 }
-
+ */
 export function GetcategoryList(query: UserPageQuery) {
 	return request({
 		url: '/api/system/question_category/list',

+ 5 - 5
src/views/position/detail/index.css

@@ -289,11 +289,11 @@
 }
 
 .step-item:hover {
-  color: #67C23A;
+  color: #0017ab;
 }
 
 .step-item:hover .step-number {
-  border-color: #67C23A;
+  border-color: #0017ab;
 }
 
 .step-number {
@@ -311,9 +311,9 @@
 }
 
 .step-item.active .step-number {
-  background-color: #67C23A;
+  background-color: #0017ab;
   color: white;
-  border-color: #67C23A;
+  border-color: #0017ab;
 }
 
 .step-line {
@@ -326,7 +326,7 @@
 }
 
 .step-line.active-line {
-  background-color: #67C23A;
+  background-color: #0017ab;
 }
 
 .step-title {

+ 443 - 24
src/views/position/detail/index.vue

@@ -450,14 +450,14 @@
         <div class="ai-video-options">
           <p class="option-tip">下面是奇才智能算法推荐的胜任力考核维度,请结合您的需求增删,确认后点击「下一步」出题</p>
           
-          <div class="new-feature-tip">
+          <!-- <div class="new-feature-tip">
             <span class="new-tag">NEW</span>
             AI根据岗位信息生成的能力,创建完步骤后,会自动将选择的新智能能力加入到该职位的考察能力列表中。
-          </div>
+          </div> -->
           
           <!-- 推荐的考核维度 -->
           <div class="recommended-dimensions">
-            <h3>推荐考核维度</h3>
+           <!--  <h3>推荐考核维度</h3> -->
             <div class="dimension-grid" >
               <el-checkbox 
                 v-for="item in competencyTags" 
@@ -475,7 +475,7 @@
 
           <!-- 备选考核维度 -->
           <div class="optional-dimensions">
-            <h3>备选考核维度</h3>
+            <h3 style="color: #808080;">备选考核维度</h3>
             <div class="dimension-grid">
               <el-checkbox v-model="aiVideoOptions.xxxx" label="XXXX">
                 <div class="ability-label">
@@ -491,7 +491,7 @@
 
           <!-- 自定义维度 -->
           <div class="custom-dimensions">
-            <h3>自定义维度</h3>
+            <h3 style="color: #808080;">自定义维度</h3>
             <div class="dimension-form">
               <div class="dimension-row">
                 <div class="dimension-input">
@@ -517,14 +517,33 @@
         <div class="interview-settings">
           <div class="interview-header">
              <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" @click="handleImportQuestion"><!-- @click="handleAddQuestion" -->
-                <el-icon><Plus /></el-icon>
-                自定义题目
+                <el-button type="primary" plain class="import-btn" >
+                  <el-icon><Document /></el-icon>
+                  导入题目
+                </el-button>
+                <el-button type="success" plain class="custom-btn" @click="handleImportQuestion"><!-- @click="handleAddQuestion" -->
+                  <el-icon><Plus /></el-icon>
+                  自定义题目
               </el-button>
+              <!-- 添加得分题和色盲题开关 -->
+              <div class="question-switches">
+                <div class="switch-item">
+                  <span class="switch-label">得分题</span>
+                  <el-switch 
+                  style="margin-top:0px;"
+                    v-model="questionSettings.enableScoreQuestions" 
+                    @change="handleScoreQuestionsChange"
+                  />
+                </div>
+                <div class="switch-item">
+                  <span class="switch-label">色盲题</span>
+                  <el-switch 
+                  style="margin-top:0px;"
+                    v-model="questionSettings.enableColorBlindQuestions" 
+                    @change="handleColorBlindQuestionsChange"
+                  />
+                </div>
+              </div>
             </div>
             <div class="interview-duration">
               <span>预计面试时长: </span>
@@ -552,6 +571,16 @@
                   >
                     AI自动组题
                   </el-button>
+                  <el-button 
+                    v-if="autoGenerateLoading && pollingController"
+                    type="warning" 
+                    plain
+                    size="small"
+                    @click="handleCancelGenerate"
+                    style="margin-left: 10px;"
+                  >
+                    取消生成
+                  </el-button>
                 </div>
              <!-- :component-data="{
                   tag: 'transition-group',
@@ -1628,7 +1657,7 @@
 </template>
 
 <script setup lang="ts">
-import { ref, reactive, onMounted, computed } from 'vue';
+import { ref, reactive, onMounted, onUnmounted, computed } from 'vue';
 import { useRouter, useRoute } from 'vue-router';
 import { ElMessage, ElMessageBox, ElDrawer } from 'element-plus';
 import * as api from '../list/api';
@@ -1637,7 +1666,7 @@ import { GetList } from '../../questionBank/classList/api';
 import { GetCompetencyList,GetQuestionList,GenerateQuestions,
   GetDraftList,SaveDraft,GetDigitalList,
   CreateConfig,GetConfig,UpdateConfig,AddDocument,
-  GetOpeningSpeech,GetVideo } from './api';
+  GetOpeningSpeech,GetVideo,BatchBind,BatchUnbind } from './api';
 import draggable from 'vuedraggable';
 import { updateFieldConfig } from './utils';
 import type { ProfileFieldsConfig } from './types';
@@ -1944,6 +1973,12 @@ const confirmResumeCollection = () => {
 // AI自动组题loading状态
 const autoGenerateLoading = ref(false);
 
+// 题目设置选项
+const questionSettings = reactive({
+  enableScoreQuestions: false, // 得分题开关
+  enableColorBlindQuestions: false // 色盲题开关
+});
+
 // 获取职位详情
 const getPositionDetail = async () => {
   try {
@@ -1963,6 +1998,13 @@ const getPositionDetail = async () => {
       const config = await GetConfig(id);
       if (config && config.data) {
         getConfigId.value=config.data.id;
+        // 根据配置状态初始化得分题和色盲题开关
+        if (config.data.enable_psychological_test !== undefined) {
+          questionSettings.enableScoreQuestions = config.data.enable_psychological_test;
+        }
+        if (config.data.enable_color_blind_test !== undefined) {
+          questionSettings.enableColorBlindQuestions = config.data.enable_color_blind_test;
+        }
       }
       // 设置职位状态
       positionStatus.value = positionData.status === 1;
@@ -2271,6 +2313,12 @@ const finishConfig = async () => {
   
   // 获取面试设置选项
   const interviewSettings = getInterviewSettings();
+  
+  // 获取题目设置选项
+  const currentQuestionSettings = {
+    enableScoreQuestions: questionSettings.enableScoreQuestions,
+    enableColorBlindQuestions: questionSettings.enableColorBlindQuestions
+  };
   if(getConfigId.value==0){
   const response = await CreateConfig({
     position_id:route.query.id,
@@ -2291,7 +2339,8 @@ const finishConfig = async () => {
           // 有开场白配置,先请求获取开场白接口
           await GetOpeningSpeech(params);
           console.log('开场白生成成功');
-          
+            showAIVideoDialog.value = false;
+            currentStep.value = 1;
           // 等待3-5秒(这里设置为4秒)
           await new Promise(resolve => setTimeout(resolve, 4000));
         } else {
@@ -2306,8 +2355,7 @@ const finishConfig = async () => {
         ElMessage.warning('视频生成中,请稍后');
       }
       
-      showAIVideoDialog.value = false;
-      currentStep.value = 1;
+    
     }else{
       ElMessage.error('配置保存失败');
     }
@@ -2327,7 +2375,8 @@ const finishConfig = async () => {
         console.log('开始生成开场白...');
         await GetOpeningSpeech(params);
         console.log('开场白生成成功');
-        
+        showAIVideoDialog.value = false;
+         currentStep.value = 1;
         // 第二步:等待3-5秒(这里设置为4秒)
         console.log('等待4秒后开始生成视频...');
         await delay(4000);
@@ -2342,14 +2391,14 @@ const finishConfig = async () => {
         ElMessage.warning('视频生成中,请稍后');
       }
       
-      showAIVideoDialog.value = false;
-      currentStep.value = 1;
+      
     }else{
       ElMessage.error('配置保存失败');
     }
   }
   console.log('保存时选中的面试官:', selectedInterviewerInfo);
   console.log('保存时的面试设置:', interviewSettings);
+  console.log('保存时的题目设置:', currentQuestionSettings);
   
       // 创建新的AI视频步骤
     const newStep = {
@@ -2590,9 +2639,40 @@ const confirmDataCollection = () => {
 onMounted(() => {
   getPositionDetail();
   getCompetencyList();
-  getDigitalList()
+  getDigitalList();
+  // 初始化配置状态
+  initializeConfigState();
 });
 
+// 组件销毁时清理轮询
+onUnmounted(() => {
+  // 取消正在进行的轮询
+  cancelPolling();
+});
+
+// 初始化配置状态
+const initializeConfigState = async () => {
+  try {
+    const id = route.query.id;
+    if (id) {
+      const config = await GetConfig(id);
+      if (config && config.data) {
+        // 同步得分题开关状态
+        if (config.data.enable_psychological_test !== undefined) {
+          questionSettings.enableScoreQuestions = config.data.enable_psychological_test;
+        }
+        // 同步色盲题开关状态
+        if (config.data.enable_color_blind_test !== undefined) {
+          questionSettings.enableColorBlindQuestions = config.data.enable_color_blind_test;
+        }
+        // 可以在这里添加其他配置状态的同步
+      }
+    }
+  } catch (error) {
+    console.error('初始化配置状态失败:', error);
+  }
+};
+
 // 添加代码测试相关的状态和方法
 const showCodeTestDialog = ref(false);
 const codeTestForm = reactive({
@@ -3360,6 +3440,11 @@ const getCompleteInterviewConfig = () => {
     },
     // 面试设置
     settings: getInterviewSettings(),
+    // 题目设置
+    questionSettings: {
+      enableScoreQuestions: questionSettings.enableScoreQuestions,
+      enableColorBlindQuestions: questionSettings.enableColorBlindQuestions
+    },
     // 选中的能力标签
     abilities: selectedAbilities.value,
     // 题目列表
@@ -3430,6 +3515,282 @@ const delay = (ms: number): Promise<void> => {
   return new Promise(resolve => setTimeout(resolve, ms));
 };
 
+// 轮询控制器,用于取消轮询
+let pollingController: { cancelled: boolean } | null = null;
+
+// 轮询获取草稿列表的函数
+const pollForDraftList = async (params: { tenant_id: number; position_id: string }, maxAttempts: number = 30, interval: number = 2000): Promise<any> => {
+  let attempts = 0;
+  
+  // 创建轮询控制器
+  pollingController = { cancelled: false };
+  const currentController = pollingController;
+  
+  return new Promise((resolve, reject) => {
+    const poll = async () => {
+      try {
+        // 检查是否已取消轮询
+        if (currentController.cancelled) {
+          console.log('轮询已被取消');
+          resolve(null);
+          return;
+        }
+        
+        attempts++;
+        console.log(`第${attempts}次轮询获取草稿列表...`);
+        
+        const response = await GetDraftList(params);
+        
+        // 再次检查是否已取消轮询(防止在异步请求期间被取消)
+        if (currentController.cancelled) {
+          console.log('轮询已被取消');
+          resolve(null);
+          return;
+        }
+        
+        // 检查是否有数据
+        if (response && response.data && response.data.dataList && response.data.dataList.length > 0) {
+          console.log('轮询成功,获取到草稿列表数据');
+          pollingController = null; // 清理控制器
+          resolve(response);
+          return;
+        }
+        
+        // 如果超过最大尝试次数,停止轮询
+        if (attempts >= maxAttempts) {
+          console.log('轮询达到最大次数,停止轮询');
+          pollingController = null; // 清理控制器
+          resolve(response); // 返回最后一次的响应,即使没有数据
+          return;
+        }
+        
+        // 继续轮询
+        setTimeout(poll, interval);
+        
+      } catch (error) {
+        console.error(`第${attempts}次轮询失败:`, error);
+        
+        // 检查是否已取消轮询
+        if (currentController.cancelled) {
+          console.log('轮询已被取消');
+          resolve(null);
+          return;
+        }
+        
+        // 如果是网络错误且还没超过最大尝试次数,继续尝试
+        if (attempts < maxAttempts) {
+          setTimeout(poll, interval);
+        } else {
+          pollingController = null; // 清理控制器
+          reject(error);
+        }
+      }
+    };
+    
+    // 开始第一次轮询
+    poll();
+  });
+};
+
+// 取消轮询的函数
+const cancelPolling = () => {
+  if (pollingController) {
+    pollingController.cancelled = true;
+    pollingController = null;
+    console.log('轮询已被手动取消');
+  }
+};
+
+// 处理取消生成题目
+const handleCancelGenerate = () => {
+  cancelPolling();
+  autoGenerateLoading.value = false;
+  ElMessage.info('已取消AI自动组题');
+};
+
+// 处理得分题开关变化
+const handleScoreQuestionsChange = async (value: boolean) => {
+  console.log('得分题开关状态:', value ? '开启' : '关闭');
+  
+  if (value) {
+    const response = await GetQuestionList({page:1,limit:1000,question_form:4,tenant_id:1});
+    console.log(response);
+    if (response && response.data) {
+      BatchBind({
+        position_id: route.query.id,
+        question_id: {question_id:response.data.items.map((item: any) => item.id)},
+        tenant_id: 1
+      }).then(async (res:any)=>{
+        if(res.code===2000){
+          // 绑定成功后更新配置中的enable_psychological_test字段
+          try {
+            if (getConfigId.value > 0) {
+              await UpdateConfig({
+                id: getConfigId.value,
+                enable_psychological_test: true
+              });
+              console.log('配置中的enable_psychological_test字段已更新为true');
+                         }else{
+               const createResponse = await CreateConfig({
+                 position_id: route.query.id,
+                 enable_psychological_test: true,
+                 tenant_id: 1
+               });
+               if (createResponse && createResponse.code === 2000) {
+                 getConfigId.value = createResponse.data?.id || createResponse.data;
+                 console.log('配置创建成功,enable_psychological_test字段已设置为true');
+               }
+             }
+          } catch (error) {
+            console.error('更新enable_psychological_test字段失败:', error);
+            // 不显示错误消息给用户,避免影响主要功能的用户体验
+          }
+          
+          ElMessage.success('得分题功能已开启');
+        }else{
+          ElMessage.error('得分题功能开启失败');
+        }
+      })
+      
+    } else {
+      ElMessage.error('获取题目列表失败');
+    }
+    // 可以在这里添加开启得分题时的特殊逻辑
+    // 比如:自动添加得分相关的题目类型、更新界面显示等
+  } else {
+    try {
+      const response = await GetQuestionList({page:1,limit:1000,question_form:4,tenant_id:1});
+      if (response && response.data) {
+      await BatchUnbind({
+        position_id: route.query.id,
+        question_id:response.data.items.map((item: any) => item.id),
+        tenant_id: 1
+      });
+      
+      // 解绑成功后更新配置中的enable_psychological_test字段
+      if (getConfigId.value > 0) {
+        await UpdateConfig({
+          id: getConfigId.value,
+          enable_psychological_test: false
+        });
+        console.log('配置中的enable_psychological_test字段已更新为false');
+      } else {
+        // 如果没有配置ID,创建新配置并设置为false
+        const createResponse = await CreateConfig({
+          position_id: route.query.id,
+          enable_psychological_test: false,
+          tenant_id: 1
+        });
+        if (createResponse && createResponse.code === 2000) {
+          getConfigId.value = createResponse.data?.id || createResponse.data;
+          console.log('配置创建成功,enable_psychological_test字段已设置为false');
+        }
+      }
+      
+      ElMessage.info('得分题功能已关闭');
+      }
+    } catch (error) {
+      console.error('关闭得分题功能失败:', error);
+      ElMessage.error('关闭得分题功能失败');
+    }
+    // 可以在这里添加关闭得分题时的清理逻辑
+  }
+  
+  // 可以在这里调用API保存设置状态
+  // await saveQuestionSettings(questionSettings);
+};
+
+// 处理色盲题开关变化
+const handleColorBlindQuestionsChange = async (value: boolean) => {
+  console.log('色盲题开关状态:', value ? '开启' : '关闭');
+  
+  if (value) {
+    // 开启色盲题
+    const response = await GetQuestionList({page:1,limit:1000,question_form:3,tenant_id:1}); // 假设色盲题的question_form为5
+    console.log(response);
+    if (response && response.data) {
+      BatchBind({
+        position_id: route.query.id,
+        question_id: {question_id:response.data.items.map((item: any) => item.id)},
+        tenant_id: 1
+      }).then(async (res:any)=>{
+        if(res.code===2000){
+          // 绑定成功后更新配置中的enable_color_blind_test字段
+          try {
+            if (getConfigId.value > 0) {
+              await UpdateConfig({
+                id: getConfigId.value,
+                enable_color_blind_test: true
+              });
+              console.log('配置中的enable_color_blind_test字段已更新为true');
+            }else{
+              const createResponse = await CreateConfig({
+                position_id: route.query.id,
+                enable_color_blind_test: true,
+                tenant_id: 1
+              });
+              if (createResponse && createResponse.code === 2000) {
+                getConfigId.value = createResponse.data?.id || createResponse.data;
+                console.log('配置创建成功,enable_color_blind_test字段已设置为true');
+              }
+            }
+          } catch (error) {
+            console.error('更新enable_color_blind_test字段失败:', error);
+            // 不显示错误消息给用户,避免影响主要功能的用户体验
+          }
+          
+          ElMessage.success('色盲题功能已开启');
+        }else{
+          ElMessage.error('色盲题功能开启失败');
+        }
+      })
+      
+    } else {
+      ElMessage.error('获取色盲题目列表失败');
+    }
+    // 可以在这里添加开启色盲题时的特殊逻辑
+    // 比如:自动添加色盲测试相关题目、设置特殊的评分标准等
+  } else {
+    // 关闭色盲题
+    try {
+      const response = await GetQuestionList({page:1,limit:1000,question_form:3,tenant_id:1}); // 假设色盲题的question_form为5
+      if (response && response.data) {
+        await BatchUnbind({
+          position_id: route.query.id,
+          question_id:response.data.items.map((item: any) => item.id),
+          tenant_id: 1
+        });
+        
+        // 解绑成功后更新配置中的enable_color_blind_test字段
+        if (getConfigId.value > 0) {
+          await UpdateConfig({
+            id: getConfigId.value,
+            enable_color_blind_test: false
+          });
+          console.log('配置中的enable_color_blind_test字段已更新为false');
+        } else {
+          // 如果没有配置ID,创建新配置并设置为false
+          const createResponse = await CreateConfig({
+            position_id: route.query.id,
+            enable_color_blind_test: false,
+            tenant_id: 1
+          });
+          if (createResponse && createResponse.code === 2000) {
+            getConfigId.value = createResponse.data?.id || createResponse.data;
+            console.log('配置创建成功,enable_color_blind_test字段已设置为false');
+          }
+        }
+        
+        ElMessage.info('色盲题功能已关闭');
+      }
+    } catch (error) {
+      console.error('关闭色盲题功能失败:', error);
+      ElMessage.error('关闭色盲题功能失败');
+    }
+    // 可以在这里添加关闭色盲题时的清理逻辑
+  }
+};
+
 // 在 script setup 中添加以下内容
 // 题目选择相关的响应式变量
 const showQuestionSelectDialog = ref(false);
@@ -3531,6 +3892,11 @@ console.log(selectedQuestions.value);
 const handleAutoGenerate = async () => {
   console.log('AI自动组题');
   
+  // 如果已经在轮询中,先取消之前的轮询
+  if (pollingController) {
+    cancelPolling();
+  }
+  
   // 设置loading状态
   autoGenerateLoading.value = true;
   
@@ -3560,13 +3926,20 @@ const handleAutoGenerate = async () => {
     const response = await GenerateQuestions(params);
     
     if (response && response.data) {
-      // 生成成功后,调用 GetDraftList 获取最新生成的题目
-      const draftResponse = await GetDraftList({
+      // 生成成功后,使用轮询获取最新生成的题目
+      const draftResponse = await pollForDraftList({
         tenant_id: 1,
         position_id: route.query.id as string
       });
   console.log(draftResponse);
-      if (draftResponse && draftResponse.data) {
+      
+      // 检查轮询是否被取消
+      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(),
@@ -3586,6 +3959,8 @@ const handleAutoGenerate = async () => {
         // 清空现有题目并添加新生成的题目
         chatQuestions.value = formattedQuestions;
         ElMessage.success(`已成功生成${formattedQuestions.length}个面试题目`);
+      } else {
+        ElMessage.warning('AI生成题目中,请稍后再试');
       }
     }
   } catch (error) {
@@ -4205,6 +4580,50 @@ const saveDisclaimer = () => {
   margin-bottom: 12px;
 }
 
+/* 题目开关样式 */
+.question-switches {
+  display: flex;
+  align-items: center;
+  gap: 20px;
+  margin-left: auto;
+  padding-left: 20px;
+  border-left: 1px solid #e4e7ed;
+  
+  .switch-item {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    
+    .switch-label {
+      font-size: 14px;
+      color: #606266;
+      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;
+    }
+  }
+}
+
+/* 确保interview-actions布局正确 */
+.interview-actions {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  margin-bottom: 16px;
+  
+  .import-btn, .custom-btn {
+    flex-shrink: 0;
+  }
+}
+
 /* 面试设置弹窗样式 */
 .interview-settings-dialog {
   :deep(.el-dialog__body) {

+ 1 - 1
src/views/position/list/crud.tsx

@@ -522,7 +522,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 						data: [
 							{ value: 0, label: '未发布' },
 							{ value: 1, label: '已发布' },
-							{ value: 2, label: '已结束' }
+							{ value: 2, label: '已过期' }
 						]
 					}),
 					form: {

+ 2 - 2
src/views/position/list/index.vue

@@ -78,13 +78,13 @@ async function generateQRCode(row: { id: string | number }) {
 function checkPositionComplete(row: any): { isComplete: boolean; missing: string[] } {
 	const required = [
 		{ field: 'title', name: '职位名称' },
-		{ field: 'job_type', name: '职位类型' },
+		/* { field: 'job_type', name: '职位类型' },
 		{ field: 'salary_range', name: '薪资范围' },
 		{ field: 'location', name: '工作地点' },
 		{ field: 'department', name: '所属部门' },
 		{ field: 'requirements', name: '职位要求' },
 		{ field: 'description', name: '职位描述' },
-		{ field: 'end_date', name: '截止日期' }
+		{ field: 'end_date', name: '截止日期' } */
 	];
 
 	const missing = required