Browse Source

添加修改样式及内容

yangg 2 months ago
parent
commit
a74faa73c6

BIN
src/assets/dorp.png


+ 37 - 21
src/views/digitalHuman/list/crud.tsx

@@ -65,11 +65,11 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					});
 					});
 					
 					
 					loading.close();
 					loading.close();
-					
+					console.log(result);
 					if (result.code === 2000) {
 					if (result.code === 2000) {
-						ElMessage.success('预览视频生成成功!');
+						ElMessage.success('数字人演示视频生成任务已提交!');
 						// 刷新列表
 						// 刷新列表
-						crudExpose.refresh();
+						crudExpose.doRefresh();
 					} else {
 					} else {
 						ElMessage.error(result.msg || '生成预览视频失败');
 						ElMessage.error(result.msg || '生成预览视频失败');
 					}
 					}
@@ -233,24 +233,6 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						],
 						],
 					},
 					},
 				},
 				},
-				description: {
-					title: '描述',
-					search: {
-						show: false,
-						size: 'small',
-						col:{ span:3},
-					},
-					type: 'textarea',
-					column: {
-						minWidth: 200,
-						showOverflowTooltip: true,
-					},
-					form: {
-						component: {
-							span: 24,
-						},
-					},
-				},
 				avatar_url: {
 				avatar_url: {
 					title: '头像',
 					title: '头像',
 					type: 'cropper-uploader',
 					type: 'cropper-uploader',
@@ -352,10 +334,23 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						}
 						}
 					},
 					},
 					column: {
 					column: {
+						show: false,
 						minWidth: 180,
 						minWidth: 180,
 						
 						
 					}
 					}
 				},
 				},
+				demo_video_url: {
+					title: '演示视频',
+					type: 'file-uploader',
+					column: {
+						
+						width: 300,
+						
+					},
+					form: {
+						show: false,
+					},
+				},
 				status: {
 				status: {
 					title: '状态',
 					title: '状态',
 					search: {
 					search: {
@@ -378,6 +373,24 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						],
 						],
 					}),
 					}),
 				},
 				},
