yanghao 1 개월 전
부모
커밋
302828b2d0
2개의 변경된 파일과 122개의 추가작업 그리고 5개의 파일을 삭제
  1. 4 0
      src/api/expert/index.ts
  2. 118 5
      src/views/expert/team/index.vue

+ 4 - 0
src/api/expert/index.ts

@@ -43,3 +43,7 @@ export const deleteTeam = (id: number) => {
 export const getTeamDetail = (id: number) => {
   return request.get({ url: `/rd/team/get?id=${id}` })
 }
+
+export const getTeamMemberList = (id) => {
+  return request.get({ url: `/rd/team/get?id=${id}` })
+}

+ 118 - 5
src/views/expert/team/index.vue

@@ -47,7 +47,7 @@
   </ContentWrap>
 
   <ContentWrap>
-    <el-table v-loading="loading" :data="list">
+    <el-table v-loading="loading" :data="list" row-key="id" @row-click="handleRowClick">
       <el-table-column label="团队所属公司" align="center" min-width="180">
         <template #default="{ row }">
           {{ getDeptName(row.deptId) || '-' }}
@@ -67,7 +67,13 @@
           <span v-else>-</span>
         </template>
       </el-table-column>
-      <el-table-column label="团队概述" align="center" prop="summary" min-width="260" show-overflow-tooltip />
+      <el-table-column
+        label="团队概述"
+        align="center"
+        prop="summary"
+        min-width="260"
+        show-overflow-tooltip
+      />
       <el-table-column label="创建时间" align="center" prop="createTime" min-width="180">
         <template #default="{ row }">
           {{ formatDate(row.createTime) }}
@@ -75,8 +81,8 @@
       </el-table-column>
       <el-table-column label="操作" align="center" width="160" fixed="right">
         <template #default="{ row }">
-          <el-button link type="primary" @click="openForm('update', row.id)">编辑</el-button>
-          <el-button link type="danger" @click="handleDelete(row.id)">删除</el-button>
+          <el-button link type="primary" @click.stop="openForm('update', row.id)">编辑</el-button>
+          <el-button link type="danger" @click.stop="handleDelete(row.id)">删除</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -138,15 +144,67 @@
       <el-button type="primary" :loading="submitLoading" @click="submitForm">确 定</el-button>
     </template>
   </Dialog>
+
+  <el-drawer
+    v-model="memberDrawerVisible"
+    size="52%"
+    :with-header="false"
+    destroy-on-close
+    class="team-member-drawer"
+  >
+    <div class="member-drawer-shell" v-loading="memberLoading">
+      <div class="member-drawer-header">
+        <div>
+          <h3>{{ currentTeamName || '团队专家' }}</h3>
+        </div>
+      </div>
+
+      <el-table :data="teamMembers" class="member-table" table-layout="fixed">
+        <el-table-column prop="expertName" label="专家姓名" min-width="100" fixed="left" />
+        <el-table-column label="所属公司" min-width="180">
+          <template #default="{ row }">
+            {{ getDeptName(row.deptId) || '-' }}
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="professionalTitle"
+          label="职称"
+          min-width="120"
+          show-overflow-tooltip
+        />
+        <el-table-column prop="jobTitle" label="岗位" min-width="120" show-overflow-tooltip />
+        <el-table-column prop="school" label="毕业院校" min-width="150" show-overflow-tooltip />
+        <el-table-column prop="educationLabel" label="学历" min-width="120" show-overflow-tooltip />
+        <el-table-column
+          prop="specialDirection"
+          label="专业方向"
+          min-width="120"
+          show-overflow-tooltip
+        >
+          <template #default="scope">
+            {{ getSpecialDirectionLabels(scope.row.specialDirection) }}
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+  </el-drawer>
 </template>
 
 <script setup lang="ts">
 import { computed, onMounted, reactive, ref } from 'vue'
 import { ElMessage, ElMessageBox, FormRules } from 'element-plus'
-import { getTeamList, createTeam, updateTeam, deleteTeam, getTeamDetail } from '@/api/expert'
+import {
+  getTeamList,
+  createTeam,
+  updateTeam,
+  deleteTeam,
+  getTeamDetail,
+  getTeamMemberList
+} from '@/api/expert'
 import * as DeptApi from '@/api/system/dept'
 import { defaultProps } from '@/utils/tree'
 import { formatDate } from '@/utils/formatTime'
+import { DICT_TYPE, getStrDictOptions, getIntDictOptions } from '@/utils/dict'
 
 type TeamFormData = {
   id?: number
@@ -156,6 +214,16 @@ type TeamFormData = {
   summary: string
 }
 
+type TeamMember = {
+  id: number
+  expertName: string
+  deptId?: number
+  professionalTitle?: string
+  jobTitle?: string
+  school?: string
+  specialDirection?: number[]
+}
+
 const defaultFormData = (): TeamFormData => ({
   id: undefined,
   deptId: undefined,
@@ -172,10 +240,14 @@ const dialogVisible = ref(false)
 const dialogTitle = ref('')
 const formLoading = ref(false)
 const submitLoading = ref(false)
+const memberLoading = ref(false)
 const queryFormRef = ref()
 const formRef = ref()
 const formType = ref<'create' | 'update'>('create')
 const formData = ref<TeamFormData>(defaultFormData())
+const memberDrawerVisible = ref(false)
+const currentTeamName = ref('')
+const teamMembers = ref<TeamMember[]>([])
 
 const queryParams = reactive({
   pageNo: 1,
@@ -214,6 +286,20 @@ const getDeptOptions = async () => {
   deptList.value = await DeptApi.getSimpleDeptList()
 }
 
+const getSpecialDirectionLabels = (specialDirection?: number[]) => {
+  if (!Array.isArray(specialDirection) || !specialDirection.length) return '-'
+  return (
+    specialDirection
+      .map(
+        (value) =>
+          getIntDictOptions(DICT_TYPE.RD_EXPERT_TECHNICAL).find((dict) => dict.value === value)
+            ?.label
+      )
+      .filter(Boolean)
+      .join('、') || '-'
+  )
+}
+
 const getList = async () => {
   loading.value = true
   try {
@@ -254,6 +340,33 @@ const normalizeDetail = (data: any): TeamFormData => ({
   summary: data.summary || ''
 })
 
+const normalizeTeamMembers = (data: any): TeamMember[] => {
+  const members = data?.experts || data?.expertList || data?.members || data?.memberList || []
+  if (!Array.isArray(members)) return []
+  return members.map((item: any) => ({
+    id: item.id,
+    expertName: item.expertName || '-',
+    deptId: item.deptId,
+    professionalTitle: item.professionalTitle || '',
+    jobTitle: item.jobTitle || '',
+    school: item.school || '',
+    educationLabel: item.educationLabel || '',
+    specialDirection: Array.isArray(item.specialDirection) ? item.specialDirection : []
+  }))
+}
+
+const handleRowClick = async (row: any) => {
+  memberDrawerVisible.value = true
+  currentTeamName.value = row.teamName || ''
+  memberLoading.value = true
+  try {
+    const res = await getTeamMemberList(row.id)
+    teamMembers.value = normalizeTeamMembers(res)
+  } finally {
+    memberLoading.value = false
+  }
+}
+
 const openForm = async (type: 'create' | 'update', id?: number) => {
   dialogVisible.value = true
   dialogTitle.value = type === 'create' ? '新增团队' : '编辑团队'