Ver código fonte

Merge branch 'master' of http://gogs.gisvg.com/YDM/graduate-ui

# Conflicts:
#	src/views/system/Home/Index.vue
lmm 3 semanas atrás
pai
commit
cea8773075

+ 70 - 0
src/api/system/studentSelectSupervisorRecord/index.ts

@@ -0,0 +1,70 @@
+import request from '@/config/axios'
+
+// 师生互选记录 VO
+export interface studentSelectSupervisorRecordVO {
+  id: number // 选择id,自增
+  projectId: number // 项目id
+  studentId: number // 学生id
+  supervisorId: number // 校内导师id
+  selectType: number // 选择状态(0编辑(撤回),1待处理,2同意,3退回)
+  studentSignature: string // 学生电子签名
+  supervisorApproveTime: Date // 导师审批时间
+  supervisorSignature: string // 导师电子签名
+  externalSupervisorId: number // 校外导师id
+  masterType:number//硕士类型
+  agreeDate:Date//同意日期
+  supervisorType:string//导师类型
+}
+
+// 师生互选记录 API
+export const studentSelectSupervisorRecordApi = {
+  // 查询师生互选记录分页
+  getStudentSelectSupervisorRecordPage: async (params: any) => {
+    return await request.get({ url: `/system/student-select-supervisor-record/page`, params })
+  },
+
+  getSelectSupervisorRecordList: async (params: any) => {
+    return await request.get({ url: `/system/student-select-supervisor-record/getRecordList`,params})
+  },
+
+  // 查询师生互选记录详情
+  getStudentSelectSupervisorRecord: async (id: number) => {
+    return await request.get({ url: `/system/student-select-supervisor-record/get?id=` + id })
+  },
+
+  // 新增师生互选记录
+  createStudentSelectSupervisorRecord: async (data: studentSelectSupervisorRecordVO) => {
+    return await request.post({ url: `/system/student-select-supervisor-record/create`, data })
+  },
+
+  // 修改师生互选记录
+  updateStudentSelectSupervisorRecord: async (data: studentSelectSupervisorRecordVO) => {
+    return await request.put({ url: `/system/student-select-supervisor-record/update`, data })
+  },
+
+  // 删除师生互选记录
+  deleteStudentSelectSupervisorRecord: async (id: number) => {
+    return await request.delete({ url: `/system/student-select-supervisor-record/delete?id=` + id })
+  },
+
+  // 导出师生互选记录 Excel
+  exportStudentSelectSupervisorRecord: async (params) => {
+    return await request.download({ url: `/system/student-select-supervisor-record/export-excel`, params })
+  },
+
+  //通过
+  agreeStudentSelectSupervisorRecord: async (data: studentSelectSupervisorRecordVO) => {
+    return await request.put({ url: `/system/student-select-supervisor-record/agree`, data })
+  },
+
+  //退回
+  refuseStudentSelectSupervisorRecord: async (data: studentSelectSupervisorRecordVO) => {
+    return await request.put({ url: `/system/student-select-supervisor-record/refuse`, data })
+  },
+  //撤回
+  withdrawStudentSelectSupervisorRecord: async (data: studentSelectSupervisorRecordVO) => {
+    return await request.put({ url: `/system/student-select-supervisor-record/withdraw`, data })
+  },
+
+
+}

+ 45 - 0
src/api/system/studentSelectionProject/index.ts

@@ -0,0 +1,45 @@
+import request from '@/config/axios'
+
+// 师生互选项目 VO
+export interface studentSelectionProjectVO {
+  id: number // 项目id
+  projectName: string // 项目名称
+  studentStartTime: Date // 学生开始时间
+  supervisorConfirmDeadline: Date // 导师截止时间
+  studentGrade: string // 学生年级
+  isSupervisor: number,
+  isStudent: number,
+}
+
+// 师生互选项目 API
+export const studentSelectionProjectApi = {
+  // 查询师生互选项目分页
+  getStudentSelectionProjectPage: async (params: any) => {
+    return await request.get({ url: `/system/student-selection-project/page`, params })
+  },
+
+  // 查询师生互选项目详情
+  getStudentSelectionProject: async (id: number) => {
+    return await request.get({ url: `/system/student-selection-project/get?id=` + id })
+  },
+
+  // 新增师生互选项目
+  createStudentSelectionProject: async (data: studentSelectionProjectVO) => {
+    return await request.post({ url: `/system/student-selection-project/create`, data })
+  },
+
+  // 修改师生互选项目
+  updateStudentSelectionProject: async (data: studentSelectionProjectVO) => {
+    return await request.put({ url: `/system/student-selection-project/update`, data })
+  },
+
+  // 删除师生互选项目
+  deleteStudentSelectionProject: async (id: number) => {
+    return await request.delete({ url: `/system/student-selection-project/delete?id=` + id })
+  },
+
+  // 导出师生互选项目 Excel
+  exportStudentSelectionProject: async (params) => {
+    return await request.download({ url: `/system/student-selection-project/export-excel`, params })
+  },
+}

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

@@ -0,0 +1,47 @@
+import request from '@/config/axios'
+
+// 导师学硕专硕名额设置 VO
+export interface supervisorSelectionSettingVO {
+  id: number // 自增id
+  projectId: number // 项目id
+  supervisorId: number // 导师id
+  academicSlots: number // 学硕名额
+  professionalSlots: number // 专硕名额
+  supervisorName :string//导师姓名
+  userType:string;//导师类型
+  occupiedAcademicSlots:number//已招的学硕名额
+  occupiedProfessionalSlots:number//已招的专硕名额
+}
+
+// 导师学硕专硕名额设置 API
+export const supervisorSelectionSettingApi = {
+  // 查询导师学硕专硕名额设置分页
+  getSupervisorSelectionSettingPage: async (params: any) => {
+    return await request.get({ url: `/system/supervisor-selection-setting/page`, params })
+  },
+
+  // 查询导师学硕专硕名额设置详情
+  getSupervisorSelectionSetting: async (id: number) => {
+    return await request.get({ url: `/system/supervisor-selection-setting/get?id=` + id })
+  },
+
+  // 新增导师学硕专硕名额设置
+  createSupervisorSelectionSetting: async (data: supervisorSelectionSettingVO) => {
+    return await request.post({ url: `/system/supervisor-selection-setting/create`, data })
+  },
+
+  // 修改导师学硕专硕名额设置
+  updateSupervisorSelectionSetting: async (data: supervisorSelectionSettingVO) => {
+    return await request.put({ url: `/system/supervisor-selection-setting/update`, data })
+  },
+
+  // 删除导师学硕专硕名额设置
+  deleteSupervisorSelectionSetting: async (id: number) => {
+    return await request.delete({ url: `/system/supervisor-selection-setting/delete?id=` + id })
+  },
+
+  // 导出导师学硕专硕名额设置 Excel
+  exportSupervisorSelectionSetting: async (params) => {
+    return await request.download({ url: `/system/supervisor-selection-setting/export-excel`, params })
+  },
+}

+ 17 - 0
src/api/system/user/pop.ts

@@ -0,0 +1,17 @@
+import request from '@/config/axios'
+
+export interface PopDo {
+  id:number
+  isStudent :number
+  isSupervisor :number
+}
+
+// 查询弹窗信息
+export const getPopData = () => {
+  return request.get({ url: '/system/user/getPopData' })
+}
+
+// 更新是否弹窗信息
+export const updateIsPop = (data: PopDo) => {
+  return request.put({ url: '/system/user/updateIsPop', data })
+}

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