+				description: {
+					title: '描述',
+					search: {
+						show: false,
+						size: 'small',
+						col:{ span:3},
+					},
+					type: 'textarea',
+					column: {
+						minWidth: 200,
+						showOverflowTooltip: true,
+					},
+					form: {
+						component: {
+							span: 24,
+						},
+					},
+				},
 				/* config: {
 				/* config: {
 					title: '配置信息',
 					title: '配置信息',
 					type: 'text',
 					type: 'text',
@@ -454,6 +467,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					title: '创建人',
 					title: '创建人',
 					type: 'text',
 					type: 'text',
 					column: {
 					column: {
+						
 						minWidth: 120,
 						minWidth: 120,
 					},
 					},
 					form: {
 					form: {
@@ -464,6 +478,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					title: '创建时间',
 					title: '创建时间',
 					type: 'datetime',
 					type: 'datetime',
 					column: {
 					column: {
+						show: false,
 						minWidth: 160,
 						minWidth: 160,
 					},
 					},
 					form: {
 					form: {
@@ -474,6 +489,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					title: '更新时间',
 					title: '更新时间',
 					type: 'datetime',
 					type: 'datetime',
 					column: {
 					column: {
+						show: false,
 						minWidth: 160,
 						minWidth: 160,
 					},
 					},
 					form: {
 					form: {

+ 9 - 4
src/views/digitalHuman/list/index.vue

@@ -184,6 +184,7 @@ const defaultFormData = {
 	avatar_url: '',
 	avatar_url: '',
 	status: 1,
 	status: 1,
 	template_video_url: '',
 	template_video_url: '',
+	voice_type: '',
 	config: {
 	config: {
 		voice_type: '',
 		voice_type: '',
 		style: 'professional'
 		style: 'professional'
@@ -308,6 +309,7 @@ const submitForm = async () => {
 				voice_type: submitData.config.voice_type || '',
 				voice_type: submitData.config.voice_type || '',
 				style: submitData.config.style || ''
 				style: submitData.config.style || ''
 			};
 			};
+			submitData.voice_type = submitData.config.voice_type;
 			// 将config转为字符串
 			// 将config转为字符串
 			submitData.config = JSON.stringify(config) as any; // 使用类型断言解决类型错误
 			submitData.config = JSON.stringify(config) as any; // 使用类型断言解决类型错误
 		}
 		}
@@ -360,15 +362,18 @@ const fetchData = () => {
 	crudExpose.doRefresh();
 	crudExpose.doRefresh();
 };
 };
 const voiceList = ref([
 const voiceList = ref([
-	{ label: '龙小夏', value: 'longxiaoxia' },
-	{ label: '龙小春', value: 'longxiaochun' },
+	{ label: '龙小夏-女', value: 'longxiaoxia' },
+	/* { label: '龙小春', value: 'longxiaochun' },
 	{ label: '龙小瑶', value: 'longxiaoyao' },
 	{ label: '龙小瑶', value: 'longxiaoyao' },
 	{ label: '龙小婧', value: 'longxiaojing' },
 	{ label: '龙小婧', value: 'longxiaojing' },
-	{ label: '龙青周', value: 'longqingzhou' },
+	{ label: '龙青周-女', value: 'longqingzhou' },
 	{ label: '女声清新风格', value: 'female1' },
 	{ label: '女声清新风格', value: 'female1' },
 	{ label: '女声稳重风格', value: 'female2' },
 	{ label: '女声稳重风格', value: 'female2' },
 	{ label: '男声清新风格', value: 'male1' },
 	{ label: '男声清新风格', value: 'male1' },
-	{ label: '男声稳重风格', value: 'male2' },
+	{ label: '男声稳重风格', value: 'male2' }, */
+	{ label: '女声中英文', value: 'loongstella' },
+	{ label: '男声中文', value: 'longxiang' },
+	{ label: '男童声中英文', value: 'longjielidou' },
 ]);
 ]);
 /* 获取语音列表 */
 /* 获取语音列表 */
 const getVoiceList = async () => {
 const getVoiceList = async () => {

+ 1 - 1
src/views/position/detail/api.ts

@@ -101,7 +101,7 @@ export function GetOpeningSpeech(obj: AddReq) {
 	return request({
 	return request({
 	  url: '/api/system/digital_human/generate_question_videos',
 	  url: '/api/system/digital_human/generate_question_videos',
 	  method: 'post',
 	  method: 'post',
-	  data: {...obj,tenant_id:"1"},
+	  data: {...obj,tenant_id:"1",force_regenerate: true},
 	  timeout: 0
 	  timeout: 0
 	});
 	});
   }
   }

+ 48 - 9
src/views/position/detail/index.css

@@ -471,11 +471,10 @@
   gap: 10px;
   gap: 10px;
 }
 }
 
 
