Browse Source

修改部分bug

yangg 6 days ago
parent
commit
2f83da793d

+ 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 = 'https://backend.qicai321.com'
 # 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'

+ 23 - 4
src/views/JobApplication/list/components/smSnotification.vue

@@ -411,10 +411,29 @@ const handleSend = async () => {
     );
     
     if (response.data.code === 2000) {
-      ElMessage.success('通知发送成功');
-      dialogVisible.value = false;
-      emit('success');
-      props.crudExpose.doRefresh();
+      // 发送短信成功后,更新状态为已通知待面试
+      try {
+        const updateData = {
+          application_ids: form.application_ids,
+          new_status: 1, // 1: 已通知待面试
+          note: '已发送面试通知短信',
+          tenant_id: Session.get('tenant_id')
+        };
+        
+        const updateRes = await updateBatchStatus(updateData);
+        
+        if (updateRes.code === 2000) {
+          ElMessage.success('通知发送成功,状态已更新');
+          dialogVisible.value = false;
+          emit('success');
+          props.crudExpose.doRefresh();
+        } else {
+          ElMessage.warning('通知发送成功,但状态更新失败');
+        }
+      } catch (error) {
+        console.error('状态更新失败:', error);
+        ElMessage.warning('通知发送成功,但状态更新失败');
+      }
     } else {
       ElMessage.error(response.data.msg || '发送失败');
     }

+ 16 - 2
src/views/JobApplication/list/index.vue

@@ -97,7 +97,7 @@
 </template>
 
 <script lang="ts" setup name="areas">
-import { onMounted, ref, reactive } from 'vue';
+import { onMounted, ref, reactive, computed } from 'vue';
 import { useFs } from '@fast-crud/fast-crud';
 import { createCrudOptions } from './crud';
 import { GetPermission } from './api';