@@ -3,6 +3,8 @@ import UserAchievement from '@/views/system/workroomTeacher/userAchievement/inde
 import UserAchievementcopy from '@/views/system/workroomCollege/userAchievement/index.vue'
 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/studentSelectSupervisorRecord/index.vue";
 
 const { t } = useI18n()
 /**
@@ -56,6 +58,38 @@ const remainingRouter: AppRouteRecordRaw[] = [
       hidden: true
     },
     children: [
+
+      {
+        path: 'studentSelectSupervisorRecord/index',
+        component: studentSelectSupervisorRecord,
+        name: 'studentSelectSupervisorRecord',
+        meta: {
+          title: '师生互选记录',
+          icon: 'ep:user-filled',
+          noCache: false,
+          affix: false,
+          breadcrumb: false,
+          noTagsView: false,
+          hidden: true
+        }
+      },
+
+
+      {
+        path: 'supervisorSelectionSetting/index',
+        component: supervisorSelectionSetting,
+        name: 'supervisorSelectionSetting',
+        meta: {
+          title: '导师招生情况',
+          icon: 'ep:user-filled',
+          noCache: false,
+          affix: false,
+          breadcrumb: false,
+          noTagsView: false,
+          hidden: true
+        }
+      },
+
       {
         path: 'user-achievement',
         component: UserAchievement,

+ 2 - 0
src/utils/dict.ts

@@ -132,6 +132,8 @@ export enum DICT_TYPE {
   SYSTEM_STUDENT_ATTENDANCE_TYPE = 'system_student_attendance_type',// 学生考勤类型
   SYSTEM_STUDENT_FACE_TYPE = 'system_student_face_type',// 学生人脸导入类型
   SYSTEM_STUDENT_GRADUATE_STATUS = 'system_student_graduate_status',// 是否达成毕业条件
+  SYSTEM_STUDENT_MASTER_TYPE = 'system_student_master_type',
+  SYSTEM_STUDENT_SELECT_RECORD_SELECT_TYPE = 'system_student_select_record_select_type',
 
   // ========== INFRA 模块 ==========
   INFRA_BOOLEAN_STRING = 'infra_boolean_string',

+ 6 - 6
src/views/system/graduateStudent/UserForm.vue

@@ -63,11 +63,11 @@
         <el-col :span="12">
           <el-form-item label="硕士类型" prop="masterType">
             <!-- <el-input v-model="formData.masterType" placeholder="请输入学位类型" /> -->
-            <el-select v-model="formData.masterType" placeholder="请选择学位类型">
+            <el-select v-model="formData.masterType" placeholder="请选择硕士类型">
               <el-option
                 v-for="option in masterTypeOptions"
                 :key="option.value"
-                :label="option.value"
+                :label="option.label"
                 :value="option.value"
               />
             </el-select>
@@ -221,7 +221,7 @@ const formData = ref({
   supervisorMobile: '',
   workPlace:"",
   major: "",
-  masterType: "",
+  masterType: undefined,
 })
 const formRules = reactive<FormRules>({
   nickname: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
@@ -278,8 +278,8 @@ const majorOptions = [
 
 // 获取所有学位类型
 const masterTypeOptions = [
-  { value: '学硕' },
-  { value: '专硕' },
+  { value: 1, label:"学硕" },
+  { value: 2 , label:"专硕"},
 ]
 
 //获取所有导师
@@ -383,7 +383,7 @@ const resetForm = () => {
     supervisorMobile: '',
     workPlace:"",
     major: "",
-    masterType: "",
+    masterType: undefined,
   }
   formRef.value?.resetFields()
 }

+ 10 - 4
src/views/system/graduateStudent/index.vue

@@ -73,7 +73,7 @@
           <el-form-item label="硕士类型" prop="masterType"> 
             <el-select 
               v-model="queryParams.masterType" 
-              placeholder="请选择学位类型"
+              placeholder="请选择硕士类型"
               @change="handleSupervisorChange"
               clearable
               filterable
@@ -227,7 +227,13 @@
           <el-table-column label="年级" align="center" prop="grade" width="120" />
           <el-table-column label="学号" align="center" prop="userNumber" width="150" />
           <el-table-column label="专业" align="center" prop="major" width="120" />
-          <el-table-column label="硕士类型" align="center" prop="masterType" width="120" />
+
+            <el-table-column label="硕士类型" align="center" prop="masterType" width="120">
+              <template #default="scope">
+                <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_MASTER_TYPE" :value="scope.row.masterType" />
+              </template>
+            </el-table-column>
+
           <el-table-column label="手机号码" align="center" prop="mobile" width="120" />
           <el-table-column label="邮箱" align="center" prop="email" width="120" />
 
@@ -438,8 +444,8 @@ const majorOptions = [
 
 // 获取所有学位类型
 const masterTypeOptions = [
-  { value: '学硕' },
-  { value: '专硕' },
+  { value: '1' },
+  { value: '2' },
 ]
 
 // const NewList = (inputList) => {

+ 379 - 0
src/views/system/studentSelectSupervisorRecord/index.vue

@@ -0,0 +1,379 @@
+<template>
+  <ContentWrap>
+    <!-- 搜索工作栏 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="68px"
+    >
+<!--      <el-form-item label="项目id" prop="projectId">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.projectId"-->
+<!--          placeholder="请输入项目id"-->
+<!--          clearable-->
+<!--          @keyup.enter="handleQuery"-->
+<!--          class="!w-240px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="学生id" prop="studentId">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.studentId"-->
+<!--          placeholder="请输入学生id"-->
+<!--          clearable-->
+<!--          @keyup.enter="handleQuery"-->
+<!--          class="!w-240px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="校内导师id" prop="supervisorId">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.supervisorId"-->
+<!--          placeholder="请输入校内导师id"-->
+<!--          clearable-->
+<!--          @keyup.enter="handleQuery"-->
+<!--          class="!w-240px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+
+<!--      <el-form-item label="选择状态(0编辑(撤回),1待处理,2同意,3退回)" prop="selectType">-->
+<!--        <el-select-->
+<!--          v-model="queryParams.selectType"-->
+<!--          placeholder="请选择选择状态(0编辑(撤回),1待处理,2同意,3退回)"-->
+<!--          clearable-->
+<!--          class="!w-240px"-->
+<!--        >-->
+<!--          <el-option label="请选择字典生成" value="" />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="学生电子签名" prop="studnetSignature">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.studnetSignature"-->
+<!--          placeholder="请输入学生电子签名"-->
+<!--          clearable-->
+<!--          @keyup.enter="handleQuery"-->
+<!--          class="!w-240px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="创建时间" prop="createTime">-->
+<!--        <el-date-picker-->
+<!--          v-model="queryParams.createTime"-->
+<!--          value-format="YYYY-MM-DD HH:mm:ss"-->
+<!--          type="daterange"-->
+<!--          start-placeholder="开始日期"-->
+<!--          end-placeholder="结束日期"-->
+<!--          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"-->
+<!--          class="!w-220px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="导师审批时间" prop="supervisorApproveTime">-->
+<!--        <el-date-picker-->
+<!--          v-model="queryParams.supervisorApproveTime"-->
+<!--          value-format="YYYY-MM-DD HH:mm:ss"-->
+<!--          type="daterange"-->
+<!--          start-placeholder="开始日期"-->
+<!--          end-placeholder="结束日期"-->
+<!--          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"-->
+<!--          class="!w-220px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="导师电子签名" prop="supervisorSignature">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.supervisorSignature"-->
+<!--          placeholder="请输入导师电子签名"-->
+<!--          clearable-->
+<!--          @keyup.enter="handleQuery"-->
+<!--          class="!w-240px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="校外导师id" prop="externalSupervisorId">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.externalSupervisorId"-->
+<!--          placeholder="请输入校外导师id"-->
+<!--          clearable-->
+<!--          @keyup.enter="handleQuery"-->
+<!--          class="!w-240px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+      <el-form-item>
+<!--        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>-->
+<!--        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>-->
+<!--        <el-button-->
+<!--          type="primary"-->
+<!--          plain-->
+<!--          @click="openForm('create')"-->
+<!--          v-hasPermi="['system:student-select-supervisor-record:create']"-->
+<!--        >-->
+<!--          <Icon icon="ep:plus" class="mr-5px" /> 新增-->
+<!--        </el-button>-->
+        <el-button
+          type="success"
+          plain
+          @click="handleExport"
+          :loading="exportLoading"
+          v-hasPermi="['system:student-select-supervisor-record:export']"
+        >
+          <Icon icon="ep:download" class="mr-5px" /> 导出
+        </el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
+      <el-table-column type="index" width="50" />
+<!--      <el-table-column label="Id" align="center" prop="id" />-->
+<!--      <el-table-column label="项目id" align="center" prop="projectId" />-->
+      <el-table-column label="学生姓名" align="center" prop="studentName" />
+
+      <el-table-column label="硕士类型" align="center" prop="masterType" >
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_MASTER_TYPE" :value="scope.row.masterType" />
+        </template>
+      </el-table-column>
+
+      <el-table-column label="专业" align="center" prop="major" />
+
+      <el-table-column label="简历" align="center" prop="introduction" />
+
+      <el-table-column label="申请状态" align="center" prop="selectType" >
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_SELECT_RECORD_SELECT_TYPE" :value="scope.row.selectType" />
+        </template>
+      </el-table-column>
+      <el-table-column label="学生电子签名" align="center" prop="studentSignature" />
+      <el-table-column label="导师电子签名" align="center" prop="supervisorSignature" />
+      <el-table-column
+        label="提交时间"
+        align="center"
+        prop="createTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column
+        label="导师审批时间"
+        align="center"
+        prop="supervisorApproveTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+<!--      <el-table-column label="校外导师id" align="center" prop="externalSupervisorId" />-->
+      <el-table-column label="操作" align="center" min-width="120px">
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="handelAgree(scope.row.id)"
+            v-hasPermi="['system:student-select-supervisor-record:agree']"
+            v-if="userInfo?.userType === '3' &&scope.row.selectType ==1"
+          >
+            通过
+          </el-button>
+
+          <el-button
+            link
+            type="danger"
+            @click="handelRefuse(scope.row.id)"
+            v-hasPermi="['system:student-select-supervisor-record:refuse']"
+            v-if="userInfo?.userType === '3' &&scope.row.selectType ==1"
+          >
+            退回
+          </el-button>
+
+<!--          <el-button-->
+<!--            link-->
+<!--            type="primary"-->
+<!--            @click="openForm('update', scope.row.id)"-->
+<!--            v-hasPermi="['system:student-select-supervisor-record:update']"-->
+<!--          >-->
+<!--            编辑-->
+<!--          </el-button>-->
+
+<!--          <el-button-->
+<!--            link-->
+<!--            type="danger"-->
+<!--            @click="handleDelete(scope.row.id)"-->
+<!--            v-hasPermi="['system:student-select-supervisor-record:delete']"-->
+<!--          >-->
+<!--            删除-->
+<!--          </el-button>-->
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+
+  <!-- 表单弹窗:添加/修改 -->
+  <studentSelectSupervisorRecordForm ref="formRef" @success="getList" />
+</template>
+
+<script setup lang="ts">
+import { dateFormatter } from '@/utils/formatTime'
+import download from '@/utils/download'
+import { studentSelectSupervisorRecordApi, studentSelectSupervisorRecordVO } from '@/api/system/studentSelectSupervisorRecord'
+import studentSelectSupervisorRecordForm from './studentSelectSupervisorRecordForm.vue'
+import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
+import {useRoute} from "vue-router";
+import {ref} from "vue";
+import { DICT_TYPE } from '@/utils/dict'
+
+/** 师生互选记录 列表 */
+defineOptions({ name: 'studentSelectSupervisorRecord' })
+
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+
+const loading = ref(true) // 列表的加载中
+const list = ref<studentSelectSupervisorRecordVO[]>([]) // 列表的数据
+const total = ref(0) // 列表的总页数
+
+const selectionList = ref<studentSelectSupervisorRecordVO[]>([]) //下面的
+
+const route = useRoute()
+const supervisorId = route.query.supervisorId
+const projectId = route.query.projectId
+
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  projectId: projectId,
+  studentId: undefined,
+  supervisorId: supervisorId,
+  selectType: undefined,
+  studentSignature: undefined,
+  createTime: [],
+  supervisorApproveTime: [],
+  supervisorSignature: undefined,
+  externalSupervisorId: undefined,
+})
+
+const formData = ref({
+  id: undefined,
+  projectId: undefined,
+  studentId: undefined,
+  supervisorId: undefined,
+  selectType: undefined,
+  studentSignature: "",
+  supervisorApproveTime: undefined,
+  supervisorSignature: "",
+  externalSupervisorId: undefined,
+  masterType:undefined,
+  agreeDate:[]//同意日期
+})
+const queryFormRef = ref() // 搜索的表单
+const exportLoading = ref(false) // 导出的加载中
+
+//获取登录人员信息
+const userInfo = ref({} as ProfileVO)
+const getUserInfo = async () => {
+  const users = await getUserProfile()
+  userInfo.value = users
+}
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await studentSelectSupervisorRecordApi.getStudentSelectSupervisorRecordPage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (type: string, id?: number) => {
+  formRef.value.open(type, id)
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (id: number) => {
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    // 发起删除
+    await studentSelectSupervisorRecordApi.deleteStudentSelectSupervisorRecord(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 导出按钮操作 */
+const handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportLoading.value = true
+    const data = await studentSelectSupervisorRecordApi.exportStudentSelectSupervisorRecord(queryParams)
+    download.excel(data, '师生互选记录.xls')
+  } catch {
+  } finally {
+    exportLoading.value = false
+  }
+}
+
+const handelAgree = async (id:number) => {
+  console.log(id)
+  try {
+    await message.confirm()
+    formData.value.id=id
+    const data =formData.value as unknown as studentSelectSupervisorRecordVO
+    await studentSelectSupervisorRecordApi.agreeStudentSelectSupervisorRecord(data)
+    message.success("通过了申请")
+    await getList()
+  } catch {}
+}
+
+const handelRefuse = async (id:number) => {
+  try {
+    await message.confirm()
+    formData.value.id=id
+    const data =formData.value as unknown as studentSelectSupervisorRecordVO
+    await studentSelectSupervisorRecordApi.refuseStudentSelectSupervisorRecord(data)
+    message.success("拒绝了申请")
+    await getList()
+  } catch {}
+}
+
+/** 查询列表 */
+const getRecordList = async () => {
+  loading.value = true
+  try {
+    const data = await studentSelectSupervisorRecordApi.getSelectSupervisorRecordList(null)
+    selectionList.value = data.list
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 初始化 **/
+onMounted(() => {
+  getUserInfo()
+  getList()
+  getRecordList()
+})
+</script>

+ 180 - 0
src/views/system/studentSelectSupervisorRecord/record.vue

@@ -0,0 +1,180 @@
+<template>
+  <!--  是学生-->
+  <ContentWrap v-if="userInfo.userType==='1' ||userInfo.userType==='4'" >
+      <el-table
+        v-loading="loading"
+        :data="selectionList"
+        row-key="id"
+      >
+      <el-table-column type="index" width="50" />
+      <el-table-column label="学生姓名" align="center" prop="studentName" />
+      <el-table-column label="硕士类型" align="center" prop="masterType" >
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_MASTER_TYPE" :value="scope.row.masterType" />
+        </template>
+      </el-table-column>
+        <el-table-column label="导师姓名" align="center" prop="supervisor" />
+
+        <el-table-column
+          label="导师类型"
+          align="center"
+          prop="supervisorType"
+          :formatter="userTypeFormatter"
+        />
+
+<!--      <el-table-column label="简历" align="center" prop="introduction" />-->
+
+      <el-table-column label="申请状态" align="center" prop="selectType" >
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_SELECT_RECORD_SELECT_TYPE" :value="scope.row.selectType" />
+        </template>
+      </el-table-column>
+<!--      <el-table-column label="学生电子签名" align="center" prop="studentSignature" />-->
+<!--      <el-table-column label="导师电子签名" align="center" prop="supervisorSignature" />-->
+      <el-table-column
+        label="提交时间"
+        align="center"
+        prop="createTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column
+        label="导师审批时间"
+        align="center"
+        prop="supervisorApproveTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+    </el-table>
+  </ContentWrap>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { dateFormatter } from '@/utils/formatTime'
+import download from '@/utils/download'
+import { supervisorSelectionSettingApi, supervisorSelectionSettingVO } from '@/api/system/supervisorSelectionSetting'
+import * as UserApi from '@/api/system/user'
+import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
+import {
+  studentSelectSupervisorRecordApi,
+  studentSelectSupervisorRecordVO
+} from "@/api/system/studentSelectSupervisorRecord";
+import {DICT_TYPE} from "@/utils/dict";
+
+/** 导师学硕专硕名额设置 列表 */
+defineOptions({ name: 'recordList' })
+
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+
+const loading = ref(true) // 列表的加载中
+const list = ref<supervisorSelectionSettingVO[]>([]) // 列表的数据
+
+const total = ref(0) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  projectId: undefined,
+  supervisorId: undefined,
+  academicSlots: undefined,
+  professionalSlots: undefined,
+  supervisorName:undefined,
+  userType:undefined,
+  createTime: [],
+})
+const queryFormRef = ref() // 搜索的表单
+const exportLoading = ref(false) // 导出的加载中
+
+//记录页面
+const router = useRouter()
+const openStudentSelectSupervisorRecord = (projectId,supervisorId) => {
+  router.push({ name: 'studentSelectSupervisorRecord', query: { projectId: projectId ,supervisorId :supervisorId} });
+}
+
+//导师类型
+const userTypeFormatter = (row, column, cellValue, index) => {
+  switch (cellValue) {
+    case "3":
+      return '校内导师';
+    case "5":
+      return '校外导师';
+    default:
+      return '未知';
+  }
+};
+
+//获取登录人员信息
+const userInfo = ref({} as ProfileVO)
+const getUserInfo = async () => {
+  const users = await getUserProfile()
+  userInfo.value = users
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+//获取所有导师
+const supervisors = ref()
+const getSupervisor= async () => {
+  try {
+    const result = await UserApi.getSupervisor()
+    supervisors.value = result
+  } catch (error) {
+    console.error('未获取到导师', error)
+  }
+}
+
+const recordData = ref({
+  id: undefined,
+  projectId: undefined,
+  studentId: undefined,
+  supervisorId: undefined,
+  selectType: undefined,
+  studentSignature: "",
+  supervisorApproveTime: undefined,
+  supervisorSignature: "",
+  externalSupervisorId: undefined,
+  masterType:undefined,
+  agreeDate:[]//同意日期
+})
+const handelWithdraw = async (supervisorId:number) => {
+  try {
+    await message.confirm()
+    recordData.value.supervisorId=supervisorId
+    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(queryParams)
+    selectionList.value = data
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 初始化 **/
+onMounted(() => {
+  getList()
+  getUserInfo()
+  getSupervisor()
+  getRecordList()
+})
+</script>

+ 181 - 0
src/views/system/studentSelectSupervisorRecord/studentSelectSupervisorRecordForm.vue

@@ -0,0 +1,181 @@
+<template>
+  <Dialog :title="dialogTitle" v-model="dialogVisible">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="100px"
+      v-loading="formLoading"
+    >
+      <el-row>
+        <el-col :span="12" >
+          <el-form-item label="导师姓名" prop="nickname">
+            <el-input v-model="formData.nickname" placeholder="请输入姓名" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" v-if="formType === 'detail'">
+          <el-form-item label="职称" prop="">
+            <el-input model-value="导师"  />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row >
+        <el-col :span="12">
+          <el-form-item label="" prop="major">
+            <el-input v-model="formData.major" placeholder="导师暂未填写" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="对研究生毕业的成果要求" prop="studentAchievementRequirement">
+            <Editor v-model="formData.studentAchievementRequirement" ref="editorRef"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+<!--      &lt;!&ndash; 学生电子签名 &ndash;&gt;-->
+<!--      <el-form-item label="学生电子签名" prop="studentSignature">-->
+<!--        <vue-esign ref="studentSignaturePad" :width="400" :height="200" @save="handleStudentSignatureSave" />-->
+<!--      </el-form-item>-->
+
+<!--      &lt;!&ndash; 导师电子签名 &ndash;&gt;-->
+<!--      <el-form-item label="导师电子签名" prop="supervisorSignature">-->
+<!--        <vue-esign ref="supervisorSignaturePad" :width="400" :height="200" @save="handleSupervisorSignatureSave" />-->
+<!--      </el-form-item>-->
+
+    </el-form>
+    <template #footer>
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+      <button @click="saveSupervisorSignature">保存签名</button>
+    </template>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+import { studentSelectSupervisorRecordApi, studentSelectSupervisorRecordVO } from '@/api/system/studentSelectSupervisorRecord'
+import { CommonStatusEnum } from '@/utils/constants'
+import * as UserApi from '@/api/system/user'
+import { defineOptions, defineExpose, ref, reactive } from 'vue'
+import {data} from "autoprefixer";
+
+/** 师生互选记录 表单 */
+defineOptions({ name: 'studentSelectSupervisorRecordForm' })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const formData = ref({
+  id: undefined,
+  projectId: undefined,
+  studentId: undefined,
+  supervisorId: undefined,
+  selectType: undefined,
+  studentSignature: "",
+  supervisorApproveTime: undefined,
+  supervisorSignature: "",
+  externalSupervisorId: undefined,
+
+  //导师的
+  nickname: '',
+  remark: ' ',
+  major:'',
+  studentAchievementRequirement:"",
+})
+const formRules = reactive({
+  // projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }],
+  // studentId: [{ required: true, message: '学生id不能为空', trigger: 'blur' }],
+})
+const supervisorSignaturePad = ref(null);
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+
+const open = async (type: string, projectId?: number ,supervisorId?:number) => {
+  dialogVisible.value = true
+  dialogTitle.value = "志愿填报"
+  formType.value = type
+  resetForm()
+  // 修改时,设置数据
+  if (supervisorId) {
+    formLoading.value = true
+    try {
+      console.log(supervisorId)
+      const user = await UserApi.getUser(supervisorId);
+      // formData.value = await studentSelectSupervisorRecordApi.getstudentSelectSupervisorRecord(id)
+      console.log(user)
+      formData.value.supervisorId =supervisorId;
+      formData.value.projectId = projectId;
+      formData.value.nickname = user.nickname;
+      formData.value.studentAchievementRequirement = user.studentAchievementRequirement;
+      formData.value.major = user.major;
+    } finally {
+      formLoading.value = false
+    }
+  }
+}
+
+const handleStudentSignatureSave = (data: string) => {
+  console.log("Student Signature Data:", data); // 调试输出签名数据
+  formData.value.studentSignature = data;  // 保存学生签名数据
+};
+
+const handleSupervisorSignatureSave = (data: string) => {
+  console.log("Supervisor Signature Data:", data); // 调试输出签名数据
+  formData.value.supervisorSignature = data;  // 保存导师签名数据
+};
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  await formRef.value.validate();
+
+  // 在提交前检查签名数据
+  // if (!formData.value.studentSignature) {
+  //   message.warning("请签署学生电子签名!");
+  //   return;
+  // }
+  formLoading.value = true;
+  try {
+    const data = formData.value as unknown as studentSelectSupervisorRecordVO;
+    if (formType.value === 'create') {
+      await studentSelectSupervisorRecordApi.createStudentSelectSupervisorRecord(data);
+      message.success(t('common.createSuccess'));
+    } else {
+      await studentSelectSupervisorRecordApi.updateStudentSelectSupervisorRecord(data);
+      message.success(t('common.updateSuccess'));
+    }
+    dialogVisible.value = false;
+    emit('success');
+  } finally {
+    formLoading.value = false;
+  }
+};
+
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    id: undefined,
+    projectId: undefined,
+    studentId: undefined,
+    supervisorId: undefined,
+    selectType: undefined,
+    studentSignature: "",
+    supervisorApproveTime: undefined,
+    supervisorSignature: "",
+    externalSupervisorId: undefined,
+  }
+  formRef.value?.resetFields()
+}
+</script>
+

+ 353 - 0
src/views/system/studentSelectionProject/index.vue

@@ -0,0 +1,353 @@
+<template>
+  <!-- 弹窗开关 -->
+  <el-form
+    class="switch-form"
+    :inline="true"
+    label-width="200px"
+  >
+    <el-form-item label="是否开启导师弹窗"  v-if="userInfo?.userType === '4' || userInfo?.userType ==null ">
+      <el-switch v-model="popData.isSupervisor" :active-value="1" :inactive-value="0" @change="(val) => handleSwitchChange(popData.id, 'isSupervisor', val)" />
+    </el-form-item>
+
+    <el-form-item label="是否开启学生弹窗"  v-if="userInfo?.userType === '4'">
+      <el-switch v-model="popData.isStudent" :active-value="1" :inactive-value="0" @change="(val) => handleSwitchChange(popData.id, 'isStudent', val)" />
+    </el-form-item>
+  </el-form>
+
+  <ContentWrap>
+    <!-- 搜索工作栏 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="100px"
+    >
+      <el-form-item label="项目名称" prop="projectName">
+        <el-input
+          v-model="queryParams.projectName"
+          placeholder="请输入项目名称"
+          clearable
+          @keyup.enter="handleQuery"
+          class="!w-240px"
+        />
+      </el-form-item>
+      <el-form-item label="学生开始时间" prop="studentStartTime">
+        <el-date-picker
+          v-model="queryParams.studentStartTime"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="datetime"
+          placeholder="选择学生开始时间"
+          class="!w-220px"
+        />
+      </el-form-item>
+      <el-form-item label="导师截止时间" prop="supervisorConfirmDeadline">
+        <el-date-picker
+          v-model="queryParams.supervisorConfirmDeadline"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="datetime"
+          placeholder="选择导师截止时间"
+          clearable
+          class="!w-220px"
+        />
+      </el-form-item>
+      <el-form-item label="参与学生年级" prop="studentGrade">
+        <el-select
+          v-model="queryParams.studentGrade"
+        placeholder="请选择参与学生年级"
+        clearable
+        @change="handleQuery"
+        class="!w-240px"
+        >
+        <el-option
+          v-for="year in gradeOptions"
+          :key="year"
+          :label="year"
+          :value="year"
+        />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="创建时间" prop="createTime">
+        <el-date-picker
+          v-model="queryParams.createTime"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="daterange"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
+          class="!w-220px"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button
+          type="primary"
+          plain
+          @click="openForm('create')"
+          v-hasPermi="['system:student-selection-project:create']"
+        >
+          <Icon icon="ep:plus" class="mr-5px" /> 新增
+        </el-button>
+        <el-button
+          type="success"
+          plain
+          @click="handleExport"
+          :loading="exportLoading"
+          v-hasPermi="['system:student-selection-project:export']"
+        >
+          <Icon icon="ep:download" class="mr-5px" /> 导出
+        </el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
+      <el-table-column type="index" width="50" />
+      <el-table-column label="项目名称" align="center" prop="projectName" />
+      <el-table-column
+        label="学生开始时间"
+        align="center"
+        prop="studentStartTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column
+        label="导师截止时间"
+        align="center"
+        prop="supervisorConfirmDeadline"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column label="参与学生年级" align="center" prop="studentGrade" />
+      <el-table-column
+        label="创建时间"
+        align="center"
+        prop="createTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+
+      <el-table-column label="操作" align="center" min-width="120px">
+        <template #default="scope">
+<!--          校内导师查看项目详情,互选记录-->
+          <el-button type="text" v-if="userInfo?.userType === '3'" @click="openStudentSelectSupervisorRecord(scope.row.id)" v-hasPermi="['system:student-select-supervisor-record:query']">
+          <Icon icon="ep:bell" />
+           详情
+          </el-button>
+
+<!--          学院或者学生查看详情,导师名额设置页面-->
+          <el-button type="text"  v-if="userInfo?.userType === '4' || userInfo?.userType === '1'" @click="openSupervisorSelectionSetting(scope.row.id)" v-hasPermi="['system:supervisor-selection-setting:query']" >
+            <Icon icon="ep:bell" />
+            详情
+          </el-button>
+
+          <el-button
+            link
+            type="primary"
+            @click="openForm('update', scope.row.id)"
+            v-hasPermi="['system:student-selection-project:update']"
+            v-if="userInfo?.userType === '4'"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="handleDelete(scope.row.id)"
+            v-hasPermi="['system:student-selection-project:delete']"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <studentSelectionProjectForm ref="formRef" @success="getList" />
+</template>
+
+<script setup lang="ts">
+import { dateFormatter } from '@/utils/formatTime'
+import download from '@/utils/download'
+import { studentSelectionProjectApi, studentSelectionProjectVO } from '@/api/system/studentSelectionProject'
+import studentSelectionProjectForm from './studentSelectionProjectForm.vue'
+import { ref } from 'vue'
+import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
+import { getPopData, updateIsPop,PopDo } from '@/api/system/user/pop'
+
+/** 师生互选项目 列表 */
+defineOptions({ name: 'studentSelectionProject' })
+
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+
+const isPopDataLoaded = ref(false); // 标志,用于防止初始时更新
+const popData = ref<PopDo>({
+  id: 1,
+  isStudent: undefined,
+  isSupervisor: undefined
+});
+
+const loading = ref(true) // 列表的加载中
+const list = ref<studentSelectionProjectVO[]>([]) // 列表的数据
+const total = ref(0) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  projectName: undefined,
+  studentStartTime: [],
+  supervisorConfirmDeadline: undefined,
+  studentGrade: undefined,  // 年级属性绑定到 queryParams
+  createTime: [],
+})
+const queryFormRef = ref() // 搜索的表单
+const exportLoading = ref(false) // 导出的加载中
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await studentSelectionProjectApi.getStudentSelectionProjectPage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+//获取登录人员信息
+const userInfo = ref({} as ProfileVO)
+const getUserInfo = async () => {
+  const users = await getUserProfile()
+  userInfo.value = users
+  // userType.value = Number(users.userType)
+}
+
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (type: string, id?: number) => {
+  formRef.value.open(type, id)
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (id: number) => {
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    // 发起删除
+    await studentSelectionProjectApi.deleteStudentSelectionProject(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 导出按钮操作 */
+const handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportLoading.value = true
+    const data = await studentSelectionProjectApi.exportStudentSelectionProject(queryParams)
+    download.excel(data, '师生互选项目.xls')
+  } catch {
+  } finally {
+    exportLoading.value = false
+  }
+}
+
+const currentYear = new Date().getFullYear(); // 获取当前年份
+const gradeOptions = computed(() => {
+  return [
+    currentYear + '级',         // 今年
+    currentYear - 1 + '级',     // 去年
+    currentYear - 2 + '级',     // 前年
+    currentYear - 3 + '级',     // 大前年
+    currentYear - 4 + '级',     // 大大前年
+  ];
+});
+
+//不同人员跳转不同页面
+const router = useRouter()
+const openStudentSelectSupervisorRecord = (id) => {
+  router.push({ name: 'studentSelectSupervisorRecord', query: { projectId: id} });
+}
+const openSupervisorSelectionSetting = (id) => {
+  router.push({ name: 'supervisorSelectionSetting', query: { projectId: id} });
+}
+
+// 更新导师,学生开关
+const handleSwitchChange = async (id: number, field: string, value: number) => {
+  if (!isPopDataLoaded.value) return; // 如果尚未加载弹窗数据,阻止更新
+  try {
+    popData.value[field] = value;
+    console.log(popData.value)
+    updateIsPop(popData.value); // 确保传递的是popData.value
+    message.success(t('common.updateSuccess'));
+  } catch (error) {
+    message.error(t('common.updateError'));
+  }
+};
+
+// 获取弹窗数据
+const getPopDataFunction = async () => {
+  loading.value = true;
+  try {
+    popData.value = await getPopData();
+    isPopDataLoaded.value = true; // 更新标志
+    console.log(popData.value)
+  } finally {
+    loading.value = false;
+  }
+}
+
+/** 初始化 **/
+onMounted(() => {
+  getList()
+  getUserInfo()
+  if (userInfo.value.userType==="4") {
+    getPopDataFunction()
+  }
+})
+</script>
+
+<style>
+.switch-form {
+  background-color: white; /* 设置白色背景 */
+  padding: 10px; /* 根据需要添加内边距 */
+  border-radius: 4px; /* 根据需要添加边框圆角 */
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); /* 根据需要添加阴影 */
+  font-size: 16px; /* 增大字体大小 */
+  margin-bottom: 10px; /* 增加元素之间的间距 */
+}
+
+.switch-form.switch-form{
+  padding: 10px 20px; /* 增大按钮内边距 */
+}
+
+</style>

