Преглед на файлове

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/views/system/workroomTeacher/dept/index.vue
ydmyzx преди 4 месеца
родител
ревизия
c44b1f257d

+ 6 - 0
src/api/system/supervisorSelectionSetting/index.ts

@@ -45,7 +45,13 @@ export const supervisorSelectionSettingApi = {
     return await request.download({ url: `/system/supervisor-selection-setting/export-excel`, params })
   },
 
+  // 导师这个项目的设置信息
   getSupervisorInfo: async (supervisorId: number, projectId: number) => {
     return await request.get({url: `/system/supervisor-selection-setting/getSupervisorInfo?supervisorId=${supervisorId}&projectId=${projectId}`});
+  },
+
+  // 获取登录导师的设置信息
+  getLoginSupervisorInfo: async () => {
+    return await request.get({url: `/system/supervisor-selection-setting/getLoginSupervisorInfo`});
   }
 }

+ 16 - 0
src/router/modules/remaining.ts

@@ -5,6 +5,7 @@ import deptInfo from '@/views/system/workroomCollege/deptInfo/index.vue'
 import * as LoginApi from '@/api/login'
 import supervisorSelectionSetting from "@/views/system/supervisorSelectionSetting/index.vue";
 import studentSelectSupervisorRecord from "@/views/system/studentSelection/studentSelectSupervisorRecord/index.vue";
+import studentSelectSupervisorRecord2 from "@/views/system/studentSelection/studentSelectSupervisorRecord/record.vue";
 import studentForm from "@/views/system/userDetail/student.vue";
 
 const { t } = useI18n()
@@ -90,6 +91,21 @@ const remainingRouter: AppRouteRecordRaw[] = [
         }
       },
 
