feat(oa/erp): 添加合同台账报表功能

- 新增合同台账报表API接口定义和数据模型
- 实现合同查询、筛选和分页功能
- 添加导出Excel报表功能
- 构建完整的前端页面界面和交互逻辑
dev
Yangk 4 weeks ago
parent 098d833c31
commit a499cb57e2

@ -0,0 +1,56 @@
import request from '@/utils/request';
export interface ContractLedgerReportQuery {
pageNum: number;
pageSize: number;
customerContractCode?: string;
internalContractCode?: string;
projectCode?: string;
businessDirection?: string;
contractIdList?: Array<string | number>;
params?: any;
}
export interface ContractLedgerReportVO {
contractId: string | number;
month: string;
internalContractCode: string;
externalContractCode: string;
customerContractCode: string;
contractDate: string;
orderContractCode: string;
projectContractCode: string;
customerName: string;
productName: string;
mesnacContractPrice: number;
totalPrice: number;
paymentMethod: string;
deliveryStart: number;
warrantyPeriod: number;
contractManagerName: string;
contractDeptName: string;
businessDirection: string;
projectCode: string;
projectName: string;
managerName: string;
typeName: string;
finalCustomerName: string;
}
// 查询合同台账报表列表
export function listContractLedgerReport(query: ContractLedgerReportQuery) {
return request({
url: '/oa/erp/contractLedgerReport/list',
method: 'get',
params: query
});
}
// 导出合同台账报表
export function exportContractLedgerReport(query: ContractLedgerReportQuery) {
return request({
url: '/oa/erp/contractLedgerReport/export',
method: 'post',
data: query
});
}

