refactor(oa/erp): 重构项目台账报表服务

- 修改 IProjectLedgerReportService 接口添加 PageQuery 参数支持分页查询
- 更新 Controller 层接口方法签名以传递分页参数
- 重构 Mapper 层使用 MyBatis-Plus 分页插件和 Lambda 查询
- 实现分页查询逻辑并添加查询条件构建器方法
- 更新 XML 映射文件使用动态 SQL 和分页参数
- 调整 Excel 导出字段分类结构优化导出格式
- 添加序号字段用于列表显示索引标记
dev
Yangk 5 days ago
parent b0320d5bde
commit 17c48a85a7

@ -6,6 +6,7 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.oa.erp.domain.vo.ProjectLedgerReportVo;
import org.dromara.oa.erp.service.IProjectLedgerReportService;
@ -37,8 +38,8 @@ public class ProjectLedgerReportController {
*/
// @SaCheckPermission("oa:erp:projectLedgerReport:list")
@GetMapping("/list")
public TableDataInfo<ProjectLedgerReportVo> list(ProjectLedgerReportVo bo) {
return reportService.queryProjectLedgerList(bo);
public TableDataInfo<ProjectLedgerReportVo> list(ProjectLedgerReportVo bo, PageQuery pageQuery) {
return reportService.queryProjectLedgerList(bo, pageQuery);
}
/**

@ -26,36 +26,40 @@ public class ProjectLedgerReportVo implements Serializable {
/** 项目ID */
private Long projectId;
/** 序号 */
@ExcelProperty({"基本信息", "序号"})
private Integer index;
/** 合同ID */
private Long contractId;
/** 项目编号 */
@ExcelProperty(value = "项目编号")
@ExcelProperty({"基本信息", "项目编号"})
private String projectCode;
/** 客户名称 */
@ExcelProperty(value = "客户名称")
@ExcelProperty({"基本信息", "客户名称"})
private String customerName;
/** 项目名称 */
@ExcelProperty(value = "项目名称")
@ExcelProperty({"基本信息", "项目名称"})
@ColumnWidth(25)
private String projectName;
/** 项目经理 */
@ExcelProperty(value = "项目经理")
@ExcelProperty({"基本信息", "项目经理"})
private String managerName;
/** 部门 */
@ExcelProperty(value = "部门")
@ExcelProperty({"基本信息", "部门"})
private String deptName;
/** 项目类型 */
@ExcelProperty(value = "项目类型")
@ExcelProperty({"基本信息", "项目类型"})
private String typeName;
/** 产品数量 */
@ExcelProperty(value = "产品数量")
@ExcelProperty({"基本信息", "产品数量"})
private BigDecimal productAmount;
/** 项目阶段 */
@ -65,160 +69,160 @@ public class ProjectLedgerReportVo implements Serializable {
private String projectCategory;
/** 项目状态 */
@ExcelProperty(value = "状态", converter = org.dromara.common.excel.convert.ExcelDictConvert.class)
@ExcelProperty(value = {"基本信息", "状态"}, converter = org.dromara.common.excel.convert.ExcelDictConvert.class)
@org.dromara.common.excel.annotation.ExcelDictFormat(dictType = "project_status")
private String projectStatus;
/** 实际验收时间 */
@ExcelProperty(value = "实际验收时间")
@ExcelProperty({"基本信息", "实际验收时间"})
private String acceptanceDate;
/** 签订时间 */
@ExcelProperty(value = "签订时间")
@ExcelProperty({"合同信息", "签订时间"})
private String contractDate;
/** 合同额 */
@ExcelProperty(value = "合同额")
@ExcelProperty({"合同信息", "合同额"})
private BigDecimal contractAmount;
/** 客户经理 */
@ExcelProperty(value = "客户经理")
@ExcelProperty({"合同信息", "客户经理"})
private String contractManagerName;
/** 付款方式 */
@ExcelProperty(value = "付款方式")
@ExcelProperty({"合同信息", "付款方式"})
private String paymentMethod;
/** 预算 */
@ExcelProperty(value = "预算")
@ExcelProperty({"预算及成本", "预算"})
private BigDecimal budgetCost;
/** 预算毛利率 */
@ExcelProperty(value = "预算毛利率")
@ExcelProperty({"预算及成本", "预算毛利率"})
private BigDecimal budgetRate;
/** 降成本后预算 */
@ExcelProperty(value = "降成本后预算")
@ExcelProperty({"预算及成本", "将成本后预算"})
private BigDecimal reduceBudgetCost;
/** 降成本后预算毛利率 */
@ExcelProperty(value = "降成本后预算毛利率")
@ExcelProperty({"预算及成本", "降成本后预算毛利率"})
private BigDecimal reduceBudgetRate;
/** 收入(合同额/1.13 */
@ExcelProperty(value = "收入")
@ExcelProperty({"预算及成本", "收入"})
private BigDecimal revenue;
/** 累计工时 */
@ExcelProperty(value = "累计工时")
@ExcelProperty({"预算及成本", "累计工时"})
private BigDecimal totalHours;
// --- 启动阶段 ---
@ExcelProperty(value = "启动计划开始时间")
@ExcelProperty({"启动", "计划开始时间"})
private String startupPlanStartTime;
@ExcelProperty(value = "启动计划结束时间")
@ExcelProperty({"启动", "计划结束时间"})
private String startupPlanEndTime;
@ExcelProperty(value = "启动实际开始时间")
@ExcelProperty({"启动", "实际开始时间"})
private String startupRealStartTime;
@ExcelProperty(value = "启动实际结束时间")
@ExcelProperty({"启动", "实际结束时间"})
private String startupRealEndTime;
@ExcelProperty(value = "启动原因说明")
@ExcelProperty({"启动", "原因说明"})
private String startupReasonsExplanation;
// --- 设计阶段 ---
@ExcelProperty(value = "设计计划开始时间")
@ExcelProperty({"设计", "计划开始时间"})
private String designPlanStartTime;
@ExcelProperty(value = "设计计划结束时间")
@ExcelProperty({"设计", "计划结束时间"})
private String designPlanEndTime;
@ExcelProperty(value = "设计实际开始时间")
@ExcelProperty({"设计", "实际开始时间"})
private String designRealStartTime;
@ExcelProperty(value = "设计实际结束时间")
@ExcelProperty({"设计", "实际结束时间"})
private String designRealEndTime;
@ExcelProperty(value = "设计原因说明")
@ExcelProperty({"设计", "原因说明"})
private String designReasonsExplanation;
// --- 采购阶段 ---
@ExcelProperty(value = "采购计划开始时间")
@ExcelProperty({"采购", "计划开始时间"})
private String purchasePlanStartTime;
@ExcelProperty(value = "采购计划结束时间")
@ExcelProperty({"采购", "计划结束时间"})
private String purchasePlanEndTime;
@ExcelProperty(value = "采购实际开始时间")
@ExcelProperty({"采购", "实际开始时间"})
private String purchaseRealStartTime;
@ExcelProperty(value = "采购实际结束时间")
@ExcelProperty({"采购", "实际结束时间"})
private String purchaseRealEndTime;
@ExcelProperty(value = "采购原因说明")
@ExcelProperty({"采购", "原因说明"})
private String purchaseReasonsExplanation;
// --- 发货阶段 ---
@ExcelProperty(value = "发货计划开始时间")
@ExcelProperty({"发货", "计划开始时间"})
private String shipmentPlanStartTime;
@ExcelProperty(value = "发货计划结束时间")
@ExcelProperty({"发货", "计划结束时间"})
private String shipmentPlanEndTime;
@ExcelProperty(value = "发货实际开始时间")
@ExcelProperty({"发货", "实际开始时间"})
private String shipmentRealStartTime;
@ExcelProperty(value = "发货实际结束时间")
@ExcelProperty({"发货", "实际结束时间"})
private String shipmentRealEndTime;
@ExcelProperty(value = "发货原因说明")
@ExcelProperty({"发货", "原因说明"})
private String shipmentReasonsExplanation;
// --- 实施阶段 ---
@ExcelProperty(value = "实施计划开始时间")
@ExcelProperty({"实施", "计划开始时间"})
private String implementPlanStartTime;
@ExcelProperty(value = "实施计划结束时间")
@ExcelProperty({"实施", "计划结束时间"})
private String implementPlanEndTime;
@ExcelProperty(value = "实施实际开始时间")
@ExcelProperty({"实施", "实际开始时间"})
private String implementRealStartTime;
@ExcelProperty(value = "实施实际结束时间")
@ExcelProperty({"实施", "实际结束时间"})
private String implementRealEndTime;
@ExcelProperty(value = "实施原因说明")
@ExcelProperty({"实施", "原因说明"})
private String implementReasonsExplanation;
// --- 调试阶段 ---
@ExcelProperty(value = "调试计划开始时间")
@ExcelProperty({"调试", "计划开始时间"})
private String debugPlanStartTime;
@ExcelProperty(value = "调试计划结束时间")
@ExcelProperty({"调试", "计划结束时间"})
private String debugPlanEndTime;
@ExcelProperty(value = "调试实际开始时间")
@ExcelProperty({"调试", "实际开始时间"})
private String debugRealStartTime;
@ExcelProperty(value = "调试实际结束时间")
@ExcelProperty({"调试", "实际结束时间"})
private String debugRealEndTime;
@ExcelProperty(value = "调试原因说明")
@ExcelProperty({"调试", "原因说明"})
private String debugReasonsExplanation;
// --- 试运行阶段 ---
@ExcelProperty(value = "试运行计划开始时间")
@ExcelProperty({"试运行", "计划开始时间"})
private String pilotRunPlanStartTime;
@ExcelProperty(value = "试运行计划结束时间")
@ExcelProperty({"试运行", "计划结束时间"})
private String pilotRunPlanEndTime;
@ExcelProperty(value = "试运行实际开始时间")
@ExcelProperty({"试运行", "实际开始时间"})
private String pilotRunRealStartTime;
@ExcelProperty(value = "试运行实际结束时间")
@ExcelProperty({"试运行", "实际结束时间"})
private String pilotRunRealEndTime;
@ExcelProperty(value = "试运行原因说明")
@ExcelProperty({"试运行", "原因说明"})
private String pilotRunReasonsExplanation;
// --- 验收阶段 ---
@ExcelProperty(value = "验收计划开始时间")
@ExcelProperty({"验收", "计划开始时间"})
private String acceptancePlanStartTime;
@ExcelProperty(value = "验收计划结束时间")
@ExcelProperty({"验收", "计划结束时间"})
private String acceptancePlanEndTime;
@ExcelProperty(value = "验收实际开始时间")
@ExcelProperty({"验收", "实际开始时间"})
private String acceptanceRealStartTime;
@ExcelProperty(value = "验收实际结束时间")
@ExcelProperty({"验收", "实际结束时间"})
private String acceptanceRealEndTime;
@ExcelProperty(value = "验收原因说明")
@ExcelProperty({"验收", "原因说明"})
private String acceptanceReasonsExplanation;
// --- 质保阶段 ---
@ExcelProperty(value = "质保计划开始时间")
@ExcelProperty({"质保", "计划开始时间"})
private String warrantyPlanStartTime;
@ExcelProperty(value = "质保计划结束时间")
@ExcelProperty({"质保", "计划结束时间"})
private String warrantyPlanEndTime;
@ExcelProperty(value = "质保实际开始时间")
@ExcelProperty({"质保", "实际开始时间"})
private String warrantyRealStartTime;
@ExcelProperty(value = "质保实际结束时间")
@ExcelProperty({"质保", "实际结束时间"})
private String warrantyRealEndTime;
@ExcelProperty(value = "质保原因说明")
@ExcelProperty({"质保", "原因说明"})
private String warrantyReasonsExplanation;
/** 业务方向(查询条件用) */

@ -2,6 +2,10 @@ package org.dromara.oa.erp.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.dromara.oa.erp.domain.ErpProjectInfo;
import org.dromara.oa.erp.domain.vo.ProjectLedgerReportVo;
import java.util.List;
@ -16,10 +20,12 @@ import java.util.List;
public interface ProjectLedgerReportMapper {
/**
*
*
* @param bo
* @return
*
*/
List<ProjectLedgerReportVo> selectProjectLedgerList(@Param("bo") ProjectLedgerReportVo bo);
Page<ProjectLedgerReportVo> selectProjectLedgerList(@Param("page") Page<ProjectLedgerReportVo> page, @Param(Constants.WRAPPER) MPJLambdaWrapper<ErpProjectInfo> wrapper);
/**
*
*/
List<ProjectLedgerReportVo> selectProjectLedgerList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpProjectInfo> wrapper);
}

@ -1,12 +1,13 @@
package org.dromara.oa.erp.service;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.oa.erp.domain.vo.ProjectLedgerReportVo;
import java.util.List;
/**
* Service
* Service
*
* @author Yangk
* @date 2026-03-11
@ -14,12 +15,12 @@ import java.util.List;
public interface IProjectLedgerReportService {
/**
*
*
*/
TableDataInfo<ProjectLedgerReportVo> queryProjectLedgerList(ProjectLedgerReportVo bo);
TableDataInfo<ProjectLedgerReportVo> queryProjectLedgerList(ProjectLedgerReportVo bo, PageQuery pageQuery);
/**
*
*
*/
List<ProjectLedgerReportVo> queryProjectLedgerAll(ProjectLedgerReportVo bo);
}

@ -1,12 +1,19 @@
package org.dromara.oa.erp.service.impl;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.oa.erp.domain.ErpProjectInfo;
import org.dromara.oa.erp.domain.vo.ProjectLedgerReportVo;
import org.dromara.oa.erp.mapper.ProjectLedgerReportMapper;
import org.dromara.oa.erp.service.IProjectLedgerReportService;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
@ -21,14 +28,43 @@ public class ProjectLedgerReportServiceImpl implements IProjectLedgerReportServi
private final ProjectLedgerReportMapper reportMapper;
private MPJLambdaWrapper<ErpProjectInfo> buildQueryWrapper(ProjectLedgerReportVo bo) {
MPJLambdaWrapper<ErpProjectInfo> lqw = JoinWrappers.lambda(ErpProjectInfo.class);
lqw.eq(ErpProjectInfo::getDelFlag, "0");
lqw.ne(ErpProjectInfo::getProjectCategory, "9");
if (bo.getParams() != null && bo.getParams().get("projectIds") != null && StringUtils.isNotBlank(bo.getParams().get("projectIds").toString())) {
List<String> projectIds = Arrays.asList(bo.getParams().get("projectIds").toString().split(","));
lqw.in(ErpProjectInfo::getProjectId, projectIds);
}
lqw.like(StringUtils.isNotBlank(bo.getProjectName()), ErpProjectInfo::getProjectName, bo.getProjectName());
lqw.like(StringUtils.isNotBlank(bo.getProjectCode()), ErpProjectInfo::getProjectCode, bo.getProjectCode());
lqw.eq(StringUtils.isNotBlank(bo.getBusinessDirection()), ErpProjectInfo::getBusinessDirection, bo.getBusinessDirection());
lqw.eq(StringUtils.isNotBlank(bo.getProjectStatus()), ErpProjectInfo::getProjectStatus, bo.getProjectStatus());
lqw.orderByDesc(ErpProjectInfo::getCreateTime);
return lqw;
}
@Override
public TableDataInfo<ProjectLedgerReportVo> queryProjectLedgerList(ProjectLedgerReportVo bo) {
List<ProjectLedgerReportVo> list = reportMapper.selectProjectLedgerList(bo);
return TableDataInfo.build(list);
public TableDataInfo<ProjectLedgerReportVo> queryProjectLedgerList(ProjectLedgerReportVo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpProjectInfo> lqw = buildQueryWrapper(bo);
Page<ProjectLedgerReportVo> result = reportMapper.selectProjectLedgerList(pageQuery.build(), lqw);
List<ProjectLedgerReportVo> list = result.getRecords();
for (int i = 0; i < list.size(); i++) {
list.get(i).setIndex((int) ((pageQuery.getPageNum() - 1) * pageQuery.getPageSize() + i + 1));
}
return TableDataInfo.build(result);
}
@Override
public List<ProjectLedgerReportVo> queryProjectLedgerAll(ProjectLedgerReportVo bo) {
return reportMapper.selectProjectLedgerList(bo);
MPJLambdaWrapper<ErpProjectInfo> lqw = buildQueryWrapper(bo);
List<ProjectLedgerReportVo> list = reportMapper.selectProjectLedgerList(lqw);
for (int i = 0; i < list.size(); i++) {
list.get(i).setIndex(i + 1);
}
return list;
}
}

@ -6,12 +6,12 @@
<select id="selectProjectLedgerList" resultType="org.dromara.oa.erp.domain.vo.ProjectLedgerReportVo">
SELECT
p.project_id,
p.project_code,
p.project_name,
p.project_category,
p.project_status,
p.payment_method,
t.project_id,
t.project_code,
t.project_name,
t.project_category,
t.project_status,
t.payment_method,
c.contract_id,
u1.nick_name AS manager_name,
d.dept_name,
@ -80,28 +80,28 @@
stages_sub.warranty_real_end_time,
stages_sub.warranty_reasons_explanation
FROM
erp_project_info p
LEFT JOIN erp_project_type t1 ON t1.project_type_id = p.project_type_id
erp_project_info t
LEFT JOIN erp_project_type t1 ON t1.project_type_id = t.project_type_id
LEFT JOIN erp_project_type t2 ON t1.parent_id = t2.project_type_id
LEFT JOIN sys_dept d ON d.dept_id = p.dept_id
LEFT JOIN sys_user u1 ON u1.user_id = p.manager_id
LEFT JOIN sys_dept d ON d.dept_id = t.dept_id
LEFT JOIN sys_user u1 ON u1.user_id = t.manager_id
<!-- 合同 + 客户 + 客户经理 -->
LEFT JOIN erp_contract_info c ON c.contract_id = (
SELECT contract_id FROM erp_project_contracts
WHERE project_id = p.project_id AND del_flag = '0'
WHERE project_id = t.project_id AND del_flag = '0'
ORDER BY sort_order ASC LIMIT 1
) AND c.del_flag = '0'
LEFT JOIN crm_customer_info cust ON c.one_customer_id = cust.customer_id AND cust.del_flag = '0'
LEFT JOIN sys_user u2 ON c.contract_manager_id = u2.user_id
<!-- 预算(取已审批的) -->
LEFT JOIN erp_budget_info b ON p.project_id = b.project_id AND b.budget_status = '3' AND b.del_flag = '0'
LEFT JOIN erp_budget_info b ON t.project_id = b.project_id AND b.budget_status = '3' AND b.del_flag = '0'
<!-- 验收(取已完成审批的) -->
LEFT JOIN (
SELECT project_id, MAX(acceptance_date) AS acceptance_date
FROM erp_project_acceptance
WHERE del_flag = '0' AND flow_status = 'finish'
GROUP BY project_id
) acc ON p.project_id = acc.project_id
) acc ON t.project_id = acc.project_id
<!-- 累计工时 -->
LEFT JOIN (
SELECT tp.project_id, COALESCE(SUM(tp.hours), 0) AS total_hours
@ -109,7 +109,7 @@
JOIN erp_timesheet_info ti ON tp.timesheet_id = ti.timesheet_id AND ti.del_flag = '0'
WHERE tp.del_flag = '0' AND ti.timesheet_status = '3'
GROUP BY tp.project_id
) hours_sub ON p.project_id = hours_sub.project_id
) hours_sub ON t.project_id = hours_sub.project_id
<!-- 产品数量(按合同聚合) -->
LEFT JOIN (
SELECT contract_id, SUM(amount) AS product_amount
@ -178,30 +178,8 @@
LEFT JOIN sys_dict_data d ON s.project_phases = d.dict_value AND d.dict_type = 'project_phases'
WHERE s.del_flag = '0'
GROUP BY s.project_id
) stages_sub ON p.project_id = stages_sub.project_id
<where>
p.del_flag = '0'
AND p.project_category &lt;&gt; '9'
<if test="bo.params != null and bo.params.projectIds != null and bo.params.projectIds != ''">
AND p.project_id IN
<foreach collection="bo.params.projectIds.split(',')" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
<if test="bo.projectName != null and bo.projectName != ''">
AND p.project_name LIKE concat('%', #{bo.projectName}, '%')
</if>
<if test="bo.projectCode != null and bo.projectCode != ''">
AND p.project_code LIKE concat('%', #{bo.projectCode}, '%')
</if>
<if test="bo.businessDirection != null and bo.businessDirection != ''">
AND p.business_direction = #{bo.businessDirection}
</if>
<if test="bo.projectStatus != null and bo.projectStatus != ''">
AND p.project_status = #{bo.projectStatus}
</if>
</where>
ORDER BY p.create_time DESC
) stages_sub ON t.project_id = stages_sub.project_id
${ew.customSqlSegment}
</select>
</mapper>

Loading…
Cancel
Save