|
|
|
|
@ -99,7 +99,7 @@
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
|
|
<!-- 调整汇总工时对话框 -->
|
|
|
|
|
<el-dialog :title="adjustDialog.title" v-model="adjustDialog.visible" width="1000px" append-to-body>
|
|
|
|
|
<el-dialog :title="adjustDialog.title" v-model="adjustDialog.visible" width="1200px" append-to-body>
|
|
|
|
|
<div v-if="adjustData" class="mt-4">
|
|
|
|
|
<el-descriptions title="汇总统计" :column="4" border class="mb-4">
|
|
|
|
|
<el-descriptions-item label="项目总工时">{{ adjustData.totalProjectHours }}</el-descriptions-item>
|
|
|
|
|
@ -109,9 +109,21 @@
|
|
|
|
|
<el-descriptions-item label="标准天数">{{ adjustData.standardDays }}</el-descriptions-item>
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
|
|
|
|
|
<div class="mb-4 flex items-center">
|
|
|
|
|
<div class="mb-4 flex flex-wrap items-center">
|
|
|
|
|
<div class="mr-6 mb-2 flex items-center">
|
|
|
|
|
<span class="mr-2 text-sm font-medium">人员搜索:</span>
|
|
|
|
|
<el-input v-model="staffSearchName" placeholder="输入姓名搜索..." clearable style="width: 250px" prefix-icon="Search" />
|
|
|
|
|
<el-select v-model="staffSearchUserId" placeholder="输入人员搜索" clearable filterable style="width: 200px">
|
|
|
|
|
<el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.userId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mr-6 mb-2 flex items-center">
|
|
|
|
|
<span class="mr-2 text-sm font-medium">原项目号:</span>
|
|
|
|
|
<el-input v-model="staffSearchProjectCode" placeholder="输入项目号搜索" clearable style="width: 200px" prefix-icon="Search" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mr-6 mb-2 flex items-center">
|
|
|
|
|
<span class="mr-2 text-sm font-medium">原项目名:</span>
|
|
|
|
|
<el-input v-model="staffSearchProjectName" placeholder="输入项目名搜索" clearable style="width: 250px" prefix-icon="Search" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<el-table :data="filteredDetailList" border max-height="400">
|
|
|
|
|
@ -124,15 +136,31 @@
|
|
|
|
|
</el-tag>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="原始项目" prop="originalProjectName" align="center" show-overflow-tooltip />
|
|
|
|
|
<el-table-column label="原始工时" prop="originalHours" align="center" />
|
|
|
|
|
<el-table-column label="调整项目" align="center" width="200">
|
|
|
|
|
<el-table-column label="原项目号" prop="originalProjectCode" align="center" show-overflow-tooltip />
|
|
|
|
|
<el-table-column label="原项目名" prop="originalProjectName" align="center" show-overflow-tooltip />
|
|
|
|
|
<el-table-column label="原工时" prop="originalHours" align="center" />
|
|
|
|
|
<el-table-column label="调整项目号" align="center" width="200">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="scope.row.adjustedProjectId"
|
|
|
|
|
filterable
|
|
|
|
|
clearable
|
|
|
|
|
placeholder="请选择项目"
|
|
|
|
|
placeholder="选择项目号"
|
|
|
|
|
v-if="scope.row.isProject === '1'"
|
|
|
|
|
@change="(val) => handleProjectChange(val, scope.row)"
|
|
|
|
|
>
|
|
|
|
|
<el-option v-for="item in projectList" :key="item.projectId" :label="item.projectCode" :value="item.projectId" />
|
|
|
|
|
</el-select>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="调整项目名" align="center" width="250">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="scope.row.adjustedProjectId"
|
|
|
|
|
filterable
|
|
|
|
|
clearable
|
|
|
|
|
placeholder="选择项目名"
|
|
|
|
|
v-if="scope.row.isProject === '1'"
|
|
|
|
|
@change="(val) => handleProjectChange(val, scope.row)"
|
|
|
|
|
>
|
|
|
|
|
@ -228,6 +256,7 @@ import {
|
|
|
|
|
import { TimesheetSummaryVO, TimesheetSummaryQuery, TimesheetSummaryForm } from '@/api/oa/erp/timesheetSummary/types';
|
|
|
|
|
import { getErpProjectInfoList } from '@/api/oa/erp/projectInfo';
|
|
|
|
|
import { allListDept } from '@/api/system/dept';
|
|
|
|
|
import { listUser } from '@/api/system/user';
|
|
|
|
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
|
|
|
|
|
|
|
@ -249,6 +278,13 @@ const dialog = reactive<DialogOption>({
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const deptList = ref<any[]>([]);
|
|
|
|
|
const userList = ref<any[]>([]);
|
|
|
|
|
|
|
|
|
|
/** 查询用户列表 */
|
|
|
|
|
const getUserList = async () => {
|
|
|
|
|
const res = await listUser({ pageNum: 1, pageSize: 1000 } as any);
|
|
|
|
|
userList.value = res.rows;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 查询部门列表 */
|
|
|
|
|
const getDeptList = async () => {
|
|
|
|
|
@ -262,8 +298,8 @@ const columns = ref<FieldOption[]>([
|
|
|
|
|
{ key: 1, label: `租户编号`, visible: true },
|
|
|
|
|
{ key: 2, label: `汇总编号`, visible: true },
|
|
|
|
|
{ key: 3, label: `月份编码(YYYYMM)`, visible: true },
|
|
|
|
|
{ key: 4, label: `部门ID`, visible: true },
|
|
|
|
|
{ key: 5, label: `汇总人(部门负责人)用户ID`, visible: true },
|
|
|
|
|
{ key: 4, label: `部门`, visible: true },
|
|
|
|
|
{ key: 5, label: `部门负责人`, visible: true },
|
|
|
|
|
{ key: 6, label: `关联月标准工时ID`, visible: false },
|
|
|
|
|
{ key: 7, label: `月标准工时天数(冗余,取自标准月表)`, visible: true },
|
|
|
|
|
{ key: 8, label: `项目工时合计(天)`, visible: true },
|
|
|
|
|
@ -409,7 +445,8 @@ const handleExport = () => {
|
|
|
|
|
proxy?.download(
|
|
|
|
|
'oa/erp/timesheetSummary/export',
|
|
|
|
|
{
|
|
|
|
|
...queryParams.value
|
|
|
|
|
...queryParams.value,
|
|
|
|
|
summaryIds: ids.value
|
|
|
|
|
},
|
|
|
|
|
`timesheetSummary_${new Date().getTime()}.xlsx`
|
|
|
|
|
);
|
|
|
|
|
@ -418,6 +455,7 @@ const handleExport = () => {
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getDeptList();
|
|
|
|
|
getList();
|
|
|
|
|
getUserList();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 调整汇总明细逻辑
|
|
|
|
|
@ -427,14 +465,22 @@ const adjustDialog = reactive({
|
|
|
|
|
});
|
|
|
|
|
const adjustData = ref<TimesheetSummaryVO | null>(null);
|
|
|
|
|
const projectList = ref<any[]>([]);
|
|
|
|
|
const staffSearchName = ref('');
|
|
|
|
|
const staffSearchUserId = ref<string | number | undefined>(undefined);
|
|
|
|
|
const staffSearchProjectCode = ref('');
|
|
|
|
|
const staffSearchProjectName = ref('');
|
|
|
|
|
|
|
|
|
|
const filteredDetailList = computed(() => {
|
|
|
|
|
if (!adjustData.value || !adjustData.value.summaryDetailList) return [];
|
|
|
|
|
if (!staffSearchName.value) return adjustData.value.summaryDetailList;
|
|
|
|
|
return adjustData.value.summaryDetailList.filter(
|
|
|
|
|
(item) => item.staffName && item.staffName.toLowerCase().includes(staffSearchName.value.toLowerCase())
|
|
|
|
|
);
|
|
|
|
|
return adjustData.value.summaryDetailList.filter((item) => {
|
|
|
|
|
const matchUser = !staffSearchUserId.value || item.staffUserId === staffSearchUserId.value;
|
|
|
|
|
const matchProjCode =
|
|
|
|
|
!staffSearchProjectCode.value ||
|
|
|
|
|
(item.originalProjectCode && item.originalProjectCode.toLowerCase().includes(staffSearchProjectCode.value.toLowerCase()));
|
|
|
|
|
const matchProjName =
|
|
|
|
|
!staffSearchProjectName.value ||
|
|
|
|
|
(item.originalProjectName && item.originalProjectName.toLowerCase().includes(staffSearchProjectName.value.toLowerCase()));
|
|
|
|
|
return matchUser && matchProjCode && matchProjName;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const loadProjectList = async () => {
|
|
|
|
|
@ -451,7 +497,9 @@ const handleAdjust = async (row: TimesheetSummaryVO) => {
|
|
|
|
|
const summaryId = row.summaryId;
|
|
|
|
|
const res = await getTimesheetSummary(summaryId);
|
|
|
|
|
adjustData.value = res.data;
|
|
|
|
|
staffSearchName.value = '';
|
|
|
|
|
staffSearchUserId.value = undefined;
|
|
|
|
|
staffSearchProjectCode.value = '';
|
|
|
|
|
staffSearchProjectName.value = '';
|
|
|
|
|
|
|
|
|
|
await loadProjectList();
|
|
|
|
|
|
|
|
|
|
|