-.dimension-item {
-  border: 1px solid #dcdfe6;
-  border-radius: 4px;
+/* .dimension-item {
+ 
 }
 }
-
+ */
 .dimension-header {
 .dimension-header {
   display: flex;
   display: flex;
   align-items: center;
   align-items: center;
@@ -752,6 +751,15 @@
   margin-bottom: 16px;
   margin-bottom: 16px;
   box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
   box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
 }
 }
+.drag-handle{
+  display: flex;
+  justify-content: center;
+  .dorp{
+    width: 30px;
+    height: 30px;
+    cursor: pointer;
+  }
+}
 
 
 .question-header {
 .question-header {
   display: flex;
   display: flex;
@@ -1477,13 +1485,14 @@
 
 
   .dimension-list {
   .dimension-list {
     .dimension-item {
     .dimension-item {
+    
+      border-radius: 4px;
       display: flex;
       display: flex;
-    justify-content: space-between;
-    align-items: center;
-      background: #fff;
+      justify-content: space-between;
+      align-items: center;
       border-radius: 4px;
       border-radius: 4px;
       margin-bottom: 12px;
       margin-bottom: 12px;
-      position: relative;
+      
       .sheng{
       .sheng{
         position: absolute;
         position: absolute;
         right: 0;
         right: 0;
@@ -1493,6 +1502,10 @@
       }
       }
 
 
       .dimension-header {
       .dimension-header {
+        border: 1px solid #dcdfe6;
+        position: relative;
+        width: 90%;
+        background: #fff;
         padding: 12px 16px;
         padding: 12px 16px;
         display: flex;
         display: flex;
         align-items: center;
         align-items: center;
@@ -1545,13 +1558,39 @@
       }
       }
 
 
       .dimension-content {
       .dimension-content {
-        padding: 0 16px 16px;
+        padding: 11px 16px;
         width: 30px;
         width: 30px;
+        cursor: pointer;
+        transition: all 0.3s ease;
+        position: relative;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        
+        /* &:hover {
+          background-color: #f56c6c;
+          color: white;
+          
+          .ability-description {
+            display: none;
+          }
+          
+          .delete-icon {
+            display: block;
+          }
+        } */
+        
         .ability-description {
         .ability-description {
           color: #606266;
           color: #606266;
           font-size: 14px;
           font-size: 14px;
           line-height: 1.5;
           line-height: 1.5;
         }
         }
+        
+        .delete-icon {
+          display: none;
+          font-size: 16px;
+          color: white;
+        }
       }
       }
     }
     }
   }
   }

+ 196 - 66
src/views/position/detail/index.vue

@@ -539,7 +539,7 @@
             <el-button type="primary" plain size="small" class="customize-btn">定制面试间</el-button>
             <el-button type="primary" plain size="small" class="customize-btn">定制面试间</el-button>
           </div> -->
           </div> -->
             <div class="interview-content">
             <div class="interview-content">
-               <div class="interview-questions-container" :loading="autoGenerateLoading">
+               <div class="interview-questions-container" v-loading="autoGenerateLoading" element-loading-text="AI正在生成题目...">
                 <div class="no-questions" v-if="chatQuestions.length === 0">
                 <div class="no-questions" v-if="chatQuestions.length === 0">
                   <p>暂无题目</p>
                   <p>暂无题目</p>
                   <p class="ai-tip">点击"AI自动组题"按钮</p>
                   <p class="ai-tip">点击"AI自动组题"按钮</p>
@@ -547,7 +547,7 @@
                   <el-button 
                   <el-button 
                     type="success" 
                     type="success" 
                     class="auto-generate-btn" 
                     class="auto-generate-btn" 
-                   
+                    :loading="autoGenerateLoading"
                     @click="handleAutoGenerate"
                     @click="handleAutoGenerate"
                   >
                   >
                     AI自动组题
                     AI自动组题
@@ -560,23 +560,32 @@
             <div class="question-list" v-else>
             <div class="question-list" v-else>
               <draggable 
               <draggable 
                 v-model="chatQuestions"
                 v-model="chatQuestions"
-               
                 item-key="id"
                 item-key="id"
                 handle=".drag-handle"
                 handle=".drag-handle"
-                @start="drag = true"
-                @end="drag = false"
+                @start="handleDragStart"
+                @end="handleDragEnd"
+                animation="200"
+                ghost-class="sortable-ghost"
+                chosen-class="sortable-chosen"
+                drag-class="sortable-drag"
               >
               >
                 <template #item="{ element }">
                 <template #item="{ element }">
                   <div class="question-card">
                   <div class="question-card">
+                      <div class="drag-handle">
+                          <img src="../../../assets/dorp.png" alt="" class="dorp">
+                        </div>
                     <div class="question-header">
                     <div class="question-header">
                       <div class="question-title">
                       <div class="question-title">
-                        <span class="question-number">题目{{ chatQuestions.indexOf(element) + 1 }}</span>
-                        <span><span style="color: #0017ab;">{{ '「'+element.question_form_name +'」'}}</span>{{ element.title }}</span>
+                      
+                        <div class="title-content">
+                          <span class="question-number">题目{{ chatQuestions.indexOf(element) + 1 }}</span>
+                          <span><span style="color: #0017ab;">{{ '「'+element.question_form_name +'」'}}</span>{{ element.title }}</span>
+                        </div>
                       </div>
                       </div>
-                      <div>
-                      <el-button type="text" @click="editQuestion(chatQuestions.indexOf(element))">
+                      <div class="question-actions">
+                       <!--  <el-button type="text" @click="editQuestion(chatQuestions.indexOf(element))">
                           <el-icon><Edit /></el-icon>
                           <el-icon><Edit /></el-icon>
-                        </el-button>
+                        </el-button> -->
                         <el-button type="text" @click="deleteQuestion(chatQuestions.indexOf(element))">
                         <el-button type="text" @click="deleteQuestion(chatQuestions.indexOf(element))">
                           <el-icon><Delete /></el-icon>
                           <el-icon><Delete /></el-icon>
                         </el-button>
                         </el-button>
@@ -630,15 +639,16 @@
               <div class="multi-dimension-questions">
               <div class="multi-dimension-questions">
                 <div class="dimension-title">已选胜任力考核维度</div>
                 <div class="dimension-title">已选胜任力考核维度</div>
                 <div class="dimension-list">
                 <div class="dimension-list">
-                  <div v-for="ability in selectedAbilities" :key="ability.value" class="dimension-item">
+                  <div v-for="(ability, index) in selectedAbilities" :key="ability.value" class="dimension-item">
                     <div class="dimension-header">
                     <div class="dimension-header">
                       <div class="dimension-info">
                       <div class="dimension-info">
                         <span class="ability-name">{{ ability.label }}</span>
                         <span class="ability-name">{{ ability.label }}</span>
                         <img src="../../../assets/sheng.png"  alt=""class="sheng">
                         <img src="../../../assets/sheng.png"  alt=""class="sheng">
                       </div>
                       </div>
                     </div>
                     </div>
-                    <div class="dimension-content">
-                      <div class="ability-description">{{ "-" }}</div>
+                    <div class="dimension-content" @click="removeSelectedAbility(index)" title="点击删除此胜任力标签">
+                      <div class="ability-description">{{ "—" }}</div>
+                     <!--  <el-icon class="delete-icon"><Delete /></el-icon> -->
                     </div>
                     </div>
                   </div>
                   </div>
                 </div>
                 </div>
@@ -687,11 +697,12 @@
             <div class="interview-settings">
             <div class="interview-settings">
               <div class="setting-item">
               <div class="setting-item">
                 <div class="setting-label">「回答视频保留」</div>
                 <div class="setting-label">「回答视频保留」</div>
+                 <div class="setting-desc">当候选人不符合中断条件时,保留其回答视频</div>
                 <el-switch 
                 <el-switch 
                   v-model="settings.keepVideo" 
                   v-model="settings.keepVideo" 
                   @change="(value) => handleSettingChange('keepVideo', value)"
                   @change="(value) => handleSettingChange('keepVideo', value)"
                 />
                 />
-                <div class="setting-desc">当候选人不符合中断条件时,保留其回答视频</div>
+               
               </div>
               </div>
 
 
               <div class="setting-item">
               <div class="setting-item">
@@ -699,29 +710,31 @@
                 <div class="setting-options">
                 <div class="setting-options">
                   <el-radio 
                   <el-radio 
                     v-model="settings.interruptionMode" 
                     v-model="settings.interruptionMode" 
-                    label="previous"
+                    label="current"
                     @change="handleSettingChange('interruptionMode', settings.interruptionMode)"
                     @change="handleSettingChange('interruptionMode', settings.interruptionMode)"
                   >
                   >
-                    从上一问重新作答
+                  从当前问题重新作答
                   </el-radio>
                   </el-radio>
                   <el-radio 
                   <el-radio 
                     v-model="settings.interruptionMode" 
                     v-model="settings.interruptionMode" 
-                    label="current"
+                    label="previous"
                     @change="handleSettingChange('interruptionMode', settings.interruptionMode)"
                     @change="handleSettingChange('interruptionMode', settings.interruptionMode)"
                   >
                   >
-                    从当前问题作答
+                  从头作答
                   </el-radio>
                   </el-radio>
+                  
                 </div>
                 </div>
                 <div class="setting-desc"></div>
                 <div class="setting-desc"></div>
               </div>
               </div>
 
 
               <div class="setting-item">
               <div class="setting-item">
                 <div class="setting-label">「智慧追问」</div>
                 <div class="setting-label">「智慧追问」</div>
+                <div class="setting-desc">当候选人给出特殊关键词时,系统将自动追问</div>
                 <el-switch 
                 <el-switch 
                   v-model="settings.smartFollowUp" 
                   v-model="settings.smartFollowUp" 
                   @change="(value) => handleSettingChange('smartFollowUp', value)"
                   @change="(value) => handleSettingChange('smartFollowUp', value)"
                 />
                 />
-                <div class="setting-desc">当候选人给出特殊关键词时,系统将自动追问</div>
+                
               </div>
               </div>
             </div>
             </div>
           </div>
           </div>
@@ -1947,6 +1960,10 @@ const getPositionDetail = async () => {
     const response = await api.GetObj(id); // 使用 infoReq 而不是 id
     const response = await api.GetObj(id); // 使用 infoReq 而不是 id
     if (response && response.data) {
     if (response && response.data) {
       Object.assign(positionData, response.data);
       Object.assign(positionData, response.data);
+      const config = await GetConfig(id);
+      if (config && config.data) {
+        getConfigId.value=config.data.id;
+      }
       // 设置职位状态
       // 设置职位状态
       positionStatus.value = positionData.status === 1;
       positionStatus.value = positionData.status === 1;
     }
     }
@@ -2306,23 +2323,19 @@ const finishConfig = async () => {
       try {
       try {
         const params = { config_id: getConfigId.value };
         const params = { config_id: getConfigId.value };
         
         
-        // 检查是否有开场白配置
-        const hasOpeningSpeech = interviewSettings.beforeStartText && 
-                                 interviewSettings.beforeStartText.trim() !== '';
+        // 第一步:请求获取开场白接口
+        console.log('开始生成开场白...');
+        await GetOpeningSpeech(params);
+        console.log('开场白生成成功');
         
         
-        if (hasOpeningSpeech) {
-          // 有开场白配置,先请求获取开场白接口
-          await GetOpeningSpeech(params);
-          console.log('开场白生成成功');
-          
-          // 等待3-5秒(这里设置为4秒)
-          await new Promise(resolve => setTimeout(resolve, 4000));
-        } else {
-          console.log('无开场白配置,跳过开场白生成');
-        }
+        // 第二步:等待3-5秒(这里设置为4秒)
+        console.log('等待4秒后开始生成视频...');
+        await delay(4000);
         
         
-        // 请求获取视频接口
+        // 第三步:请求获取视频接口
+        console.log('开始生成视频...');
         await GetVideo(params);
         await GetVideo(params);
+        console.log('视频生成请求已发送');
         ElMessage.success('视频开始生成');
         ElMessage.success('视频开始生成');
       } catch (error) {
       } catch (error) {
         console.error('获取开场白和视频失败:', error);
         console.error('获取开场白和视频失败:', error);
@@ -3318,6 +3331,24 @@ const validateInterviewSettings = () => {
   return validation;
   return validation;
 };
 };
 
 
+// 拖拽开始处理
+const handleDragStart = (evt: any) => {
+  drag.value = true;
+  console.log('开始拖拽题目:', evt);
+};
+
+// 拖拽结束处理
+const handleDragEnd = (evt: any) => {
+  drag.value = false;
+  console.log('拖拽结束:', evt);
+  console.log('当前题目顺序:', chatQuestions.value);
+  
+  // 这里可以调用API保存新的题目顺序
+  // await saveQuestionOrder(chatQuestions.value);
+  
+  ElMessage.success('题目顺序已更新');
+};
+
 // 获取完整的面试配置信息
 // 获取完整的面试配置信息
 const getCompleteInterviewConfig = () => {
 const getCompleteInterviewConfig = () => {
   return {
   return {
@@ -3361,9 +3392,44 @@ const handleCompetencyChange = (item: any, val: boolean) => {
   }
   }
 };
 };
 
 
+// 删除选中的胜任力标签
+const removeSelectedAbility = (index: number) => {
+  ElMessageBox.confirm('确认删除这个胜任力标签吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    // 获取被删除的能力标签
+    const removedAbility = selectedAbilities.value[index];
+    
+    // 从 selectedAbilities 数组中移除
+    selectedAbilities.value.splice(index, 1);
+    
+    // 同时从 selectedDimensions 数组中移除对应项
+    selectedDimensions.value = selectedDimensions.value.filter(
+      dimension => dimension.name !== removedAbility.label
+    );
+    
+    // 更新对应的checkbox状态 - 将对应的competencyTags项的selected设为false
+    const competencyTag = competencyTags.value.find((tag: any) => tag.name === removedAbility.label);
+    if (competencyTag) {
+      competencyTag.selected = false;
+    }
+    
+    ElMessage.success('胜任力标签已删除');
+  }).catch(() => {
+    // 用户取消删除
+  });
+};
+
 // 在 script setup 部分添加以下代码
 // 在 script setup 部分添加以下代码
 const selectedDimensions = ref<Array<{name: string, description: string}>>([]);
 const selectedDimensions = ref<Array<{name: string, description: string}>>([]);
 
 
+// 创建延迟函数
+const delay = (ms: number): Promise<void> => {
+  return new Promise(resolve => setTimeout(resolve, ms));
+};
+
 // 在 script setup 中添加以下内容
 // 在 script setup 中添加以下内容
 // 题目选择相关的响应式变量
 // 题目选择相关的响应式变量
 const showQuestionSelectDialog = ref(false);
 const showQuestionSelectDialog = ref(false);
@@ -3846,17 +3912,54 @@ const saveBeforeStart = async () => {
   }
   }
   
   
   interviewSettings.beforeStartText = editingBeforeStartText.value.trim();
   interviewSettings.beforeStartText = editingBeforeStartText.value.trim();
-  const response = await UpdateConfig({
-    id:getConfigId.value,
-    digital_human_opening_speech:editingBeforeStartText.value.trim()
-  })
-  if(response.code==2000){
-    ElMessage.success('开始前提示内容已更新');
-    isEditingBeforeStart.value = false;
-  }else{
-    ElMessage.error('开始前提示内容更新失败');
-  }
   
   
+  try {
+    let response;
+      console.log(getConfigId.value);
+    // 根据getConfigId的值决定调用哪个接口
+    if (getConfigId.value == 0) {
+      // getConfigId不等于0时,调用CreateConfig接口
+      response = await CreateConfig({
+        position_id: route.query.id,
+        digital_human_opening_speech: editingBeforeStartText.value.trim()
+      });
+      
+      if (response.code === 2000) {
+        // 创建成功后更新getConfigId
+        getConfigId.value = response.data?.id || response.data;
+        ElMessage.success('开始前提示内容已创建');
+        isEditingBeforeStart.value = false;
+      } else {
+        ElMessage.error('开始前提示内容创建失败');
+      }
+    } else {
+      // getConfigId等于0时,调用UpdateConfig接口
+      response = await UpdateConfig({
+        id: getConfigId.value,
+        digital_human_opening_speech: editingBeforeStartText.value.trim()
+      });
+      
+      if (response.code === 2000) {
+        ElMessage.success('开始前提示内容已更新');
+        isEditingBeforeStart.value = false;
+        
+        // 调用GetOpeningSpeech接口
+        try {
+          const params = { config_id: getConfigId.value };
+          await GetOpeningSpeech(params);
+          console.log('开场白生成成功');
+        } catch (error) {
+          console.error('获取开场白失败:', error);
+          ElMessage.warning('开场白生成中,请稍后');
+        }
+      } else {
+        ElMessage.error('开始前提示内容更新失败');
+      }
+    }
+  } catch (error) {
+    console.error('保存开始前提示内容失败:', error);
+    ElMessage.error('保存失败,请重试');
+  }
 };
 };
 
 
 // 开始后提醒编辑方法
 // 开始后提醒编辑方法
@@ -3952,21 +4055,58 @@ const saveDisclaimer = () => {
   &:hover {
   &:hover {
     box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
     box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
   }
   }
+}
 
 
-  .drag-handle {
-    position: absolute;
-    left: -20px;
-    top: 50%;
-    transform: translateY(-50%);
-    cursor: move;
-    color: #909399;
-    padding: 4px;
-    
-    &:hover {
-      color: #409EFF;
+/* 拖拽状态样式 */
+.sortable-ghost {
+  opacity: 0.5;
+  background: #f5f7fa;
+  border: 2px dashed #c0c4cc;
+}
+
+// .sortable-chosen {
+//   cursor: grabbing;
+//   transform: rotate(5deg);
+// }
+
+.sortable-drag {
+  cursor: grabbing;
+  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+  transform: rotate(5deg);
+}
+
+  .question-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-start;
+    margin-bottom: 12px;
+
+    .question-title {
+      display: flex;
+      align-items: flex-start;
+      gap: 12px;
+      flex: 1;
+
+
+      .title-content {
+        flex: 1;
+        display: flex;
+        align-items: flex-start;
+        gap: 10px;
+        flex-direction: column;
+
+        .question-number {
+          color: #909399;
+          font-size: 12px;
+        }
+      }
+    }
+
+    .question-actions {
+      display: flex;
+      gap: 4px;
     }
     }
   }
   }
-}
 
 
 .question-info {
 .question-info {
   .info-item {
   .info-item {
@@ -3982,17 +4122,7 @@ const saveDisclaimer = () => {
     }
     }
   }
   }
 }
 }
