6 files modified
3 files added
1 files deleted
| | |
| | | export const add = (row) => { |
| | | return request({ |
| | | url: '/evaluate/evaluateTask/submit', |
| | | // url: '/evaluate/evaluateTask/sava', |
| | | method: 'post', |
| | | data: row |
| | | }) |
| | |
| | | }) |
| | | } |
| | | |
| | | |
| | | // 获取候选人列表 |
| | | export const getCandidateList = (current, size, params) => { |
| | | return request({ |
| | | url: '/evaluate/evaluateCandidate/list', |
| | |
| | | }) |
| | | } |
| | | |
| | | // 添加候选人 |
| | | export const addCandidate = (data) => { |
| | | return request({ |
| | | url: '/evaluate/evaluateCandidate/submit', |
| | |
| | | }) |
| | | } |
| | | |
| | | // 删除候选人 |
| | | export const removeCandidate = (ids) => { |
| | | return request({ |
| | | url: '/evaluate/evaluateCandidate/remove', |
| | |
| | | }) |
| | | } |
| | | |
| | | // 获取单个候选人的评定人 |
| | | export const getAssessorList = (current, size, evaluateCandidateId) => { |
| | | return request({ |
| | | url: '/evaluate/evaluateCandidateAssessor/list', |
| | | method: 'get', |
| | | params: { |
| | | current, |
| | | size, |
| | | evaluateCandidateId |
| | | } |
| | | }) |
| | | } |
| | | |
| | | |
| | | // 添加评定人 |
| | | export const addAssessorSubmit = (data) => { |
| | | return request({ |
| | | url: '/evaluate/evaluateCandidateAssessor/submit', |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | | |
| | | |
| | | // 获取最终结果 |
| | | // url: '/evaluate/evaluateCandidate/page', |
| | | export const getFinallyResult = (params) => { |
| | | return request({ |
| | |
| | | // label: "title", |
| | | // }, |
| | | formatter: (row, value) => { |
| | | let num = 0 |
| | | if (value === void 0) { |
| | | num = 0 |
| | | } else { |
| | | if (!row.type) { |
| | | value.forEach(item => { |
| | | num += Number(item.val) |
| | | }) |
| | | } else { |
| | | row.candidateNum.forEach(item => { |
| | | num += Number(item.users.length) |
| | | }) |
| | | } |
| | | } |
| | | return num + '人' |
| | | return 0 |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }] |
| | | }, |
| | | { |
| | | label: "候选人截止日期", |
| | | prop: "candidateCutoffTime", |
| | | type: "date", |
| | | format: "YYYY-MM-DD HH:mm:ss", |
| | | valueFormat: "YYYY-MM-DD HH:mm:ss", |
| | | minWidth: '200px' |
| | | }, |
| | | { |
| | | label: "候选人状态", |
| | | label: "第一轮状态", |
| | | prop: "candidateState", |
| | | type: "input", |
| | | addDisplay: false, |
| | |
| | | minWidth: '100px' |
| | | }, |
| | | { |
| | | label: "第一轮结束时间", |
| | | prop: "candidateCutoffTimeEnd", |
| | | type: "input", |
| | | minWidth: '170px' |
| | | }, |
| | | { |
| | | label: "评优数量", |
| | | prop: "evaluateNum", |
| | | type: "input", |
| | | minWidth: '100px' |
| | | }, |
| | | { |
| | | label: "评优评先截止时间", |
| | | prop: "evaluateCutoffTime", |
| | | type: "date", |
| | | format: "YYYY-MM-DD HH:mm:ss", |
| | | valueFormat: "YYYY-MM-DD HH:mm:ss", |
| | | minWidth: '200px' |
| | | }, |
| | | { |
| | | label: "评优评选状态", |
| | | label: "第二轮状态", |
| | | prop: "evaluateState", |
| | | type: "input", |
| | | addDisplay: false, |
| | |
| | | return status[value] |
| | | }, |
| | | minWidth: '100px' |
| | | }, |
| | | { |
| | | label: "第二轮结束时间", |
| | | prop: "evaluateCutoffTimeEnd", |
| | | type: "input", |
| | | minWidth: '170px' |
| | | }, |
| | | { |
| | | label: "创建人", |
| | |
| | | minWidth: '100px', |
| | | slot: 'true', |
| | | formatter: (row, value) => { |
| | | let num = 0 |
| | | if (value === void 0) { |
| | | num = 0 |
| | | } else { |
| | | if (!row.type) { |
| | | value.forEach(item => { |
| | | num += Number(item.val) |
| | | }) |
| | | } else { |
| | | row.candidateNum.forEach(item => { |
| | | num += Number(item.users.length) |
| | | }) |
| | | } |
| | | } |
| | | return num + '人' |
| | | |
| | | return 0 |
| | | }, |
| | | }, |
| | | { |
| | |
| | | minWidth: '100px' |
| | | }, |
| | | { |
| | | label: "评优评先截止时间", |
| | | prop: "evaluateCutoffTime", |
| | | type: "date", |
| | | format: "YYYY-MM-DD HH:mm:ss", |
| | | valueFormat: "YYYY-MM-DD HH:mm:ss", |
| | | minWidth: '200px' |
| | | }, |
| | | { |
| | | label: "评优评选状态", |
| | | label: "评选状态", |
| | | prop: "evaluateState", |
| | | type: "input", |
| | | addDisplay: false, |
| | |
| | | minWidth: '100px' |
| | | }, |
| | | { |
| | | label: "截止时间", |
| | | prop: "candidateCutoffTimeEnd", |
| | | minWidth: '200px' |
| | | }, |
| | | { |
| | | label: "创建人", |
| | | prop: "createUser", |
| | | type: "input", |
| New file |
| | |
| | | <template> |
| | | <el-dialog v-model="props.params.visible" :title="`${tipInfo.evaluateTaskName}-评定人列表`" width="50%" destroy-on-close> |
| | | <div class="tips"> |
| | | <el-tag style="width: 100%;" size="large">当前评优任务:{{ tipInfo.evaluateTaskName }}</el-tag> |
| | | <div class="tags"> |
| | | <el-tag size="large" class="item">候选人姓名:{{ tipInfo.userName }}</el-tag> |
| | | <el-tag size="large" class="item">候选人部门:{{ tipInfo.deptName }}</el-tag> |
| | | <el-tag size="large" class="item">候选人职位:{{ tipInfo.postName }}</el-tag> |
| | | </div> |
| | | </div> |
| | | <avue-crud :data="table.data" :option="tableOption" v-model:page="table.page"> |
| | | <template #menu-left> |
| | | <el-button type="primary" icon="el-icon-plus" @click="assessorDialog">新增评定人</el-button> |
| | | </template> |
| | | </avue-crud> |
| | | <selectAssessor v-model:params="selectAssessorParams" @refresh="refresh" /> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getAssessorList } from '@/api/evaluate/evaluateTask' |
| | | import { ElMessage } from 'element-plus'; |
| | | import { markRaw, reactive, watch } from 'vue'; |
| | | import selectAssessor from './selectAssessor.vue'; |
| | | |
| | | |
| | | const props = defineProps({ |
| | | params: { |
| | | type: Object, |
| | | default: () => { |
| | | return { |
| | | visible: false, |
| | | taskInfo: {}, |
| | | candidateInfo: {} |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | |
| | | const tableOption = markRaw({ |
| | | height: '240', |
| | | calcHeight: 30, |
| | | tip: false, |
| | | searchShow: true, |
| | | searchMenuSpan: 6, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: false, |
| | | addBtn: false, |
| | | editBtn: false, |
| | | delBtn: false, |
| | | selection: false, |
| | | dialogClickModal: false, |
| | | menuFixed: 'right', |
| | | labelWidth: '70', |
| | | menu: false, |
| | | column: [ |
| | | { |
| | | label: '任务id', |
| | | prop: 'evaluateTaskId', |
| | | type: 'input', |
| | | hide: true, |
| | | }, |
| | | { |
| | | label: '候选人id', |
| | | prop: 'userId', |
| | | type: 'input', |
| | | hide: true, |
| | | }, |
| | | { |
| | | label: '候选人姓名', |
| | | prop: 'userName', |
| | | type: 'input' |
| | | }, |
| | | { |
| | | label: '部门id', |
| | | prop: 'deptId', |
| | | type: 'input', |
| | | hide: true, |
| | | }, |
| | | { |
| | | label: '部门名称', |
| | | prop: 'deptName', |
| | | type: 'input' |
| | | }, |
| | | { |
| | | label: '职位名称', |
| | | prop: 'postName', |
| | | type: 'input' |
| | | } |
| | | ] |
| | | }) |
| | | |
| | | const tipInfo = reactive({}) |
| | | |
| | | const table = reactive({ |
| | | data: [], |
| | | page: { |
| | | current: 1, |
| | | size: 10, |
| | | total: 10 |
| | | }, |
| | | }) |
| | | |
| | | const selectAssessorParams = reactive({ |
| | | visible: false, |
| | | evaluateCandidateId: '' |
| | | }) |
| | | |
| | | const initData = () => { |
| | | const { current, size } = table.page |
| | | const { id } = props.params.candidateInfo |
| | | getAssessorList(current, size, id).then(res => { |
| | | const result = res.data.data |
| | | table.data = result.records |
| | | table.page.total = result.total |
| | | }, error => { |
| | | ElMessage.error(error) |
| | | }) |
| | | } |
| | | |
| | | const refresh = () => { |
| | | table.page.total = 0 |
| | | initData() |
| | | } |
| | | |
| | | const assessorDialog = () => { |
| | | selectAssessorParams.visible = true |
| | | selectAssessorParams.evaluateCandidateId = props.params.candidateInfo.id |
| | | } |
| | | |
| | | watch(() => props.params.visible, (val) => { |
| | | if (!val) return |
| | | const { evaluateTaskName } = props.params.taskInfo |
| | | const { postName, deptName, userName } = props.params.candidateInfo |
| | | tipInfo.evaluateTaskName = evaluateTaskName |
| | | tipInfo.postName = postName |
| | | tipInfo.deptName = deptName |
| | | tipInfo.userName = userName |
| | | initData() |
| | | |
| | | }, { |
| | | deep: true |
| | | }) |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .tips { |
| | | margin-bottom: 15px; |
| | | |
| | | .tags { |
| | | display: flex; |
| | | width: 100%; |
| | | margin: 5px 0; |
| | | |
| | | .item { |
| | | flex: 1; |
| | | |
| | | &:nth-child(2) { |
| | | margin: 0 5px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <el-dialog v-model="params.visible" title="新增候选人" width="60%" destroy-on-close> |
| | | <avue-crud v-model="form" :option="option" :data="data" v-model:page="table.page" :table-loading="table.loading" |
| | | @row-save="rowSave" @selection-change="selectionChange" @on-load="onLoad"> |
| | | <template #menu="{ row }"> |
| | | <el-popconfirm title="是否确认删除当前候选人?" @confirm="rowDel(row)"> |
| | | <template #reference> |
| | | <el-button text plan type="primary" icon="el-icon-delete">删除</el-button> |
| | | </template> |
| | | </el-popconfirm> |
| | | </template> |
| | | </avue-crud> |
| | | <el-dialog v-model="props.dialogParams.visible" title="添加候选人" @close="dialogClose"> |
| | | <div style="margin-bottom: 20px;" v-if="!form.deptId"> |
| | | <el-alert title="请先选择部门信息" type="warning" /> |
| | | </div> |
| | | <el-form :model="form" ref="formRef" :rules="rules" label-width="70px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="部门" prop="deptId"> |
| | | <el-cascader v-model="form.deptId" :props="cascaderProps" placeholder="请选择部门" @change="deptChange" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="候选人" prop="userId"> |
| | | <el-select v-model="form.userId" placeholder="请选择候选人" |
| | | :disabled="userSelectOption.length > 0 ? false : true" @change="userSelectChange" |
| | | style="width: 100%;"> |
| | | <el-option v-for="item in userSelectOption" :label="item.name" :key="item.id" |
| | | :value="item.id" /> |
| | | <div class="loading-more" @click="loadMore">{{ loadingMoreText }}</div> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="职务"> |
| | | <el-input v-model="form.postName" placeholder="请填写职务" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="() => props.dialogParams.visible = false">取消</el-button> |
| | | <el-button type="primary" @click="submit">确定</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, getCurrentInstance, reactive, ref, watch } from 'vue'; |
| | | import _ from 'lodash' |
| | | import { ElMessage } from 'element-plus' |
| | | import { |
| | | getList |
| | | } from '@/api/system/user'; |
| | | import { |
| | | getCandidateList, |
| | | addCandidate, |
| | | removeCandidate |
| | | } from '@/api/evaluate/evaluateTask' |
| | | import { computed, markRaw, reactive, ref, watch } from 'vue'; |
| | | import { getDeptLazyTree } from '@/api/system/dept.js' |
| | | import { getList } from '@/api/system/user.js' |
| | | import { addCandidate } from '@/api/evaluate/evaluateTask' |
| | | import { ElMessage } from 'element-plus'; |
| | | |
| | | const dataSourceStatus = { |
| | | 0: '系统分配', |
| | | 1: '手动添加' |
| | | } |
| | | |
| | | const config = getCurrentInstance().appContext.config.globalProperties |
| | | |
| | | const $props = defineProps({ |
| | | params: { |
| | | const props = defineProps({ |
| | | dialogParams: { |
| | | type: Object, |
| | | default: () => ({ |
| | | visible: false, |
| | | type: 0, |
| | | data: {}, |
| | | }), |
| | | } |
| | | }) |
| | | |
| | | const $emit = defineEmits(['refreshTable']) |
| | | |
| | | const data = ref([]) |
| | | const form = ref() |
| | | const table = reactive({ |
| | | loading: false, |
| | | page: { |
| | | pageSize: 10, |
| | | currentPage: 1, |
| | | total: 0, |
| | | default: () => { } |
| | | }, |
| | | selectionList: [], |
| | | }) |
| | | |
| | | const option = reactive({ |
| | | height: '300', |
| | | tip: false, |
| | | searchShow: true, |
| | | searchMenuSpan: 6, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: false, |
| | | addBtn: true, |
| | | editBtn: false, |
| | | delBtn: false, |
| | | selection: false, |
| | | refreshBtn: false, |
| | | dialogClickModal: false, |
| | | menuFixed: 'right', |
| | | labelWidth: 100, |
| | | column: [ |
| | | const emits = defineEmits(['refresh']) |
| | | |
| | | const formRef = ref(null) |
| | | |
| | | const form = reactive({ |
| | | userId: '', |
| | | userName: '', |
| | | deptId: '', |
| | | deptName: '', |
| | | postName: '' |
| | | }) |
| | | |
| | | const rules = markRaw({ |
| | | userId: [ |
| | | { |
| | | label: '候选人姓名', |
| | | prop: 'userId', |
| | | type: 'select', |
| | | dicData: [], |
| | | props: { |
| | | label: 'name', |
| | | value: 'id' |
| | | }, |
| | | control: (val, row) => { |
| | | const { findObject } = config |
| | | const column = findObject(option.column, 'userId') || [] |
| | | const params = column.dicData.find(item => item.id === val) |
| | | if (!params) return |
| | | row.deptName = params.deptName |
| | | row.postName = params.postName |
| | | row.userName = params.name |
| | | }, |
| | | rules: [ |
| | | { |
| | | required: true, |
| | | message: '请选择候选人', |
| | | trigger: 'blur', |
| | | }, |
| | | ] |
| | | }, |
| | | required: true, |
| | | message: '请选择候选人', |
| | | trigger: 'click', |
| | | } |
| | | ], |
| | | deptId: [ |
| | | { |
| | | label: '部门', |
| | | prop: 'deptName', |
| | | type: 'input', |
| | | disabled: true, |
| | | }, |
| | | { |
| | | label: '部门', |
| | | prop: 'postName', |
| | | type: 'input', |
| | | disabled: true, |
| | | }, |
| | | { |
| | | label: '数据来源', |
| | | prop: 'dataSource', |
| | | type: 'input', |
| | | display: false, |
| | | formatter: (row) => { |
| | | return dataSourceStatus[row.dataSource] || '系统分配' |
| | | }, |
| | | required: true, |
| | | message: '请选择部门', |
| | | trigger: 'click', |
| | | } |
| | | ] |
| | | }) |
| | | |
| | | |
| | | const initData = () => { |
| | | const { findObject } = config |
| | | const column = findObject(option.column, 'userId'); |
| | | getList(1, 999999, { userType: 2 }).then(res => { |
| | | column.dicData = res.data.data.records |
| | | }) |
| | | } |
| | | |
| | | const rowSave = (row, done, loading) => { |
| | | const { data: { id, taskName } } = $props.params |
| | | const value = data.value.find(item => item.userId === row.userId) |
| | | if (value) { |
| | | ElMessage.warning('当前候选人已存在,不可重复添加!!') |
| | | loading() |
| | | return |
| | | } |
| | | addCandidate({ |
| | | evaluateTaskId: id, |
| | | evaluateTaskName: taskName, |
| | | ...row, |
| | | dataSource: 1 |
| | | }).then(res => { |
| | | ElMessage.success('新增候选人成功'); |
| | | onLoad(table.page); |
| | | done(); |
| | | }, error => { |
| | | loading(); |
| | | console.log(error); |
| | | }) |
| | | } |
| | | |
| | | const rowDel = ({ id }) => { |
| | | removeCandidate(id).then(res => { |
| | | ElMessage.success('删除当前候选人成功'); |
| | | onLoad(table.page); |
| | | }, error => { |
| | | ElMessage.error(error); |
| | | console.log(error); |
| | | }) |
| | | } |
| | | |
| | | const selectionChange = (list) => { |
| | | table.selectionList = list; |
| | | } |
| | | |
| | | const onLoad = (page, params = {}) => { |
| | | table.loading = true; |
| | | |
| | | let values = { |
| | | evaluateTaskId: $props.params.data.id, |
| | | ...params |
| | | }; |
| | | getCandidateList(page.currentPage, page.pageSize, values).then(res => { |
| | | const candidateRes = res.data.data; |
| | | table.page.total = candidateRes.total; |
| | | data.value = candidateRes.records; |
| | | table.loading = false; |
| | | }); |
| | | } |
| | | |
| | | watch(() => $props.params.visible, (val) => { |
| | | val && initData(); |
| | | }, { |
| | | deep: true, |
| | | immediate: true |
| | | const requestParams = reactive({ |
| | | evaluateTaskId: '', |
| | | evaluateTaskName: '', |
| | | userId: '', |
| | | userName: '', |
| | | deptId: '', |
| | | deptName: '', |
| | | postName: '' |
| | | }) |
| | | |
| | | const ids = computed(() => { |
| | | let ids = []; |
| | | table.selectionList.forEach(ele => { |
| | | ids.push(ele.id); |
| | | }); |
| | | return ids.join(','); |
| | | // 当前部门 |
| | | const currentDeptId = ref('') |
| | | |
| | | // options 数据 |
| | | const userSelectOption = ref([]) |
| | | |
| | | // 懒加载 |
| | | const isOptionsLoading = ref(false) |
| | | |
| | | const loadingMoreText = computed(() => { |
| | | if (userSelectOption.value.length >= page.total) { |
| | | return '数据已全部加载完成' |
| | | } |
| | | if (isOptionsLoading.value) { |
| | | return '加载中...' |
| | | } |
| | | if (!isOptionsLoading.value) { |
| | | return '点击加载更多' |
| | | } |
| | | }) |
| | | // 分页 |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0 |
| | | }) |
| | | |
| | | const loadMore = async () => { |
| | | isOptionsLoading.value = true |
| | | page.current += 1 |
| | | const res = await initUserList(currentDeptId.value) |
| | | userSelectOption.value = [...userSelectOption.value, ...res] |
| | | isOptionsLoading.value = false |
| | | } |
| | | |
| | | // 初始化部门数据 |
| | | const initDept = async (parentId) => { |
| | | const deptResult = await getDeptLazyTree(parentId) |
| | | return deptResult.data.data |
| | | } |
| | | |
| | | // 初始化用户列表 |
| | | const initUserList = (deptId) => { |
| | | return getList( |
| | | page.current, |
| | | page.size, |
| | | { |
| | | userType: 2, |
| | | }, |
| | | deptId, |
| | | ).then(res => { |
| | | page.total = res.data.data.total |
| | | return res.data.data.records |
| | | }) |
| | | } |
| | | |
| | | // 选择部门改变 |
| | | const deptChange = async (value) => { |
| | | const id = value[value.length - 1] |
| | | currentDeptId.value = id |
| | | const userList = await initUserList(id) |
| | | userSelectOption.value = userList |
| | | } |
| | | |
| | | // 级联配置 |
| | | const cascaderProps = { |
| | | lazy: true, |
| | | label: 'title', |
| | | value: 'id', |
| | | multiple: false, |
| | | lazyLoad: async (node, resovle) => { |
| | | const level = node.level || 0 |
| | | if (level == 0) { |
| | | const res = await initDept(level) |
| | | resovle(res) |
| | | } else { |
| | | const { value } = node |
| | | const res = await initDept(value) |
| | | resovle(res) |
| | | } |
| | | }, |
| | | leaf(node) { |
| | | const { hasChildren } = node |
| | | return !hasChildren |
| | | } |
| | | } |
| | | |
| | | const userSelectChange = (value) => { |
| | | const obj = userSelectOption.value.find(item => item.id == value) |
| | | const { id, deptName, deptId, postName, realName } = obj |
| | | requestParams.userId = id |
| | | requestParams.deptId = deptId |
| | | requestParams.userName = realName |
| | | requestParams.deptName = deptName |
| | | requestParams.postName = postName |
| | | |
| | | form.deptName = deptName |
| | | form.postName = postName |
| | | } |
| | | |
| | | const submit = () => { |
| | | formRef.value.validate(valid => { |
| | | if (!valid) return ElMessage.error('添加候选人失败') |
| | | addCandidate(requestParams).then(res => { |
| | | ElMessage.success('添加候选人成功') |
| | | props.dialogParams.visible = false |
| | | emits('refresh') |
| | | }, error => { |
| | | ElMessage.error(error) |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | const dialogClose = () => { |
| | | formRef.value.resetFields() |
| | | } |
| | | |
| | | watch(() => props.dialogParams.visible, (val) => { |
| | | if (!val) return |
| | | const { evaluateTaskId, evaluateTaskName } = props.dialogParams.taskParams |
| | | requestParams.evaluateTaskName = evaluateTaskName |
| | | requestParams.evaluateTaskId = evaluateTaskId |
| | | }, { |
| | | deep: true |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .loading-more { |
| | | text-align: center; |
| | | cursor: pointer; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <el-dialog v-model="params.visible" :title="params.title" width="70%" destroy-on-close @close="dialogClose"> |
| | | <el-dialog v-model="params.visible" :title="params.title" width="50%" destroy-on-close @close="dialogClose"> |
| | | <div class="content"> |
| | | <el-form :model="addForm" label-width="170px" :rules="rules" ref="addFormRef"> |
| | | <el-form-item label="任务名称:" prop="taskName"> |
| | |
| | | <el-form-item label="认定标准描述:" prop="remark"> |
| | | <el-input type="textarea" v-model="addForm.remark" placeholder="请输入认定标准描述"></el-input> |
| | | </el-form-item> |
| | | <el-form-item :label="params.type ? '评定人:' : '候选部门:'" prop="candidateNum"> |
| | | <el-select :disabled="!addForm.taskName" v-model="selectGroup" value-key="deptId" multiple style="width: 100%;" placeholder="请选择候选部门" |
| | | collapse-tags collapse-tags-tooltip :max-collapse-tags="4"> |
| | | <el-option v-for="dept in depts" :key="dept.deptId" |
| | | :label="dept.employees.length === 0 ? (dept.deptName + '(当前部门下员工人数为0)') : dept.deptName" |
| | | :value="dept" :disabled="dept.employees.length === 0"></el-option> |
| | | </el-select> |
| | | <div class="select-list"> |
| | | <div v-if="!addForm.taskName"> |
| | | <el-alert title="请先填写任务名称" type="warning" style="margin-top: 15px;" /> |
| | | </div> |
| | | <div v-else> |
| | | <el-form-item label-width="130px" v-for="content in selectGroup" :key="content.deptId" |
| | | :label="content.deptName" required class="select-item"> |
| | | <span v-if="!params.type"> |
| | | <el-input-number min="0" :max="content.employees.length || Infinity" |
| | | v-model="content.val" controls-position="right" placeholder="请输入候选人数量" |
| | | class="select-num"></el-input-number> |
| | | </span> |
| | | <el-select v-model="content.users" value-key="id" multiple collapse-tags |
| | | collapse-tags-tooltip :max-collapse-tags="4" |
| | | :placeholder="params.type ? '请选择评定人' : '请选择候选人'"> |
| | | <div class="allSelected"> |
| | | <el-checkbox @change="handleEmployeeChange($event, content)">全选</el-checkbox> |
| | | </div> |
| | | <el-option v-for="employee in content.employees" :key="employee.id" |
| | | :label="employee.name" :value="employee"></el-option> |
| | | </el-select> |
| | | <el-button type="primary" @click="assessorDialog(content)" |
| | | v-if="!params.type">设置评选人</el-button> |
| | | </el-form-item> |
| | | </div> |
| | | |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item :label="`${params.type ? '评优截止日期' : '第一次评优截止日期'}`" prop="candidateCutoffTime"> |
| | | <el-date-picker v-model="addForm.candidateCutoffTime" type="datetimerange" placeholder="请选择截止时间" |
| | | start-placeholder="请选择开始时间" end-placeholder="请选择结束时间" format="YYYY-MM-DD HH:mm:ss" |
| | | valueFormat="YYYY-MM-DD HH:mm:ss" style="width: 100%;" /> |
| | | </el-form-item> |
| | | <el-form-item label="评优数量:" prop="evaluateNum"> |
| | | <el-input-number min="0" :max="(params.type ? false : maxEvaluateNum) || Infinity" |
| | | v-model="addForm.evaluateNum" controls-position="right" |
| | | :placeholder="`请输入评优数量${params.type ? '' : '(最多可选' + maxEvaluateNum + '人)'}`" |
| | | class="evaluateNum-input"></el-input-number> |
| | | </el-form-item> |
| | | <el-form-item label="是否需要进行二次评优:" prop="isAgain" v-if="!params.type"> |
| | | <el-radio-group v-model="addForm.isAgain"> |
| | |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | <set-assessor :params="assessorDialogParams"></set-assessor> |
| | | </template> |
| | | |
| | | <script> |
| | | import website from '@/config/website'; |
| | | import { getDeptTree } from '@/api/system/dept'; |
| | | import { add, update } from '@/api/evaluate/evaluateTask'; |
| | | import { getList } from '@/api/system/user.js'; |
| | | import _ from 'lodash'; |
| | | import setAssessor from './setAssessor.vue'; |
| | | |
| | | export default { |
| | | components: { |
| | | setAssessor |
| | | }, |
| | | props: { |
| | | params: { |
| | | type: Object, |
| | |
| | | title: '新增', |
| | | isEdit: false, |
| | | type: 0, |
| | | taskData: {}, |
| | | addForm: {}, |
| | | }; |
| | | }, |
| | |
| | | evaluateCutoffTime: '', |
| | | evaluateState: '', |
| | | isAgain: null, |
| | | createUser: '', |
| | | createDept: '', |
| | | createTime: '', |
| | | updateUser: '', |
| | | updateTime: '', |
| | | status: '', |
| | | isDeleted: '', |
| | | }, |
| | | rules: { |
| | | taskName: [ |
| | |
| | | type: [ |
| | | { required: true, message: '请选择评优类型', trigger: 'blur' } |
| | | ], |
| | | candidateNum: [ |
| | | { required: true, message: '请选择候选人', trigger: 'click' } |
| | | ], |
| | | candidateCutoffTime: [ |
| | | { required: true, message: '请选择候选人截止日期', trigger: 'click' }, |
| | | ], |
| | | evaluateNum: [ |
| | | { required: true, message: '请输入评优数量', trigger: 'click' } |
| | | ], |
| | | isAgain: [ |
| | | { required: true, message: '请选择是否进行二次评优', trigger: 'click' } |
| | |
| | | { required: true, message: '请选择评优截止时间', trigger: 'click' }, |
| | | ], |
| | | }, |
| | | maxEvaluateNum: 0, |
| | | assessorDialogParams: { |
| | | visible: false, |
| | | data: [] |
| | | } |
| | | maxEvaluateNum: 0 |
| | | }; |
| | | }, |
| | | watch: { |
| | | 'params.visible': { |
| | | handler(val) { |
| | | val && this.initData(website.tenantId); |
| | | this.addForm = this.params.addForm; |
| | | val && (this.addForm.type = this.params.type + '') |
| | | if (this.params.isEdit) { |
| | |
| | | deep: true, |
| | | immediate: true, |
| | | }, |
| | | selectGroup: { |
| | | handler(val) { |
| | | // this.addForm.candidateNum = 0; |
| | | // this.addForm.candidateEntities = [] |
| | | val.forEach(item => { |
| | | // const candidates = [] |
| | | // item.users.forEach(user => { |
| | | // users.push({ |
| | | // id: user.id, |
| | | // name: user.name, |
| | | // }); |
| | | // }); |
| | | // if (!this.params.type) { |
| | | // this.maxEvaluateNum += (item.val * 1); |
| | | // } else { |
| | | // this.maxEvaluateNum += item.users.length; |
| | | // } |
| | | // this.addForm.candidateNum.push({ |
| | | // deptId: item.deptId, |
| | | // deptName: item.deptName, |
| | | // val: this.params.type ? item.users.length : item.val, |
| | | // users, |
| | | // }); |
| | | }); |
| | | }, |
| | | deep: true, |
| | | }, |
| | | }, |
| | | methods: { |
| | | submitOrEdit() { |
| | | const { candidateNum } = this.addForm |
| | | const isExist = candidateNum.find(item => item.val === void 0 || item.val === 0 || item.users.length === 0) |
| | | candidateNum.forEach(candidate => { |
| | | if (candidate.val > candidate.users.length) { |
| | | candidate.val = candidate.users.length |
| | | } |
| | | }) |
| | | if (isExist) { |
| | | this.$message.warning(`${isExist.deptName}候选人人数不可为空或者0`) |
| | | } else { |
| | | Object.keys(this.addForm).forEach(key => { |
| | | if (['evaluateCutoffTime', 'candidateCutoffTime'].includes(key)) { |
| | | const [start, end] = this.addForm[key] |
| | | if (key === 'candidateCutoffTime') { |
| | | this.addForm.candidateCutoffTimeStart = start |
| | | this.addForm.candidateCutoffTimeEnd = end |
| | | } else if (this.addForm.isAgain) { |
| | | this.addForm.evaluateCutoffTimeStart = start |
| | | this.addForm.evaluateCutoffTimeEnd = end |
| | | } |
| | | } |
| | | }) |
| | | this.params.isEdit ? this.handleEdit() : this.handleSubmit() |
| | | } |
| | | this.params.isEdit ? this.handleEdit() : this.handleSubmit() |
| | | }, |
| | | handleSubmit() { |
| | | this.$refs.addFormRef.validate(valid => { |
| | | this.params.type && (this.addForm.evaluateState = 1) |
| | | valid && add(this.addForm).then( |
| | | this.params.type && (data.evaluateState = 1) |
| | | if (!valid) return |
| | | const data = _.cloneDeep(this.addForm) |
| | | Object.keys(data).forEach(key => { |
| | | if (['candidateCutoffTime', 'evaluateCutoffTime'].includes(key)) { |
| | | const [start, end] = this.addForm[key] |
| | | if (key === 'candidateCutoffTime') { |
| | | data.candidateCutoffTimeStart = start |
| | | data.candidateCutoffTimeEnd = end |
| | | } else { |
| | | data.evaluateCutoffTimeStart = start |
| | | data.evaluateCutoffTimeEnd = end |
| | | } |
| | | delete data[key] |
| | | } |
| | | }) |
| | | add(data).then( |
| | | () => { |
| | | this.$message({ |
| | | type: 'success', |
| | |
| | | }); |
| | | this.params.visible = false; |
| | | }, |
| | | async initData(tenantId) { |
| | | const deptTreeRes = await getDeptTree(tenantId) |
| | | let deptList = [] |
| | | const cloneDeptTreeRes = _.cloneDeep(deptTreeRes.data.data) |
| | | // 扁平化deptTree |
| | | cloneDeptTreeRes.forEach(item => { |
| | | deptList.push(item); |
| | | if (item.children) { |
| | | item.children.forEach(ic => { |
| | | ic.title = item.title + '/' + ic.title; |
| | | }) |
| | | deptList = deptList.concat(item.children); |
| | | delete item.children; |
| | | } |
| | | }) |
| | | const depts_list = _.cloneDeep(deptList) |
| | | this.depts = [] |
| | | for (const dept of depts_list) { |
| | | const employeeRes = await getList(1, 99999, { userType: 2 }, dept.id) |
| | | const { records } = employeeRes.data.data |
| | | this.depts.push({ |
| | | deptId: dept.id, |
| | | deptName: dept.title, |
| | | users: [], |
| | | employees: records |
| | | }); |
| | | } |
| | | const params = _.cloneDeep(this.params.addForm.candidateNum) || [] |
| | | const newParams = params.map(item => { |
| | | const value = this.depts.find(dept => item.deptId === dept.deptId); |
| | | item.employees = value?.employees || []; |
| | | return item |
| | | }) |
| | | let defaultUsers = [] |
| | | newParams.forEach(item => { |
| | | const users = item.users.filter(user => item.employees.find(employee => employee.id === user.id)) |
| | | // 判断当前item.users和users的区别 |
| | | defaultUsers = item.users.filter(iUser => !users.includes(iUser)) |
| | | // 改变为修改后的users |
| | | item.users = users |
| | | }) |
| | | const resParams = newParams.filter(item => item.employees.length > 0 && item.users.length > 0) |
| | | this.selectGroup = resParams |
| | | // 是否有修改的user, 有的话去修改 |
| | | defaultUsers.length > 0 && update(this.addForm) |
| | | }, |
| | | handleEmployeeChange(val, content) { |
| | | console.log(this.params); |
| | | if (val) { |
| | | content.users = [] |
| | | content.employees.forEach(item => { |
| | | content.users.push({ |
| | | id: item.id, |
| | | name: item.name |
| | | }) |
| | | }) |
| | | } else { |
| | | content.users = [] |
| | | } |
| | | }, |
| | | dialogClose() { |
| | | this.selectGroup = [] |
| | | this.$refs.addFormRef.resetFields() |
| | | }, |
| | | assessorDialog(value) { |
| | | if (value.users.length == 0) { |
| | | return this.$message.warning('请选择候选人') |
| | | } |
| | | this.assessorDialogParams = { |
| | | visible: true, |
| | | data: value |
| | | } |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
| New file |
| | |
| | | <template> |
| | | <el-dialog v-model="props.params.visible" title="添加评选人" @close="dialogClose"> |
| | | <div style="margin-bottom: 20px;" v-if="!form.deptId"> |
| | | <el-alert title="请先选择部门信息" type="warning" /> |
| | | </div> |
| | | <el-form :model="form" ref="formRef" :rules="rules" label-width="70px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="部门" prop="deptId"> |
| | | <el-cascader v-model="form.deptId" :props="cascaderProps" placeholder="请选择部门" @change="deptChange" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="候选人" prop="userId"> |
| | | <el-select v-model="form.userId" placeholder="请选择候选人" |
| | | :disabled="userSelectOption.length > 0 ? false : true" @change="userSelectChange" |
| | | style="width: 100%;"> |
| | | <el-option v-for="item in userSelectOption" :label="item.name" :key="item.id" |
| | | :value="item.id" /> |
| | | <div class="loading-more" @click="loadMore">{{ loadingMoreText }}</div> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="职务"> |
| | | <el-input v-model="form.postName" placeholder="请填写职务" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="() => props.params.visible = false">取消</el-button> |
| | | <el-button type="primary" @click="submit">确定</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, markRaw, reactive, ref, watch } from 'vue'; |
| | | import { getDeptLazyTree } from '@/api/system/dept.js' |
| | | import { getList } from '@/api/system/user.js' |
| | | import { addAssessorSubmit } from '@/api/evaluate/evaluateTask' |
| | | import { ElMessage } from 'element-plus'; |
| | | |
| | | const props = defineProps({ |
| | | params: { |
| | | type: Object, |
| | | default: () => { |
| | | return { |
| | | visible: false, |
| | | evaluateCandidateId: '' |
| | | } |
| | | } |
| | | }, |
| | | }) |
| | | |
| | | const emits = defineEmits(['refresh']) |
| | | |
| | | const formRef = ref(null) |
| | | |
| | | const form = reactive({ |
| | | userId: '', |
| | | userName: '', |
| | | deptId: '', |
| | | deptName: '', |
| | | postName: '' |
| | | }) |
| | | |
| | | const rules = markRaw({ |
| | | userId: [ |
| | | { |
| | | required: true, |
| | | message: '请选择候选人', |
| | | trigger: 'click', |
| | | } |
| | | ], |
| | | deptId: [ |
| | | { |
| | | required: true, |
| | | message: '请选择部门', |
| | | trigger: 'click', |
| | | } |
| | | ] |
| | | }) |
| | | |
| | | const requestParams = reactive({ |
| | | evaluateCandidateId: '', |
| | | userId: '', |
| | | userName: '', |
| | | deptId: '', |
| | | deptName: '', |
| | | postName: '' |
| | | }) |
| | | |
| | | // 当前部门 |
| | | const currentDeptId = ref('') |
| | | |
| | | // options 数据 |
| | | const userSelectOption = ref([]) |
| | | |
| | | // 懒加载 |
| | | const isOptionsLoading = ref(false) |
| | | |
| | | const loadingMoreText = computed(() => { |
| | | if (userSelectOption.value.length >= page.total) { |
| | | return '数据已全部加载完成' |
| | | } |
| | | if (isOptionsLoading.value) { |
| | | return '加载中...' |
| | | } |
| | | if (!isOptionsLoading.value) { |
| | | return '点击加载更多' |
| | | } |
| | | }) |
| | | // 分页 |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0 |
| | | }) |
| | | |
| | | const loadMore = async () => { |
| | | isOptionsLoading.value = true |
| | | page.current += 1 |
| | | const res = await initUserList(currentDeptId.value) |
| | | userSelectOption.value = [...userSelectOption.value, ...res] |
| | | isOptionsLoading.value = false |
| | | } |
| | | |
| | | // 初始化部门数据 |
| | | const initDept = async (parentId) => { |
| | | const deptResult = await getDeptLazyTree(parentId) |
| | | return deptResult.data.data |
| | | } |
| | | |
| | | // 初始化用户列表 |
| | | const initUserList = (deptId) => { |
| | | return getList( |
| | | page.current, |
| | | page.size, |
| | | { |
| | | userType: 2, |
| | | }, |
| | | deptId, |
| | | ).then(res => { |
| | | page.total = res.data.data.total |
| | | return res.data.data.records |
| | | }) |
| | | } |
| | | |
| | | // 选择部门改变 |
| | | const deptChange = async (value) => { |
| | | const id = value[value.length - 1] |
| | | currentDeptId.value = id |
| | | const userList = await initUserList(id) |
| | | userSelectOption.value = userList |
| | | } |
| | | |
| | | // 级联配置 |
| | | const cascaderProps = { |
| | | lazy: true, |
| | | label: 'title', |
| | | value: 'id', |
| | | multiple: false, |
| | | lazyLoad: async (node, resovle) => { |
| | | const level = node.level || 0 |
| | | if (level == 0) { |
| | | const res = await initDept(level) |
| | | resovle(res) |
| | | } else { |
| | | const { value } = node |
| | | const res = await initDept(value) |
| | | resovle(res) |
| | | } |
| | | }, |
| | | leaf(node) { |
| | | const { hasChildren } = node |
| | | return !hasChildren |
| | | } |
| | | } |
| | | |
| | | const userSelectChange = (value) => { |
| | | const obj = userSelectOption.value.find(item => item.id == value) |
| | | const { id, deptName, deptId, postName, realName } = obj |
| | | requestParams.userId = id |
| | | requestParams.deptId = deptId |
| | | requestParams.userName = realName |
| | | requestParams.deptName = deptName |
| | | requestParams.postName = postName |
| | | |
| | | form.deptName = deptName |
| | | form.postName = postName |
| | | } |
| | | |
| | | const submit = () => { |
| | | formRef.value.validate(valid => { |
| | | console.log(requestParams); |
| | | if (!valid) return ElMessage.error('添加评选人失败') |
| | | addAssessorSubmit(requestParams).then(res => { |
| | | ElMessage.success('添加评选人成功') |
| | | props.params.visible = false |
| | | emits('refresh') |
| | | }, error => { |
| | | ElMessage.error(error) |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | const dialogClose = () => { |
| | | formRef.value.resetFields() |
| | | } |
| | | |
| | | watch(() => props.params.visible, (val) => { |
| | | if (!val) return |
| | | requestParams.evaluateCandidateId = props.params.evaluateCandidateId |
| | | }, { |
| | | deep: true |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .loading-more { |
| | | text-align: center; |
| | | cursor: pointer; |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <el-dialog v-model="props.params.visible" :title="`${taskParams.evaluateTaskName}-候选人列表`" width="60%" destroy-on-close |
| | | align-center> |
| | | <avue-crud :data="table.data" :option="candidatesOptions" v-model:page="table.page" @refresh-change="refreshChange"> |
| | | <template #menu-left> |
| | | <el-button type="primary" icon="el-icon-plus" @click="addCandidateDialog">新增候选人</el-button> |
| | | </template> |
| | | <template #menu="{ row }"> |
| | | <el-button type="primary" icon="el-icon-plus" text plain @click="addAssessor(row)">添加评定人</el-button> |
| | | <el-popconfirm width="200px" title="是否删除当前候选人?" @confirm="rowDel(row)"> |
| | | <template #reference> |
| | | <el-button type="danger" icon="el-icon-delete" text plain>删除</el-button> |
| | | </template> |
| | | </el-popconfirm> |
| | | </template> |
| | | </avue-crud> |
| | | <addCandidate v-model:dialogParams="dialogParams" @refresh="refreshChange" /> |
| | | <addAssessors v-model:params="dialogAssessorParams" @refresh="refreshChange" /> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import addCandidate from './addCandidate.vue'; |
| | | import addAssessors from './addAssessors.vue'; |
| | | import { markRaw, reactive, watch } from 'vue'; |
| | | import { getCandidateList, removeCandidate } from '@/api/evaluate/evaluateTask' |
| | | import { ElMessage } from 'element-plus'; |
| | | |
| | | const dialogParams = reactive({ |
| | | visible: false, |
| | | taskParams: {} |
| | | }) |
| | | |
| | | const props = defineProps({ |
| | | params: { |
| | | type: Object, |
| | | default: () => ({ |
| | | visible: false, |
| | | task: {} |
| | | }), |
| | | }, |
| | | }) |
| | | |
| | | const candidatesOptions = markRaw({ |
| | | height: '400', |
| | | calcHeight: 30, |
| | | tip: false, |
| | | searchShow: true, |
| | | searchMenuSpan: 6, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: false, |
| | | addBtn: false, |
| | | editBtn: false, |
| | | delBtn: false, |
| | | selection: false, |
| | | dialogClickModal: false, |
| | | menuFixed: 'right', |
| | | labelWidth: '70', |
| | | column: [ |
| | | { |
| | | label: '任务id', |
| | | prop: 'evaluateTaskId', |
| | | type: 'input', |
| | | hide: true, |
| | | }, |
| | | { |
| | | label: '任务名称', |
| | | prop: 'evaluateTaskName', |
| | | type: 'input' |
| | | }, |
| | | { |
| | | label: '候选人id', |
| | | prop: 'userId', |
| | | type: 'input', |
| | | hide: true, |
| | | }, |
| | | { |
| | | label: '候选人姓名', |
| | | prop: 'userName', |
| | | type: 'input' |
| | | }, |
| | | { |
| | | label: '部门id', |
| | | prop: 'deptId', |
| | | type: 'input', |
| | | hide: true, |
| | | }, |
| | | { |
| | | label: '部门名称', |
| | | prop: 'deptName', |
| | | type: 'input' |
| | | }, |
| | | { |
| | | label: '职位名称', |
| | | prop: 'postName', |
| | | type: 'input' |
| | | } |
| | | ] |
| | | }) |
| | | |
| | | const table = reactive({ |
| | | data: [], |
| | | page: { |
| | | current: 1, |
| | | size: 10, |
| | | total: 0 |
| | | } |
| | | }) |
| | | |
| | | const taskParams = reactive({ |
| | | evaluateTaskId: '', |
| | | evaluateTaskName: '', |
| | | }) |
| | | |
| | | const addCandidateDialog = () => { |
| | | dialogParams.visible = true |
| | | dialogParams.taskParams = taskParams |
| | | } |
| | | |
| | | const initTableData = () => { |
| | | const { current, size } = table.page |
| | | getCandidateList(current, size, { evaluateTaskId: taskParams.evaluateTaskId }).then(res => { |
| | | const resultData = res.data.data |
| | | table.data = resultData.records |
| | | table.page.total = resultData.total |
| | | }) |
| | | } |
| | | |
| | | const refreshChange = () => { |
| | | table.data = [], |
| | | table.page.total = 0 |
| | | initTableData() |
| | | } |
| | | |
| | | const dialogAssessorParams = reactive({ |
| | | visible: false, |
| | | taskInfo: {}, |
| | | candidateInfo: {} |
| | | }) |
| | | |
| | | const addAssessor = (row) => { |
| | | dialogAssessorParams.visible = true |
| | | dialogAssessorParams.taskInfo = taskParams |
| | | dialogAssessorParams.candidateInfo = row |
| | | } |
| | | |
| | | const rowDel = (row) => { |
| | | removeCandidate(row.id).then(res => { |
| | | ElMessage.success('删除候选人成功') |
| | | refreshChange() |
| | | }, error => { |
| | | ElMessage.error(error) |
| | | }) |
| | | } |
| | | |
| | | watch(() => props.params.visible, (val) => { |
| | | if (!val) return |
| | | const { id, taskName } = props.params.task |
| | | taskParams.evaluateTaskId = id |
| | | taskParams.evaluateTaskName = taskName |
| | | initTableData() |
| | | }, { |
| | | deep: true |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| | |
| | | <template> |
| | | <el-dialog title="信息预览" v-model="params.visible" width="70%"> |
| | | <div class="descriptions"> |
| | | <div class="descriptions-item" v-for="item in taskDateil" :key="item.prop" :style="{ width: item.width }"> |
| | | <div class="label">{{ item.title }}</div> |
| | | <div class="value" v-if="!item.isSlot">{{ item.value }}</div> |
| | | <div class="table" v-else> |
| | | <template v-if="item.evaluateState === 2"> |
| | | <avue-crud :option="item.option" :data="item.data" ref="crud" @current-change="currentChange" |
| | | @size-change="sizeChange" @refresh-change="refreshChange"></avue-crud> |
| | | </template> |
| | | <template v-else>当前任务暂未结束</template> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { reactive, watch, getCurrentInstance, ref } from 'vue'; |
| | | import { |
| | | getCandidateList, |
| | | getFinallyResult, |
| | | getSectionFinallyResult |
| | | } from '@/api/evaluate/evaluateTask' |
| | | import _ from 'lodash' |
| | | |
| | | const { findObject } = getCurrentInstance().appContext.config.globalProperties; |
| | | |
| | | |
| | | const props = defineProps({ |
| | | params: { |
| | | type: Object, |
| | | default: () => ({ |
| | | visible: false, |
| | | data: {}, |
| | | }), |
| | | } |
| | | }) |
| | | |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0 |
| | | }) |
| | | |
| | | const taskDateil = ref(null) |
| | | |
| | | const personOption = reactive([ |
| | | { |
| | | title: '任务名称', |
| | | prop: 'taskName', |
| | | value: '', |
| | | width: 'calc(100% / 3)' |
| | | }, |
| | | { |
| | | title: '任务类别', |
| | | prop: 'taskType', |
| | | value: '', |
| | | width: 'calc(100% / 3)' |
| | | }, |
| | | { |
| | | title: '评定标准', |
| | | prop: 'remark', |
| | | value: '', |
| | | width: 'calc(100% / 3)' |
| | | }, |
| | | { |
| | | title: '候选人截止日期', |
| | | prop: 'candidateCutoffTime', |
| | | value: '', |
| | | width: '50%' |
| | | }, |
| | | { |
| | | title: '评优截止日期', |
| | | prop: 'evaluateCutoffTime', |
| | | value: '', |
| | | width: '50%' |
| | | }, |
| | | { |
| | | title: '候选人状态', |
| | | prop: 'candidateState', |
| | | value: '', |
| | | width: 'calc(100% / 3)' |
| | | }, |
| | | { |
| | | title: '评优评先状态', |
| | | prop: 'evaluateState', |
| | | value: '', |
| | | width: 'calc(100% / 3)' |
| | | }, |
| | | { |
| | | title: '评优数量', |
| | | prop: 'evaluateNum', |
| | | value: '', |
| | | width: 'calc(100% / 3)' |
| | | }, |
| | | { |
| | | title: '候选人数量', |
| | | prop: 'candidateNum', |
| | | value: '', |
| | | width: '100%' |
| | | }, |
| | | { |
| | | title: '候选结果', |
| | | prop: 'candidateResult', |
| | | value: '', |
| | | width: '100%' |
| | | }, |
| | | { |
| | | title: '最终评定结果', |
| | | prop: 'finallyResult', |
| | | isSlot: true, |
| | | width: '100%', |
| | | evaluateState: 0, |
| | | data: [], |
| | | option: { |
| | | height: 260, |
| | | calcHeight: 30, |
| | | tip: false, |
| | | searchShow: true, |
| | | border: true, |
| | | index: true, |
| | | dialogClickModal: false, |
| | | menu: false, |
| | | menuLeft: false, |
| | | header: false, |
| | | menuFixed: 'right', |
| | | column: [{ |
| | | label: '评优项目', |
| | | prop: 'evaluateTaskName', |
| | | type: 'input', |
| | | }, |
| | | { |
| | | label: '候选人', |
| | | prop: 'userName', |
| | | type: 'input', |
| | | }, |
| | | { |
| | | label: '部门', |
| | | prop: 'deptName', |
| | | type: 'input' |
| | | }, |
| | | { |
| | | label: '票数', |
| | | prop: 'voteNum', |
| | | type: 'input' |
| | | }], |
| | | } |
| | | } |
| | | ]) |
| | | |
| | | const sectionOption = reactive([ |
| | | { |
| | | title: '任务名称', |
| | | prop: 'taskName', |
| | | value: '', |
| | | width: 'calc(100% / 3)' |
| | | }, |
| | | { |
| | | title: '任务类别', |
| | | prop: 'taskType', |
| | | value: '', |
| | | width: 'calc(100% / 3)' |
| | | }, |
| | | { |
| | | title: '评定标准', |
| | | prop: 'remark', |
| | | value: '', |
| | | width: 'calc(100% / 3)' |
| | | }, |
| | | { |
| | | title: '候选人截止日期', |
| | | prop: 'candidateCutoffTime', |
| | | value: '', |
| | | width: '50%' |
| | | }, |
| | | { |
| | | title: '评优截止日期', |
| | | prop: 'evaluateCutoffTime', |
| | | value: '', |
| | | width: '50%' |
| | | }, |
| | | { |
| | | title: '评优评先状态', |
| | | prop: 'evaluateState', |
| | | value: '', |
| | | width: '50%' |
| | | }, |
| | | { |
| | | title: '评优数量', |
| | | prop: 'evaluateNum', |
| | | value: '', |
| | | width: '50%' |
| | | }, |
| | | { |
| | | title: '评优人数量', |
| | | prop: 'candidateNum', |
| | | value: '', |
| | | width: '100%' |
| | | }, |
| | | { |
| | | title: '最终评定结果', |
| | | prop: 'finallyResult', |
| | | isSlot: true, |
| | | width: '100%', |
| | | evaluateState: 0, |
| | | data: [], |
| | | option: { |
| | | height: 260, |
| | | calcHeight: 30, |
| | | tip: false, |
| | | searchShow: true, |
| | | border: true, |
| | | index: true, |
| | | dialogClickModal: false, |
| | | menu: false, |
| | | menuLeft: false, |
| | | header: false, |
| | | menuFixed: 'right', |
| | | column: [{ |
| | | label: '评优项目', |
| | | prop: 'evaluateTaskName', |
| | | type: 'input', |
| | | }, |
| | | { |
| | | label: '部门', |
| | | prop: 'deptName', |
| | | type: 'input' |
| | | }, |
| | | { |
| | | label: '票数', |
| | | prop: 'voteNum', |
| | | type: 'input' |
| | | }], |
| | | } |
| | | } |
| | | ]) |
| | | |
| | | watch(() => props.params.visible, (val) => { |
| | | if (!val) return |
| | | initData() |
| | | }, { |
| | | deep: true |
| | | }) |
| | | |
| | | const candidateList = () => { |
| | | let values = { |
| | | evaluateTaskId: props.params.data.id |
| | | }; |
| | | return getCandidateList(1, 99999, values).then(res => { |
| | | const candidateRes = res.data.data.records; |
| | | return candidateRes |
| | | }); |
| | | } |
| | | |
| | | const getFinallyList = () => { |
| | | const { type } = props.params |
| | | const { id, evaluateNum } = props.params.data |
| | | const params = { |
| | | evaluateTaskId: id, |
| | | current: 1, |
| | | size: evaluateNum, |
| | | type: !type ? 2 : 1 |
| | | } |
| | | return (!type ? getFinallyResult(params) : getSectionFinallyResult(params)).then(res => { |
| | | return res.data.data.records |
| | | }) |
| | | } |
| | | |
| | | const initData = async () => { |
| | | const data = props.params.data |
| | | taskDateil.value = !props.params.type ? personOption : sectionOption |
| | | const status = { |
| | | 0: '未开始', |
| | | 1: '进行中', |
| | | 2: '已完成' |
| | | } |
| | | |
| | | for (const item of taskDateil.value) { |
| | | item.value = data[item.prop] || '暂未完善' |
| | | |
| | | if (['candidateState', 'evaluateState'].includes(item.prop)) { |
| | | item.value = status[data[item.prop]] |
| | | if (item.prop === 'evaluateState') { |
| | | const obj = taskDateil.value.find(s => s.prop === 'finallyResult') |
| | | obj.evaluateState = data[item.prop] |
| | | } |
| | | } |
| | | |
| | | if (item.prop === 'candidateNum') { |
| | | const candidateNumStrArr = [] |
| | | const { candidateNum } = _.cloneDeep(data) |
| | | candidateNum.forEach(item => { |
| | | const userList = [] |
| | | item.users.forEach(user => { |
| | | userList.push(user.name) |
| | | }) |
| | | candidateNumStrArr.push(`${item.deptName}(${item.users.length}人):${userList.join('、')}`) |
| | | }) |
| | | item.value = candidateNumStrArr.join('\n') |
| | | } |
| | | |
| | | if (item.prop === 'candidateResult') { |
| | | const res = await candidateList() |
| | | if (res.length == 0) { |
| | | item.value = '暂无候选人' |
| | | } else { |
| | | const candidates = {} |
| | | const candidateStrArr = [] |
| | | const { candidateNum } = data |
| | | candidateNum.forEach(candidate => { |
| | | res.forEach(r => { |
| | | const value = candidate.users.find(user => user.id === r.userId) |
| | | if (value) { |
| | | if (candidates[candidate.deptName] === void 0) { |
| | | candidates[candidate.deptName] = [] |
| | | } |
| | | candidates[candidate.deptName].push(value.name) |
| | | } |
| | | }) |
| | | }) |
| | | Object.keys(candidates).forEach(key => { candidateStrArr.push(`${key}(${candidates[key].length}人):${candidates[key].join('、')}`) }) |
| | | item.value = candidateStrArr.join('\n') |
| | | console.log(candidateStrArr.join('\n')); |
| | | } |
| | | } |
| | | |
| | | if (item.prop === 'finallyResult') { |
| | | const res = await getFinallyList() |
| | | item.data = res |
| | | } |
| | | } |
| | | |
| | | console.log(taskDateil.value); |
| | | |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .descriptions { |
| | | width: 100%; |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | |
| | | border: { |
| | | top: 1px solid #eeeded; |
| | | right: 1px solid #eeeded; |
| | | } |
| | | |
| | | |
| | | .descriptions-item { |
| | | display: flex; |
| | | box-sizing: border-box; |
| | | |
| | | border: { |
| | | bottom: 1px solid #eeeded; |
| | | left: 1px solid #eeeded; |
| | | } |
| | | |
| | | .label, |
| | | .value { |
| | | padding: 10px 5px; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .label { |
| | | width: 100px; |
| | | flex-shrink: 0; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | background-color: aliceblue; |
| | | border-right: 1px solid #eeeded; |
| | | } |
| | | |
| | | .value { |
| | | white-space: pre-line; |
| | | } |
| | | |
| | | .table { |
| | | padding: 10px; |
| | | width: calc(100% - 20px); |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <!-- <el-button type="warning" plain icon="el-icon-download" @click="handleExport">导出</el-button> --> |
| | | </template> |
| | | <template #menu="{ size, row, index }"> |
| | | <el-button type="primary" text plain icon="el-icon-view" @click="viewDateilDialog(row)">详情</el-button> |
| | | <el-button type="primary" text plain icon="el-icon-setting" @click="taskSettingDialog(row)">任务配置</el-button> |
| | | <!-- <el-button type="primary" text plain icon="el-icon-view" @click="viewDateilDialog(row)">详情</el-button> --> |
| | | <!-- <el-button type="primary" text plain icon="el-icon-edit" @click="editDialog(row)">编辑</el-button> --> |
| | | <el-button type="primary" text plain icon="el-icon-position" @click="publicTimeBtn(row)" |
| | | v-if="row.candidateState === 2 && row.evaluateState === 0">发布</el-button> |
| | | <el-button type="primary" v-if="row.type === 0 && row.candidateState === 2 && row.evaluateState === 0" text plain icon="el-icon-plus" |
| | | @click="addCandidateHandle(row)">新增候选人</el-button> |
| | | <!-- <el-button type="primary" text plain icon="el-icon-download">导出</el-button> --> |
| | | <el-button type="danger" text plain icon="el-icon-delete" @click="rowDel(row)">删除</el-button> |
| | | </template> |
| | | </avue-crud> |
| | | <!-- 发布弹窗 --> |
| | | <el-dialog v-model="dialogVisible" title="发布" width="500px"> |
| | | <el-form :model="publicForm" :rules="publicRules" ref="publicFormRef"> |
| | | <el-form-item label="评优评先截止时间:" prop="publicData"> |
| | | <el-date-picker v-model="publicForm.publicData" type="datetime" placeholder="请选择截止时间" |
| | | value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%;" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="timeSubmit">确认</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- 新增编辑弹窗 --> |
| | | <addDialog :params="addParams" @refreshTable="this.onLoad" /> |
| | | <!-- 新增候选人 --> |
| | | <addCandidate :params="addCandidateParams" @refreshTable="this.onLoad" /> |
| | | <add-dialog :params="addParams" @refreshTable="this.onLoad" /> |
| | | <!-- 候选人添加及配置 --> |
| | | <task-setting :params="taskSettingParams" /> |
| | | <!-- 预览弹窗 --> |
| | | <viewEvaluateDetail :params="viewEvaluateDetailParams" /> |
| | | <!-- <viewEvaluateDetail :params="viewEvaluateDetailParams" /> --> |
| | | </basic-container> |
| | | </template> |
| | | |
| | |
| | | import { dateNow } from '@/utils/date'; |
| | | import NProgress from 'nprogress'; |
| | | import 'nprogress/nprogress.css'; |
| | | import addDialog from './components/addDialog.vue'; |
| | | import addCandidate from './components/addCandidate.vue'; |
| | | import addDialog from './components/addDialog.vue';; |
| | | import viewEvaluateDetail from './components/viewEvaluateDetail.vue'; |
| | | import { getDeptTree } from '@/api/system/dept'; |
| | | import taskSetting from './components/taskSetting.vue'; |
| | | |
| | | export default { |
| | | components: { |
| | | addDialog, |
| | | addCandidate, |
| | | taskSetting, |
| | | viewEvaluateDetail |
| | | }, |
| | | data() { |
| | |
| | | selectionList: [], |
| | | option: option, |
| | | data: [], |
| | | // 发布弹窗 |
| | | dialogVisible: false, |
| | | publicForm: { |
| | | publicData: '', |
| | | }, |
| | | publicRules: { |
| | | publicData: [ |
| | | { required: true, message: '请选择发布时间', trigger: 'click' }, |
| | | ] |
| | | }, |
| | | isAddDialogVisible: false, |
| | | addParams: {}, |
| | | viewParams: {}, |
| | |
| | | }, |
| | | ], |
| | | }, |
| | | // 新增候选人params |
| | | addCandidateParams: {}, |
| | | // 任务设置参数 |
| | | taskSettingParams: {}, |
| | | // 信息预览弹窗 |
| | | viewEvaluateDetailParams: {}, |
| | | }; |
| | |
| | | this.selectionClear(); |
| | | }); |
| | | }, |
| | | deptData() { |
| | | return getDeptTree(this.website.tenantId).then(deptResult => { |
| | | const result = deptResult.data.data; |
| | | let deptList = []; |
| | | result.forEach(dept => { |
| | | if (dept.children) { |
| | | deptList = result.concat(dept.children); |
| | | delete dept.children; |
| | | } else { |
| | | deptList.push(dept); |
| | | } |
| | | }); |
| | | return deptList; |
| | | }); |
| | | }, |
| | | publicTimeBtn(row) { |
| | | this.rowData = row; |
| | | this.dialogVisible = true; |
| | | }, |
| | | // 发布 |
| | | timeSubmit() { |
| | | this.$refs.publicFormRef.validate(valid => { |
| | | if (!valid) return |
| | | const { id } = this.rowData; |
| | | const params = { |
| | | id, |
| | | // candidateState: 1, |
| | | evaluateState: 1, |
| | | evaluateCutoffTime: this.publicForm.publicData, |
| | | }; |
| | | update(params).then( |
| | | res => { |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '操作成功!', |
| | | }); |
| | | this.refreshChange(); |
| | | }, |
| | | error => { |
| | | this.$message({ |
| | | type: 'success', |
| | | message: error, |
| | | }); |
| | | } |
| | | ); |
| | | this.dialogVisible = false; |
| | | }) |
| | | }, |
| | | addCandidateHandle(row) { |
| | | this.addCandidateParams = { |
| | | visible: true, |
| | | type: 0, |
| | | data: { |
| | | ...row |
| | | } |
| | | } |
| | | }, |
| | | tabChange(value) { |
| | | this.defaultTaskType = value.prop; |
| | | }, |
| | | taskSettingDialog(row) { |
| | | this.taskSettingParams = { |
| | | visible: true, |
| | | task: row |
| | | } |
| | | } |
| | | }, |
| | | }; |
| | | </script> |