From 43492eb5d2e9964110bbb8766f0bbd8138a8f27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98wangjiuyun?= <‘1595161655@qq.com> Date: Fri, 3 Jan 2025 18:00:18 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A9=E6=95=88=E8=80=83=E6=A0=B8=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E5=9F=BA=E6=9C=AC=E5=AE=8C=E6=88=90=20=E5=89=A9?= =?UTF-8?q?=E4=BD=99=E4=BB=BB=E5=8A=A1=E7=BC=96=E8=BE=91=EF=BC=8C=E6=8C=87?= =?UTF-8?q?=E6=A0=87=E9=85=8D=E7=BD=AE=20=E4=BA=BA=E5=91=98=E7=BB=A9?= =?UTF-8?q?=E6=95=88=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/task/right.png | Bin 0 -> 223 bytes src/assets/task/titleIcon.png | Bin 0 -> 14503 bytes src/components/CustomTable.vue | 4 + src/components/SelectUser.vue | 56 ++- src/utils/api.js | 51 ++ src/views/project/list.vue | 9 +- src/views/workAppraisal/detail.vue | 377 +++++++++------ src/views/workAppraisal/manager.vue | 250 ++++++---- src/views/workAppraisal/managerUser.vue | 573 ++++++++++++----------- src/views/workAppraisal/normalWorker.vue | 358 ++++++++------ src/views/workAppraisal/taskSet.vue | 226 +++++---- 11 files changed, 1137 insertions(+), 767 deletions(-) create mode 100644 src/assets/task/right.png create mode 100644 src/assets/task/titleIcon.png diff --git a/src/assets/task/right.png b/src/assets/task/right.png new file mode 100644 index 0000000000000000000000000000000000000000..b52c789b67fa37f0390daed064a45da4fab7fb26 GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP>``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&eBeu<}xV@L(#+ldEx8x(k4qxIut8v_eu{f#=+ zOL@&31n)SwJ$SV;?9fDquV=hDd~fghvxI?Hhxe-!SJj3Xxjd)Iw_h&s@%X<ce3Ooh zooa_>nV+L!>!b2Ryo-$`jx^13QPJ=`($sTgzt9!w*p(mI<99nbA7FkqRi{qu%#RO1 P`x!i4{an^LB{Ts5Pa8>P literal 0 HcmV?d00001 diff --git a/src/assets/task/titleIcon.png b/src/assets/task/titleIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..d75c8f310c2926acc2590a450a9caae2654c0182 GIT binary patch literal 14503 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 FV1jXQ@00)l literal 0 HcmV?d00001 diff --git a/src/components/CustomTable.vue b/src/components/CustomTable.vue index 9fe4962..25ef062 100644 --- a/src/components/CustomTable.vue +++ b/src/components/CustomTable.vue @@ -9,6 +9,7 @@ :border="border" :highlight-current-row="highligt" @row-click="rowClick" + @sort-change="sortChange" :row-key="rowKey" :height="tableHeight" > @@ -184,6 +185,9 @@ export default { toggleRowSelection(row, selected) { this.$refs.elTableRef?.toggleRowSelection(row, selected); }, + sortChange(data) { + this.$emit("sortChange", data); + }, }, updated() { if (this.$refs.elTableRef && this.$refs.elTableRef.doLayout) { diff --git a/src/components/SelectUser.vue b/src/components/SelectUser.vue index df6502e..677adaf 100644 --- a/src/components/SelectUser.vue +++ b/src/components/SelectUser.vue @@ -86,11 +86,10 @@ export default { type: Boolean, default: false, }, - highligt:{ + highligt: { type: Boolean, default: true, - } - + }, }, data() { return { @@ -148,7 +147,6 @@ export default { this.handleClose(); }, handleSelectionChange(val) { - if (this.isInternalChange) return; if (!this.multiSelect) { this.isInternalChange = true; @@ -184,13 +182,11 @@ export default { this.selectedUsers = [val]; }, rowClick(row) { - - if(!this.showSelection){ + if (!this.showSelection) { if (row.userId == this.selectedUsers[0]?.userId) - this.$refs.customTableRef.$refs.elTableRef.setCurrentRow(); - else this.selectedUsers = [row] + this.$refs.customTableRef.$refs.elTableRef.setCurrentRow(); + else this.selectedUsers = [row]; } - ; }, }, watch: { @@ -219,13 +215,27 @@ export default { currentSelectedUser: { handler(newVal) { this.$nextTick(() => { - let row = this.userData.find( - (ele) => ele.userId == newVal[0]?.userId - ); - if (row) { - this.$refs.customTableRef?.setCurrentRow(row); - this.selectedUsers = [row]; - } else this.$refs.customTableRef?.setCurrentRow(); + if (!this.showSelection) { + let row = this.userData.find( + (ele) => ele.userId == newVal[0]?.userId + ); + if (row) { + this.$refs.customTableRef?.setCurrentRow(row); + this.selectedUsers = [row]; + } else { + this.selectedUsers = []; + this.$refs.customTableRef?.setCurrentRow(); + } + } else { + if (!newVal.length) { + this.selectedUsers = []; + this.$refs.customTableRef?.clearSelection(); + } else { + newVal.forEach((ele) => { + this.$refs.customTableRef?.toggleRowSelection(ele, true); + }); + } + } }); }, immediate: true, @@ -234,12 +244,14 @@ export default { userData: { handler(newVal) { this.$nextTick(() => { - let row = this.userData.find( - (ele) => ele.userId == this.currentSelectedUser[0]?.userId - ); - if (row) { - this.selectedUsers = [row]; - this.$refs.customTableRef?.setCurrentRow(row); + if (!this.showSelection) { + let row = this.userData.find( + (ele) => ele.userId == this.currentSelectedUser[0]?.userId + ); + if (row) { + this.selectedUsers = [row]; + this.$refs.customTableRef?.setCurrentRow(row); + } } }); }, diff --git a/src/utils/api.js b/src/utils/api.js index c074c0b..e1e4bb0 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -134,3 +134,54 @@ export const systemApi = { method: 'get', }), } + +// 任务考核板块 +export const taskApi = { + getTaskUserList: (data) => request({ + url: '/examine/user', + method: 'get', + params: data, + }), + getTaskScoreDetail: (data) => request({ + url: '/examine/detail', + method: 'get', + params: data, + }), + saveTaskUserScore: (data) => request({ + url: '/examine/detail/batch', + method: 'post', + data: data, + }), + getTaskListSelf: (data) => request({ + url: '/task/list', + method: 'get', + params: data, + }), + + getTaskList: (data) => request({ + url: '/task/get', + method: 'get', + params: data, + }), + addTask: (data) => request({ + url: '/task/add', + method: 'post', + data: data, + }), + upDateTask: (data) => request({ + url: '/task/update', + method: 'put', + data: data, + }), + delTask: (id) => request({ + url: `/task/${id}`, + method: 'delete', + }), + getTaskSet: (id) => request({ + url: `/task/target/${id}`, + method: 'get', + }), + + + +} diff --git a/src/views/project/list.vue b/src/views/project/list.vue index fa2f214..7d202f1 100644 --- a/src/views/project/list.vue +++ b/src/views/project/list.vue @@ -20,7 +20,11 @@ ></el-input> </el-form-item> <el-form-item label="项目状态" class="form-item"> - <el-select v-model="searchForm.projectState" placeholder="项目状态" clearable> + <el-select + v-model="searchForm.projectState" + placeholder="项目状态" + clearable + > <el-option v-for="item in statusList" :key="item.dictValue" @@ -161,7 +165,7 @@ export default { return `<span style="color: ${color}">${status}</span>`; }, }, - { prop: "teamNum", label: "参与项目人数",width:100 }, + { prop: "teamNum", label: "参与项目人数", width: 100 }, { prop: "createByName", label: "项目创建人" }, { prop: "operation", @@ -188,6 +192,7 @@ export default { Object.keys(this.searchForm).forEach((key) => { this.searchForm[key] = ""; }); + this.currentSelectedUser = []; this.fetchProjectList(); }, addProject() { diff --git a/src/views/workAppraisal/detail.vue b/src/views/workAppraisal/detail.vue index 281d492..eae902a 100644 --- a/src/views/workAppraisal/detail.vue +++ b/src/views/workAppraisal/detail.vue @@ -2,93 +2,110 @@ <div class="conetentBox"> <div class="flex-row jcsb aic userBox"> <div>张三 2024年员工年度考核</div> - <div>考核评分:</div> + <div v-if="!isNormal">考核评分:{{ saveData.manageScore }}</div> </div> - <div - v-for="(table, index) in tableData" - :key="index" - style="margin-bottom: 20px" - > - <div class="userBox">表格 {{ index + 1 }}</div> - <el-table :data="table" style="width: 100%"> - <el-table-column - v-for="(header, hIndex) in headers" - :key="hIndex" - :label="header.label" - :prop="header.prop" - :width="header.width" - > - </el-table-column> - <el-table-column label="评分" prop="score" width="300"> - <template slot-scope="scope"> - <div style="width: 80%; position: relative"> - <div> - <el-slider - v-model="scope.row.score" - :min="0" - :max="10" - @change="updateScore(scope.row)" - ></el-slider> - </div> - <div class="statusText">未打分</div> - - <div class="flex-row jcsb" style="margin-left: 10px"> - <div>0</div> - <div class="scoreText">{{ scope.row.score }}分</div> - <div>10</div> - </div> - </div> - </template> - </el-table-column> - <el-table-column - label="自评总结" - prop="score" - width="300" - v-if="isNormal" - > - <template slot-scope="scope"> - <div> - <el-button - @click="handleEdit(scope.row)" - type="text" - size="mini" - icon="el-icon-edit" - :class="{ hasEdit: !scope.row.remark }" - >{{ scope.row.remark ? "已填写" : "未填写" }}</el-button - > - </div> - </template> - </el-table-column> - </el-table> - </div> - <div> - <div v-if="!isNormal"> - <div class="userBox">总体评价</div> - <div> - <el-input - type="textarea" - :autosize="{ minRows: 4 }" - placeholder="0/300" - v-model="managerText" + <div class="tableBox"> + <div + v-for="(table, index) in tableData" + :key="index" + style="margin-bottom: 20px" + > + <div class="userBox">{{ table[0].reviewCategory }}</div> + <el-table :data="table" style="width: 100%"> + <el-table-column + v-for="(header, hIndex) in headers" + :key="hIndex" + :label="header.label" + :prop="header.prop" + :width="header.width" > - </el-input> + </el-table-column> + <el-table-column label="评分" prop="score" width="300"> + <template slot-scope="scope"> + <div style="width: 80%; position: relative"> + <div> + <el-slider + v-model="scope.row.score" + :min="0" + :max="10" + @change="updateScore(scope.row)" + :disabled="!isEdit" + ></el-slider> + </div> + <div class="statusText" v-show="scope.row.score == 0"> + 未打分 + </div> + + <div class="flex-row jcsb" style="margin-left: 10px"> + <div>0</div> + <div class="scoreText">{{ scope.row.score }}分</div> + <div>10</div> + </div> + </div> + </template> + </el-table-column> + <el-table-column + label="自评总结" + prop="score" + width="300" + v-if="isNormal" + > + <template slot-scope="scope"> + <div> + <el-button + v-if="isEdit" + @click="handleEdit(scope.row)" + type="text" + size="mini" + icon="el-icon-edit" + :class="{ hasEdit: !scope.row.remark }" + >{{ scope.row.remark ? "已填写" : "未填写" }}</el-button + > + <el-button + v-if="!isEdit && scope.row.remark" + @click="handleEdit(scope.row)" + type="text" + size="mini" + icon="el-icon-view" + :class="{ hasEdit: !scope.row.remark }" + >查看</el-button + > + <el-button + v-if="!isEdit && !scope.row.remark" + type="text" + size="mini" + :class="{ hasEdit: !scope.row.remark }" + >未填写</el-button + > + </div> + </template> + </el-table-column> + </el-table> + </div> + <div> + <div v-if="!isNormal"> + <div class="userBox">总体评价</div> + <div> + <el-input + type="textarea" + :autosize="{ minRows: 4 }" + placeholder="0/300" + v-model="saveData.judgeContent" + :disabled="!isEdit" + > + </el-input> + </div> </div> </div> - <p class="flex-row jcc" style="gap: 40px"> - <el-button - type="default" - style="width: 150px" - @click="saveScoreCheck(0)" - >保存</el-button - > - <el-button - type="primary" - style="width: 150px" - @click="saveScoreCheck(1)" - >提交</el-button - > - </p> </div> + <p class="flex-row jcc" style="gap: 40px" v-if="isEdit"> + <el-button type="default" style="width: 150px" @click="saveScoreCheck(0)" + >保存</el-button + > + <el-button type="primary" style="width: 150px" @click="saveScoreCheck(1)" + >提交</el-button + > + </p> <el-dialog title="自评总结" :visible.sync="dialogVisible" width="30%"> <div> <el-input @@ -96,76 +113,93 @@ :autosize="{ minRows: 4 }" placeholder="0/200" v-model="remark" + :disabled="!isEdit" > </el-input> </div> - <span slot="footer" class="dialog-footer"> + <span slot="footer" class="dialog-footer" v-if="isEdit"> <el-button @click="cancelEdit">取 消</el-button> <el-button type="primary" @click="saveEdit">确 定</el-button> </span> </el-dialog> - <el-dialog - title="确认提交绩效评分" - :visible.sync="dialogVisible2" - width="25%" - center - > - <div>提交后将无法修改,该操作不可逆,请确认后再试</div> - <span slot="footer" class="dialog-footer"> - <el-button @click="dialogVisible2 = false">取 消</el-button> - <el-button type="primary" @click="saveScore">确 定</el-button> - </span> - </el-dialog> - <el-dialog - title="提交失败" - :visible.sync="dialogVisible3" - width="25%" - center - > - <div>存在未评分绩效项,请完善后再试</div> - <span slot="footer" class="dialog-footer"> - <el-button @click="dialogVisible3 = false">关闭</el-button> - </span> - </el-dialog> </div> </template> <script> +import { taskApi } from "@/utils/api"; + export default { data() { return { taskId: "", isNormal: false, dialogVisible: false, - dialogVisible2: false, - dialogVisible3: false, selectRow: false, saveStatus: "", remark: "", + isEdit: "", headers: [ - { label: "考核项", prop: "name", width: 300 }, - { label: "评分标准", prop: "description" }, + { label: "考核项", prop: "reviewItem", width: 300 }, + { label: "评分标准", prop: "remarks" }, ], // 二维数组,每个子数组代表一个表格的数据 tableData: [ - [ - { name: "项目1", description: "描述1", score: 0, remark: "ss" }, - { name: "项目2", description: "描述2", score: 0, remark: "" }, - ], - [ - { name: "项目3", description: "描述3", score: 0, remark: "" }, - { name: "项目4", description: "描述4", score: 0, remark: "ss" }, - ], // 可以根据需要添加更多表格数据 ], - managerText: "", + // 获取评分的参数 + examineTaskId: "", + examineId: "", + reviewType: "", + userId: "", + reviewType: "", + // 保存评分的参数 + saveData: { + examineId: "", + examineStatus: "", + examineStatusSelf: "", + manageScore: "", + taskId: "", + judgeContent: "", + examineDetailList: [], + }, }; }, methods: { updateScore(row) { - // 这里可以添加更新评分后的逻辑 - console.log(`项目: ${row.name}, 评分: ${row.score}`); + // 实时计算组长评分数 + if (!this.isNormal) + this.saveData.manageScore = + this.tableData + .flat() + .reduce((total, ele) => (ele.score || 0) * ele.weight + total, 0) / + 10; + }, + // 获取评分详情 + getSocreDetail() { + let param = { + examineTaskId: this.examineTaskId, + reviewType: this.reviewType, + }; + if (this.isNormal) { + param.userId = this.userId; + } else { + param.examineId = this.examineId; + } + taskApi.getTaskScoreDetail(param).then((res) => { + let objData = {}; + res.data.examineConfigDetailVoList.forEach((ele) => { + if (!objData[ele.reviewCategory]) objData[ele.reviewCategory] = []; + objData[ele.reviewCategory].push(ele); + }); + this.tableData = Object.values(objData); + if (!this.examineId) { + this.examineId = res.data.examineUser.examineId; + } else { + this.saveData.judgeContent = res.data.examineUser.judgeContent; + this.saveData.manageScore = res.data.examineUser.manageScore; + } + }); }, handleEdit(row) { this.dialogVisible = true; @@ -186,25 +220,99 @@ export default { cancelEdit() { this.dialogVisible = false; }, - saveScoreCheck(status) { - this.dialogVisible2 = true; - this.saveStatus = status; + saveDataSet(status) { + if (!this.isNormal) { + this.saveData.examineStatus = status; + } else { + this.saveData.examineStatusSelf = status; + } + this.saveData.examineDetailList = this.tableData.flat().map((ele) => ({ + score: ele.score, + configId: ele.id, + remark: ele.remark, + })); + this.saveData.taskId = this.examineTaskId; + this.saveData.examineId = this.examineId; }, - saveScore() { - this.dialogVisible2 = false; - if (this.managerText.length > 300) { + saveScoreCheck(status) { + // 组装保存数据 + this.saveDataSet(status); + + // 保存 + if (status == 0) { + this.saveScore(); + return; + } + // 提交 + if ( + this.saveData.examineDetailList.filter((ele) => !ele.score).length && + !this.isNormal + ) { + this.$alert("存在未评分绩效项,请完善后再试", "提交失败", { + confirmButtonText: "确定", + type: "warning", + }); + } else if ( + this.saveData.examineDetailList.filter((ele) => !ele.remark).length && + this.isNormal && + status + ) { + this.$alert("自评总结为必填,请完善后再试", "提交失败", { + confirmButtonText: "确定", + type: "warning", + }); + } else if (this.saveData.judgeContent.length > 300) { this.$message({ message: "总体评价限制300个字符", type: "warning", }); + } else if (!this.saveData.judgeContent.length && !this.isNormal) { + this.$message({ + message: "总体评价为必填", + type: "warning", + }); + } else { + if (status) { + this.$confirm( + "提交后将无法修改,该操作不可逆,请确认后再试", + "确认提交绩效评分", + { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning", + } + ).then(() => { + this.saveScore(); + }); + } else { + this.saveScore(); + } } - if(this.tableData.filter((ele)=>!ele.remark).length){ - this.dialogVisible3=true - } + }, + saveScore() { + taskApi.saveTaskUserScore(this.saveData).then((res) => { + this.$message({ + message: "操作成功", + type: "success", + }); + this.$router.go(-1); + }); + }, + getRouteData() { + this.isNormal = this.$route.query.isNormal || ""; + this.examineTaskId = this.$route.query.examineTaskId; + this.examineId = this.$route.query.examineId; + this.reviewType = this.$route.query.reviewType; + this.saveData.reviewType = this.$route.query.reviewType; + this.isEdit = this.$route.query.edit == 1 ? true : false; + this.userId = this.$store.state.user.id; }, }, created() { - this.isNormal = this.$route.query.isNormal || ""; + this.getRouteData(); + }, + mounted() { + this.getSocreDetail(); }, }; </script> @@ -230,6 +338,9 @@ export default { margin: 10px !important; /* width: 95%; */ } +::v-deep .el-slider__runway.disabled .el-slider__bar { + background-color: #ff5722; +} ::v-deep .el-slider__bar { height: 20px; border-radius: 20px; @@ -260,4 +371,8 @@ export default { ::v-deep .el-dialog { margin-top: 15% !important; } +.tableBox { + height: 85%; + overflow: auto; +} </style> diff --git a/src/views/workAppraisal/manager.vue b/src/views/workAppraisal/manager.vue index a14f4d2..fc3d019 100644 --- a/src/views/workAppraisal/manager.vue +++ b/src/views/workAppraisal/manager.vue @@ -1,150 +1,167 @@ <template> <div class="appraisal-manager"> - <el-row class="assessment-container"> - <div class="statusText">进行中</div> - <el-col :span="8" v-for="item in ongoingAssessments" :key="item.id"> - <el-card class="card"> - <div class="card-content"> - <div class="flex-row jcsb"> - <div>{{ item.title }}</div> - <div>考核人数:{{ item.participants }}</div> - </div> - <p>截止时间:{{ item.deadline }}</p> - <div class="status-actions"> - <el-tag>进行中</el-tag> - <div class="action-buttons"> - <el-button type="primary" @click="viewDetails(item.id,1)">考核评分</el-button> + <el-tabs v-model="activeName" @tab-click="handleClick"> + <el-tab-pane label="进行中" name="进行中"> + <div class="assessment-container flex-row"> + <div v-for="item in taskList['0']" :key="item.id" class="taskBox"> + <div class="card-content"> + <div class="cardBox flex-col"> + <img + src="@/assets/task/titleIcon.png" + alt="" + style="width: 32px; height: 34px" + /> + <div class="flex-row aic nameBox"> + <div>{{ item.taskName }}</div> + <el-tag type="warning" size="mini">进行中</el-tag> + </div> + <div class="timeBox"> + 截止时间:{{ item.endTime.split(" ")[0] }} + </div> + </div> + <div class="status-actions aic"> + <div class="peopleNumber"> + 考核人数:{{ item.peopleNumber }} + </div> + <div + class="action-buttons aic" + @click="viewDetails(item.id, 0)" + > + 考核评分 + <img + src="@/assets/task/right.png" + alt="" + style="width: 16px; height: 16px" + /> + </div> </div> </div> - </div> - </el-card> - </el-col> - </el-row> - <el-row class="assessment-container"> - <div class="statusText">已过期</div> - <el-col :span="8" v-for="item in expiredAssessments" :key="item.id"> - <el-card class="card"> - <div class="card-content"> - <div class="flex-row jcsb"> - <div>{{ item.title }}</div> - <div>考核人数:{{ item.participants }}</div> - </div> - <p>截止时间:{{ item.deadline }}</p> - <div class="status-actions"> - <el-tag type="info">已过期</el-tag> - <div class="action-buttons"> - <el-button type="primary" @click="viewDetails(item.id,0)">查看详情</el-button> + </div></div + ></el-tab-pane> + <el-tab-pane label="已过期" name="已过期"> + <div class="assessment-container flex-row"> + <div v-for="item in taskList['2']" :key="item.id" class="taskBox"> + <div class="card-content"> + <div class="cardBox flex-col"> + <img + src="@/assets/task/titleIcon.png" + alt="" + style="width: 32px; height: 34px" + /> + <div class="flex-row aic nameBox"> + <div>{{ item.taskName }}</div> + <el-tag type="info" size="mini">进行中</el-tag> + </div> + <div class="timeBox"> + 截止时间:{{ item.endTime.split(" ")[0] }} + </div> + </div> + <div class="status-actions aic"> + <div class="peopleNumber"> + 考核人数:{{ item.peopleNumber }} + </div> + <div + class="action-buttons aic" + @click="viewDetails(item.id, 0)" + > + 考核评分 + <img + src="@/assets/task/right.png" + alt="" + style="width: 16px; height: 16px" + /> + </div> </div> </div> - </div> - </el-card> - </el-col> - </el-row> - + </div></div + ></el-tab-pane> + </el-tabs> </div> </template> <script> +import { taskApi } from "@/utils/api"; + export default { name: "AppraisalManager", data() { return { - ongoingAssessments: [ - { - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - },{ - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - },{ - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - },{ - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - },{ - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - }, - ], - expiredAssessments: [ - { - id: 2, - title: '2023年员工年度考核', - deadline: '2023.12.31', - participants: 10, - }, - { - id: 3, - title: '2024年Q3员工年度考核', - deadline: '2024.10.15', - participants: 10, - }, - { - id: 4, - title: '2024年Q2员工年度考核', - deadline: '2024.10.15', - participants: 10, - }, - ], + activeName: "进行中", + taskList: [], }; }, methods: { - goToAssessment(id) { - // 跳转到考核页面 - console.log(`跳转到考核 ID: ${id}`); + getTaks() { + taskApi.getTaskListSelf().then((res) => { + this.taskList = res.data; + }); }, - - viewDetails(id,edit) { + viewDetails(id, isOutData) { // 查看考核详情 this.$router.push({ - path: "/workAppraisal/managerUser", - query: { id: id,edit }, - }); + path: "/workAppraisal/managerUser", + query: { taskId: id, isOutData }, + }); }, }, + created() { + this.getTaks(); + }, }; </script> <style scoped> .appraisal-manager { padding: 30px; - background-color: #f8f8f8; - height: 100vh; /* 设置整体高度 */ + background-color: #fff; + height: calc(100vh - 100px); /* 设置整体高度 */ } .assessment-container { - max-height:45%; /* 减去标题高度 */ + max-height: 650px; /* 减去标题高度 */ overflow-y: auto; /* 允许垂直滚动 */ + gap: 2%; + padding-top: 20px; + padding-left: 20px; + flex-wrap: wrap; +} +.taskBox { + width: 23%; + height: 200px; + margin-bottom: 40px; } .card { margin-bottom: 20px; - border-radius: 10px; + border-radius: 8px; width: 80%; } .card-content { - padding:0 10px; + padding: 20px 0 0 0; background-color: #fff; border-radius: 10px; - /* box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); */ + box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); +} +.cardBox { + gap: 20px; + + padding: 0 20px; } .status-actions { display: flex; justify-content: space-between; /* 两端对齐 */ align-items: center; /* 垂直居中 */ + height: 44px; + background-color: #f7faff; + padding: 0 20px; + margin-top: 20px; +} +.peopleNumber { + color: #666; + font-size: 14px; + font-weight: bold; } .status-text { @@ -154,10 +171,41 @@ export default { .action-buttons { display: flex; gap: 10px; /* 按钮之间的间距 */ + color: #4096ff; + font-size: 16px; + font-weight: bold; + cursor: pointer; } -.statusText{ +.statusText { font-size: 26px; margin: 20px 0; font-weight: bold; } -</style> \ No newline at end of file +.timeBox { + font-size: 14px; + color: #999999; + font-weight: bold; +} +::v-deep .el-tabs__item.is-active { + color: #4096ff; +} +::v-deep .el-tabs__item { + font-size: 18px; + font-weight: bold; + color: #999999; +} +::v-deep .el-tabs__active-bar { + height: 3px; + width: 32px !important; + left: 10px; +} +.nameBox { + font-size: 16px; + font-weight: bold; + color: #333; + gap: 10px; +} +::v-deep .el-tag--warning { + color: #ea741e; +} +</style> diff --git a/src/views/workAppraisal/managerUser.vue b/src/views/workAppraisal/managerUser.vue index 6e80694..4ee3fb3 100644 --- a/src/views/workAppraisal/managerUser.vue +++ b/src/views/workAppraisal/managerUser.vue @@ -1,288 +1,311 @@ <template> - <div class="project-list"> - <div class="search-bar"> - <el-form - :inline="true" - :model="searchForm" - class="demo-form-inline" - size="small" - > - <el-form-item label="考核人员" class="form-item"> - <el-input - v-model="searchForm.projectLeaderName" - placeholder="考核人员" - readonly - @click.native="openUserSelectDialog" - ><el-button slot="append" icon="el-icon-s-custom"></el-button - ></el-input> - </el-form-item> - <el-form-item label="状态" class="form-item"> - <el-select v-model="searchForm.projectState" placeholder="状态" clearable> - <el-option - v-for="item in statusList" - :key="item.value" - :label="item.label" - :value="item.value" - /> - </el-select> - </el-form-item> - <el-form-item class="search-buttons"> - <el-button type="primary" @click="onSearch">查询</el-button> - <el-button @click="onReset">重置</el-button> - </el-form-item> - </el-form> - </div> - - <div class="f1 df"> - <CustomTable - :columns="columns" - :tableData="tableData" - :total="total" - :show-selection="false" - :show-index="true" - @size-change="handleSizeChange" - @current-change="handleCurrentChange" - tableHeight="495px" - > - <template slot="operation" slot-scope="{ row }"> - <div class="operation-buttons"> - <el-button - @click="handleEdit(row,1)" - type="text" - size="mini" - icon="el-icon-edit" - >去评分</el-button - > - <el-button - type="text" - size="mini" - icon="el-icon-view" - @click="handleEdit(row,0)" - >查看详情</el-button - > - </div> - </template> - </CustomTable> - </div> - <SelectUser - :dialogVisible="userSelectDialogVisible" - :currentSelectedUser="currentSelectedUser" - :showSelection="true" - :highligt="false" - @confirm="handleUserConfirm" - @close="handleUserClose" - /> + <div class="project-list"> + <div class="search-bar"> + <el-form + :inline="true" + :model="searchForm" + class="demo-form-inline" + size="small" + > + <el-form-item label="考核人员" class="form-item"> + <el-input + v-model="searchForm.userName" + placeholder="考核人员" + readonly + @click.native="openUserSelectDialog" + ><el-button slot="append" icon="el-icon-s-custom"></el-button + ></el-input> + </el-form-item> + <el-form-item label="状态" class="form-item"> + <el-select + v-model="searchForm.examineStatus" + placeholder="状态" + clearable + > + <el-option + v-for="item in statusList" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + <el-form-item class="search-buttons"> + <el-button type="primary" @click="onSearch">查询</el-button> + <el-button @click="onReset">重置</el-button> + </el-form-item> + </el-form> </div> - </template> - - <script> - import CustomTable from "@/components/CustomTable.vue"; - import SelectUser from "@/components/SelectUser.vue"; - import { projectApi, systemApi } from "@/utils/api"; - - export default { - components: { - CustomTable, - SelectUser, - }, - data() { - return { - searchForm: { - projectName: "", - projectLeaderName: "", - projectLeader: "", - projectState: "", + + <div class="f1 df"> + <CustomTable + :columns="columns" + :tableData="tableData" + :total="total" + :show-selection="false" + :show-index="true" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + @sortChange="sortChange" + tableHeight="495px" + > + <template slot="operation" slot-scope="{ row }"> + <div class="operation-buttons"> + <el-button + v-if="isOutData == 0 && row.examineStatus == '0'" + @click="handleEdit(row, 1)" + type="text" + size="mini" + icon="el-icon-edit" + >去评分</el-button + > + <el-button + v-if="row.examineStatus == '1' || isOutData == 1" + type="text" + size="mini" + icon="el-icon-view" + @click="handleEdit(row, 0)" + >查看详情</el-button + > + </div> + </template> + </CustomTable> + </div> + <SelectUser + :dialogVisible="userSelectDialogVisible" + :currentSelectedUser="currentSelectedUser" + :showSelection="true" + :highligt="false" + @confirm="handleUserConfirm" + @close="handleUserClose" + /> + </div> +</template> + +<script> +import CustomTable from "@/components/CustomTable.vue"; +import SelectUser from "@/components/SelectUser.vue"; +import { taskApi } from "@/utils/api"; + +export default { + components: { + CustomTable, + SelectUser, + }, + data() { + return { + searchForm: { + userIdList: [], + userName: "", + examineStatus: "", + }, + taskId: "", + isOutData: "", + columns: [ + { prop: "userName", label: "考核人员" }, + { prop: "manageScore", label: "考核评分", sortable: "custom" }, + { + prop: "examineStatus", + label: "状态", + type: "status", + callback: (value) => { + if (value == 0) var color = "#333"; + else var color = "#1686d68"; + + return `<span style="color: ${color}">${ + value == 0 ? "待评分" : "已完成" + }</span>`; + }, }, - columns: [ - { prop: "projectName", label: "考核人员"}, - { prop: "projectCode", label: "考核评分", sortable: true}, - { - prop: "projectState", - label: "状态", - type: "status", - callback: (value) => { - if(value==1) - var color = "#333"; - else - var color = "#1686d68"; - - return `<span style="color: ${color}">${value}</span>`; - }, - }, - { - prop: "operation", - label: "操作", - width: "250", - className: "operation-column", - }, - ], - tableData: [], - total: 0, - userSelectDialogVisible: false, - currentSelectedUser: [], - pageNum: 1, // 当前页码 - pageSize: 10, // 每页条数 - statusList: [ - {label:'全部',value:''}, - {label:'待评分',value:'0'}, - {label:'已完成',value:'1'}, - - ], - }; + { + prop: "operation", + label: "操作", + width: "250", + className: "operation-column", + }, + ], + tableData: [], + total: 0, + userSelectDialogVisible: false, + currentSelectedUser: [], + pageNum: 1, // 当前页码 + pageSize: 10, // 每页条数 + statusList: [ + { label: "全部", value: "" }, + { label: "待评分", value: "0" }, + { label: "已完成", value: "1" }, + ], + isAsc: "", + }; + }, + methods: { + onSearch() { + this.taskUserList(); }, - methods: { - onSearch() { - this.fetchProjectList(); - }, - onReset() { - Object.keys(this.searchForm).forEach((key) => { - this.searchForm[key] = ""; + onReset() { + Object.keys(this.searchForm).forEach((key) => { + this.searchForm[key] = ""; + }); + this.currentSelectedUser = []; + this.taskUserList(); + }, + handleEdit(row, edit) { + this.$router.push({ + path: "/workAppraisal/detail", + query: { + edit, + examineTaskId: this.taskId, + examineId: row.id, + reviewType: 0, + }, + }); + }, + taskUserList() { + taskApi + .getTaskUserList({ + ...this.searchForm, + taskId: this.taskId, + pageNum: this.pageNum, + pageSize: this.pageSize, + isAsc: this.isAsc, + }) + .then((res) => { + this.tableData = res.rows; + this.total = res.total; }); - this.fetchProjectList(); - }, - handleEdit(row,edit) { - this.$router.push({ - path: "/workAppraisal/detail", - query: { id: row.id,edit }, - }); - }, - fetchProjectList() { - projectApi - .listProject({ - ...this.searchForm, - pageNum: this.pageNum, - pageSize: this.pageSize, - }) - .then((res) => { - this.tableData = res.rows; - this.total = res.total; - }); - }, - handleSizeChange(size) { - this.pageSize = size; - this.pageNum = 1; // 重置为第一页 - this.fetchProjectList(); - }, - handleCurrentChange(page) { - this.pageNum = page; - this.fetchProjectList(); - }, - openUserSelectDialog() { - this.userSelectDialogVisible = true; - }, - handleUserConfirm(data) { - this.searchForm.projectLeaderName = data.map((ele)=>ele.nickName); - this.searchForm.projectLeader = data.map((ele)=>ele.userId); - }, - handleUserClose() { - this.userSelectDialogVisible = false; - }, }, - mounted() { - this.fetchProjectList(); + handleSizeChange(size) { + this.pageSize = size; + this.pageNum = 1; // 重置为第一页 + this.taskUserList(); }, - }; - </script> - - <style lang="scss" scoped> - .project-list { - padding: 20px; - background-color: white; - height: 88vh; - box-sizing: border-box; - overflow: hidden; - display: flex; - flex-direction: column; - } - - .search-bar { - margin-bottom: 20px; - } - - .demo-form-inline { - // display: flex; - // flex-wrap: nowrap; - // align-items: flex-start; - } - - .demo-form-inline .el-form-item { - // margin-right: 50px; /* 将间距设置为 30px */ - margin-bottom: 0; - } - - .demo-form-inline .el-form-item:last-child { - margin-right: 0; /* 移除最后一个元素的右边距 */ - } - - .form-item { - flex: 1; - } - - .form-item ::v-deep .el-form-item__content { - // width: 100%; - } - - .form-item ::v-deep .el-input, - .form-item ::v-deep .el-select { - // width: 100%; - } - - .search-buttons { - white-space: nowrap; - } - - ::v-deep .operation-buttons .el-button { - padding: 4px 8px; - margin: 0 2px; - } - - ::v-deep .operation-column { - background-color: #ffffff; - box-shadow: -2px 0 5px rgba(241, 112, 6, 0.1); - } - - .el-button.is-text { - min-width: 32px !important; - } - - .dialog-footer { - display: flex; - justify-content: center; - align-items: center; - } - - .dialog-footer .el-button { - margin: 0 10px; - } - - .delete-content { - display: flex; - align-items: center; - justify-content: center; - text-align: center; - } - - .warning-icon { - font-size: 24px; - color: #e6a23c; - margin-right: 10px; - } - - /* 添加以下样式来使对话框垂直居中 */ - ::v-deep .delete-dialog.el-dialog { - margin-top: 0 !important; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } - ::v-deep .el-table th { + handleCurrentChange(page) { + this.pageNum = page; + this.taskUserList(); + }, + openUserSelectDialog() { + this.userSelectDialogVisible = true; + }, + handleUserConfirm(data) { + this.searchForm.userName = data.map((ele) => ele.nickName).join(","); + this.searchForm.userIdList = data.map((ele) => ele.userId); + }, + handleUserClose() { + this.userSelectDialogVisible = false; + }, + sortChange({ order }) { + this.isAsc = + order == "descending" ? "desc" : order == "ascending" ? "asc" : ""; + this.taskUserList(); + }, + }, + created() { + this.taskId = this.$route.query.taskId; + this.isOutData = this.$route.query.isOutData; + }, + mounted() { + this.taskUserList(); + }, +}; +</script> + +<style lang="scss" scoped> +.project-list { + padding: 20px; + background-color: white; + height: 88vh; + box-sizing: border-box; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.search-bar { + margin-bottom: 20px; +} + +.demo-form-inline { + // display: flex; + // flex-wrap: nowrap; + // align-items: flex-start; +} + +.demo-form-inline .el-form-item { + // margin-right: 50px; /* 将间距设置为 30px */ + margin-bottom: 0; +} + +.demo-form-inline .el-form-item:last-child { + margin-right: 0; /* 移除最后一个元素的右边距 */ +} + +.form-item { + flex: 1; +} + +.form-item ::v-deep .el-form-item__content { + // width: 100%; +} + +.form-item ::v-deep .el-input, +.form-item ::v-deep .el-select { + // width: 100%; +} + +.search-buttons { + white-space: nowrap; +} + +::v-deep .operation-buttons .el-button { + padding: 4px 8px; + margin: 0 2px; +} + +::v-deep .operation-column { + background-color: #ffffff; + box-shadow: -2px 0 5px rgba(241, 112, 6, 0.1); +} + +.el-button.is-text { + min-width: 32px !important; +} + +.dialog-footer { + display: flex; + justify-content: center; + align-items: center; +} + +.dialog-footer .el-button { + margin: 0 10px; +} + +.delete-content { + display: flex; + align-items: center; + justify-content: center; + text-align: center; +} + +.warning-icon { + font-size: 24px; + color: #e6a23c; + margin-right: 10px; +} + +/* 添加以下样式来使对话框垂直居中 */ +::v-deep .delete-dialog.el-dialog { + margin-top: 0 !important; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} +::v-deep .el-table th { text-align: center; } ::v-deep .el-table .cell { text-align: center; } - - </style> - \ No newline at end of file +</style> diff --git a/src/views/workAppraisal/normalWorker.vue b/src/views/workAppraisal/normalWorker.vue index fa0c445..8d7f9e8 100644 --- a/src/views/workAppraisal/normalWorker.vue +++ b/src/views/workAppraisal/normalWorker.vue @@ -1,163 +1,217 @@ <template> - <div class="appraisal-manager"> - <el-row class="assessment-container"> - <div class="statusText">进行中</div> - <el-col :span="8" v-for="item in ongoingAssessments" :key="item.id"> - <el-card class="card"> + <div class="appraisal-manager"> + <el-tabs v-model="activeName" @tab-click="handleClick"> + <el-tab-pane label="进行中" name="进行中"> + <div class="assessment-container flex-row"> + <div v-for="item in taskList['0']" :key="item.id" class="taskBox"> <div class="card-content"> - <div class="flex-row jcsb"> - <div>{{ item.title }}</div> - <div>考核人数:{{ item.participants }}</div> - </div> - <p>截止时间:{{ item.deadline }}</p> - <div class="status-actions"> - <el-tag>进行中</el-tag> - <div class="action-buttons"> - <el-button type="primary" @click="viewDetails(item.id,1)">考核评分</el-button> + <div class="cardBox flex-col"> + <img + src="@/assets/task/titleIcon.png" + alt="" + style="width: 32px; height: 34px" + /> + <div class="flex-row aic nameBox"> + <div>{{ item.taskName }}</div> + <el-tag type="warning" size="mini">进行中</el-tag> + </div> + <div class="timeBox"> + 截止时间:{{ item.endTime.split(" ")[0] }} + </div> + </div> + <div class="status-actions aic"> + <div class="peopleNumber"> + 考核人数:{{ item.peopleNumber }} + </div> + <div + class="action-buttons aic" + @click="viewDetails(item.id, 0)" + > + 考核评分 + <img + src="@/assets/task/right.png" + alt="" + style="width: 16px; height: 16px" + /> </div> </div> </div> - </el-card> - </el-col> - </el-row> - <el-row class="assessment-container"> - <div class="statusText">已过期</div> - <el-col :span="8" v-for="item in expiredAssessments" :key="item.id"> - <el-card class="card"> + </div></div + ></el-tab-pane> + <el-tab-pane label="已过期" name="已过期"> + <div class="assessment-container flex-row"> + <div v-for="item in taskList['2']" :key="item.id" class="taskBox"> <div class="card-content"> - <div class="flex-row jcsb"> - <div>{{ item.title }}</div> - <div>考核人数:{{ item.participants }}</div> - </div> - <p>截止时间:{{ item.deadline }}</p> - <div class="status-actions"> - <el-tag type="info">已过期</el-tag> - <div class="action-buttons"> - <el-button type="primary" @click="viewDetails(item.id,0)">查看详情</el-button> + <div class="cardBox flex-col"> + <img + src="@/assets/task/titleIcon.png" + alt="" + style="width: 32px; height: 34px" + /> + <div class="flex-row aic nameBox"> + <div>{{ item.taskName }}</div> + <el-tag type="info" size="mini">进行中</el-tag> + </div> + <div class="timeBox"> + 截止时间:{{ item.endTime.split(" ")[0] }} + </div> + </div> + <div class="status-actions aic"> + <div class="peopleNumber"> + 考核人数:{{ item.peopleNumber }} + </div> + <div + class="action-buttons aic" + @click="viewDetails(item.id, 0)" + > + 考核评分 + <img + src="@/assets/task/right.png" + alt="" + style="width: 16px; height: 16px" + /> </div> </div> </div> - </el-card> - </el-col> - </el-row> - - </div> - </template> - - <script> - export default { - name: "NormalWorker", - data() { - return { - ongoingAssessments: [ - { - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - },{ - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - },{ - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - },{ - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - },{ - id: 1, - title: '2024年员工年度考核', - deadline: '2024.12.31', - participants: 10, - }, - ], - expiredAssessments: [ - { - id: 2, - title: '2023年员工年度考核', - deadline: '2023.12.31', - participants: 10, - }, - { - id: 3, - title: '2024年Q3员工年度考核', - deadline: '2024.10.15', - participants: 10, - }, - { - id: 4, - title: '2024年Q2员工年度考核', - deadline: '2024.10.15', - participants: 10, - }, - ], - }; + </div></div + ></el-tab-pane> + </el-tabs> + </div> +</template> + +<script> +import { taskApi } from "@/utils/api"; + +export default { + name: "NormalWorker", + data() { + return { + activeName: "进行中", + taskList: [], + }; + }, + methods: { + getTaks() { + taskApi.getTaskListSelf().then((res) => { + this.taskList = res.data; + }); }, - methods: { - goToAssessment(id) { - // 跳转到考核页面 - console.log(`跳转到考核 ID: ${id}`); - }, - - viewDetails(id,edit) { - // 查看考核详情 - this.$router.push({ - path: "/workAppraisal/detail", - query: { id: id,edit,isNormal:true }, - }); - }, + viewDetails(id, edit) { + // 查看考核详情 + this.$router.push({ + path: "/workAppraisal/detail", + query: { + id: id, + edit, + isNormal: true, + examineTaskId: 1, + reviewType: 1, + }, + }); }, - }; - </script> - - <style scoped> - .appraisal-manager { - padding: 30px; - background-color: #f8f8f8; - height: 100vh; /* 设置整体高度 */ - } - - .assessment-container { - max-height:45%; /* 减去标题高度 */ - overflow-y: auto; /* 允许垂直滚动 */ - } - - .card { - margin-bottom: 20px; - border-radius: 10px; - width: 80%; - } - - .card-content { - padding:0 10px; - background-color: #fff; - border-radius: 10px; - /* box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); */ - } - - .status-actions { - display: flex; - justify-content: space-between; /* 两端对齐 */ - align-items: center; /* 垂直居中 */ - } - - .status-text { - font-weight: bold; /* 状态文本加粗 */ - } - - .action-buttons { - display: flex; - gap: 10px; /* 按钮之间的间距 */ - } - .statusText{ - font-size: 26px; - margin: 20px 0; - font-weight: bold; - } - </style> \ No newline at end of file + }, + created() { + this.getTaks(); + }, +}; +</script> + +<style scoped> +.appraisal-manager { + padding: 30px; + background-color: #fff; + height: calc(100vh - 100px); /* 设置整体高度 */ +} + +.assessment-container { + max-height: 650px; /* 减去标题高度 */ + overflow-y: auto; /* 允许垂直滚动 */ + gap: 2%; + padding-top: 20px; + padding-left: 20px; + flex-wrap: wrap; +} +.taskBox { + width: 23%; + height: 200px; + margin-bottom: 40px; +} + +.card { + margin-bottom: 20px; + border-radius: 8px; + width: 80%; +} + +.card-content { + padding: 20px 0 0 0; + background-color: #fff; + border-radius: 10px; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); +} +.cardBox { + gap: 20px; + + padding: 0 20px; +} + +.status-actions { + display: flex; + justify-content: space-between; /* 两端对齐 */ + align-items: center; /* 垂直居中 */ + height: 44px; + background-color: #f7faff; + padding: 0 20px; + margin-top: 20px; +} +.peopleNumber { + color: #666; + font-size: 14px; + font-weight: bold; +} + +.status-text { + font-weight: bold; /* 状态文本加粗 */ +} + +.action-buttons { + display: flex; + gap: 10px; /* 按钮之间的间距 */ + color: #4096ff; + font-size: 16px; + font-weight: bold; + cursor: pointer; +} +.statusText { + font-size: 26px; + margin: 20px 0; + font-weight: bold; +} +.timeBox { + font-size: 14px; + color: #999999; + font-weight: bold; +} +::v-deep .el-tabs__item.is-active { + color: #4096ff; +} +::v-deep .el-tabs__item { + font-size: 18px; + font-weight: bold; + color: #999999; +} +::v-deep .el-tabs__active-bar { + height: 3px; + width: 32px !important; + left: 10px; +} +.nameBox { + font-size: 16px; + font-weight: bold; + color: #333; + gap: 10px; +} +::v-deep .el-tag--warning { + color: #ea741e; +} +</style> diff --git a/src/views/workAppraisal/taskSet.vue b/src/views/workAppraisal/taskSet.vue index 4bc66bc..796eeac 100644 --- a/src/views/workAppraisal/taskSet.vue +++ b/src/views/workAppraisal/taskSet.vue @@ -8,11 +8,14 @@ size="small" > <el-form-item label="任务名称" class="form-item"> - <el-input v-model="searchForm.name" placeholder="任务名称"></el-input> + <el-input + v-model="searchForm.taskName" + placeholder="任务名称" + ></el-input> </el-form-item> <el-form-item label="任务状态" class="form-item"> <el-select - v-model="searchForm.projectState" + v-model="searchForm.taskStatus" placeholder="状态" clearable > @@ -94,16 +97,20 @@ :rules="rules" label-width="100px" > - <el-form-item label="任务名称" class="form-item" prop="name"> + <el-form-item label="任务名称" class="form-item" prop="taskName"> <el-input - v-model="taskData.name" + v-model="taskData.taskName" placeholder="0/20" style="width: 90%" ></el-input> </el-form-item> - <el-form-item label="考核人员" class="form-item" prop="userName"> + <el-form-item + label="考核人员" + class="form-item" + prop="peopleNumberDetail" + > <el-input - v-model="taskData.userName" + v-model="taskData.peopleNumberDetail" placeholder="考核人员" readonly style="width: 90%" @@ -111,12 +118,13 @@ ><el-button slot="append" icon="el-icon-s-custom"></el-button ></el-input> </el-form-item> - <el-form-item label="截止时间" class="form-item" prop="time"> + <el-form-item label="截止时间" class="form-item" prop="endTime"> <el-date-picker - v-model="taskData.time" + v-model="taskData.endTime" type="date" style="width: 90%" placeholder="选择日期" + value-format="yyyy-MM-dd 23:59:59" > </el-date-picker> </el-form-item> @@ -131,35 +139,42 @@ <div class="modal"> <div class="left"> <div class="setText">累计权重</div> - <el-collapse v-model="letfValue" :accordion="true" style="height: 300px;"> + <el-collapse + v-model="letfValue" + :accordion="true" + style="height: 300px;overflow: auto;" + > <el-collapse-item v-for="(item, index) in scoreList" :key="index" - :name="item.name" + :name="item.title" > <template #title> <div class="jcsb flex-row contentTitle"> <span class="setTitle">{{ item.title }}</span> - <span class="statusText">{{ item.score }}%</span> + <span class="statusText">{{ item.weight }}%</span> </div> </template> <div> <div - v-for="(item, index) in item.list" + v-for="(ele, index) in item.list" :key="index" class="flex-row jcsb leftSub" > - <div>{{ item.name }}</div> - <div class="statusText">{{ item.score }}%</div> + <div>{{ ele.reviewItem }}</div> + <div class="statusText">{{ ele.weight }}%</div> </div> </div> </el-collapse-item> </el-collapse> - <div class="flex-row jcsb" style="margin-top: 20px;padding-right: 15px;"> + <div + class="flex-row jcsb" + style="margin-top: 20px; padding-right: 15px" + > <div class="setTitle">总计</div> <div class="statusText"> {{ - scoreList.reduce((total, ele) => total + (ele.score || 0), 0) + scoreList.reduce((total, ele) => total + (ele.weight || 0), 0) }}% </div> </div> @@ -172,18 +187,22 @@ <div> <div v-for="(item, index) in ( - scoreList.find((ele) => ele.name == letfValue) || {} + scoreList.find((ele) => ele.title == letfValue) || {} ).list" :key="index" style="margin-bottom: 10px" class="flex-row jcsb aic" > - <div style="width: 50%">{{ item.name }}</div> + <div style="width: 50%">{{ item.reviewItem }}</div> <div class="center" style="width: 50%"> - <el-slider v-model="item.score" :max="20"></el-slider> + <el-slider + v-model="item.weight" + :max="20" + @change="totalWeight" + ></el-slider> <div class="flex-row jcsb scoreBox" style="margin-left: 15px"> <div>0%</div> - <div class="scoreText">{{ item.score }}%</div> + <div class="scoreText">{{ item.weight }}%</div> <div>20%</div> </div> </div> @@ -202,7 +221,7 @@ <script> import CustomTable from "@/components/CustomTable.vue"; import SelectUser from "@/components/SelectUser.vue"; -import { projectApi, systemApi } from "@/utils/api"; +import { taskApi } from "@/utils/api"; export default { components: { @@ -212,25 +231,41 @@ export default { data() { return { searchForm: { - name: "", - status: "", + taskName: "", + taskStatus: "", }, columns: [ - { prop: "projectName", label: "任务名称" }, - { prop: "projectCode", label: "考核人数" }, + { prop: "taskName", label: "任务名称" }, + { prop: "peopleNumber", label: "考核人数" }, { - prop: "projectState", + prop: "taskStatus", label: "任务状态", type: "status", callback: (value) => { if (value == 1) var color = "#333"; else var color = "#1686d68"; - return `<span style="color: ${color}">${value}</span>`; + return `<span style="color: ${color}">${ + value ? "已过期" : "进行中" + }</span>`; + }, + }, + { + prop: "createTime", + label: "创建时间", + type: "status", + callback: (value) => { + return value.split(" ")[0]; + }, + }, + { + prop: "endTime", + label: "截至时间", + type: "status", + callback: (value) => { + return value.split(" ")[0]; }, }, - { prop: "projectCode", label: "创建时间" }, - { prop: "projectCode", label: "截至时间" }, { prop: "operation", @@ -253,57 +288,36 @@ export default { dialogVisible1: false, isEdit: false, taskData: { - name: "", - time: "", - userName: "", - userId: [], + id: "", + taskName: "", + peopleNumberDetail: "", + userIdList: [], + endTime: "", + peopleNumber: 0, }, rules: { - name: [ + taskName: [ { required: true, message: "请输入活动名称", trigger: "blur" }, { min: 1, max: 20, message: "长度在 3 到 5 个字符", trigger: "blur" }, ], - userName: [ + peopleNumberDetail: [ { required: true, message: "请选择考核人员", trigger: "blur" }, ], - time: [{ required: true, message: "请选择截止时间", trigger: "blur" }], + endTime: [ + { required: true, message: "请选择截止时间", trigger: "blur" }, + ], }, dialogVisible2: false, letfValue: "", - scoreList: [ - { - name: "progress", - title: "项目进度符合度", - score: 0, - list: [{ name: "1111" }, { name: "22" }], - }, - { - name: "achievement", - title: "项目成果达成度", - score: 0, - list: [{ name: "33" }, { name: "44" }], - }, - { - name: "documentation", - title: "项目文档完整性", - score: 0, - list: [{ name: "55" }, { name: "66" }], - }, - { - name: "innovation", - title: "技术创新点及影响力", - score: 0, - list: [{ name: "77" }, { name: "88" }], - }, - ], + scoreList: [], }; }, watch: { scoreList: { handler(newVal, oldVal) { this.scoreList.forEach((ele) => { - ele.score = ele.list.reduce( - (total, ele) => total + (ele.score || 0), + ele.weight = ele.list.reduce( + (total, ele) => total + (ele.weight || 0), 0 ); }); @@ -313,17 +327,17 @@ export default { }, methods: { onSearch() { - this.fetchProjectList(); + this.getTaskList(); }, onReset() { Object.keys(this.searchForm).forEach((key) => { this.searchForm[key] = ""; }); - this.fetchProjectList(); + this.getTaskList(); }, - fetchProjectList() { - projectApi - .listProject({ + getTaskList() { + taskApi + .getTaskList({ ...this.searchForm, pageNum: this.pageNum, pageSize: this.pageSize, @@ -336,18 +350,21 @@ export default { handleSizeChange(size) { this.pageSize = size; this.pageNum = 1; // 重置为第一页 - this.fetchProjectList(); + this.getTaskList(); }, handleCurrentChange(page) { this.pageNum = page; - this.fetchProjectList(); + this.getTaskList(); }, openUserSelectDialog() { this.userSelectDialogVisible = true; }, handleUserConfirm(data) { - this.taskData.userName = data.map((ele) => ele.nickName); - this.taskData.userId = data.map((ele) => ele.userId); + this.taskData.peopleNumberDetail = data + .map((ele) => ele.nickName) + .join(","); + this.taskData.userIdList = data.map((ele) => ele.userId); + this.taskData.peopleNumber = data.length; }, handleUserClose() { this.userSelectDialogVisible = false; @@ -359,12 +376,33 @@ export default { editTask(row) { this.isEdit = true; this.dialogVisible1 = true; - this.taskData = row; + this.taskData.id = row.id; + this.taskData.taskName = row.taskName; + this.taskData.peopleNumber = row.peopleNumber; + this.taskData.peopleNumberDetail = row.peopleNumberDetail; + this.taskData.userIdList = row.userIdList; + this.currentSelectedUser = []; + (row.userIdList || []).forEach((ele) => { + this.currentSelectedUser.push(ele); + }); }, setTask(row) { - this.dialogVisible2 = true; + taskApi.getTaskSet(row.id).then((res) => { + let objData = {}; + res.data.forEach((ele) => { + if (!objData[ele.reviewCategory]) objData[ele.reviewCategory] = []; + objData[ele.reviewCategory].push(ele); + }); + this.scoreList = Object.values(objData).map((ele) => ({ + title: ele[0].reviewCategory, + list: ele, + weight: ele.reduce((total, ele) => (ele.weight || 0) + total, 0), + })); + + this.dialogVisible2 = true; + }); }, - delTask() { + delTask(row) { this.$confirm( "删除任务及绩效数据,该操作不可逆,请谨慎操作", "确认删除任务", @@ -374,16 +412,37 @@ export default { type: "warning", } ).then(() => { - this.$message({ - type: "success", - message: "删除成功!", + taskApi.delTask(row.id).then((res) => { + this.$message({ + type: "success", + message: "删除成功!", + }); + this.getTaskList(); }); }); }, saveTask() { this.$refs.taskFormRef.validate((valid) => { if (valid) { - alert("submit!"); + if (this.taskData.id) { + taskApi.upDateTask(this.taskData).then((res) => { + this.$message({ + type: "success", + message: "修改成功!", + }); + this.dialogVisible1 = false; + this.getTaskList(); + }); + } else { + taskApi.addTask(this.taskData).then((res) => { + this.$message({ + type: "success", + message: "新增成功!", + }); + this.dialogVisible1 = false; + this.getTaskList(); + }); + } } else { console.log("error submit!!"); return false; @@ -392,7 +451,7 @@ export default { }, }, mounted() { - this.fetchProjectList(); + this.getTaskList(); }, }; </script> @@ -503,7 +562,6 @@ export default { display: flex; border-bottom: 1px solid #ccc; border-top: 1px solid #ccc; - } .left { width: 40%; @@ -566,7 +624,7 @@ export default { .statusText { color: #ff5722; } -::v-deep .el-collapse{ - border: none !important; +::v-deep .el-collapse { + border: none !important; } </style>