pms-front/src/views/projectBank/userProject.vue

316 lines
7.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="project-progress-container">
<!-- 左侧固定列表格 -->
<div class="content flex-col">
<div class="flex-row aic mb20">
<h2 class="textC">人员项目表</h2>
<div class="selectBox flex-row aic">
<span>选择人员</span>
<el-input
v-model="selectedUserName"
placeholder="请选择用户"
readonly
@click.native="openUserSelectDialog"
></el-input>
</div>
<div class="date-range-container">
<span class="date-range-label">统计时间:</span>
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
:clearable="false"
/>
</div>
</div>
<div class="f1">
<CustomTable
:columns="fixedColumns"
:tableData="executionData"
:showPagination="false"
:showSummary="true"
:summaryMethod="getFixedColumnsSummaries"
:tableHeight="600"
></CustomTable>
</div>
</div>
<!-- 用户选择对话框 -->
<SelectUser
:dialogVisible="userSelectDialogVisible"
:multiSelect="false"
:currentSelectedUser="selectedUser ? [selectedUser] : []"
@confirm="handleUserSelect"
@close="handleUserClose"
/>
</div>
</template>
<script>
import CustomTable from "@/components/CustomTable.vue";
import SelectUser from "@/components/SelectUser.vue";
import { projectBank } from "@/utils/api";
export default {
components: {
CustomTable,
SelectUser,
},
data() {
return {
fixedColumns: [],
executionData: [],
dateRange: [],
selectedUserName: "超级管理员",
selectedUserId: 1,
selectedUser: {
userId: 1,
selectedUserName: "超级管理员",
},
userSelectDialogVisible: false,
};
},
methods: {
getDefaultDateRange() {
const startOfMonth = this.moment().startOf("month").format("YYYY-MM-DD");
const endOfMonth = this.moment().endOf("month").format("YYYY-MM-DD");
this.dateRange = [startOfMonth, endOfMonth];
},
openUserSelectDialog() {
this.userSelectDialogVisible = true;
},
async getUserProject() {
const res = await projectBank.porjectProgress({
startDate: this.dateRange[0] + " 00:00:00",
endDate: this.dateRange[1] + " 00:00:00",
userId: this.selectedUserId,
});
this.executionData = res.data;
},
getFixedColumnsSummaries(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = "合计工时(天)";
return;
}
const values =
column.property === "detailList"
? data.map((item) => Number(item[column.property][index - 2]))
: data.map((item) => Number(item[column.property]));
if (!values.every((value) => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
return !isNaN(value) ? prev + curr : prev;
}, 0);
sums[index] = Number(sums[index].toFixed(2));
} else {
sums[index] = "";
}
});
return sums;
},
handleUserSelect(users) {
if (users.length > 0) {
this.selectedUser = users[0];
this.selectedUserId = users[0].userId;
this.selectedUserName = users[0].nickName;
} else {
this.selectedUser = null;
this.selectedUserId = "";
this.selectedUserName = "";
}
this.userSelectDialogVisible = false;
this.getUserProject();
},
goToDetail(row) {
this.$router.push({
path: "/project/detail",
query: {
id: row.projectId,
},
});
},
handleUserClose() {
this.userSelectDialogVisible = false;
},
},
watch: {
dateRange: {
deep: true,
handler(newVal) {
const days = [];
if (newVal && newVal.length === 2) {
const start = new Date(this.dateRange[0]);
const end = new Date(this.dateRange[1]);
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
const dayOfWeek = [
"周日",
"周一",
"周二",
"周三",
"周四",
"周五",
"周六",
][d.getDay()];
const dateStr = `${d.getMonth() + 1}/${d.getDate()}`;
let index = days.length;
days.push({
prop: "detailList",
label: `${dayOfWeek}\n${dateStr}`,
minWidth: 100,
type: "array",
callback: (data, row) => {
return data[index];
},
});
}
}
this.fixedColumns = [
{
prop: "projectName",
label: "项目",
type: "button",
fixed: "left",
width: 160,
callback: (data, row) => {
return `<span style="color:#1686d8;cursor:pointer">${data}</span>`;
},
Event: (data, row) => {
this.goToDetail(row);
},
},
{
prop: "allWorkTime",
label: "统计工时\n",
width: 160,
fixed: "left",
},
...days,
];
this.$nextTick(this.getUserProject());
},
},
},
mounted() {
this.getDefaultDateRange();
},
beforeDestroy() {},
};
</script>
<style lang="scss" scoped>
.project-progress-container {
display: flex;
height: 88vh;
background-color: white;
padding: 30px;
}
.content {
width: 100%;
}
.placeholder-header {
height: 102px; /* 与左侧表格的标题和日期选择器高度一致 */
}
.date-range-container {
display: flex;
align-items: center;
width: 500px;
margin-left: 100px;
}
.date-range-label {
white-space: nowrap;
margin-right: 10px;
}
.selectBox {
width: 200px;
margin-left: 35px;
}
.selectBox span {
width: 120px;
}
::v-deep .el-table {
height: 100% !important;
}
::v-deep .el-table__header th {
background-color: #4a4a4a;
color: white;
text-align: center;
}
::v-deep .el-table__body td {
text-align: center;
}
::v-deep .el-table__footer td {
background-color: #f5f7fa;
font-weight: bold;
text-align: center; /* 确保合计行内容居中 */
}
::v-deep .el-table__header .cell,
::v-deep .el-table__body .cell,
::v-deep .el-table__footer .cell {
white-space: pre-wrap;
line-height: 1.2;
padding: 8px 0;
}
::v-deep .el-table__body-wrapper {
overflow: auto;
}
::v-deep .el-table__body-wrapper ::-webkit-scrollbar {
}
/* 确保两个表格的高度一致 */
.left-section ::v-deep .el-table,
.right-section ::v-deep .el-table {
height: 100% !important;
}
/* 调整日期选择器样式 */
::v-deep .el-date-editor {
width: 100%;
}
/* 调整表格内容的字体大小 */
::v-deep .el-table {
font-size: 14px;
}
/* 调整表头的样式 */
::v-deep .el-table__header-wrapper {
background-color: #f5f7fa;
}
::v-deep .el-table__header th {
background-color: #f5f7fa;
color: #606266;
font-weight: bold;
}
/* 调整合计行的样式 */
::v-deep .el-table__footer td {
background-color: #c0c4cc !important;
font-weight: bold;
color: #606266;
}
.project-name {
cursor: pointer;
color: #409eff;
}
.project-name:hover {
text-decoration: underline;
}
::v-deep thead .el-table-fixed-column--left {
background: #d7d7d7 !important;
}
::v-deep .el-table__fixed {
box-shadow: 5px 20px 20px rgba(7, 7, 7, 0.5) !important;
}
.custom-table {
height: 100%;
}
::v-deep .el-table__footer-wrapper {
background-color: #f5f7fa;
bottom: 0;
position: absolute;
}
</style>