|
|
@@ -324,14 +324,10 @@
|
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
|
<el-form-item label="所属团队" prop="teamIds">
|
|
|
- <el-select v-model="formData.teamIds" placeholder="请选择所属团队" clearable multiple>
|
|
|
- <el-option
|
|
|
- v-for="team in formTeamOptions"
|
|
|
- :key="team.value"
|
|
|
- :label="team.label"
|
|
|
- :value="team.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
+ <div class="team-select-field">
|
|
|
+ <el-input :model-value="selectedTeamNames" placeholder="请选择所属团队" readonly />
|
|
|
+ <el-button type="primary" plain @click="openTeamDialog">选择团队</el-button>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
@@ -405,15 +401,67 @@
|
|
|
<el-button type="primary" @click="submitForm" :loading="submitLoading">确 定</el-button>
|
|
|
</template>
|
|
|
</Dialog>
|
|
|
+
|
|
|
+ <Dialog v-model="teamDialogVisible" title="选择所属团队" width="70%">
|
|
|
+ <el-form :inline="true" :model="teamQueryParams" class="-mb-15px">
|
|
|
+ <el-form-item label="团队名称">
|
|
|
+ <el-input
|
|
|
+ v-model="teamQueryParams.teamName"
|
|
|
+ placeholder="请输入团队名称"
|
|
|
+ clearable
|
|
|
+ @keyup.enter="handleTeamQuery"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button @click="handleTeamQuery">
|
|
|
+ <Icon icon="ep:search" class="mr-5px" />
|
|
|
+ 搜索
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="resetTeamQuery">
|
|
|
+ <Icon icon="ep:refresh" class="mr-5px" />
|
|
|
+ 重置
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <div style="margin-bottom: 20px">
|
|
|
+ <el-table
|
|
|
+ ref="teamTableRef"
|
|
|
+ v-loading="teamLoading"
|
|
|
+ :data="teamList"
|
|
|
+ row-key="id"
|
|
|
+ @selection-change="handleTeamSelectionChange"
|
|
|
+ >
|
|
|
+ <el-table-column type="selection" width="55" reserve-selection />
|
|
|
+ <el-table-column label="团队名称" prop="teamName" min-width="180" />
|
|
|
+ <el-table-column label="团队概述" prop="summary" min-width="240" show-overflow-tooltip />
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div style="margin-top: 20px">
|
|
|
+ <Pagination
|
|
|
+ v-model:page="teamQueryParams.pageNo"
|
|
|
+ v-model:limit="teamQueryParams.pageSize"
|
|
|
+ :total="teamTotal"
|
|
|
+ @pagination="getTeamOptionsList"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="teamDialogVisible = false">取 消</el-button>
|
|
|
+ <el-button type="primary" @click="confirmTeamSelection">确 定</el-button>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { computed, onMounted, reactive, ref } from 'vue'
|
|
|
-import { createExpert, getExpertList } from '@/api/expert'
|
|
|
+import { computed, nextTick, onMounted, reactive, ref } from 'vue'
|
|
|
+import { createExpert, getExpertList, getTeamList } from '@/api/expert'
|
|
|
import * as DeptApi from '@/api/system/dept'
|
|
|
import { defaultProps } from '@/utils/tree'
|
|
|
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
|
|
+import { ElTable } from 'element-plus'
|
|
|
|
|
|
const defaultFormData = () => ({
|
|
|
expertName: '',
|
|
|
@@ -437,15 +485,22 @@ const deptList2 = ref<Tree[]>([]) // 树形结构
|
|
|
|
|
|
const formLoading = ref(false) // 表单加载中
|
|
|
const submitLoading = ref(false) // 提交按钮加载中
|
|
|
+const teamLoading = ref(false)
|
|
|
|
|
|
// 对话框相关
|
|
|
const dialogVisible = ref(false)
|
|
|
const dialogTitle = ref('')
|
|
|
const isEdit = ref(false)
|
|
|
+const teamDialogVisible = ref(false)
|
|
|
|
|
|
// 表单相关
|
|
|
const formRef = ref()
|
|
|
const formData = ref(defaultFormData())
|
|
|
+const teamTableRef = ref<InstanceType<typeof ElTable>>()
|
|
|
+const teamList = ref<any[]>([])
|
|
|
+const teamTotal = ref(0)
|
|
|
+const tempSelectedTeams = ref<any[]>([])
|
|
|
+const selectedTeams = ref<any[]>([])
|
|
|
|
|
|
const formRules = {
|
|
|
expertName: [{ required: true, message: '请输入专家名称', trigger: 'blur' }],
|
|
|
@@ -468,6 +523,8 @@ const formRules = {
|
|
|
// 重置表单
|
|
|
const resetForm = () => {
|
|
|
formData.value = defaultFormData()
|
|
|
+ selectedTeams.value = []
|
|
|
+ tempSelectedTeams.value = []
|
|
|
formRef.value?.clearValidate()
|
|
|
}
|
|
|
// 关闭对话框
|
|
|
@@ -692,14 +749,16 @@ const wordCloudWords = [
|
|
|
{ text: '研究生', size: 16, rotate: -5, color: '#7f85b5', left: '79%', top: '28%' }
|
|
|
]
|
|
|
|
|
|
-const formTeamOptions = [
|
|
|
- { label: '技术评审组', value: 1 },
|
|
|
- { label: '经营评审组', value: 2 },
|
|
|
- { label: '成果验收组', value: 3 },
|
|
|
- { label: '专项咨询组', value: 4 }
|
|
|
-]
|
|
|
-
|
|
|
const cellBookmarks = ['技术', '经营', '商务', '安全', '法务']
|
|
|
+const selectedTeamNames = computed(() =>
|
|
|
+ selectedTeams.value.map((team) => team.teamName).join('、')
|
|
|
+)
|
|
|
+
|
|
|
+const teamQueryParams = reactive({
|
|
|
+ pageNo: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ teamName: undefined
|
|
|
+})
|
|
|
|
|
|
const getColumnPercent = (row: TableRow, index: number) => {
|
|
|
if (!row.columnWidths || row.columnWidths.length === 0) {
|
|
|
@@ -754,6 +813,59 @@ const handleWordClick = (word: string) => {
|
|
|
searchQuery.value = word
|
|
|
}
|
|
|
|
|
|
+const handleTeamSelectionChange = (rows: any[]) => {
|
|
|
+ const currentPageIds = teamList.value.map((item) => item.id)
|
|
|
+ const retainedSelections = tempSelectedTeams.value.filter(
|
|
|
+ (item) => !currentPageIds.includes(item.id)
|
|
|
+ )
|
|
|
+ tempSelectedTeams.value = [...retainedSelections, ...rows]
|
|
|
+}
|
|
|
+
|
|
|
+const syncTeamSelection = async () => {
|
|
|
+ await nextTick()
|
|
|
+ teamTableRef.value?.clearSelection()
|
|
|
+ teamList.value.forEach((row) => {
|
|
|
+ if (formData.value.teamIds.includes(row.id)) {
|
|
|
+ teamTableRef.value?.toggleRowSelection(row, true)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const getTeamOptionsList = async () => {
|
|
|
+ teamLoading.value = true
|
|
|
+ try {
|
|
|
+ const res = await getTeamList(teamQueryParams)
|
|
|
+ teamList.value = res.list || []
|
|
|
+ teamTotal.value = res.total || 0
|
|
|
+ await syncTeamSelection()
|
|
|
+ } finally {
|
|
|
+ teamLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const handleTeamQuery = async () => {
|
|
|
+ teamQueryParams.pageNo = 1
|
|
|
+ await getTeamOptionsList()
|
|
|
+}
|
|
|
+
|
|
|
+const resetTeamQuery = async () => {
|
|
|
+ teamQueryParams.pageNo = 1
|
|
|
+ teamQueryParams.teamName = undefined
|
|
|
+ await getTeamOptionsList()
|
|
|
+}
|
|
|
+
|
|
|
+const openTeamDialog = async () => {
|
|
|
+ teamDialogVisible.value = true
|
|
|
+ tempSelectedTeams.value = [...selectedTeams.value]
|
|
|
+ await getTeamOptionsList()
|
|
|
+}
|
|
|
+
|
|
|
+const confirmTeamSelection = () => {
|
|
|
+ selectedTeams.value = [...tempSelectedTeams.value]
|
|
|
+ formData.value.teamIds = selectedTeams.value.map((team) => team.id)
|
|
|
+ teamDialogVisible.value = false
|
|
|
+}
|
|
|
+
|
|
|
// 显示新增对话框
|
|
|
const handleAdd = () => {
|
|
|
isEdit.value = false
|
|
|
@@ -828,6 +940,16 @@ onMounted(async () => {
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
+.team-select-field {
|
|
|
+ display: flex;
|
|
|
+ width: 100%;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.team-select-field :deep(.el-input) {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
.search-layout {
|
|
|
display: grid;
|
|
|
grid-template-columns: minmax(220px, 0.34fr) minmax(0, 1fr);
|