|
|
@@ -4,27 +4,42 @@
|
|
|
<div class="search-layout">
|
|
|
<section class="filter-panel">
|
|
|
<div class="filter-fields">
|
|
|
- <el-input v-model="searchQuery" placeholder="姓名 / 专业 / 业绩" clearable />
|
|
|
+ <el-input
|
|
|
+ @change="getList"
|
|
|
+ v-model="searchQuery"
|
|
|
+ placeholder="姓名 / 专业 / 业绩"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
|
|
|
- <el-select v-model="selectedEducation" placeholder="选择学历" clearable>
|
|
|
+ <el-select
|
|
|
+ @change="getList"
|
|
|
+ v-model="queryParams.education"
|
|
|
+ placeholder="请选择专家学历"
|
|
|
+ clearable
|
|
|
+ >
|
|
|
<el-option
|
|
|
- v-for="option in educationOptions"
|
|
|
- :key="option.value"
|
|
|
- :label="option.label"
|
|
|
- :value="option.value"
|
|
|
+ v-for="dict in getStrDictOptions(DICT_TYPE.RD_EXPERT_EDUCATION)"
|
|
|
+ :key="dict.value"
|
|
|
+ :label="dict.label"
|
|
|
+ :value="dict.value"
|
|
|
/>
|
|
|
</el-select>
|
|
|
|
|
|
- <el-select v-model="selectedTeam" placeholder="选择梯队" clearable>
|
|
|
+ <el-select
|
|
|
+ @change="getList"
|
|
|
+ v-model="queryParams.echelon"
|
|
|
+ placeholder="请选择专家梯队"
|
|
|
+ clearable
|
|
|
+ >
|
|
|
<el-option
|
|
|
- v-for="option in teamOptions"
|
|
|
- :key="option.value"
|
|
|
- :label="option.label"
|
|
|
- :value="option.value"
|
|
|
+ v-for="dict in getStrDictOptions(DICT_TYPE.RD_EXPERT_ECHELON)"
|
|
|
+ :key="dict.value"
|
|
|
+ :label="dict.label"
|
|
|
+ :value="dict.value"
|
|
|
/>
|
|
|
</el-select>
|
|
|
|
|
|
- <el-button type="primary" @click="handleCreateExpert"
|
|
|
+ <el-button type="primary" @click="handleAdd"
|
|
|
><Icon icon="ep:plus" class="mr-5px" />新增专家</el-button
|
|
|
>
|
|
|
</div>
|
|
|
@@ -187,13 +202,284 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-drawer>
|
|
|
+
|
|
|
+ <Dialog
|
|
|
+ :title="dialogTitle"
|
|
|
+ v-model="dialogVisible"
|
|
|
+ destroy-on-close
|
|
|
+ @close="closeDialog"
|
|
|
+ width="60%"
|
|
|
+ >
|
|
|
+ <el-form
|
|
|
+ ref="formRef"
|
|
|
+ :model="formData"
|
|
|
+ :rules="formRules"
|
|
|
+ v-loading="formLoading"
|
|
|
+ label-width="auto"
|
|
|
+ >
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="部门" prop="deptId">
|
|
|
+ <el-tree-select
|
|
|
+ clearable
|
|
|
+ v-model="formData.deptId"
|
|
|
+ :data="deptList2"
|
|
|
+ :props="defaultProps"
|
|
|
+ :check-strictly="false"
|
|
|
+ node-key="id"
|
|
|
+ filterable
|
|
|
+ placeholder="请选择所在部门"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="专家姓名" prop="expertName">
|
|
|
+ <el-input v-model="formData.expertName" placeholder="请输入专家姓名" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="专家序列" prop="expertRank">
|
|
|
+ <el-select
|
|
|
+ multiple
|
|
|
+ v-model="formData.expertRank"
|
|
|
+ placeholder="请选择专家序列"
|
|
|
+ clearable
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="dict in getStrDictOptions(DICT_TYPE.RD_EXPERT_RANK)"
|
|
|
+ :key="dict.value"
|
|
|
+ :label="dict.label"
|
|
|
+ :value="dict.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="专家梯队" prop="echelon">
|
|
|
+ <el-select v-model="formData.echelon" placeholder="请选择专家梯队" clearable>
|
|
|
+ <el-option
|
|
|
+ v-for="dict in getStrDictOptions(DICT_TYPE.RD_EXPERT_ECHELON)"
|
|
|
+ :key="dict.value"
|
|
|
+ :label="dict.label"
|
|
|
+ :value="dict.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="学历" prop="education">
|
|
|
+ <el-select v-model="formData.education" placeholder="请选择专家学历" clearable>
|
|
|
+ <el-option
|
|
|
+ v-for="dict in getStrDictOptions(DICT_TYPE.RD_EXPERT_EDUCATION)"
|
|
|
+ :key="dict.value"
|
|
|
+ :label="dict.label"
|
|
|
+ :value="dict.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="专业方向" prop="specialDirection">
|
|
|
+ <el-select
|
|
|
+ v-model="formData.specialDirection"
|
|
|
+ placeholder="请选择专业方向"
|
|
|
+ clearable
|
|
|
+ multiple
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="dict in getStrDictOptions(DICT_TYPE.RD_EXPERT_TECHNICAL)"
|
|
|
+ :key="dict.value"
|
|
|
+ :label="dict.label"
|
|
|
+ :value="dict.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="专业软件技能" prop="softwareSkills">
|
|
|
+ <el-select
|
|
|
+ v-model="formData.softwareSkills"
|
|
|
+ placeholder="请选择专业软件技能"
|
|
|
+ clearable
|
|
|
+ multiple
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="dict in getStrDictOptions(DICT_TYPE.RD_EXPERT_SOFTWARE)"
|
|
|
+ :key="dict.value"
|
|
|
+ :label="dict.label"
|
|
|
+ :value="dict.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="所属团队" prop="teamIds" />
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="毕业院校" prop="school">
|
|
|
+ <el-input
|
|
|
+ v-model="formData.school"
|
|
|
+ placeholder="请输入毕业院校"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="出生日期" prop="birthday">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData.birthday"
|
|
|
+ type="date"
|
|
|
+ value-format="x"
|
|
|
+ placeholder="请选择出生日期"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="头像" prop="avatar">
|
|
|
+ <UploadImg v-model="formData.avatar" height="50px" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="历任岗位" prop="formerPost">
|
|
|
+ <el-input v-model="formData.formerPost" placeholder="请输入历任岗位" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="岗位" prop="jobTitle">
|
|
|
+ <el-input v-model="formData.jobTitle" placeholder="请输入岗位" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="职称" prop="professionalTitle">
|
|
|
+ <el-input v-model="formData.professionalTitle" placeholder="请输入职称" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="主要业绩" prop="achievement">
|
|
|
+ <el-input
|
|
|
+ type="textarea"
|
|
|
+ v-model="formData.achievement"
|
|
|
+ placeholder="请输入主要业绩"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="closeDialog">取 消</el-button>
|
|
|
+ <el-button type="primary" @click="submitForm" :loading="submitLoading">确 定</el-button>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { computed, ref } from 'vue'
|
|
|
import { createExpert, getExpertList } from '@/api/expert'
|
|
|
+import * as DeptApi from '@/api/system/dept'
|
|
|
+import { defaultProps } from '@/utils/tree'
|
|
|
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
|
|
+const deptList2 = ref<Tree[]>([]) // 树形结构
|
|
|
+
|
|
|
+const formLoading = ref(false) // 表单加载中
|
|
|
+const submitLoading = ref(false) // 提交按钮加载中
|
|
|
+
|
|
|
+// 对话框相关
|
|
|
+const dialogVisible = ref(false)
|
|
|
+const dialogTitle = ref('')
|
|
|
+const isEdit = ref(false)
|
|
|
+
|
|
|
+// 表单相关
|
|
|
+const formRef = ref()
|
|
|
+const formData = ref({
|
|
|
+ expertName: '',
|
|
|
+ achievement: '',
|
|
|
+ echelon: '',
|
|
|
+ education: '',
|
|
|
+ specialDirection: '',
|
|
|
+ softwareSkills: '',
|
|
|
+ teamIds: '',
|
|
|
+ school: null,
|
|
|
+ birthday: null,
|
|
|
+ avatar: '',
|
|
|
+ deptId: '',
|
|
|
+ formerPost: '',
|
|
|
+ jobTitle: '',
|
|
|
+ professionalTitle: '',
|
|
|
+ expertRank: ''
|
|
|
+})
|
|
|
+
|
|
|
+const formRules = {
|
|
|
+ expertName: [{ required: true, message: '请输入专家名称', trigger: 'blur' }],
|
|
|
+ achievement: [{ required: true, message: '请输入成果', trigger: 'blur' }],
|
|
|
+ echelon: [{ required: true, message: '请选择专家层级', trigger: 'blur' }],
|
|
|
+ education: [{ required: true, message: '请选择专家学历', trigger: 'blur' }],
|
|
|
+ specialDirection: [{ required: true, message: '请选择专业方向', trigger: 'blur' }],
|
|
|
+ softwareSkills: [{ required: true, message: '请选择专业软件技能', trigger: 'blur' }],
|
|
|
+ teamIds: [{ required: true, message: '请选择所属团队', trigger: 'blur' }],
|
|
|
+ school: [{ required: true, message: '请输入毕业院校', trigger: 'blur' }],
|
|
|
+ birthday: [{ required: true, message: '请选择出生日期', trigger: 'blur' }],
|
|
|
+ avatar: [{ required: true, message: '请上传头像', trigger: 'blur' }],
|
|
|
+ deptId: [{ required: true, message: '请选择部门', trigger: 'blur' }],
|
|
|
+ formerPost: [{ required: true, message: '请输入历任岗位', trigger: 'blur' }],
|
|
|
+ jobTitle: [{ required: true, message: '请输入岗位', trigger: 'blur' }],
|
|
|
+ professionalTitle: [{ required: true, message: '请输入职称', trigger: 'blur' }],
|
|
|
+ expertRank: [{ required: true, message: '请选择专家序列', trigger: 'blur' }]
|
|
|
+}
|
|
|
+
|
|
|
+// 重置表单
|
|
|
+const resetForm = () => {
|
|
|
+ formData.value = {
|
|
|
+ measureName: '',
|
|
|
+ measureUnit: '',
|
|
|
+ dutyPerson: '',
|
|
|
+ brand: '',
|
|
|
+ modelName: '',
|
|
|
+ classify: '',
|
|
|
+ status: '',
|
|
|
+ offTime: null,
|
|
|
+ buyDate: null,
|
|
|
+ remark: '',
|
|
|
+ deptId: '',
|
|
|
+ measureCode: '',
|
|
|
+ // validity: null, // 有效期
|
|
|
+
|
|
|
+ measurePrice: 0, // 价格
|
|
|
+ measureCertNo: ''
|
|
|
+ }
|
|
|
+ formRef.value?.clearValidate()
|
|
|
+}
|
|
|
+// 关闭对话框
|
|
|
+const closeDialog = () => {
|
|
|
+ dialogVisible.value = false
|
|
|
+ resetForm()
|
|
|
+}
|
|
|
|
|
|
type CellItem =
|
|
|
| {
|
|
|
@@ -411,14 +697,6 @@ const wordCloudWords = [
|
|
|
{ text: '研究生', size: 16, rotate: -5, color: '#7f85b5', left: '79%', top: '28%' }
|
|
|
]
|
|
|
|
|
|
-const educationOptions = [
|
|
|
- { label: '全部', value: '' },
|
|
|
- { label: '博士', value: '博士' },
|
|
|
- { label: '硕士', value: '硕士' },
|
|
|
- { label: '本科', value: '本科' },
|
|
|
- { label: '专科', value: '专科' }
|
|
|
-]
|
|
|
-
|
|
|
const teamOptions = [
|
|
|
{ label: '全部', value: '' },
|
|
|
{ label: '第一梯队', value: '第一梯队' },
|
|
|
@@ -480,6 +758,39 @@ const handleMemberClick = (member: string) => {
|
|
|
const handleWordClick = (word: string) => {
|
|
|
searchQuery.value = word
|
|
|
}
|
|
|
+
|
|
|
+// 显示新增对话框
|
|
|
+const handleAdd = () => {
|
|
|
+ isEdit.value = false
|
|
|
+ dialogTitle.value = '新增专家'
|
|
|
+ resetForm()
|
|
|
+ dialogVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+let loading = ref(false)
|
|
|
+const list = ref([]) // 列表的数据
|
|
|
+const queryParams = reactive({
|
|
|
+ deptId: undefined,
|
|
|
+ education: undefined,
|
|
|
+ echelon: undefined,
|
|
|
+ expertName: undefined
|
|
|
+})
|
|
|
+
|
|
|
+const getList = async () => {
|
|
|
+ loading.value = true
|
|
|
+ try {
|
|
|
+ const data = await getExpertList(queryParams)
|
|
|
+ list.value = data.list
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ getList()
|
|
|
+
|
|
|
+ deptList2.value = await DeptApi.getSimpleDeptList()
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|