@@ -144,6 +144,12 @@ const statusCounts = reactive<Record<number, number>>({
 
 // 职位列表
 const showPositionList = ref(true);
+
+const getStepStyle = computed(() => (step: { name: string }) => {
+    return {
+        marginLeft: (step.name === '已通过' || step.name === '已淘汰') ? '32px' : '0'
+    };
+});
 const positions = ref<Array<{id: number|string, title: string, count?: number}>>([]);
 
 // 获取职位列表
@@ -393,8 +399,14 @@ const getPositionList = async () => {
 	padding: 10px 16px;
 	cursor: pointer;
 	transition: background-color 0.3s;
+	width: 185px;
 }
-
+.item-content span{
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		width: 100%;
+	}
 .tree-item:hover {
 	background-color: #f5f7fa;
 }
@@ -409,6 +421,8 @@ const getPositionList = async () => {
 	display: flex;
 	align-items: center;
 	gap: 8px;
+	min-width: 0;
+	flex: 1;
 }
 
 .item-count {

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

@@ -285,14 +285,14 @@ const handleVideoSuccess = (res: any, file: any) => {
 // 视频上传前验证
 const beforeVideoUpload = (file: any) => {
 	const isMp4 = file.type === 'video/mp4';
-	const isLt50M = file.size / 1024 / 1024 < 50;
+	const isLt50M = file.size / 1024 / 1024 < 20;
 
 	if (!isMp4) {
 		ElMessage.error('请上传MP4格式的视频文件!');
 		return false;
 	}
 	if (!isLt50M) {
-		ElMessage.error('上传视频大小不能超过 50MB!');
+		ElMessage.error('上传视频大小不能超过 20MB!');
 		return false;
 	}
 	return true;
@@ -329,7 +329,7 @@ const submitForm = async () => {
 		crudExpose.doRefresh();
 	} catch (error) {
 		console.error('表单提交错误:', error);
-		ElMessage.error('提交失败,请检查表单信息');
+		/* ElMessage.error('请检查表单信息'); */
 	}
 };
 
@@ -482,6 +482,7 @@ const getStyleName = (style: string) => {
 }
 
 .video-uploader {
+	height: 132px;
 	text-align: center;
 	border: 1px dashed #d9d9d9;
 	border-radius: 6px;

+ 22 - 2
src/views/position/detail/index.css

@@ -1801,6 +1801,26 @@
   }
   
   .custom-switch {
-    margin-left: auto;
-  }
+  margin-left: auto;
+}
+
+.salary-range-container {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  width: 100%;
+}
+
+.salary-type-select {
+  width: 120px;
+}
+
+.salary-input {
+  width: 150px;
+}
+
+.salary-separator {
+  color: #606266;
+  margin: 0 5px;
+}
 }

+ 92 - 30
src/views/position/detail/index.vue

@@ -100,12 +100,38 @@
             </el-button>
           </div>
           <div class="title-edit-container" v-else>
-            <el-input 
-              v-model="editingSalary" 
-              placeholder="请输入职位薪资" 
-              maxlength="30"
-              show-word-limit
-            />
+            <div class="salary-range-container">
+              <el-select 
+                v-model="editingSalaryType" 
+                placeholder="薪资类型" 
+                class="salary-type-select"
+                @change="updateSalaryRange"
+              >
+                <el-option label="月薪" value="月薪" />
+                <el-option label="年薪" value="年薪" />
+                <el-option label="日薪" value="日薪" />
+                <el-option label="时薪" value="时薪" />
+              </el-select>
+              <el-input-number
+                v-model="editingStartSalary" 
+                placeholder="起始薪资" 
+                class="salary-input"
+                type="number"
+                controls-position="right"
+                min="0"
+                @input="updateSalaryRange"
+              />
+              <span class="salary-separator">-</span>
+              <el-input-number
+                v-model="editingEndSalary" 
+                placeholder="最高薪资" 
+                class="salary-input"
+                controls-position="right"
+                type="number"
+                min="0"
+                @input="updateSalaryRange"
+              />
+            </div>
             <div class="title-edit-actions">
               <el-button size="small" @click="cancelEditSalary">取消</el-button>
               <el-button size="small" type="primary" @click="saveSalary">保存</el-button>
@@ -207,9 +233,9 @@
           <div class="title-edit-container" v-else>
             <el-date-picker
               v-model="editingEndDate"
-              type="date"
-              placeholder="请选择截止日期"
-              value-format="YYYY-MM-DD HH:mm:ss"
+              type="datetime"
+                placeholder="请选择截止日期"
+            value-format="YYYY-MM-DD HH:mm:ss"
               style="width: 100%"
             />
             <div class="title-edit-actions">
@@ -360,7 +386,8 @@
               :class="{ 'disabled': !step.active }"
               v-show="step.visible"
             >
-              <div class="step-number">{{ getVisibleStepNumber(index) }}</div>
+              <div class="step-number" v-if="step.name!='已通过' && step.name!='已淘汰'" 
+              >{{ getVisibleStepNumber(index) }}</div>
               <div class="step-content">
                 <div class="step-title">{{ step.name }}</div>
                 <!-- <div class="step-desc">{{ step.description }}</div> -->
@@ -398,17 +425,17 @@
             class="process-edit-item"
             :class="{ 'highlight': step.active }"
           >
-            <div class="process-number">{{ getVisibleStepNumber(index) }}</div>
+            <div class="process-number" v-if="step.name!='已通过' && step.name!='已淘汰'">{{ getVisibleStepNumber(index) }}</div>
             <div class="process-edit-content">
               <div>{{ step.name }}</div>
-              <div class="process-edit-desc">{{ step.description }}</div>
+              <!-- <div class="process-edit-desc">{{ step.description }}</div> -->
             </div><!--  v-if="step.name=='AI考察'" -->
             <div class="process-edit-btn" v-if="step.name!='已通过' && step.name!='已淘汰'">
                <el-button 
                 type="info" 
                 size="small" 
                 plain 
-                
+                v-if="step.name!='简历收集'"
                 @click="editProcessStep(step, index)"
               >
                 修改
@@ -1245,15 +1272,14 @@
           </el-select>
           <div class="form-tip">选择题目的形式:开放问题、单选题、多选题、填空题、自言语</div>
         </div>
-
+<!--  :disabled="true" -->
         <div class="form-item">
           <div class="form-label">适用职位</div>
           <el-select
-            v-model="questionForm.position"
+            v-model="positionId"
             placeholder="请选择适用职位类型"
             class="full-width"
-            :disabled="true"
-            multiple
+           :disabled="true"
           >
             <el-option 
               v-for="pos in positionOptions" 
@@ -1719,6 +1745,7 @@
             placeholder="请输入步骤名称"
             maxlength="30"
             show-word-limit
+            :disabled="true"
                   />
                 </div>
         
@@ -2009,7 +2036,7 @@
                 <el-input
                   v-model="editingBeforeStartText"
                   type="textarea"
-                  rows="2"
+                  rows="5"
                   maxlength="150"
                   placeholder="请输入开始前提示内容"
                   
@@ -2796,13 +2823,7 @@ const getcompetency_tags = (value:any)=>{
 const competencyTagOptions = ref<CompetencyTag[]>([]);
 
 // 职位类型选项
-const positionOptions = ref([
-  { label: '后端开发', value: 'backend' },
-  { label: '前端开发', value: 'frontend' },
-  { label: '产品经理', value: 'product_manager' },
-  { label: '项目经理', value: 'project_manager' },
-  { label: '测试工程师', value: 'test_engineer' }
-]);
+const positionOptions = ref([]);
 
 // 题目分类选项
 const categoryOptions = ref([
@@ -2841,6 +2862,21 @@ const resetQuestionForm = () => {
   });
 };
 
+/* 获取职位列表 */
+const getPosList = async () => {
+  const response = await api.GetList({
+    page: 1,
+    page_size: 50
+  });
+  console.log(response);
+  positionOptions.value = response.data.map((item:any)=>{
+    return {
+      label: item.title,
+      value: String(item.id)
+    }
+  })
+}
+
 // 取消添加问题
 const cancelAddQuestion = () => {
   showQuestionDialog.value = false;
@@ -3362,7 +3398,8 @@ const addSelectedStepType = async (type: string, label: string) => {
   
   // 添加视频宣讲类型的处理
   if (type === 'video_presentation') {
-    showVideoLectureConfig();
+    confirmResumeCollection();
+
     showOptionsMenu.value = false;
     return;
   }
@@ -4049,6 +4086,7 @@ onMounted(() => {
   getPositionDetail();
   getCompetencyList();
   getDigitalList();
+  getPosList()
   // 初始化配置状态
   initializeConfigState();
 });
@@ -4369,11 +4407,27 @@ const saveLocation = async () => {
 
 // 职位薪资编辑
 const isEditingSalary = ref(false);
-const editingSalary = ref('');
+const editingSalaryType = ref('月薪');
+const editingStartSalary = ref(0);
+const editingEndSalary = ref(0);
 
 // 开始编辑职位薪资
 const startEditSalary = () => {
-  editingSalary.value = positionData.salary_range || '';
+  if (positionData.salary_range) {
+    const parts = positionData.salary_range.split(' ');
+    if (parts.length >= 2) {
+      editingSalaryType.value = parts[0];
+      const range = parts[1].split('-');
+      if (range.length === 2) {
+        editingStartSalary.value = parseInt(range[0]) || 0;
+        editingEndSalary.value = parseInt(range[1]) || 0;
+      }
+    }
+  } else {
+    editingSalaryType.value = '月薪';
+    editingStartSalary.value = 0;
+    editingEndSalary.value = 0;
+  }
   isEditingSalary.value = true;
 };
 
@@ -4382,17 +4436,25 @@ const cancelEditSalary = () => {
   isEditingSalary.value = false;
 };
 
+// 更新薪资范围
+const updateSalaryRange = () => {
+  if (editingStartSalary.value > editingEndSalary.value && editingEndSalary.value !== 0) {
+    editingStartSalary.value = editingEndSalary.value;
+  }
+};
+
 // 保存职位薪资
 const saveSalary = async () => {
   try {
     const id = route.query.id;
+    const salaryRange = `${editingSalaryType.value} ${editingStartSalary.value}-${editingEndSalary.value}`;
     await api.UpdateObj({
       id: id,
-      salary_range: editingSalary.value.trim()
+      salary_range: salaryRange
     });
     
     // 更新本地数据
-    positionData.salary_range = editingSalary.value.trim();
+    positionData.salary_range = salaryRange;
     isEditingSalary.value = false;
     ElMessage.success('职位薪资已更新');
   } catch (error) {

+ 20 - 5
src/views/questionBank/list/crud.tsx

@@ -667,14 +667,16 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 					search: { show: false },
 					column: { show: false },
 					form: {
-						show: compute(({ form }) => {
-							// 只有当选择了胜任力标签时才显示配置
+						show: compute(({ form, mode }) => {
+							// 只有在编辑模式下且选择了胜任力标签时才显示配置
+							form.mode= mode
 							return form && form.competency_tags && form.competency_tags.length > 0;
 						}),
 						component: {
 							name: 'el-card',
 							children: {
 								default: ({ form }: { form: any }) => {
+									console.log(form)
 									// 确保competency_tags_config数组已初始化
 									if (!form.competency_tags_config) {
 										form.competency_tags_config = [];
@@ -739,7 +741,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 									// 渲染表格
 									return (
 										<div>
-											<el-table border style="width: 100%" data={form.competency_tags_config}>
+											<el-table border style="width: 100%" disabled={form.mode} data={form.competency_tags_config}>
 												<el-table-column label="标签" width="200">
 													{{
 														default: ({ row }: { row: any }) => (
@@ -750,6 +752,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 												<el-table-column label="权重" width="100">
 													{{
 														default: ({ row }: { row: any }) => (
+															
 															<div class="weight-input" style="display: flex; align-items: center;">
 																<el-input-number 
 																	v-model={row.weight} 
@@ -759,6 +762,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 																	precision={0}
 																	controls={false}
 																	style="width: calc(100% - 20px)"
+																	disabled={form.mode === 'view'}
 																/>
 																<span style="margin-left: 4px;">%</span>
 															</div>
@@ -773,6 +777,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 																min={1}
 																controls={false}
 																style="width: 100%"
+																disabled={form.mode === 'view'}
 															/>
 														)
 													}}
@@ -1227,8 +1232,9 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 					}),
 					form: {
 						value: false,
-						show: compute(({ form }) => {
+						show: compute(({ form ,mode}) => {
 							// 只有单选题和多选题才显示红线问题选项
+							form.mode= mode
 							return form && (form.question_form === 1 || form.question_form === 2);
 						}),
 						component: {
@@ -1259,7 +1265,8 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 					search: { show: false },
 					column: { show: false },
 					form: {
-						show: compute(({ form }) => {
+						show: compute(({ form ,mode}) => {
+							form.mode= mode
 							return form && (form.question_form === 1 || form.question_form === 2 || form.question_form === 4);
 						}),
 						component: {
@@ -1285,6 +1292,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 															v-model={option.option_text} 
 															placeholder="请输入选项内容" 
 															style="flex: 1; margin-right: 10px;"
+															disabled={form.mode === 'view'}
 														/>
 														<el-input-number
 															v-model={option.score}
@@ -1292,6 +1300,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 															max={10}
 															style="width: 120px;"
 															placeholder="分值"
+															disabled={form.mode === 'view'}
 														/>
 													</div>
 												))}
@@ -1306,6 +1315,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 																Math.max(...form.options.map((o: any) => o.sort || 0)) + 1 : 1;
 															form.options.push({ option_text: '', score: 0, sort });
 														}}
+														disabled={form.mode === 'view'}
 													>
 														添加选项
 													</el-button>
@@ -1313,6 +1323,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 													{form.options.length > 2 && (
 														<el-button 
 															type="danger" 
+															disabled={form.mode === 'view'}
 															onClick={() => {
 																form.options.pop();
 															}}
@@ -1338,11 +1349,13 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 														v-model={option.option_text} 
 														placeholder="请输入选项内容" 
 														style="flex: 1; margin-right: 10px;"
+														disabled={form.mode === 'view'}
 													/>
 													<el-tooltip 
 														content="设置为正确答案" 
 														placement="top" 
 														effect="light"
+														disabled={form.mode === 'view'}
 													>
 														<div 
 															onClick={() => {
@@ -1377,6 +1390,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 											<div style="display: flex; justify-content: space-between; margin-top: 10px;">
 												<el-button 
 													type="primary" 
+													disabled={form.mode === 'view'}
 													onClick={() => {
 														// 确保options数组已初始化
 														if (!form.options) {
@@ -1394,6 +1408,7 @@ export const createCrudOptions = function ({ crudExpose, context }: CreateCrudOp
 												{form.options.length > 2 && (
 													<el-button 
 														type="danger" 
+														disabled={form.mode === 'view'}
 														onClick={() => {
 															form.options.pop();
 														}}

+ 3 - 0
src/views/questionBank/positionList/components/DocumentTreeCom/index.vue

@@ -144,12 +144,15 @@ defineExpose({
   flex: 1;
   min-width: 0;
   position: relative;
+  width:130px;
   
   .ml-2 {
     overflow: hidden;
     white-space: nowrap;
     text-overflow: ellipsis;
     flex: 1;
+    margin-right: 8px;
+    
   }
 }
 

+ 4 - 4
src/views/questionBank/positionList/components/editor.vue

@@ -305,14 +305,14 @@ const fetchQuestionDetail = async (id: string | number) => {
       questionForm.content = questionData.question || '';
       questionForm.type = questionData.question_form === 1 ? 'single' : 
                         questionData.question_form === 2 ? 'multiple' : 'open';
-      questionForm.position = questionData.positions || [];
+      questionForm.position = questionData.position_types || [];
       questionForm.category = questionData.category_id || '';
       questionForm.tags = questionData.tags || [];
       const competencyTags = questionData.competency_tags || [];
       questionForm.competency_tags = competencyTags;
       questionForm.options = questionData.options || [];
       questionForm.question_form = questionData.question_form;
-      questionForm.suggestedDuration = questionData.duration || 0;
+      questionForm.suggestedDuration = questionData.recommended_duration || 0;
       questionForm.scoring_reference = questionData.scoring_reference || '';
       
       // 更新胜任力标签选择
@@ -550,10 +550,10 @@ const confirmAddQuestion = async () => {
       id: props.questionId,
       question: questionForm.content,
       question_form: questionForm.question_form,
-      positions: questionForm.position,
+      position_types: questionForm.position,
       category_id: questionForm.category,
       tags: questionForm.tags,
-      competency_tag_info: questionForm.competency_tags,
+      competency_tags: questionForm.competency_tags,
       options: questionForm.options,
       recommended_duration: questionForm.suggestedDuration,
       scoring_reference: questionForm.scoring_reference

+ 11 - 1
src/views/talent/list/index.vue

@@ -293,7 +293,7 @@ const handleNodeClick = (data: any) => {
 		// 按职位筛选
 		crudExpose.doSearch({
 			form: {
-				position_title: data.value
+				title: data.value
 			}
 		});
 	}
@@ -418,7 +418,14 @@ onMounted(async () => {
 	padding: 10px 16px;
 	cursor: pointer;
 	transition: background-color 0.3s;
+	width: 185px;
 }
+.item-content span{
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		width: 100%;
+	}
 
 .tree-item:hover {
 	background-color: #f5f7fa;
@@ -434,6 +441,8 @@ onMounted(async () => {
 	display: flex;
 	align-items: center;
 	gap: 8px;
+	min-width: 0;
+	flex: 1;
 }
 
 .item-count {
@@ -463,6 +472,7 @@ onMounted(async () => {
 }
 
 .position-list {
+	width: 100%;
 	padding-left: 8px;
 }
 

+ 1 - 1
src/views/talent/overseas/components/BatchStatusDialog.vue

@@ -10,7 +10,7 @@
       <el-form-item label="选择状态">
         <el-select v-model="form.status" placeholder="请选择状态" style="width: 100%">
           <el-option label="曾就职" :value="6" />
-          <el-option label="转入在外人才库" :value="7" />
+          <el-option label="拒不录用" :value="7" />
           <el-option label="待面试" :value="0" />
           <el-option label="已面试" :value="1" />
           <el-option label="已录用" :value="2" />

+ 1 - 1
src/views/talent/overseas/crud.tsx

@@ -631,7 +631,7 @@ export const createCrudOptions = function ({ crudExpose, context}: CreateCrudOpt
 							{ value: 4, label: '已离职' },
 							{ value: 5, label: '在职已盘点' }, */
 							{ value: 6, label: '曾就职' },
-							{ value: 7, label: '转入在外人才库' },
+							{ value: 7, label: '拒不录用' },
 						
 						]
 					}),

+ 12 - 2
src/views/talent/overseas/index.vue

@@ -57,7 +57,7 @@
 					<div class="tree-item" :class="{ active: activeNode === 'status-7' }" @click="handleNodeClick({ type: 'status', value: 6, id: 'status-7' })">
 						<div class="item-content">
 							<el-icon><RefreshRight /></el-icon>
-							<span>面试未通过</span>
+							<span>拒不录用</span>
 						</div>
 						<div class="item-count" v-if="statusCounts['6']">{{ statusCounts['6'] }}</div>
 					</div>
@@ -225,7 +225,7 @@ const handleNodeClick = (data: any) => {
 	} else if (data.type === 'position') {
 		crudExpose.doSearch({
 			form: {
-				position_title: data.value
+				title: data.value
 			}
 		});
 	}
@@ -316,7 +316,14 @@ onMounted(async () => {
 	padding: 10px 16px;
 	cursor: pointer;
 	transition: background-color 0.3s;
+	width: 185px;
 }
+.item-content span{
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		width: 100%;
+	}
 
 .tree-item:hover {
 	background-color: #f5f7fa;
@@ -332,6 +339,8 @@ onMounted(async () => {
 	display: flex;
 	align-items: center;
 	gap: 8px;
+	min-width: 0;
+	flex: 1;
 }
 
 .item-count {
@@ -361,6 +370,7 @@ onMounted(async () => {
 }
 
 .position-list {
+	width: 100%;
 	padding-left: 8px;
 }