@ -0,0 +1,228 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryFormRef" :inline="true" v-show="showSearch" label-width="120px">
<el-form-item label="客户合同编号" prop="customerContractCode">
<el-input v-model="queryParams.customerContractCode" placeholder="请输入客户合同编号" clearable style="width: 180px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="海威SAP订单号" prop="internalContractCode">
<el-input
v-model="queryParams.internalContractCode"
placeholder="请输入海威SAP订单号"
clearable
style="width: 180px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="项目编号" prop="projectCode">
<el-input v-model="queryParams.projectCode" placeholder="请输入项目编号" clearable style="width: 180px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="业务方向" prop="businessDirection">
<el-select v-model="queryParams.businessDirection" placeholder="请选择业务方向" clearable style="width: 180px">
<el-option v-for="dict in business_direction" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="签订时间" style="width: 320px">
<el-date-picker
v-model="daterangeContractDate"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
<el-button type="warning" plain icon="Download" @click="handleExport"></el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="reportList" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" fixed="left" />
<el-table-column label="月份" prop="month" width="100" align="center" fixed="left" />
<!-- ========== 合同信息 ========== -->
<el-table-column label="合同信息" align="center">
<el-table-column label="海威SAP订单号" prop="internalContractCode" width="140" align="center" show-overflow-tooltip fixed="left" />
<el-table-column label="海威合同归档编号" prop="externalContractCode" width="150" align="center" show-overflow-tooltip />
<el-table-column label="客户合同编号" prop="customerContractCode" width="150" align="center" show-overflow-tooltip />
<el-table-column label="签订时间" prop="contractDate" width="110" align="center" show-overflow-tooltip />
<el-table-column label="软控SAP订单号" prop="orderContractCode" width="140" align="center" show-overflow-tooltip />
<el-table-column label="软控SAP项目号" prop="projectContractCode" width="140" align="center" show-overflow-tooltip />
<el-table-column label="客户名称" prop="customerName" width="200" align="center" show-overflow-tooltip />
<el-table-column label="产品名称" prop="productName" width="180" align="center" show-overflow-tooltip />
<el-table-column label="软控合同额(元)" prop="mesnacContractPrice" width="130" align="center">
<template #default="scope">
{{ scope.row.mesnacContractPrice != null ? formatNumber(scope.row.mesnacContractPrice) : '-' }}
</template>
</el-table-column>
<el-table-column label="海威合同额(元)" prop="totalPrice" width="130" align="center">
<template #default="scope">
{{ scope.row.totalPrice != null ? formatNumber(scope.row.totalPrice) : '-' }}
</template>
</el-table-column>
<el-table-column label="付款方式" prop="paymentMethod" width="180" align="center" show-overflow-tooltip />
<el-table-column label="交货期" prop="deliveryStart" width="100" align="center">
<template #default="scope">
{{ scope.row.deliveryStart != null ? scope.row.deliveryStart + '天' : '-' }}
</template>
</el-table-column>
<el-table-column label="质保期" prop="warrantyPeriod" width="100" align="center">
<template #default="scope">
{{ scope.row.warrantyPeriod != null ? scope.row.warrantyPeriod + '天' : '-' }}
</template>
</el-table-column>
<el-table-column label="签订人" prop="contractManagerName" width="100" align="center" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.contractManagerName || '-' }}
</template>
</el-table-column>
<el-table-column label="部门" prop="contractDeptName" width="120" align="center" show-overflow-tooltip />
<el-table-column label="业务方向" prop="businessDirection" width="120" align="center">
<template #default="scope">
<dict-tag :options="business_direction" :value="scope.row.businessDirection" />
</template>
</el-table-column>
</el-table-column>
<!-- ========== 项目基本信息 ========== -->
<el-table-column label="项目基本信息" align="center">
<el-table-column label="项目编号" prop="projectCode" width="140" align="center" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.projectCode || '-' }}
</template>
</el-table-column>
<el-table-column label="项目名称" prop="projectName" width="200" align="center" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.projectName || '-' }}
</template>
</el-table-column>
<el-table-column label="项目经理" prop="managerName" width="100" align="center">
<template #default="scope">
{{ scope.row.managerName || '-' }}
</template>
</el-table-column>
<el-table-column label="项目类型" prop="typeName" width="130" align="center" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.typeName || '-' }}
</template>
</el-table-column>
</el-table-column>
<!-- ========== 备注 ========== -->
<el-table-column label="备注" align="center">
<el-table-column label="最终客户" prop="finalCustomerName" width="200" align="center" show-overflow-tooltip>
<template #default="scope">
{{ scope.row.finalCustomerName || '-' }}
</template>
</el-table-column>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
</template>
<script setup lang="ts" name="ContractLedgerReport">
import { ref, reactive, onMounted, ComponentInternalInstance, getCurrentInstance, toRefs } from 'vue';
import { ElForm } from 'element-plus';
import { listContractLedgerReport, ContractLedgerReportQuery, ContractLedgerReportVO } from '@/api/oa/erp/contractLedgerReport';
type ElFormInstance = InstanceType<typeof ElForm>;
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { business_direction } = toRefs<any>(proxy?.useDict('business_direction'));
const reportList = ref<ContractLedgerReportVO[]>([]);
const selectedRows = ref<ContractLedgerReportVO[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const daterangeContractDate = ref<[any, any]>(['', '']);
const queryFormRef = ref<ElFormInstance>();
const queryParams = reactive<ContractLedgerReportQuery>({
pageNum: 1,
pageSize: 10,
customerContractCode: undefined,
internalContractCode: undefined,
projectCode: undefined,
businessDirection: undefined,
params: {}
});
/** 查询列表 */
const getList = async () => {
loading.value = true;
queryParams.params = {};
if (daterangeContractDate.value && daterangeContractDate.value.length === 2 && daterangeContractDate.value[0]) {
queryParams.params.beginContractDate = daterangeContractDate.value[0];
queryParams.params.endContractDate = daterangeContractDate.value[1];
}
const res = await listContractLedgerReport(queryParams);
reportList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
daterangeContractDate.value = ['', ''];
queryFormRef.value?.resetFields();
handleQuery();
};
/** 导出按钮操作 */
const handleExport = () => {
const exportParams = { ...queryParams };
if (daterangeContractDate.value && daterangeContractDate.value.length === 2 && daterangeContractDate.value[0]) {
exportParams.params = {
beginContractDate: daterangeContractDate.value[0],
endContractDate: daterangeContractDate.value[1]
};
} else {
exportParams.params = {};
}
if (selectedRows.value.length > 0) {
exportParams.contractIdList = selectedRows.value.map((row) => row.contractId);
}
proxy?.download('/oa/erp/contractLedgerReport/export', exportParams, `合同台账报表_${new Date().getTime()}.xlsx`);
};
/** 勾选变化 */
const handleSelectionChange = (selection: ContractLedgerReportVO[]) => {
selectedRows.value = selection;
};
/** 格式化数字:保留两位小数并加千分位 */
const formatNumber = (num: number | string | undefined | null) => {
if (num === null || num === undefined || num === '') return '-';
const n = Number(num);
if (isNaN(n)) return num;
return n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
};
onMounted(() => {
getList();
});
</script>
<style scoped>
/* 可根据需要调整样式 */
</style>
Loading…
Cancel
Save