+      {
+        path: 'studentSelection/studentSelectSupervisorRecord/record',
+        component: studentSelectSupervisorRecord2,
+        name: 'studentSelectSupervisorRecord2',
+        meta: {
+          title: '师生互选记录2',
+          icon: 'ep:user-filled',
+          noCache: false,
+          affix: false,
+          breadcrumb: false,
+          noTagsView: false,
+          hidden: true
+        }
+      },
+
 
       {
         path: 'supervisorSelectionSetting/index',

+ 2 - 1
src/views/system/studentSelection/studentSelectSupervisorRecord/record.vue

@@ -108,7 +108,7 @@
         </el-form>
         <el-button type="primary" @click="exportWordTemplate" :loading="exportLoading" v-if="userInfo.userType==='1'">导出互选表</el-button>
       </ContentWrap>
-    
+
       <ContentWrap v-if="userInfo.userType==='1' ||userInfo.userType==='4'" >
         <el-table
           v-loading="loading"
@@ -235,6 +235,7 @@ defineOptions({ name: 'RecordList' })
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 
+
 const loading = ref(true) // 列表的加载中
 const isLoading = ref(false)
 const total = ref(0) // 列表的总页数

+ 30 - 4
src/views/system/studentSelection/studentSelectSupervisorRecord/studentSelectSupervisorRecordForm.vue

@@ -38,6 +38,13 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row>
+          <el-col :span="24"> 
+            <el-form-item label="学生简历">
+              <el-button v-model="studentData.introduction" type="text" @click="handleDownload" style="text-align: right;">预览 PDF</el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
       </div>
 
       <!-- 学生志愿 -->
@@ -237,6 +244,7 @@ const studentData = ref({
   userNumber:"",
   major:"",
   mobile:"",
+  introduction:"",
 })
 const formRules = reactive({
   // projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }],
@@ -339,6 +347,7 @@ const open = async (type: string, projectId?: number, supervisorId?:number, id?:
         studentData.value.userNumber=result.userNumber
         studentData.value.major=result.major
         studentData.value.mobile=result.mobile
+        studentData.value.introduction=result.introduction
         const supervisor = await supervisorSelectionSettingApi.getSupervisorInfo(supervisorId,projectId);
         //显示的
         supervisorData.value.nickname = supervisor.supervisorName;
@@ -364,6 +373,7 @@ const open = async (type: string, projectId?: number, supervisorId?:number, id?:
     if (id) {
       formLoading.value = true
       try {
+        formData.value.id = id
         formData.value = await studentSelectSupervisorRecordApi.getStudentSelectSupervisorRecord(id)
         formData.value.selectType = selectType
         console.log(formData.value,'formData.value');
@@ -397,7 +407,7 @@ const open = async (type: string, projectId?: number, supervisorId?:number, id?:
         studentData.value.userNumber=result.userNumber
         studentData.value.major=result.major
         studentData.value.mobile=result.mobile
-
+        studentData.value.introduction=result.introduction
         // const supervisor = await supervisorSelectionSettingApi.getSupervisorInfo(supervisorId,projectId);
         // //显示的
         // supervisorData.value.nickname = supervisor.supervisorName;
@@ -417,6 +427,7 @@ const open = async (type: string, projectId?: number, supervisorId?:number, id?:
     submitFormText.value = '编辑'
     formType.value = type
     resetForm()
+    console.log(id);
     if (studentId) {
       formLoading.value = true
       try {
@@ -426,6 +437,7 @@ const open = async (type: string, projectId?: number, supervisorId?:number, id?:
         studentData.value.userNumber=result.userNumber
         studentData.value.major=result.major
         studentData.value.mobile=result.mobile
+        studentData.value.introduction=result.introduction
         // formData.value.supervisorId = result.supervisorId
       } finally {
         formLoading.value = false
@@ -434,9 +446,8 @@ const open = async (type: string, projectId?: number, supervisorId?:number, id?:
     if(id) {
       formLoading.value = true
       try {
-        formData.value = await studentSelectSupervisorRecordApi.getStudentSelectSupervisorRecord(id)
         formData.value.id = id
-        // formData.value.selectType = selectType
+        formData.value = await studentSelectSupervisorRecordApi.getStudentSelectSupervisorRecord(id)
         console.log(formData.value,'formData.value');
       } finally {
         formLoading.value = false
@@ -459,6 +470,7 @@ const open = async (type: string, projectId?: number, supervisorId?:number, id?:
         studentData.value.userNumber=result.userNumber
         studentData.value.major=result.major
         studentData.value.mobile=result.mobile
+        studentData.value.introduction=result.introduction
       } finally {
         formLoading.value = false
       }
@@ -466,7 +478,6 @@ const open = async (type: string, projectId?: number, supervisorId?:number, id?:
     if(id) {
       formLoading.value = true
       try {
-        // formData.value.selectType = selectType
         formData.value = await studentSelectSupervisorRecordApi.getStudentSelectSupervisorRecord(id)
         console.log(formData.value,'formData.value');
       } finally {
@@ -496,6 +507,7 @@ const open = async (type: string, projectId?: number, supervisorId?:number, id?:
         studentData.value.userNumber=result.userNumber
         studentData.value.major=result.major
         studentData.value.mobile=result.mobile
+        studentData.value.introduction=result.introduction
         const supervisor = await supervisorSelectionSettingApi.getSupervisorInfo(supervisorId,projectId);
         //显示的
         supervisorData.value.nickname = supervisor.supervisorName;
@@ -644,6 +656,20 @@ const handleSupervisorSignatureSave = () => {
     console.warn('Canvas element is not initialized yet');
   }
 };
+const handleDownload = () => {
+  const url = studentData.value.introduction;
+    if (url) {
+      const link = document.createElement('a');
+      link.href = url;
+      link.download = '学生简历';
+      link.target = '_blank';
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+    } else {
+      console.error('地址无效');
+    }
+};
 
 // defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 /** 提交表单 */

+ 23 - 3
src/views/system/studentSelection/studentSelectionNo/index.vue

@@ -91,9 +91,15 @@
           <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_SELECT_RECORD_SELECT_STATUS" :value="scope.row.selectStatus" />
         </template>
       </el-table-column>
-      <el-table-column label="照片" align="center" prop="photoUrl">
+      <el-table-column label="学生简历" align="center" prop="introduction">
         <template #default="scope">
-          <img :src="scope.row.photoUrl" class="w-100px h-100px" />
+          <el-button
+            v-if="scope.row.introduction"
+            type="text"
+            @click="handleDownload(scope.row)"
+          >
+            预览简历
+          </el-button>
         </template>
       </el-table-column>
       <el-table-column label="操作" align="center">
@@ -219,11 +225,25 @@ const resetQuery = () => {
   handleQuery()
 }
 
-const formRef = ref(); // 确保初始化为 null
+const formRef = ref();
 const openForm = (type: string, projectId?: number, supervisorId?:number, id?:number, studentId?:number, selectType?:number) => {
   formRef.value.open(type, projectId, supervisorId, id, studentId, selectType)
 }
 
+const handleDownload = (row) => {
+  const url = row.introduction;
+    if (url) {
+      const link = document.createElement('a');
+      link.href = url;
+      link.download = '学生简历';
+      link.target = '_blank';
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+    } else {
+      console.error('下载地址无效');
+    }
+};
 
 onMounted(() => {
   getUnPassList()

+ 93 - 3
src/views/system/studentSelection/studentSelectionProject/index.vue

@@ -102,6 +102,72 @@
     </el-form>
   </ContentWrap>
 
+  <ContentWrap v-if="userInfo?.userType === '3' || userInfo?.userType === '5'">
+    <el-table v-loading="loading" :data="oneList">
+      <el-table-column label="导师姓名" align="center" prop="supervisorName"/>
+      <el-table-column label="招生指标" align="center">
+        <template #default="scope">
+          学硕/{{ scope.row.academicSlots }} 专硕/{{ scope.row.professionalSlots }}
+        </template>
+      </el-table-column>
+      <el-table-column label="已招生名额" align="center" min-width="90px">
+        <template #default="scope">
+          <span>
+            <span v-if="scope.row.occupiedAcademicSlots">
+              学硕/{{ scope.row.occupiedAcademicSlots }}
+            </span>
+            <span v-if="scope.row.occupiedProfessionalSlots">
+              专硕/{{ scope.row.occupiedProfessionalSlots }}
+            </span>
+            <span v-if="!scope.row.occupiedAcademicSlots && !scope.row.occupiedProfessionalSlots">
+              暂无
+            </span>
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column label="剩余名额" align="center" min-width="100px">
+        <template #default="scope">
+          学硕/{{ scope.row.academicSlots - scope.row.occupiedAcademicSlots }} 专硕/{{ scope.row.professionalSlots - scope.row.occupiedProfessionalSlots }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="更新时间"
+        align="center"
+        prop="updateTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column label="导师详情" align="center">
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openTeacherRequireForm('update', scope.row.supervisorId, scope.row.userType)"
+            v-hasPermi="['system:user:query']"
+          >
+            <Icon icon="ep:bell" />
+            编辑
+          </el-button>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" min-width="120px" >
+        <template #default="scope">
+          <!--学院查看招生详情-->
+          <el-button
+            type="text"
+            @click="openStudentSelectSupervisorRecord2(scope.row.projectId,scope.row.supervisorId)"
+            v-hasPermi="['system:student-select-supervisor-record:query']"
+          >
+            <Icon icon="ep:bell" />
+            招生详情
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </ContentWrap>
+  <!-- 导师详情弹窗-->
+  <teacherRequireForm ref="teacherRequireFormRef"/>
+
   <!-- 列表 -->
   <ContentWrap>
     <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
@@ -232,14 +298,26 @@ const getList = async () => {
   try {
     const data = await studentSelectionProjectApi.getStudentSelectionProjectPage(queryParams)
     list.value = data.list
-    console.log(data.list);
-    
+    // console.log(data.list);
     total.value = data.total
   } finally {
     loading.value = false
   }
 }
 
+const oneList = ref([])
+const getOneList = async () => {
+  loading.value = true
+  try {
+    const data = await supervisorSelectionSettingApi.getLoginSupervisorInfo();
+    oneList.value = Array.isArray(data) ? data : [data];
+    console.log("oneList",oneList.value);
+  } finally {
+    loading.value = false
+  }
+}
+
+
 //获取登录人员信息
 const userInfo = ref({} as ProfileVO)
 const getUserInfo = async () => {
@@ -319,6 +397,10 @@ const openStudentSelectSupervisorRecord = (id) => {
 
 
 
+// 招生详情
+const openStudentSelectSupervisorRecord2 = (projectId,supervisorId) => {
+  router.push({ name: 'studentSelectSupervisorRecord', query: { projectId: projectId ,supervisorId :supervisorId} });
+}
 const openSupervisorSelectionSetting = (id) => {
   router.push({ name: 'supervisorSelectionSetting', query: { projectId: id} });
 }
@@ -328,7 +410,7 @@ const handleSwitchChange = async (id: number, field: string, value: number) => {
   if (!isPopDataLoaded.value) return; // 如果尚未加载弹窗数据,阻止更新
   try {
     popData.value[field] = value;
-    console.log(popData.value)
+    // console.log(popData.value)
     updateIsPop(popData.value); // 确保传递的是popData.value
     message.success(t('common.updateSuccess'));
   } catch (error) {
@@ -347,6 +429,11 @@ const getPopDataFunction = async () => {
   }
 }
 
+const teacherRequireFormRef = ref()
+const openTeacherRequireForm = ( supervisorId?: number, userType?: string) => {
+  teacherRequireFormRef.value.open("update",supervisorId,userType)
+}
+
 /** 初始化 **/
 onMounted(async () => {
   getList();
@@ -354,6 +441,9 @@ onMounted(async () => {
   if (userInfo.value.userType === '4') {
     getPopDataFunction();
   }
+  if (userInfo.value.userType === '3' || userInfo.value.userType === '5') {
+    await getOneList();
+  }
 });
 </script>
 

+ 27 - 4
src/views/system/studentSelection/studentSelectionYes/index.vue

@@ -95,9 +95,15 @@
           <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_SELECT_RECORD_SELECT_STATUS" :value="scope.row.selectStatus" />
         </template>
       </el-table-column>
-      <el-table-column label="照片" align="center" prop="photoUrl">
+      <el-table-column label="学生简历" align="center" prop="introduction">
         <template #default="scope">
-          <img :src="scope.row.photoUrl" class="w-100px h-100px" />
+          <el-button
+            v-if="scope.row.introduction"
+            type="text"
+            @click="handleDownload(scope.row)"
+          >
+            预览简历
+          </el-button>
         </template>
       </el-table-column>
       <el-table-column label="操作" align="center">
@@ -212,10 +218,27 @@ const resetQuery = () => {
 }
 
 const formRef = ref(); // 确保初始化为 null
-const openForm = (type: string, projectId?: number, supervisorId?:number, recordId?:number, studentId?:number, selectType?:number) => {
-  formRef.value.open(type, projectId, supervisorId, recordId, studentId, selectType)
+const openForm = (type: string, projectId?: number, supervisorId?:number, id?:number, studentId?:number, selectType?:number) => {
+  formRef.value.open(type, projectId, supervisorId, id, studentId, selectType)
 }
 
+const handleDownload = (row) => {
+  // window.open(url, '_blank');
+  const url = row.introduction;
+    if (url) {
+      // 创建一个 a 标签并模拟点击,实现下载
+      const link = document.createElement('a');
+      link.href = url;
+      link.download = '学生简历'; // 提示浏览器下载文件
+      link.target = '_blank'; // 在新标签页打开链接
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+    } else {
+      console.error('下载地址无效');
+    }
+};
+
 onMounted(() => {
   getPassList()
   getSupervisor()

+ 69 - 46
src/views/system/supervisorSelectionSetting/index.vue

@@ -140,8 +140,8 @@
         </template>
       </el-table-column>
 
-      <!--  学生志愿填报-->
-      <el-table-column label="志愿填报" align="center" min-width="120px"  v-if=" userInfo?.userType === '1'">
+      <!--  学生志愿填报 -->
+      <el-table-column label="志愿填报" align="center" min-width="120px"  v-if=" userInfo?.userType === '1' && selectStatus.value === 0">
         <template #default="scope">
           <el-button
             type="primary"
@@ -155,6 +155,20 @@
           </el-button>
         </template>
       </el-table-column>
+      <!--  学生志愿填报后直接跳转记录页面 -->
+      <el-table-column label="详情" align="center" min-width="120px"  v-if=" userInfo?.userType === '1' && selectStatus.value !== 0">
+        <template #default="scope">
+          <el-button
+            type="primary"
+            link
+            @click="openRecord()"
+            v-if="scope.row.selectType"
+          >
+            <Icon icon="ep:bell" />
+            详情
+          </el-button>
+        </template>  
+      </el-table-column>
 
 
       <el-table-column label="操作" align="center" min-width="120px" v-if="userInfo?.userType === '4'" >
@@ -317,6 +331,10 @@ const router = useRouter();
 const openStudentSelectSupervisorRecord = (projectId,supervisorId) => {
   router.push({ name: 'studentSelectSupervisorRecord', query: { projectId: projectId ,supervisorId :supervisorId} });
 }
+const openRecord = () => {
+  router.push({ name: 'studentSelectSupervisorRecord2' });
+}
+
 
 //导师类型
 const userTypeFormatter = (row, column, cellValue, index) => {
@@ -351,6 +369,17 @@ const getUserInfo = async () => {
   // console.log("userInfo",userInfo.value);
 }
 
+const selectStatus = ref()
+const getUser = async () => {
+  if (!userInfo.value || !userInfo.value.id) {
+    console.error('用户信息未加载,无法获取用户');
+    return; // 提前返回,避免后续错误
+  }
+  const result = await UserApi.getUser(userInfo.value.id)
+  selectStatus.value = result.selectStatus
+  // console.log("selectStatus",selectStatus.value);
+}
+
 /** 搜索按钮操作 */
 const handleQuery = () => {
   queryParams.pageNo = 1
@@ -414,12 +443,6 @@ const openTeacherRequireForm = (supervisorId?: number, userType?: string) => {
   teacherRequireFormRef.value.open("detail",supervisorId,userType)
 }
 
-const selectStatus = ref()
-const getUser = async () => {
-  const result = await UserApi.getUser(userInfo.value.id)
-  selectStatus.value = result.selectStatus
-  // console.log("selectStatus",selectStatus.value);
-}
 //志愿填报弹窗
 const studentSelectSupervisorPop= ref()
 const openStudentSelectSupervisorPop = async (type: string,id:number,studentId:number,projectId?: number,supervisorId? :number) => {
@@ -431,50 +454,50 @@ const openStudentSelectSupervisorPop = async (type: string,id:number,studentId:n
   } 
 }
 
-const recordData = ref({
-  id: undefined,
-  projectId: undefined,
-  studentId: undefined,
-  supervisorId: undefined,
-  selectType: undefined,
-  studentSignature: "",
-  supervisorApproveTime: undefined,
-  supervisorSignature: "",
-  externalSupervisorId: undefined,
-  masterType:undefined,
-  studentSignDate:[],
-  supervisorSignDate:[],
-})
-const handelWithdraw = async (projectId:number,supervisorId:number) => {
-  try {
-    await message.confirm('是否确定撤回申请?')
-    recordData.value.supervisorId=supervisorId
-    recordData.value.projectId=projectId
-    const data =recordData.value as unknown as studentSelectSupervisorRecordVO
-    await studentSelectSupervisorRecordApi.withdrawStudentSelectSupervisorRecord(data)
-    message.success("撤回了申请")
-    await getList()
-  } catch {}
-}
-
-const selectionList = ref<studentSelectSupervisorRecordVO[]>([]) //下面的选择记录列表
-/** 查询互选记录列表 */
-const getRecordList = async () => {
-  loading.value = true
-  try {
-    const data = await studentSelectSupervisorRecordApi.getSelectSupervisorRecordList()
-    selectionList.value = data
-  } finally {
-    loading.value = false
-  }
-}
+// const recordData = ref({
+//   id: undefined,
+//   projectId: undefined,
+//   studentId: undefined,
+//   supervisorId: undefined,
+//   selectType: undefined,
+//   studentSignature: "",
+//   supervisorApproveTime: undefined,
+//   supervisorSignature: "",
+//   externalSupervisorId: undefined,
+//   masterType:undefined,
+//   studentSignDate:[],
+//   supervisorSignDate:[],
+// })
+// const handelWithdraw = async (projectId:number,supervisorId:number) => {
+//   try {
+//     await message.confirm('是否确定撤回申请?')
+//     recordData.value.supervisorId=supervisorId
+//     recordData.value.projectId=projectId
+//     const data =recordData.value as unknown as studentSelectSupervisorRecordVO
+//     await studentSelectSupervisorRecordApi.withdrawStudentSelectSupervisorRecord(data)
+//     message.success("撤回了申请")
+//     await getList()
+//   } catch {}
+// }
+
+// const selectionList = ref<studentSelectSupervisorRecordVO[]>([]) //下面的选择记录列表
+// /** 查询互选记录列表 */
+// const getRecordList = async () => {
+//   loading.value = true
+//   try {
+//     const data = await studentSelectSupervisorRecordApi.getSelectSupervisorRecordList()
+//     selectionList.value = data
+//   } finally {
+//     loading.value = false
+//   }
+// }
 
 /** 初始化 **/
 onMounted(async () => {
   getList()
   await getUserInfo()
   getSupervisor()
-  await getRecordList()
+  // await getRecordList()
   getUser()
 })
 </script>

+ 27 - 2
src/views/system/workroomTeacher/dept/index.vue

@@ -96,7 +96,7 @@
       <student :id="form.id" />
     </div>
   </div>
- 
+
 </template>
 
 <script lang="ts">
@@ -107,6 +107,7 @@ import { useI18n } from 'vue-i18n';
 import { useMessage } from '@/hooks/web/useMessage';
 import { updateDept, DeptVO, getUserDept } from '@/api/system/dept/index';
 import * as UserApi from '@/api/system/user'
+import { getUserProfile, ProfileVO } from '@/api/system/user/profile';
 import DeptForm from './DeptForm.vue';
 import student from './student.vue';
 import teacher from './teacher.vue';
@@ -118,6 +119,20 @@ export default defineComponent({
     teacher,
   },
   setup() {
+    const user = ref({ dept: null });
+    // 获取登陆人员的信息
+    const getUser = async () => {
+      try {
+        loading.value = true;
+        const res = await getUserProfile();
+        user.value = res;
+        console.log('获取用户信息成功:', user.value);
+      } catch (error) {
+        console.error('获取用户信息失败:', error);
+      } finally {
+        loading.value = false;
+      }
+    };
     const { t } = useI18n();
     const message = useMessage();
     const loading = ref(true) // 列表的加载中
@@ -169,7 +184,7 @@ export default defineComponent({
     });
 
     // 将 userInfo 定义放入 setup 中
-    const userInfo = ref({} as DeptVO);  
+    const userInfo = ref({} as DeptVO);
     const fetchUserInfo = async () => {
       try{
         loading.value = true; // 开始加载状态
@@ -284,6 +299,7 @@ const fetchImageUrls = async () => {
     };
 
     onMounted(async () => {
+      await getUser();
       await init();
       await fetchUserInfo();
       // getSupervisor();
@@ -311,6 +327,15 @@ const fetchImageUrls = async () => {
       extractedImageUrls,
       
     };
+  },
+  data(){
+    return {
+      user: {
+        value: {
+          dept: null // 或任何你想要初始化的值
+        }
+      },
+    };
   }
 });