yanghao vor 1 Monat
Ursprung
Commit
081a33947d
2 geänderte Dateien mit 86 neuen und 8 gelöschten Zeilen
  1. 1 1
      .env.local
  2. 85 7
      src/views/expert/list/index.vue

+ 1 - 1
.env.local

@@ -4,7 +4,7 @@ NODE_ENV=development
 VITE_DEV=true
 VITE_DEV=true
 
 
 # 请求路径
 # 请求路径
-VITE_BASE_URL='http://192.168.188.86:38080'
+VITE_BASE_URL='http://172.21.10.129:38080'
 
 
 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
 VITE_UPLOAD_TYPE=server
 VITE_UPLOAD_TYPE=server

+ 85 - 7
src/views/expert/list/index.vue

@@ -206,7 +206,7 @@
               </div>
               </div>
 
 
               <div class="profile-actions">
               <div class="profile-actions">
-                <el-button type="success" size="large">邀请评审</el-button>
+                <el-button type="success" size="large" @click="handleJoinTeam">加入团队</el-button>
                 <el-button size="large" plain>维护档案</el-button>
                 <el-button size="large" plain>维护档案</el-button>
                 <el-button size="large" plain>下载履历</el-button>
                 <el-button size="large" plain>下载履历</el-button>
               </div>
               </div>
@@ -493,7 +493,13 @@
 
 
 <script setup lang="ts">
 <script setup lang="ts">
 import { computed, nextTick, onMounted, reactive, ref } from 'vue'
 import { computed, nextTick, onMounted, reactive, ref } from 'vue'
-import { createExpert, getExpertDetail, getExpertList, getTeamList } from '@/api/expert'
+import {
+  createExpert,
+  getExpertDetail,
+  getExpertList,
+  getTeamList,
+  updateExpert
+} from '@/api/expert'
 import * as DeptApi from '@/api/system/dept'
 import * as DeptApi from '@/api/system/dept'
 import { defaultProps } from '@/utils/tree'
 import { defaultProps } from '@/utils/tree'
 import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
 import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
@@ -529,6 +535,7 @@ const dialogVisible = ref(false)
 const dialogTitle = ref('')
 const dialogTitle = ref('')
 const isEdit = ref(false)
 const isEdit = ref(false)
 const teamDialogVisible = ref(false)
 const teamDialogVisible = ref(false)
+const teamDialogMode = ref<'form' | 'drawer'>('form')
 
 
 // 表单相关
 // 表单相关
 const formRef = ref()
 const formRef = ref()
@@ -538,6 +545,7 @@ const teamList = ref<any[]>([])
 const teamTotal = ref(0)
 const teamTotal = ref(0)
 const tempSelectedTeams = ref<any[]>([])
 const tempSelectedTeams = ref<any[]>([])
 const selectedTeams = ref<any[]>([])
 const selectedTeams = ref<any[]>([])
