|
|
@@ -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' ? '新增团队' : '编辑团队'
|