+ 185 - 0
src/views/system/studentSelectionProject/studentSelectionProjectForm.vue

@@ -0,0 +1,185 @@
+<template>
+  <Dialog :title="dialogTitle" v-model="dialogVisible">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="100px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="项目名称" prop="projectName">
+        <el-input v-model="formData.projectName" placeholder="请输入项目名称" />
+      </el-form-item>
+      <el-form-item label="学生开始时间" prop="studentStartTime">
+        <el-date-picker
+          v-model="formData.studentStartTime"
+          type="datetime"
+          value-format="x"
+          placeholder="选择学生开始时间"
+        />
+      </el-form-item>
+      <el-form-item label="导师截止时间" prop="supervisorConfirmDeadline">
+        <el-date-picker
+          v-model="formData.supervisorConfirmDeadline"
+          type="datetime"
+          value-format="x"
+          placeholder="选择导师截止时间"
+        />
+      </el-form-item>
+
+      <el-form-item label="参与导师" prop="supervisorIds">
+        <el-select
+          v-model="formData.supervisorIds"
+          @change="handleSupervisorChange"
+          placeholder="请选择参与导师"
+          clearable
+          filterable
+          multiple
+          class="!w-240px"
+        >
+          <el-option
+            v-for="supervisor in supervisors"
+            :key="supervisor.id"
+            :label="supervisor.nickname"
+            :value="supervisor.id"
+          />
+        </el-select>
+      </el-form-item>
+
+      <el-form-item label="年级">
+        <el-select v-model="formData.studentGrade" placeholder="请选择年级" >
+          <el-option
+            v-for="year in gradeOptions"
+            :key="year"
+            :label="year"
+            :value="year"
+          />
+        </el-select>
+      </el-form-item>
+
+    </el-form>
+    <template #footer>
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script setup lang="ts">
+import { studentSelectionProjectApi, studentSelectionProjectVO } from '@/api/system/studentSelectionProject'
+import * as UserApi from '@/api/system/user'
+
+/** 师生互选项目 表单 */
+defineOptions({ name: 'studentSelectionProjectForm' })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const formData = ref({
+  id: undefined,
+  projectName: undefined,
+  studentStartTime: undefined,
+  supervisorConfirmDeadline: undefined,
+  studentGrade: undefined,
+  supervisorIds:[],
+  isSupervisor:ref(0),
+  isStudent:ref(0),
+})
+const formRules = reactive({
+  projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
+  studentStartTime: [{ required: true, message: '学生开始时间不能为空', trigger: 'blur' }],
+  supervisorConfirmDeadline: [{ required: true, message: '导师截止时间不能为空', trigger: 'blur' }],
+  studentGrade: [{ required: true, message: '学生年级不能为空', trigger: 'blur' }],
+})
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const open = async (type: string, id?: number) => {
+  dialogVisible.value = true
+  dialogTitle.value = t('action.' + type)
+  formType.value = type
+  resetForm()
+  // 修改时,设置数据
+  if (id) {
+    formLoading.value = true
+    try {
+      formData.value = await studentSelectionProjectApi.getStudentSelectionProject(id)
+    } finally {
+      formLoading.value = false
+    }
+  }
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  await formRef.value.validate()
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as studentSelectionProjectVO
+    if (formType.value === 'create') {
+      await studentSelectionProjectApi.createStudentSelectionProject(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await studentSelectionProjectApi.updateStudentSelectionProject(data)
+      message.success(t('common.updateSuccess'))
+    }
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+const currentYear = new Date().getFullYear(); // 获取当前年份
+const gradeOptions = computed(() => {
+  return [
+    currentYear +'级',          // 今年
+    currentYear - 1 +'级',      // 去年
+    currentYear - 2 +'级',      // 前年
+    currentYear - 3 +'级',      // 大前年
+    currentYear - 4 +'级',      // 大大前年
+  ];
+});
+
+//获取所有导师
+const supervisors = ref()
+const getSupervisor= async () => {
+  try {
+    const result = await UserApi.getSupervisor()
+    supervisors.value = result
+  } catch (error) {
+    console.error('未获取到导师', error)
+  }
+}
+
+const handleSupervisorChange = (values) => {
+  formData.value.supervisorIds = values;  // values 是选择的导师ID数组
+}
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    id: undefined,
+    projectName: undefined,
+    studentStartTime: undefined,
+    supervisorConfirmDeadline: undefined,
+    studentGrade: undefined,
+    supervisorIds:[],
+    isSupervisor:ref(0),
+    isStudent:ref(0),
+  }
+  formRef.value?.resetFields()
+}
+
+onMounted(() => {
+  getSupervisor()
+})
+</script>

