yanghao 1 місяць тому
батько
коміт
8d77d621e2
1 змінених файлів з 139 додано та 17 видалено
  1. 139 17
      src/views/expert/list/index.vue

+ 139 - 17
src/views/expert/list/index.vue

@@ -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);