-.question-title {
-  font-weight: 500;
-  display: flex;
-    align-items: flex-start;
-    gap: 10px;
-    flex-direction: column;
-  .question-number {
-    color: #909399;
-    margin-right: 8px;
-  }
-}
+
 
 
 .field-config-panel {
 .field-config-panel {
   background: #fff;
   background: #fff;

+ 4 - 4
src/views/questionBank/list/crud.tsx

@@ -49,7 +49,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 		// 如果更新成功且题目形式为0(开放题)或5,异步触发视频生成
 		// 如果更新成功且题目形式为0(开放题)或5,异步触发视频生成
 		if (editResult.code === 2000 && (form.question_form === 0 || form.question_form === 5)) {
 		if (editResult.code === 2000 && (form.question_form === 0 || form.question_form === 5)) {
 			// 使用 setTimeout 将视频生成请求放入下一个事件循环
 			// 使用 setTimeout 将视频生成请求放入下一个事件循环
-			setTimeout(async () => {
+			/* setTimeout(async () => {
 				try {
 				try {
 					// 构造视频生成请求参数
 					// 构造视频生成请求参数
 					const videoParams = {
 					const videoParams = {
@@ -89,7 +89,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 						message: '数字人视频生成失败,但题目已成功更新'
 						message: '数字人视频生成失败,但题目已成功更新'
 					});
 					});
 				}
 				}
-			}, 0);
+			}, 0); */
 		}
 		}
 
 
 		return editResult;
 		return editResult;
@@ -121,7 +121,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 		// 如果添加成功且题目形式为0(开放题)或5,异步触发视频生成
 		// 如果添加成功且题目形式为0(开放题)或5,异步触发视频生成
 		if (addResult.code === 2000 && (form.question_form === 0 || form.question_form === 5)) {
 		if (addResult.code === 2000 && (form.question_form === 0 || form.question_form === 5)) {
 			// 使用 setTimeout 将视频生成请求放入下一个事件循环
 			// 使用 setTimeout 将视频生成请求放入下一个事件循环
-			setTimeout(async () => {
+			/* setTimeout(async () => {
 				try {
 				try {
 					// 构造视频生成请求参数
 					// 构造视频生成请求参数
 					const videoParams = {
 					const videoParams = {
@@ -161,7 +161,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 						message: '数字人视频生成失败,但题目已成功保存'
 						message: '数字人视频生成失败,但题目已成功保存'
 					});
 					});
 				}
 				}
-			}, 0);
+			}, 0); */
 		}
 		}
 
 
 		return addResult;
 		return addResult;