+ 458 - 0
src/views/system/supervisorSelectionSetting/index.vue

@@ -0,0 +1,458 @@
+<template>
+  <ContentWrap>
+    <!-- 搜索工作栏 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="68px"
+    >
+
+      <el-form-item label="参与导师" prop="supervisorIds">
+        <el-select
+          v-model="queryParams.supervisorId"
+          @change="handleSupervisorChange"
+          placeholder="请选择参与导师"
+          clearable
+          filterable
+          class="!w-240px"
+        >
+          <el-option
+            v-for="supervisor in supervisors"
+            :key="supervisor.id"
+            :label="supervisor.nickname"
+            :value="supervisor.id"
+          />
+        </el-select>
+
+      </el-form-item>
+<!--      <el-form-item label="学硕名额" prop="academicSlots">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.academicSlots"-->
+<!--          placeholder="请输入学硕名额"-->
+<!--          clearable-->
+<!--          @keyup.enter="handleQuery"-->
+<!--          class="!w-240px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="专硕名额" prop="professionalSlots">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.professionalSlots"-->
+<!--          placeholder="请输入专硕名额"-->
+<!--          clearable-->
+<!--          @keyup.enter="handleQuery"-->
+<!--          class="!w-240px"-->
+<!--        />-->
+<!--      </el-form-item>-->
+      <el-form-item>
+        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+
+        <el-button
+          plain
+          type="primary"
+          @click="openForm('update', scope.row.id)"
+          v-hasPermi="['system:student-select-supervisor-record:update']"
+          v-if="userInfo?.userType === '1'"
+        >
+          志愿编辑
+        </el-button>
+<!--        <el-button-->
+<!--          type="primary"-->
+<!--          plain-->
+<!--          @click="openForm('create')"-->
+<!--          v-hasPermi="['system:supervisor-selection-setting:create']"-->
+<!--        >-->
+<!--          <Icon icon="ep:plus" class="mr-5px" /> 新增-->
+<!--        </el-button>-->
+<!--        <el-button-->
+<!--          type="success"-->
+<!--          plain-->
+<!--          @click="handleExport"-->
+<!--          :loading="exportLoading"-->
+<!--          v-hasPermi="['system:supervisor-selection-setting:export']"-->
+<!--        >-->
+<!--          <Icon icon="ep:download" class="mr-5px" /> 导出-->
+<!--        </el-button>-->
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
+      <el-table-column type="index" width="50" />
+<!--      <el-table-column label="项目名称" align="center" prop="projectId" />-->
+      <el-table-column label="导师姓名" align="center" prop="supervisorName" />
+      <el-table-column
+        label="导师类型"
+        align="center"
+        prop="userType"
+        :formatter="userTypeFormatter"
+      />
+      <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" prop="academicSlots" />-->
+<!--      <el-table-column label="专硕名额" align="center" prop="professionalSlots" />-->
+
+      <el-table-column label="已招生名额" align="center">
+        <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">
+        <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="createTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+
+      <el-table-column label="导师详情" align="center" min-width="120px"  v-if="userInfo?.userType === '4' || userInfo?.userType === '1'">
+        <template #default="scope">
+          <el-button link
+                      type="primary"
+                      @click="openTeacherRequireForm( scope.row.supervisorId)"
+                      v-hasPermi="['system:user:query']"
+          >
+            <Icon icon="ep:bell" />
+            查看
+          </el-button>
+        </template>
+      </el-table-column>
+      <!--  学生志愿填报-->
+      <el-table-column label="志愿填报" align="center" min-width="120px"  v-if=" userInfo?.userType === '1'">
+        <template #default="scope">
+          <el-button
+            type="primary"
+            link
+            @click="openStudentSelectSupervisorPop('create', scope.row.projectId,scope.row.supervisorId)"
+            v-hasPermi="['system:student-select-supervisor-record:create']"
+            v-if="userInfo?.userType === '1'"
+          >
+            <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"  v-if="userInfo?.userType === '4'" @click="openStudentSelectSupervisorRecord(scope.row.projectId,scope.row.supervisorId)" v-hasPermi="['system:student-select-supervisor-record:query']"
+                     >
+            <Icon icon="ep:bell" />
+            招生详情
+          </el-button>
+<!--       志愿填报修改-->
+          <el-button
+            link
+            type="primary"
+            @click="handelWithdraw( scope.row.supervisorId)"
+            v-hasPermi="['system:student-select-supervisor-record:withdraw']"
+            v-if="userInfo?.userType === '1'&&scope.row.selectType ==1"
+          >
+            撤回
+          </el-button>
+
+<!--名额设置-->
+          <el-button
+            link
+            type="primary"
+            @click="openForm('update', scope.row.id)"
+            v-hasPermi="['system:supervisor-selection-setting:update']"
+            v-if="userInfo?.userType === '4'"
+          >
+            编辑
+          </el-button>
+<!--          <el-button-->
+<!--            link-->
+<!--            type="danger"-->
+<!--            @click="handleDelete(scope.row.id)"-->
+<!--            v-hasPermi="['system:supervisor-selection-setting:delete']"-->
+<!--          >-->
+<!--            删除-->
+<!--          </el-button>-->
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <!--  是学生-->
+  <ContentWrap v-if="userInfo.userType==='1' ||userInfo.userType==='4'" >
+      <el-table
+        v-loading="loading"
+        :data="selectionList"
+        row-key="id"
+      >
+      <el-table-column type="index" width="50" />
+      <el-table-column label="学生姓名" align="center" prop="studentName" />
+      <el-table-column label="硕士类型" align="center" prop="masterType" >
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_MASTER_TYPE" :value="scope.row.masterType" />
+        </template>
+      </el-table-column>
+        <el-table-column label="导师姓名" align="center" prop="supervisor" />
+
+        <el-table-column
+          label="导师类型"
+          align="center"
+          prop="supervisorType"
+          :formatter="userTypeFormatter"
+        />
+
+<!--      <el-table-column label="专业" align="center" prop="major" />-->
+
+<!--      <el-table-column label="简历" align="center" prop="introduction" />-->
+
+      <el-table-column label="申请状态" align="center" prop="selectType" >
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.SYSTEM_STUDENT_SELECT_RECORD_SELECT_TYPE" :value="scope.row.selectType" />
+        </template>
+      </el-table-column>
+<!--      <el-table-column label="学生电子签名" align="center" prop="studentSignature" />-->
+<!--      <el-table-column label="导师电子签名" align="center" prop="supervisorSignature" />-->
+      <el-table-column
+        label="提交时间"
+        align="center"
+        prop="createTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column
+        label="导师审批时间"
+        align="center"
+        prop="supervisorApproveTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+    </el-table>
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <supervisorSelectionSettingForm ref="formRef" @success="getList" />
+  <!-- 导师详情弹窗-->
+  <teacherRequireForm ref="teacherRequireFormRef" @success="getList"/>
+
+  <studentSelectSupervisorRecordForm ref="studentSelectSupervisorPop" @success="getList"/>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { dateFormatter } from '@/utils/formatTime'
+import download from '@/utils/download'
+import { supervisorSelectionSettingApi, supervisorSelectionSettingVO } from '@/api/system/supervisorSelectionSetting'
+import supervisorSelectionSettingForm from './supervisorSelectionSettingForm.vue'
+import teacherRequireForm from '../userDetail/teacher.vue'
+import studentSelectSupervisorRecordForm from '../studentSelectSupervisorRecord/studentSelectSupervisorRecordForm.vue'
+import * as UserApi from '@/api/system/user'
+import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
+import {
+  studentSelectSupervisorRecordApi,
+  studentSelectSupervisorRecordVO
+} from "@/api/system/studentSelectSupervisorRecord";
+import {DICT_TYPE} from "@/utils/dict";
+
+/** 导师学硕专硕名额设置 列表 */
+defineOptions({ name: 'supervisorSelectionSetting' })
+
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+
+const loading = ref(true) // 列表的加载中
+const list = ref<supervisorSelectionSettingVO[]>([]) // 列表的数据
+
+const total = ref(0) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  projectId: undefined,
+  supervisorId: undefined,
+  academicSlots: undefined,
+  professionalSlots: undefined,
+  supervisorName:undefined,
+  userType:undefined,
+  createTime: [],
+})
+const queryFormRef = ref() // 搜索的表单
+const exportLoading = ref(false) // 导出的加载中
+
+//记录页面
+const router = useRouter()
+const openStudentSelectSupervisorRecord = (projectId,supervisorId) => {
+  router.push({ name: 'studentSelectSupervisorRecord', query: { projectId: projectId ,supervisorId :supervisorId} });
+}
+
+//导师类型
+const userTypeFormatter = (row, column, cellValue, index) => {
+  switch (cellValue) {
+    case "3":
+      return '校内导师';
+    case "5":
+      return '校外导师';
+    default:
+      return '未知';
+  }
+};
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await supervisorSelectionSettingApi.getSupervisorSelectionSettingPage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+//获取登录人员信息
+const userInfo = ref({} as ProfileVO)
+const getUserInfo = async () => {
+  const users = await getUserProfile()
+  userInfo.value = users
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (type: string, id?: number) => {
+  formRef.value.open(type, id)
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (id: number) => {
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    // 发起删除
+    await supervisorSelectionSettingApi.deleteSupervisorSelectionSetting(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 导出按钮操作 */
+const handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportLoading.value = true
+    const data = await supervisorSelectionSettingApi.exportSupervisorSelectionSetting(queryParams)
+    download.excel(data, '导师学硕专硕名额设置.xls')
+  } catch {
+  } finally {
+    exportLoading.value = false
+  }
+}
+
+//获取所有导师
+const supervisors = ref()
+const getSupervisor= async () => {
+  try {
+    const result = await UserApi.getSupervisor()
+    supervisors.value = result
+  } catch (error) {
+    console.error('未获取到导师', error)
+  }
+}
+
+
+const teacherRequireFormRef = ref()
+const openTeacherRequireForm = (supervisorId?: number) => {
+  teacherRequireFormRef.value.open(supervisorId)
+}
+
+//志愿填报弹窗
+const studentSelectSupervisorPop= ref()
+const openStudentSelectSupervisorPop =  (type: string, projectId?: number,supervisorId? :number) => {
+  console.log(supervisorId)
+  studentSelectSupervisorPop.value.open(type, projectId ,supervisorId)
+}
+
+//没处理好
+
+const recordData = ref({
+  id: undefined,
+  projectId: undefined,
+  studentId: undefined,
+  supervisorId: undefined,
+  selectType: undefined,
+  studentSignature: "",
+  supervisorApproveTime: undefined,
+  supervisorSignature: "",
+  externalSupervisorId: undefined,
+  masterType:undefined,
+  agreeDate:[]//同意日期
+})
+const handelWithdraw = async (supervisorId:number) => {
+  try {
+    await message.confirm()
+    recordData.value.supervisorId=supervisorId
+    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(() => {
+  getList()
+  getUserInfo()
+  getSupervisor()
+  getRecordList()
+})
+</script>

+ 108 - 0
src/views/system/supervisorSelectionSetting/supervisorSelectionSettingForm.vue

@@ -0,0 +1,108 @@
+<template>
+  <Dialog :title="dialogTitle" v-model="dialogVisible">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="100px"
+      v-loading="formLoading"
+    >
+<!--      <el-form-item label="项目id" prop="projectId">-->
+<!--        <el-input v-model="formData.projectId" placeholder="请输入项目id" />-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="导师id" prop="supervisorId">-->
+<!--        <el-input v-model="formData.supervisorId" placeholder="请输入导师id" />-->
+<!--      </el-form-item>-->
+      <el-form-item label="学硕名额" prop="academicSlots">
+        <el-input v-model="formData.academicSlots" placeholder="请输入学硕名额" />
+      </el-form-item>
+      <el-form-item label="专硕名额" prop="professionalSlots">
+        <el-input v-model="formData.professionalSlots" placeholder="请输入专硕名额" />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script setup lang="ts">
+import { supervisorSelectionSettingApi, supervisorSelectionSettingVO } from '@/api/system/supervisorSelectionSetting'
+
+/** 导师学硕专硕名额设置 表单 */
+defineOptions({ name: 'supervisorSelectionSettingForm' })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const formData = ref({
+  id: undefined,
+  projectId: undefined,
+  supervisorId: undefined,
+  academicSlots: undefined,
+  professionalSlots: undefined,
+})
+const formRules = reactive({
+  // projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }],
+  // supervisorId: [{ required: true, message: '导师id不能为空', trigger: 'blur' }],
+})
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const open = async (type: string, id?: number) => {
+  dialogVisible.value = true
+  dialogTitle.value = t('action.' + type)
+  formType.value = type
+  resetForm()
+  // 修改时,设置数据
+  if (id) {
+    formLoading.value = true
+    try {
+      formData.value = await supervisorSelectionSettingApi.getSupervisorSelectionSetting(id)
+    } finally {
+      formLoading.value = false
+    }
+  }
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  await formRef.value.validate()
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as supervisorSelectionSettingVO
+    if (formType.value === 'create') {
+      await supervisorSelectionSettingApi.createSupervisorSelectionSetting(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await supervisorSelectionSettingApi.updateSupervisorSelectionSetting(data)
+      message.success(t('common.updateSuccess'))
+    }
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    id: undefined,
+    projectId: undefined,
+    supervisorId: undefined,
+    academicSlots: undefined,
+    professionalSlots: undefined,
+  }
+  formRef.value?.resetFields()
+}
+</script>

+ 186 - 0
src/views/system/userDetail/teacher.vue

@@ -0,0 +1,186 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="dialogTitle">
+    <el-form
+      ref="formRef"
+      v-loading="formLoading"
+      :model="formData"
+      :rules="formRules"
+      label-width="85px"
+    >
+      <el-row>
+        <el-col :span="12" v-if="formType === 'detail'">
+          <el-form-item label="姓名" prop="nickname">
+            <el-input v-model="formData.nickname" placeholder="请输入姓名" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" v-if="formType === 'detail'">
+          <el-form-item label="职称" prop="">
+            <el-input model-value="导师"  />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row >
+        <el-col :span="12" v-if="formType === 'detail'">
+          <el-form-item label="" prop="major">
+             <el-input v-model="formData.major" placeholder="请输入研究方向" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="12" v-if="formType === 'detail'">
+          <el-form-item label="用户性别" prop="sex">
+            <el-select v-model="formData.sex" placeholder="请选择">
+              <el-option
+                v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="12" v-if="formType === 'detail'">
+          <el-form-item label="工号" prop="userNumber">
+            <el-input v-model="formData.userNumber" placeholder="请输入工号" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="24" v-if="formType === 'detail'">
+          <el-form-item label="个人简介" prop="remark" >
+            <Editor v-model="formData.remark" ref="editorRef"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="24" v-if="formType === 'detail'">
+          <el-form-item label="对研究生毕业的成果要求" prop="studentAchievementRequirement">
+            <Editor v-model="formData.studentAchievementRequirement" ref="editorRef"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+    </el-form>
+    <template #footer>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script lang="ts" setup>
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
+import { CommonStatusEnum } from '@/utils/constants'
+import * as UserApi from '@/api/system/user'
+import { FormRules } from 'element-plus'
+import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
+
+defineOptions({ name: 'teacherRequireForm' })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+const userTypeSt = ref('1')
+const userTypeT = ref('3')
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const formData = ref({
+  supervisorId:undefined,
+  nickname: '',
+  id: undefined,
+  sex: undefined,
+  remark: '',
+  status: CommonStatusEnum.ENABLE,
+  userNumber: '',
+  major:'',
+  studentAchievementRequirement:"",
+})
+const formRules = reactive<FormRules>({
+})
+const formRef = ref() // 表单 Ref
+const deptList = ref<Tree[]>([]) // 树形结构
+
+//获取登录人员信息
+const userInfo = ref({} as ProfileVO)
+const getUserInfo = async () => {
+  const users = await getUserProfile()
+  userInfo.value = users
+}
+  const open = async (supervisorId: number) => {
+  dialogVisible.value = true
+  dialogTitle.value = '查看详情'
+  formType.value = 'detail' // 假设你是要查看和编辑导师信息
+  resetForm()
+  // 获取导师信息
+  if (supervisorId) {
+    formLoading.value = true
+    try {
+      const user = await UserApi.getUser(supervisorId)
+      formData.value = {
+        ...user,
+        supervisorId: supervisorId, // 确保 supervisorId 也被设置
+      }
+    } finally {
+      formLoading.value = false
+    }
+  }
+}
+  defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  if(formType.value === 'create-S'){
+    formData.value.userType = userTypeSt.value
+  }
+  if(formType.value === 'create-T'){
+    formData.value.userType = userTypeT.value
+  }
+  console.log(formData.value,'提交的表单');
+  if (!formRef.value) return
+  const valid = await formRef.value.validate()
+  if (!valid) return
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as UserApi.UserVO
+    if (formType.value === 'create-S'|| formType.value === 'create-T') {
+      await UserApi.createUser(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await UserApi.updateUser(data)
+      message.success(t('common.updateSuccess'))
+    }
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    supervisorId:undefined,
+    nickname: '',
+    id: undefined,
+    sex: undefined,
+    remark: '',
+    status: CommonStatusEnum.ENABLE,
+    userNumber: '',
+    major:'',
+    studentAchievementRequirement:"",
+  }
+  formRef.value?.resetFields()
+}
+onMounted(() => {
+   getUserInfo()
+})
+
+</script>