+const currentExpertDetail = ref<any>(null)
 
 
 const formRules = {
 const formRules = {
   expertName: [{ required: true, message: '请输入专家名称', trigger: 'blur' }],
   expertName: [{ required: true, message: '请输入专家名称', trigger: 'blur' }],
@@ -612,6 +620,7 @@ type ExpertProfile = {
   direction: string[]
   direction: string[]
   softwareSkills: string[]
   softwareSkills: string[]
   teamNames: string[]
   teamNames: string[]
+  teamIds: number[]
   school: string
   school: string
   birthdayText: string
   birthdayText: string
   formerPost: string
   formerPost: string
@@ -639,6 +648,7 @@ type ExpertItem = {
   specialDirection: number[]
   specialDirection: number[]
   achievement: string
   achievement: string
   softwareSkills: number[]
   softwareSkills: number[]
+  teams?: Array<{ id: number; teamName?: string }>
 }
 }
 
 
 type ExpertGroup = {
 type ExpertGroup = {
@@ -719,8 +729,14 @@ const deptNameMap = computed(() => {
   return map
   return map
 })
 })
 
 
-const getTeamNames = (teamIds: number[] = []) =>
-  teamIds.map((id) => teamNameMap.value.get(id)).filter(Boolean) as string[]
+const getTeamNames = (teamIds: number[] = [], teams?: Array<{ id: number; teamName?: string }>) => {
+  if (teams?.length) {
+    return teams
+      .map((team) => team.teamName || teamNameMap.value.get(team.id))
+      .filter(Boolean) as string[]
+  }
+  return teamIds.map((id) => teamNameMap.value.get(id)).filter(Boolean) as string[]
+}
 
 
 const getDeptName = (deptId?: number) => {
 const getDeptName = (deptId?: number) => {
   if (deptId === undefined || deptId === null) return ''
   if (deptId === undefined || deptId === null) return ''
@@ -753,7 +769,8 @@ const buildExpertProfile = (expert: ExpertItem, groupLabel?: string): ExpertProf
   const rankLabels = getDictLabels(DICT_TYPE.RD_EXPERT_RANK, expert.expertRank)
   const rankLabels = getDictLabels(DICT_TYPE.RD_EXPERT_RANK, expert.expertRank)
   const directionLabels = getDictLabels(DICT_TYPE.RD_EXPERT_TECHNICAL, expert.specialDirection)
   const directionLabels = getDictLabels(DICT_TYPE.RD_EXPERT_TECHNICAL, expert.specialDirection)
   const softwareSkillLabels = getDictLabels(DICT_TYPE.RD_EXPERT_SOFTWARE, expert.softwareSkills)
   const softwareSkillLabels = getDictLabels(DICT_TYPE.RD_EXPERT_SOFTWARE, expert.softwareSkills)
-  const teamNames = getTeamNames(expert.teamIds)
+  const teamIds = expert.teams?.length ? expert.teams.map((team) => team.id) : expert.teamIds || []
+  const teamNames = getTeamNames(teamIds, expert.teams)
   return {
   return {
     id: expert.id,
     id: expert.id,
     name: expert.expertName,
     name: expert.expertName,
@@ -766,6 +783,7 @@ const buildExpertProfile = (expert: ExpertItem, groupLabel?: string): ExpertProf
     direction: directionLabels.length ? directionLabels : ['暂无'],
     direction: directionLabels.length ? directionLabels : ['暂无'],
     softwareSkills: softwareSkillLabels,
     softwareSkills: softwareSkillLabels,
     teamNames,
     teamNames,
+    teamIds,
     school: expert.school || '',
     school: expert.school || '',
     birthdayText: formatBirthday(expert.birthday),
     birthdayText: formatBirthday(expert.birthday),
     formerPost: expert.formerPost || '',
     formerPost: expert.formerPost || '',
@@ -860,6 +878,7 @@ const handleMemberClick = async (member: ExpertItem) => {
   drawerLoading.value = true
   drawerLoading.value = true
   try {
   try {
     const detail = await getExpertDetail(member.id)
     const detail = await getExpertDetail(member.id)
+    currentExpertDetail.value = detail
     activeExpert.value = buildExpertProfile(detail)
     activeExpert.value = buildExpertProfile(detail)
   } finally {
   } finally {
     drawerLoading.value = false
     drawerLoading.value = false
@@ -912,14 +931,73 @@ const resetTeamQuery = async () => {
 }
 }
 
 
 const openTeamDialog = async () => {
 const openTeamDialog = async () => {
+  teamDialogMode.value = 'form'
   teamDialogVisible.value = true
   teamDialogVisible.value = true
   tempSelectedTeams.value = [...selectedTeams.value]
   tempSelectedTeams.value = [...selectedTeams.value]
   await getTeamOptionsList()
   await getTeamOptionsList()
 }
 }
 
 
-const confirmTeamSelection = () => {
+const ensureSelectedTeams = async (teamIds: number[]) => {
+  if (!teamIds?.length) {
+    selectedTeams.value = []
+    tempSelectedTeams.value = []
+    return
+  }
+
+  const teamMap = new Map<number, any>()
+  ;[...selectedTeams.value, ...teamList.value].forEach((team) => {
+    teamMap.set(team.id, team)
+  })
+
+  const missingIds = teamIds.filter((id) => !teamMap.has(id))
+  if (missingIds.length) {
+    const res = await getTeamList({ pageNo: 1, pageSize: 10 })
+    ;(res.list || []).forEach((team) => {
+      teamMap.set(team.id, team)
+    })
+  }
+
+  selectedTeams.value = teamIds.map((id) => teamMap.get(id)).filter(Boolean)
+  tempSelectedTeams.value = [...selectedTeams.value]
+}
+
+const handleJoinTeam = async () => {
+  if (!activeExpert.value) return
+
+  teamDialogMode.value = 'drawer'
+  const currentTeamIds =
+    currentExpertDetail.value?.teams?.map((team) => team.id) || activeExpert.value.teamIds || []
+  await ensureSelectedTeams(currentTeamIds)
+  teamDialogVisible.value = true
+  await getTeamOptionsList()
+}
+
+const confirmTeamSelection = async () => {
   selectedTeams.value = [...tempSelectedTeams.value]
   selectedTeams.value = [...tempSelectedTeams.value]
-  formData.value.teamIds = selectedTeams.value.map((team) => team.id)
+  const teamIds = selectedTeams.value.map((team) => team.id)
+
+  if (teamDialogMode.value === 'drawer') {
+    if (!currentExpertDetail.value || !activeExpert.value) return
+
+    await updateExpert({
+      ...currentExpertDetail.value,
+      teams: selectedTeams.value,
+      teamIds
+    })
+
+    currentExpertDetail.value = {
+      ...currentExpertDetail.value,
+      teams: selectedTeams.value,
+      teamIds
+    }
+    activeExpert.value = buildExpertProfile(currentExpertDetail.value)
+    teamDialogVisible.value = false
+    ElMessage.success('加入团队成功')
+    await getList()
+    return
+  }
+
+  formData.value.teamIds = teamIds
   teamDialogVisible.value = false
   teamDialogVisible.value = false
 }
 }