|
@@ -52,6 +52,7 @@
|
|
|
<el-menu-item index="1-30" v-if="permissions.taskPlanCost" @click="ssl(29)"><p>{{ $t('taskPlanCostReport') }}</p></el-menu-item>
|
|
|
<el-menu-item index="1-31" v-if="permissions.reportFTEPlanAll || permissions.reportFTEPlanPart" @click="ssl(30)"><p>FTE计划报表</p></el-menu-item>
|
|
|
<el-menu-item index="1-32" v-if="permissions.reportMonthlyFinancialWorkSchedule" @click="ssl(31)"><p>月度财务工时表</p></el-menu-item>
|
|
|
+ <el-menu-item index="1-33" v-if="permissions.reportAllTimelyTaskHours || permissions.reportRartTimelyTaskHours" @click="ssl(32)"><p>任务工时填报及时表</p></el-menu-item>
|
|
|
</el-submenu>
|
|
|
</el-menu>
|
|
|
</el-col>
|
|
@@ -70,7 +71,15 @@
|
|
|
<div class="headine headConCon" ref="headine" :style="'width:'+(windowWidth - 400)+'px'">
|
|
|
<h3 ref="headHe" style="padding-left: 10px;float:left;width:15%">{{shuz[ins]}}</h3>
|
|
|
<div class="headScreen" :style="ins == 9 || ins == 21 ? 'width:60%' : 'width:72%'">
|
|
|
- <!-- 客户项目利润表的筛选 -->
|
|
|
+ <!-- 任务工时填报及时表的筛选 -->
|
|
|
+ <template v-if="ins == 32">
|
|
|
+ <el-radio-group v-model="timelyTaskHoursRadio" size="small" @change="projectChange()">
|
|
|
+ <el-radio-button label="按任务查看"></el-radio-button>
|
|
|
+ <el-radio-button label="按人员查看"></el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 客户项目利润表的筛选 -->
|
|
|
<template v-if="ins == 4">
|
|
|
<el-select v-model="customerId" :placeholder="$t('pleaseelectcustomers')" clearable filterable size="small" @change="selcts(4)" style="margin-right:20px">
|
|
|
<el-option v-for="(item) in customerList" :key="item.id" :label="item.customerName" :value="item.id">
|
|
@@ -137,7 +146,7 @@
|
|
|
<el-option v-for="(item) in projectMainIdList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
|
|
</el-select>
|
|
|
|
|
|
- <el-select v-if="!screeningCondition.project.includes(ins)" v-model="proJuctId" :placeholder="$t('defaultText.pleaseSelectSnItem')" clearable filterable size="small" @change="projectChange()" style="margin-left:10px">
|
|
|
+ <el-select v-if="!screeningCondition.project.includes(ins)" v-model="proJuctId" :placeholder="$t('defaultText.pleaseSelectSnItem')" :clearable="ins != 32" filterable size="small" @change="projectChange()" style="margin-left:10px">
|
|
|
<el-option v-for="(item) in proListOvertime" :key="item.id" :label="item.projectName + (item.projectCode ? item.projectCode : '')" :value="item.id">
|
|
|
<span style="float: left;color: #8492a6;">{{ item.projectCode }}</span>
|
|
|
<span style="float: right;font-size: 13px;margin-left: 20px">{{ item.projectName }}</span>
|
|
@@ -1618,8 +1627,34 @@
|
|
|
</el-table-column>
|
|
|
<el-table-column prop="totalTime" align="center" label="工时合计(h)" width="120px"></el-table-column>
|
|
|
</el-table>
|
|
|
+
|
|
|
+ <!-- 任务工时填报及时表 -->
|
|
|
+ <template v-if="ins == 32">
|
|
|
+ <el-table v-if="timelyTaskHoursRadio == '按任务查看'" key="32" border :data="timelyReportingOfTaskHoursList" highlight-current-row v-loading="timelyReportingOfTaskHoursLoading" :height="+tableHeight + 50" :span-method="timelyFormForFillingInTaskHoursSpanMethod" style="width: 100%;" :max-height="+tableHeight + 50">
|
|
|
+ <el-table-column prop="projectName" align="center" label="所属项目"></el-table-column>
|
|
|
+ <el-table-column prop="taskName" align="center" label="任务"></el-table-column>
|
|
|
+ <el-table-column prop="startDate" align="center" label="任务开始时间"></el-table-column>
|
|
|
+ <el-table-column prop="endDate" align="center" label="任务截止时间"></el-table-column>
|
|
|
+ <el-table-column prop="userName" align="center" label="人员"></el-table-column>
|
|
|
+ <el-table-column prop="jobNumber" align="center" label="工号"></el-table-column>
|
|
|
+ <el-table-column prop="departmentName" align="center" label="所属部门"></el-table-column>
|
|
|
+ <el-table-column prop="timelinessRate" align="center" label="填报及时率"></el-table-column>
|
|
|
+ <el-table-column prop="timelinessRateWithLeave" align="center" label="填报及时率(含请假)"></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <el-table v-if="timelyTaskHoursRadio == '按人员查看'" key="321" border :data="timelyReportingOfTaskHoursList" highlight-current-row v-loading="timelyReportingOfTaskHoursLoading" :height="+tableHeight + 50" :span-method="timelyFormForFillingInTaskHoursSpanMethod" style="width: 100%;" :max-height="+tableHeight + 50">
|
|
|
+ <el-table-column prop="userName" align="center" label="人员"></el-table-column>
|
|
|
+ <el-table-column prop="taskName" align="center" label="任务"></el-table-column>
|
|
|
+ <el-table-column prop="startDate" align="center" label="任务开始时间"></el-table-column>
|
|
|
+ <el-table-column prop="endDate" align="center" label="任务截止时间"></el-table-column>
|
|
|
+ <el-table-column prop="timelinessRate" align="center" label="填报及时率"></el-table-column>
|
|
|
+ <el-table-column prop="timelinessRateWithLeave" align="center" label="填报及时率(含请假)"></el-table-column>
|
|
|
+ <el-table-column prop="averagePercentage" align="center" label="总填报及时率"></el-table-column>
|
|
|
+ <el-table-column prop="averageLeavePercentage" align="center" label="总填报及时率(含请假)"></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </template>
|
|
|
+
|
|
|
<!--工具条-->
|
|
|
- <el-col :span="24" class="toolbar" v-if="ins != 6 && ins != 20 && ins != 21 && tabPosition==0 && tabsType == 'all' && ins != 31">
|
|
|
+ <el-col :span="24" class="toolbar" v-if="ins != 6 && ins != 20 && ins != 21 && tabPosition==0 && tabsType == 'all' && ins != 31 && ins != 32">
|
|
|
<el-pagination
|
|
|
v-if="ins == 12"
|
|
|
@size-change="groupSizeChange"
|
|
@@ -2022,7 +2057,7 @@ export default {
|
|
|
project: [4, 8, 9, 10, 11, 14, 15, 17, 19, 20, 21, 22, 28, 30, 31], // 项目筛选条件 (不等于)
|
|
|
months: [14, 15], // 月份筛选条件 (等于)
|
|
|
monthRange: [19, 30], // 月份区间筛选条件 (等于)
|
|
|
- staff: [6, 8, 9, 19, 11, 14, 18, 23, 25, 26,28, 30], // 人员筛选条件 (等于)
|
|
|
+ staff: [6, 8, 9, 19, 11, 14, 18, 23, 25, 26,28, 30, 32], // 人员筛选条件 (等于)
|
|
|
departments: [14, 15, 23,21,26,28,19, 30], // 部门筛选条件 (等于)
|
|
|
timePeriod: [5, 6, 8, 9, 10, 11, 12, 16, 17, 18, 20, 21, 22, 24, 25, 26,28], // 时间段筛选条件 (等于)
|
|
|
},
|
|
@@ -2083,14 +2118,14 @@ export default {
|
|
|
this.$t('statisticsofovertimework'),this.$t('timecostearlywarningtable'),this.$t('personneltimeallocationtable'),
|
|
|
this.$t('statisticsofstafffillingintimerate'),this.$t('dailyreporttobereviewedstatistics'),this.$t('statisticsofpersonnelhours'),this.$t('taskgrouptimesheet'),this.$t('projectcostbaselinetable'),
|
|
|
this.$t('ren-yuan-yue-du-gong-shi-biao'), this.$t('bumenchanyuqingkuang'), this.$t('ge-fen-zu-yu-jie-duan-gong-shi-biao'), this.$t('ziXiangMuGongShiChengBenBiao'), this.$t('renWuZhongQiBiao'), this.$t('fteBaoBiao'), this.$t('youXiaoGongShiShuaiBiao'), this.$t('xiangMuFenLeiGongShiZhanBiBiao'), this.$t('fenLeiGongShiMingXiBiao'),
|
|
|
- this.$t('yuanGongXiangMuJinDuBiao'), this.$t('fenZuHaoYongJinDuBiao'), this.$t('xiangMuHaoYongJinDuBiao'), this.$t('yuanGongRenWuJinDuBiao'), this.$t('xiangMuYuGuGongShiBiao'),this.$t('yuanGongRenWuWanChengQingKuangBiao'), this.$t('taskPlanCostReport'), 'FTE计划报表', '月度财务工时表'],
|
|
|
+ this.$t('yuanGongXiangMuJinDuBiao'), this.$t('fenZuHaoYongJinDuBiao'), this.$t('xiangMuHaoYongJinDuBiao'), this.$t('yuanGongRenWuJinDuBiao'), this.$t('xiangMuYuGuGongShiBiao'),this.$t('yuanGongRenWuWanChengQingKuangBiao'), this.$t('taskPlanCostReport'), 'FTE计划报表', '月度财务工时表', '任务工时填报及时表'],
|
|
|
|
|
|
shuzArr: [this.$t('projectreport'),this.$t('projectTaskReport'),this.$t('projectcoststatement'),
|
|
|
this.$t('projectbalancesheet'),this.$t('customerprojectincomestatement'),this.$t('projectphasetimesheet'),
|
|
|
this.$t('statisticsofovertimework'),this.$t('timecostearlywarningtable'),this.$t('personneltimeallocationtable'),
|
|
|
this.$t('employeereporttimelinessrate'),this.$t('dailyreporttobereviewedstatistics'),this.$t('statisticsofpersonnelhours'),this.$t('taskgrouptimesheet'),this.$t('projectcostbaselinetable'),
|
|
|
this.$t('ren-yuan-yue-du-gong-shi-biao'), this.$t('bumenchanyuqingkuang'), this.$t('ge-fen-zu-yu-jie-duan-gong-shi-biao'), this.$t('ziXiangMuGongShiChengBenBiao'), this.$t('renWuZhongQiBiao'), this.$t('fteBaoBiao'),this.$t('youXiaoGongShiShuaiBiao'), this.$t('xiangMuFenLeiGongShiZhanBiBiao'), this.$t('fenLeiGongShiMingXiBiao'),
|
|
|
- this.$t('yuanGongXiangMuJinDuBiao'), this.$t('fenZuHaoYongJinDuBiao'), this.$t('xiangMuHaoYongJinDuBiao'), this.$t('yuanGongRenWuJinDuBiao'), this.$t('xiangMuYuGuGongShiBiao'),this.$t('yuanGongRenWuWanChengQingKuangBiao'), this.$t('taskPlanCostReport'), 'FTE计划报表', '月度财务工时表'],
|
|
|
+ this.$t('yuanGongXiangMuJinDuBiao'), this.$t('fenZuHaoYongJinDuBiao'), this.$t('xiangMuHaoYongJinDuBiao'), this.$t('yuanGongRenWuJinDuBiao'), this.$t('xiangMuYuGuGongShiBiao'),this.$t('yuanGongRenWuWanChengQingKuangBiao'), this.$t('taskPlanCostReport'), 'FTE计划报表', '月度财务工时表', '任务工时填报及时表'],
|
|
|
|
|
|
ins: 10000,
|
|
|
user: JSON.parse(sessionStorage.user),
|
|
@@ -2274,6 +2309,10 @@ export default {
|
|
|
adjustWorkingHoursVisable: false,
|
|
|
immediateVisable: false,
|
|
|
immediateDateValue: '',
|
|
|
+
|
|
|
+ timelyTaskHoursRadio: '按任务查看',
|
|
|
+ timelyReportingOfTaskHoursList: [],
|
|
|
+ timelyReportingOfTaskHoursLoading: false,
|
|
|
};
|
|
|
},
|
|
|
computed: {},
|
|
@@ -2445,6 +2484,7 @@ export default {
|
|
|
if(this.permissions.taskPlanCost) {this.ssl(29);this.takCompletedStatus = '1-30';return} else
|
|
|
if(this.permissions.reportFTEPlanAll || this.permissions.reportFTEPlanPart) {this.ssl(30);this.takCompletedStatus = '1-31';return} else
|
|
|
if(this.permissions.reportMonthlyFinancialWorkSchedule) {this.ssl(31);this.takCompletedStatus = '1-32';return} else
|
|
|
+ if(this.permissions.reportAllTimelyTaskHours || this.permissions.reportRartTimelyTaskHours) {this.ssl(32);this.takCompletedStatus = '1-33';return} else
|
|
|
{this.allWrong = false}
|
|
|
},
|
|
|
rowspan(spanArr,position,spanName,dataItem = [],fields=false){
|
|
@@ -2749,7 +2789,7 @@ export default {
|
|
|
this.getGroupWorktimeAll()
|
|
|
},
|
|
|
getList(e) {
|
|
|
- let noUserList = [16, 17, 18, 19, 20, 21, 22, 24, 25, 26,27,29,30,31]
|
|
|
+ let noUserList = [16, 17, 18, 19, 20, 21, 22, 24, 25, 26,27,29,30,31,32]
|
|
|
if(this.ins == 24) {
|
|
|
if(this.tabsType == 'all') {
|
|
|
this.rangeDatas = []
|
|
@@ -2852,6 +2892,9 @@ export default {
|
|
|
if (this.ins == 31) {
|
|
|
this.getObtainMonthlyFinancialStatements();
|
|
|
}
|
|
|
+ if (this.ins == 32) {
|
|
|
+ this.getTimelyReportingOfTaskHours();
|
|
|
+ }
|
|
|
},
|
|
|
exportExcel() {
|
|
|
var url = "/project";
|
|
@@ -3097,7 +3140,16 @@ export default {
|
|
|
sl.taskType = this.taskTypeId
|
|
|
}
|
|
|
sl.projectId = this.proJuctId
|
|
|
- }
|
|
|
+ } else if(this.ins == 32) {
|
|
|
+ fName = `${this.timelyTaskHoursRadio}任务工时填报及时表.xlsx`
|
|
|
+ url = `/report/exportReportRateOfTask`
|
|
|
+ sl.projectId = this.proJuctId
|
|
|
+ sl.userIds = this.userId
|
|
|
+ sl.type = {
|
|
|
+ '按任务查看': 0,
|
|
|
+ '按人员查看': 1,
|
|
|
+ }[this.timelyTaskHoursRadio]
|
|
|
+ }
|
|
|
this.exportReportLoading = true
|
|
|
this.http.post(url, sl,
|
|
|
res => {
|
|
@@ -3188,6 +3240,9 @@ export default {
|
|
|
this.projectMainId = ''
|
|
|
this.getProjectListOvertime()
|
|
|
}
|
|
|
+ if(index == 32) {
|
|
|
+ this.proJuctId = this.proListOvertime[0] && this.proListOvertime[0].id || ''
|
|
|
+ }
|
|
|
this.getList();
|
|
|
},
|
|
|
stateKeySel(){
|
|
@@ -5103,6 +5158,96 @@ export default {
|
|
|
})
|
|
|
})
|
|
|
},
|
|
|
+ // 任务工时填报及时表
|
|
|
+ getTimelyReportingOfTaskHours() {
|
|
|
+ console.log('发起请求 任务工时填报及时表', this.timelyTaskHoursRadio, this.page, this.size, this.total, this.proJuctId, this.userId, this.timelyReportingOfTaskHoursLoading, this.timelyReportingOfTaskHoursList)
|
|
|
+ let sl = {}
|
|
|
+ sl.projectId = this.proJuctId
|
|
|
+ sl.userIds = this.userId
|
|
|
+ sl.type = {
|
|
|
+ '按任务查看': 0,
|
|
|
+ '按人员查看': 1,
|
|
|
+ }[this.timelyTaskHoursRadio]
|
|
|
+ this.timelyReportingOfTaskHoursLoading = true
|
|
|
+ this.postData(`/report/getReportRateOfTask`, { ...sl }).then(res => {
|
|
|
+ this.timelyReportingOfTaskHoursList = res.data || []
|
|
|
+ }).finally(() => {
|
|
|
+ this.timelyReportingOfTaskHoursLoading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 任务工时填报及时表开始合并
|
|
|
+ timelyFormForFillingInTaskHoursSpanMethod({ row, column, rowIndex }) {
|
|
|
+ const theFirstColumn = {
|
|
|
+ '按任务查看': ['projectName'],
|
|
|
+ '按人员查看': ['userName']
|
|
|
+ }
|
|
|
+
|
|
|
+ const secondColumn = {
|
|
|
+ '按任务查看': ['taskName'],
|
|
|
+ '按人员查看': ['averagePercentage', 'averageLeavePercentage']
|
|
|
+ }
|
|
|
+ if (theFirstColumn[this.timelyTaskHoursRadio].includes(column.property)) {
|
|
|
+ return this.getBelongingProjectSpan(rowIndex, theFirstColumn[this.timelyTaskHoursRadio]);
|
|
|
+ }
|
|
|
+ if (secondColumn[this.timelyTaskHoursRadio].includes(column.property)) {
|
|
|
+ return this.getTaskSpan(rowIndex, theFirstColumn[this.timelyTaskHoursRadio], column.property);
|
|
|
+ }
|
|
|
+
|
|
|
+ return { rowspan: 1, colspan: 1 };
|
|
|
+ },
|
|
|
+
|
|
|
+ getBelongingProjectSpan(rowIndex, filed) {
|
|
|
+ const data = this.timelyReportingOfTaskHoursList;
|
|
|
+ const currentProject = data[rowIndex][filed];
|
|
|
+ let rowspan = 1;
|
|
|
+
|
|
|
+ // 如果不是第一个或不是新分组的行,就返回 rowspan: 0(不显示)
|
|
|
+ if (rowIndex > 0 && data[rowIndex - 1][filed] === currentProject) {
|
|
|
+ return { rowspan: 0, colspan: 0 };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算 rowspan
|
|
|
+ for (let i = rowIndex + 1; i < data.length; i++) {
|
|
|
+ if (data[i][filed] === currentProject) {
|
|
|
+ rowspan++;
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return { rowspan, colspan: 1 };
|
|
|
+ },
|
|
|
+
|
|
|
+ getTaskSpan(rowIndex, preconditions, postCondition) {
|
|
|
+ const data = this.timelyReportingOfTaskHoursList;
|
|
|
+ const currentTask = data[rowIndex][postCondition];
|
|
|
+ const currentProject = data[rowIndex][preconditions];
|
|
|
+ let rowspan = 1;
|
|
|
+
|
|
|
+ // 如果上一行任务和项目都一样,说明是连续的重复项,则返回 0
|
|
|
+ if (
|
|
|
+ rowIndex > 0 &&
|
|
|
+ data[rowIndex - 1][postCondition] === currentTask &&
|
|
|
+ data[rowIndex - 1][preconditions] === currentProject
|
|
|
+ ) {
|
|
|
+ return { rowspan: 0, colspan: 0 };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算 rowspan
|
|
|
+ for (let i = rowIndex + 1; i < data.length; i++) {
|
|
|
+ if (
|
|
|
+ data[i][postCondition] === currentTask &&
|
|
|
+ data[i][preconditions] === currentProject
|
|
|
+ ) {
|
|
|
+ rowspan++;
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return { rowspan, colspan: 1 };
|
|
|
+ },
|
|
|
+
|
|
|
// 单独封装请求
|
|
|
async postData(urls, param) {
|
|
|
return new Promise((resolve, reject) => {
|