feat(oa): 更新出差申请表单和项目台账报表功能

- 将商务出行申请中的交流目的字段从输入框改为下拉选择框,并添加字典数据支持
- 在项目台账报表中增加部门、项目类型、项目阶段筛选条件
- 调整项目台账报表列显示,更新预计验收时间、异常启动信息和成本收入比例计算
- 重构项目台账报表中采购发货、开发、实施等环节的时间显示逻辑
- 移除项目台账报表中部分原因说明列并优化表格结构
dev
Yangk 3 weeks ago
parent 12d10643cd
commit 93b8f5b2cd

@ -10,6 +10,9 @@ export interface ProjectLedgerReportQuery {
projectName?: string;
businessDirection?: string;
projectStatus?: string;
deptId?: number | string;
projectTypeId?: number | string;
projectPhases?: string;
}
/**

@ -215,7 +215,9 @@
<el-col :span="12" v-if="form.tripType === '2'">
<el-form-item label="交流目的">
<el-input v-model="scope.row.exchangePurpose" placeholder="交流目的" :disabled="isFormDisabled" />
<el-select v-model="scope.row.exchangePurpose" placeholder="请选择交流目的" :disabled="isFormDisabled" style="width: 100%">
<el-option v-for="dict in exchange_purpose" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
@ -375,7 +377,7 @@ const route = useRoute();
const router = useRouter();
//
const { trip_type, business_direction } = toRefs<any>(proxy?.useDict('trip_type', 'business_direction'));
const { trip_type, business_direction, exchange_purpose } = toRefs<any>(proxy?.useDict('trip_type', 'business_direction', 'exchange_purpose'));
//
const routeParams = ref<Record<string, any>>({});
@ -451,7 +453,7 @@ const data = reactive({
exchangeObject: [{ required: true, message: '交流对象不能为空', trigger: 'blur' }],
customerId: [{ required: true, message: '请选择交流对象(客户)', trigger: 'change' }],
businessDirection: [{ required: true, message: '业务方向不能为空', trigger: 'change' }],
exchangePurpose: [{ required: true, message: '交流目的不能为空', trigger: 'blur' }],
exchangePurpose: [{ required: true, message: '交流目的不能为空', trigger: 'change' }],
exchangeFeedback: [{ required: true, message: '交流过程与反馈不能为空', trigger: 'blur' }],
meetingName: [{ required: true, message: '会议/展会名称不能为空', trigger: 'blur' }],
'variables.approverId': [
@ -466,7 +468,9 @@ const data = reactive({
},
trigger: 'change'
}
]
],
startTime: [] as any[],
endTime: [] as any[]
}
});

@ -118,7 +118,11 @@
<dict-tag :options="business_direction" :value="scope.row.businessDirection" />
</template>
</el-table-column>
<el-table-column label="交流目的" align="center" prop="exchangePurpose" width="150" show-overflow-tooltip v-if="columns[17].visible" />
<el-table-column label="交流目的" align="center" prop="exchangePurpose" width="150" show-overflow-tooltip v-if="columns[17].visible">
<template #default="scope">
<dict-tag :options="exchange_purpose" :value="scope.row.exchangePurpose" />
</template>
</el-table-column>
<el-table-column label="会议/展会名称" align="center" prop="meetingName" width="150" show-overflow-tooltip v-if="columns[19].visible" />
<el-table-column
label="交流过程与反馈"
@ -153,19 +157,19 @@
<el-tooltip content="查看详情" placement="top" v-if="scope.row.flowStatus !== 'draft' && scope.row.flowStatus">
<el-button link type="info" icon="DocumentChecked" @click="handleView(scope.row)"></el-button>
</el-tooltip>
<!-- <el-tooltip-->
<!-- content="填写反馈"-->
<!-- placement="top"-->
<!-- v-if="scope.row.tripStatus === '3' && (scope.row.tripType === '2' || scope.row.tripType === '3') && canViewRowFeedback(scope.row)"-->
<!-- >-->
<!-- <el-button-->
<!-- link-->
<!-- type="success"-->
<!-- icon="ChatDotRound"-->
<!-- @click="handleFeedback(scope.row)"-->
<!-- v-hasPermi="['oa/crm:businessTripApply:edit']"-->
<!-- ></el-button>-->
<!-- </el-tooltip>-->
<!-- <el-tooltip-->
<!-- content="填写反馈"-->
<!-- placement="top"-->
<!-- v-if="scope.row.tripStatus === '3' && (scope.row.tripType === '2' || scope.row.tripType === '3') && canViewRowFeedback(scope.row)"-->
<!-- >-->
<!-- <el-button-->
<!-- link-->
<!-- type="success"-->
<!-- icon="ChatDotRound"-->
<!-- @click="handleFeedback(scope.row)"-->
<!-- v-hasPermi="['oa/crm:businessTripApply:edit']"-->
<!-- ></el-button>-->
<!-- </el-tooltip>-->
<!-- <el-tooltip content="删除" placement="top">-->
<!-- <el-button-->
<!-- link-->
@ -226,7 +230,9 @@ const canViewRowFeedback = (row: BusinessTripApplyVO): boolean => {
if (row.createBy && currentUserId === String(row.createBy)) return true;
return false;
};
const { trip_status, trip_type, business_direction } = toRefs<any>(proxy?.useDict('trip_status', 'trip_type', 'business_direction'));
const { trip_status, trip_type, business_direction, exchange_purpose } = toRefs<any>(
proxy?.useDict('trip_status', 'trip_type', 'business_direction', 'exchange_purpose')
);
const businessTripApplyList = ref<BusinessTripApplyVO[]>([]);
const loading = ref(true);

@ -152,7 +152,7 @@ const queryFormRef = ref<ElFormInstance>();
const queryParams = reactive<ContractLedgerReportQuery>({
pageNum: 1,
pageSize: 20,
pageSize: 30,
customerContractCode: undefined,
internalContractCode: undefined,
projectCode: undefined,

@ -17,6 +17,21 @@
<el-option v-for="dict in project_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="部门" prop="deptId">
<el-select v-model="queryParams.deptId" placeholder="请选择部门" clearable filterable style="width: 200px">
<el-option v-for="dept in deptOptions" :key="dept.deptId" :label="dept.deptName" :value="dept.deptId" />
</el-select>
</el-form-item>
<el-form-item label="项目类型" prop="projectTypeId">
<el-select v-model="queryParams.projectTypeId" placeholder="请选择项目类型" clearable style="width: 200px">
<el-option v-for="item in projectTypeOptions" :key="item.projectTypeId" :label="item.typeName" :value="item.projectTypeId" />
</el-select>
</el-form-item>
<el-form-item label="项目阶段" prop="projectPhases">
<el-select v-model="queryParams.projectPhases" placeholder="请选择项目阶段" clearable style="width: 200px">
<el-option v-for="dict in project_phases" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
@ -39,13 +54,8 @@
<el-table-column label="项目经理" prop="managerName" width="90" align="center" />
<el-table-column label="部门" prop="deptName" width="120" align="center" show-overflow-tooltip />
<el-table-column label="项目类型" prop="typeName" width="120" align="center" show-overflow-tooltip />
<el-table-column label="产品型号" width="100" align="center">
<template #default>-</template>
</el-table-column>
<el-table-column label="产品数量" width="100" align="center">
<template #default="scope">
{{ scope.row.productAmount != null ? scope.row.productAmount : '-' }}
</template>
<template #default>-</template>
</el-table-column>
<el-table-column label="项目阶段" width="100" align="center">
<template #default="scope">
@ -62,7 +72,9 @@
</template>
</el-table-column>
<el-table-column label="预计验收时间" width="120" align="center">
<template #default>-</template>
<template #default="scope">
{{ scope.row.expectedAcceptanceTime ? scope.row.expectedAcceptanceTime.substring(0, 10) : '-' }}
</template>
</el-table-column>
<el-table-column label="实际验收时间" width="120" align="center">
<template #default="scope">
@ -70,10 +82,10 @@
</template>
</el-table-column>
<el-table-column label="是否异常启动" width="120" align="center">
<template #default>-</template>
<template #default="scope">{{ scope.row.abnormalStartup || '-' }}</template>
</el-table-column>
<el-table-column label="异常启动原因" width="120" align="center">
<template #default>-</template>
<template #default="scope">{{ scope.row.abnormalStartupReason || '-' }}</template>
</el-table-column>
</el-table-column>
@ -133,7 +145,13 @@
</template>
</el-table-column>
<el-table-column label="已发生成本占收入比例" width="160" align="center">
<template #default>-</template>
<template #default="scope">
{{
scope.row.actualCost != null && scope.row.revenue != null && scope.row.revenue != 0
? (Math.round((scope.row.actualCost / scope.row.revenue) * 10000) / 100).toFixed(2) + '%'
: '-'
}}
</template>
</el-table-column>
</el-table-column>
@ -153,9 +171,6 @@
<el-table-column label="实际结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.startupRealEndTime ? scope.row.startupRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="原因说明" width="150" align="center" show-overflow-tooltip>
<template #default="scope">{{ scope.row.startupReasonsExplanation || '-' }}</template>
</el-table-column>
</el-table-column>
<!-- 设计 -->
<el-table-column label="设计" align="center">
@ -171,98 +186,107 @@
<el-table-column label="实际结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.designRealEndTime ? scope.row.designRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="原因说明" width="150" align="center" show-overflow-tooltip>
<template #default="scope">{{ scope.row.designReasonsExplanation || '-' }}</template>
</el-table-column>
</el-table-column>
<!-- 采购 -->
<el-table-column label="采购" align="center">
<!-- 采购与发货 -->
<el-table-column label="采购与发货" align="center">
<el-table-column label="计划开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.purchasePlanStartTime ? scope.row.purchasePlanStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.purchaseShipmentPlanStartTime ? scope.row.purchaseShipmentPlanStartTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="计划结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.purchasePlanEndTime ? scope.row.purchasePlanEndTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.purchaseShipmentPlanEndTime ? scope.row.purchaseShipmentPlanEndTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="实际开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.purchaseRealStartTime ? scope.row.purchaseRealStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.purchaseShipmentRealStartTime ? scope.row.purchaseShipmentRealStartTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="实际结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.purchaseRealEndTime ? scope.row.purchaseRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="原因说明" width="150" align="center" show-overflow-tooltip>
<template #default="scope">{{ scope.row.purchaseReasonsExplanation || '-' }}</template>
<template #header>
<span style="color: red">实际结束时间</span>
</template>
<template #default="scope">{{
scope.row.purchaseShipmentRealEndTime ? scope.row.purchaseShipmentRealEndTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
</el-table-column>
<!-- -->
<el-table-column label="" align="center">
<!-- -->
<el-table-column label="发" align="center">
<el-table-column label="计划开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.shipmentPlanStartTime ? scope.row.shipmentPlanStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{ scope.row.developPlanStartTime ? scope.row.developPlanStartTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="计划结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.shipmentPlanEndTime ? scope.row.shipmentPlanEndTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{ scope.row.developPlanEndTime ? scope.row.developPlanEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="实际开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.shipmentRealStartTime ? scope.row.shipmentRealStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{ scope.row.developRealStartTime ? scope.row.developRealStartTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="实际结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.shipmentRealEndTime ? scope.row.shipmentRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="原因说明" width="150" align="center" show-overflow-tooltip>
<template #default="scope">{{ scope.row.shipmentReasonsExplanation || '-' }}</template>
<template #default="scope">{{ scope.row.developRealEndTime ? scope.row.developRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
</el-table-column>
<!-- 实施 -->
<el-table-column label="实施" align="center">
<!-- 组装调试设备类 -->
<el-table-column label="组装调试(设备类)" align="center">
<el-table-column label="计划开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.implementPlanStartTime ? scope.row.implementPlanStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.assemblyDebugPlanStartTime ? scope.row.assemblyDebugPlanStartTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="计划结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.implementPlanEndTime ? scope.row.implementPlanEndTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{ scope.row.assemblyDebugPlanEndTime ? scope.row.assemblyDebugPlanEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="实际开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.implementRealStartTime ? scope.row.implementRealStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.assemblyDebugRealStartTime ? scope.row.assemblyDebugRealStartTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="实际结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.implementRealEndTime ? scope.row.implementRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="原因说明" width="150" align="center" show-overflow-tooltip>
<template #default="scope">{{ scope.row.implementReasonsExplanation || '-' }}</template>
<template #default="scope">{{ scope.row.assemblyDebugRealEndTime ? scope.row.assemblyDebugRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
</el-table-column>
<!-- 调试 -->
<el-table-column label="调试" align="center">
<!-- 实施与安装调试 -->
<el-table-column label="实施与安装调试" align="center">
<el-table-column label="计划开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.debugPlanStartTime ? scope.row.debugPlanStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.implementDebugPlanStartTime ? scope.row.implementDebugPlanStartTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="计划结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.debugPlanEndTime ? scope.row.debugPlanEndTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.implementDebugPlanEndTime ? scope.row.implementDebugPlanEndTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="实际开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.debugRealStartTime ? scope.row.debugRealStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.implementDebugRealStartTime ? scope.row.implementDebugRealStartTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="实际结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.debugRealEndTime ? scope.row.debugRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="原因说明" width="150" align="center" show-overflow-tooltip>
<template #default="scope">{{ scope.row.debugReasonsExplanation || '-' }}</template>
<template #default="scope">{{
scope.row.implementDebugRealEndTime ? scope.row.implementDebugRealEndTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
</el-table-column>
<!-- 试运行 -->
<el-table-column label="试运行" align="center">
<!-- 测试与试运行 -->
<el-table-column label="测试与试运行" align="center">
<el-table-column label="计划开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.pilotRunPlanStartTime ? scope.row.pilotRunPlanStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.testPilotRunPlanStartTime ? scope.row.testPilotRunPlanStartTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="计划结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.pilotRunPlanEndTime ? scope.row.pilotRunPlanEndTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{ scope.row.testPilotRunPlanEndTime ? scope.row.testPilotRunPlanEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="实际开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.pilotRunRealStartTime ? scope.row.pilotRunRealStartTime.substring(0, 10) : '-' }}</template>
<template #default="scope">{{
scope.row.testPilotRunRealStartTime ? scope.row.testPilotRunRealStartTime.substring(0, 10) : '-'
}}</template>
</el-table-column>
<el-table-column label="实际结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.pilotRunRealEndTime ? scope.row.pilotRunRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="原因说明" width="150" align="center" show-overflow-tooltip>
<template #default="scope">{{ scope.row.pilotRunReasonsExplanation || '-' }}</template>
<template #default="scope">{{ scope.row.testPilotRunRealEndTime ? scope.row.testPilotRunRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
</el-table-column>
<!-- 验收 -->
@ -276,12 +300,12 @@
<el-table-column label="实际开始时间" width="110" align="center">
<template #default="scope">{{ scope.row.acceptanceRealStartTime ? scope.row.acceptanceRealStartTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="实际结束时间" width="110" align="center">
<el-table-column width="110" align="center">
<template #header>
<span style="color: red">实际结束时间</span>
</template>
<template #default="scope">{{ scope.row.acceptanceRealEndTime ? scope.row.acceptanceRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="原因说明" width="150" align="center" show-overflow-tooltip>
<template #default="scope">{{ scope.row.acceptanceReasonsExplanation || '-' }}</template>
</el-table-column>
</el-table-column>
<!-- 质保 -->
<el-table-column label="质保" align="center">
@ -297,9 +321,6 @@
<el-table-column label="实际结束时间" width="110" align="center">
<template #default="scope">{{ scope.row.warrantyRealEndTime ? scope.row.warrantyRealEndTime.substring(0, 10) : '-' }}</template>
</el-table-column>
<el-table-column label="原因说明" width="150" align="center" show-overflow-tooltip>
<template #default="scope">{{ scope.row.warrantyReasonsExplanation || '-' }}</template>
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
@ -310,6 +331,8 @@
<script setup lang="ts" name="ProjectLedgerReport">
import { listProjectLedgerReport, ProjectLedgerReportQuery, ProjectLedgerReportVO } from '@/api/oa/erp/projectLedgerReport';
import { allListDept, listDept } from '@/api/system/dept';
import { getErpProjectTypeList } from '@/api/oa/erp/projectType/index';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { business_direction, project_status, project_phases } = toRefs<any>(proxy?.useDict('business_direction', 'project_status', 'project_phases'));
@ -320,14 +343,19 @@ const total = ref(0);
const reportList = ref<ProjectLedgerReportVO[]>([]);
const selectedRows = ref<ProjectLedgerReportVO[]>([]);
const queryFormRef = ref<ElFormInstance>();
const deptOptions = ref<any[]>([]);
const projectTypeOptions = ref<any[]>([]);
const queryParams = reactive<ProjectLedgerReportQuery>({
pageNum: 1,
pageSize: 20,
pageSize: 30,
projectCode: undefined,
projectName: undefined,
businessDirection: undefined,
projectStatus: undefined
projectStatus: undefined,
deptId: undefined,
projectTypeId: undefined,
projectPhases: undefined
});
/** 格式化数字 */
@ -376,8 +404,22 @@ const handleExport = () => {
proxy?.download('/oa/erp/projectLedgerReport/export', exportParams, `项目台账报表_${new Date().getTime()}.xlsx`);
};
const getDeptList = async () => {
//
const res = await allListDept({ deptCategory: '03' } as any);
deptOptions.value = res.data || res.rows || [];
};
/** 查询项目类型 */
const getProjectTypeList = async () => {
const res = await getErpProjectTypeList({});
projectTypeOptions.value = res.data;
};
onMounted(() => {
getList();
getDeptList();
getProjectTypeList();
});
</script>

Loading…
Cancel
Save