Browse Source

2个报表

ecss-tx
han\hanst 4 months ago
parent
commit
038494fe94
  1. 52
      src/main/java/com/xujie/sys/modules/erf/controller/ErfApprovalCycleReportController.java
  2. 53
      src/main/java/com/xujie/sys/modules/erf/controller/ErfSampleCycleReportController.java
  3. 92
      src/main/java/com/xujie/sys/modules/erf/data/ErfApprovalCycleQueryData.java
  4. 24
      src/main/java/com/xujie/sys/modules/erf/data/ErfExpApplyData.java
  5. 135
      src/main/java/com/xujie/sys/modules/erf/dto/ErfApprovalCycleReportDto.java
  6. 106
      src/main/java/com/xujie/sys/modules/erf/dto/ErfSampleCycleReportDto.java
  7. 10
      src/main/java/com/xujie/sys/modules/erf/mapper/ErfExpApplyMapper.java
  8. 21
      src/main/java/com/xujie/sys/modules/erf/service/ErfApprovalCycleReportService.java
  9. 21
      src/main/java/com/xujie/sys/modules/erf/service/ErfSampleCycleReportService.java
  10. 159
      src/main/java/com/xujie/sys/modules/erf/service/impl/ErfApprovalCycleReportServiceImpl.java
  11. 139
      src/main/java/com/xujie/sys/modules/erf/service/impl/ErfSampleCycleReportServiceImpl.java
  12. 162
      src/main/resources/mapper/erf/ErfExpApplyMapper.xml

52
src/main/java/com/xujie/sys/modules/erf/controller/ErfApprovalCycleReportController.java

@ -0,0 +1,52 @@
package com.xujie.sys.modules.erf.controller;
import com.xujie.sys.common.utils.PageUtils;
import com.xujie.sys.common.utils.R;
import com.xujie.sys.modules.erf.data.ErfApprovalCycleQueryData;
import com.xujie.sys.modules.erf.service.ErfApprovalCycleReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* 审批周期报表控制器
*
* <p><b>功能说明</b></p>
* <ul>
* <li>查询从申请单发起日到三位经理全部审批完成的周期报表</li>
* <li>统计技术/生产/质量三类经理的审批时间及审批人</li>
* <li>计算全部审批完成时间和审批周期天数</li>
* </ul>
*
* @author System
* @since 2026-02-26
*/
@RestController
@RequestMapping("/erf/approvalCycleReport")
@Slf4j
public class ErfApprovalCycleReportController {
@Autowired
private ErfApprovalCycleReportService erfApprovalCycleReportService;
/**
* @Author System
* @Description 查询审批周期报表列表分页
* @Date 2026/2/26
* @Param [data]
* @return com.xujie.sys.common.utils.R
**/
@PostMapping("list")
public R list(@RequestBody ErfApprovalCycleQueryData data) {
try {
log.info("=== 查询审批周期报表列表 === 参数: {}", data);
PageUtils page = erfApprovalCycleReportService.queryPage(data);
return R.ok().put("page", page);
} catch (Exception e) {
log.error("查询审批周期报表列表失败: " + e.getMessage(), e);
return R.error("查询失败: " + e.getMessage());
}
}
}

53
src/main/java/com/xujie/sys/modules/erf/controller/ErfSampleCycleReportController.java

@ -0,0 +1,53 @@
package com.xujie.sys.modules.erf.controller;
import com.xujie.sys.common.utils.PageUtils;
import com.xujie.sys.common.utils.R;
import com.xujie.sys.modules.erf.data.ErfExpApplyData;
import com.xujie.sys.modules.erf.service.ErfSampleCycleReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* 样品完成周期报表控制器
*
* <p><b>功能说明</b></p>
* <ul>
* <li>查询样品完成周期报表列表分页</li>
* <li>对比期望完成时间和实际完成时间</li>
* <li>统计周期差异提前/准时/延期</li>
* <li>显示样品状态和入库数量</li>
* </ul>
*
* @author System
* @since 2026-02-12
*/
@RestController
@RequestMapping("/erf/sampleCycleReport")
@Slf4j
public class ErfSampleCycleReportController {
@Autowired
private ErfSampleCycleReportService erfSampleCycleReportService;
/**
* @Author System
* @Description 查询样品完成周期报表列表分页
* @Date 2026/2/12
* @Param [data]
* @return com.xujie.sys.common.utils.R
**/
@PostMapping("list")
public R list(@RequestBody ErfExpApplyData data) {
try {
log.info("=== 查询样品完成周期报表列表 === 参数: {}", data);
PageUtils page = erfSampleCycleReportService.queryPage(data);
return R.ok().put("page", page);
} catch (Exception e) {
log.error("查询样品完成周期报表列表失败: " + e.getMessage(), e);
return R.error("查询失败: " + e.getMessage());
}
}
}

92
src/main/java/com/xujie/sys/modules/erf/data/ErfApprovalCycleQueryData.java

@ -0,0 +1,92 @@
package com.xujie.sys.modules.erf.data;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* 审批周期报表查询条件
*
* @author System
* @since 2026-02-26
*/
@Data
public class ErfApprovalCycleQueryData implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 申请单号模糊查询
*/
private String applyNo;
/**
* 事业部代码
*/
private String buNo;
/**
* 试验类型
*/
private String experimentType;
/**
* 创建人姓名模糊查询
*/
private String creatorName;
/**
* 发起日开始日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date submitStartDate;
/**
* 发起日结束日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date submitEndDate;
/**
* 全部审批完成开始日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date allApproveStartDate;
/**
* 全部审批完成结束日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date allApproveEndDate;
/**
* 审批周期最小天数
*/
private Integer cycleDaysMin;
/**
* 审批周期最大天数
*/
private Integer cycleDaysMax;
/**
* 申请单状态过滤
*/
private String status;
/**
* 页码
*/
private Integer page;
/**
* 每页大小
*/
private Integer limit;
}

24
src/main/java/com/xujie/sys/modules/erf/data/ErfExpApplyData.java

@ -236,6 +236,30 @@ public class ErfExpApplyData implements Serializable {
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date expectedFinishEndDate;
/**
* 实际开始日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date actualFinishStartDate;
/**
* 实际结束日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date actualFinishEndDate;
/**
* 周期差异最小值用于筛选单位
*/
private Integer cycleDifferenceMin;
/**
* 周期差异最大值用于筛选单位
*/
private Integer cycleDifferenceMax;
private String pendingStatus;
/**

135
src/main/java/com/xujie/sys/modules/erf/dto/ErfApprovalCycleReportDto.java

@ -0,0 +1,135 @@
package com.xujie.sys.modules.erf.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* 审批周期报表DTO
*
* <p><b>用途</b>统计从申请单发起日到三位经理技术/生产/质量全部审批完成的周期</p>
*
* <p><b>核心字段说明</b></p>
* <ul>
* <li><b>submitTime</b>申请单发起日下达时间</li>
* <li><b>techApproveTime</b>技术经理审批完成时间</li>
* <li><b>prodApproveTime</b>生产经理全部审批完成时间最晚的那位</li>
* <li><b>qualApproveTime</b>质量经理全部审批完成时间最晚的那位</li>
* <li><b>allApproveTime</b>三类经理全部审批完成时间</li>
* <li><b>approvalCycleDays</b>审批周期从发起日到全部审批完成的天数</li>
* </ul>
*
* @author System
* @since 2026-02-26
*/
@Data
public class ErfApprovalCycleReportDto implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 申请单号
*/
private String applyNo;
/**
* 事业部编码
*/
private String buNo;
/**
* 事业部名称
*/
private String buName;
/**
* 试验类型High Risk/Low Risk
*/
private String experimentType;
/**
* 试验名称
*/
private String title;
/**
* 创建人姓名
*/
private String creatorName;
/**
* 当前状态
*/
private String status;
/**
* 创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
/**
* 申请单发起日下达时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date submitTime;
/**
* 技术经理姓名
*/
private String techManagerName;
/**
* 技术经理审批完成时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date techApproveTime;
/**
* 生产经理姓名多人时用顿号分隔
*/
private String prodManagerName;
/**
* 生产经理全部审批完成时间即最晚完成的那位审批时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date prodApproveTime;
/**
* 质量经理姓名多人时用顿号分隔
*/
private String qualManagerName;
/**
* 质量经理全部审批完成时间即最晚完成的那位审批时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date qualApproveTime;
/**
* 三类经理全部审批完成时间取三者中最晚的时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date allApproveTime;
/**
* 审批周期天数
* 从申请单发起日submit_time到全部审批完成时间all_approve_time的自然天数
* 正数=审批用时天数null=尚未全部审批完成
*/
private Integer approvalCycleDays;
/**
* 是否全部审批完成技术/生产/质量三类均已批准
*/
private Boolean isAllApproved;
}

106
src/main/java/com/xujie/sys/modules/erf/dto/ErfSampleCycleReportDto.java

@ -0,0 +1,106 @@
package com.xujie.sys.modules.erf.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 样品完成周期报表DTO
*
* <p><b>用途</b>对比期望完成时间和实际完成时间统计样品生产周期</p>
*
* @author System
* @since 2026-02-12
*/
@Data
public class ErfSampleCycleReportDto implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 申请单号
*/
private String applyNo;
/**
* 试验名称
*/
private String title;
/**
* 试验类型High Risk/Low Risk
*/
private String experimentType;
/**
* 事业部编码
*/
private String buNo;
/**
* 事业部名称
*/
private String buName;
/**
* 创建人姓名
*/
private String creatorName;
/**
* 期望完成日期第一步工程师填写
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date expectedFinishDate;
/**
* 实际完成日期步骤七工程师填写
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date actualFinishDate;
/**
* 周期差异天数
* 正数延期天数
* 负数提前天数
* 0准时完成
*/
private Integer cycleDifference;
/**
* 是否延期true=延期, false=准时或提前
*/
private Boolean isDelayed;
/**
* 样品最终状态NORMAL=正常入库, SCRAPPED=报废
*/
private String finalStatus;
/**
* 样品最终状态描述
*/
private String finalStatusDesc;
/**
* 正常入库数量
*/
private BigDecimal finalQuantity;
/**
* 当前状态
*/
private String status;
/**
* 创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
}

10
src/main/java/com/xujie/sys/modules/erf/mapper/ErfExpApplyMapper.java

@ -1,7 +1,9 @@
package com.xujie.sys.modules.erf.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xujie.sys.modules.erf.data.ErfApprovalCycleQueryData;
import com.xujie.sys.modules.erf.data.ErfExpApplyData;
import com.xujie.sys.modules.erf.dto.ErfApprovalCycleReportDto;
import com.xujie.sys.modules.erf.entity.ErfExpApply;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -44,6 +46,14 @@ public interface ErfExpApplyMapper extends BaseMapper<ErfExpApply> {
String getSiteByBu(String buNo);
/**
* 查询审批周期报表列表
*
* @param data 查询条件
* @return 审批周期报表列表
*/
List<ErfApprovalCycleReportDto> getApprovalCycleReportList(@Param("data") ErfApprovalCycleQueryData data);
/**
* 删除三方确认明细
*

21
src/main/java/com/xujie/sys/modules/erf/service/ErfApprovalCycleReportService.java

@ -0,0 +1,21 @@
package com.xujie.sys.modules.erf.service;
import com.xujie.sys.common.utils.PageUtils;
import com.xujie.sys.modules.erf.data.ErfApprovalCycleQueryData;
/**
* 审批周期报表服务接口
*
* @author System
* @since 2026-02-26
*/
public interface ErfApprovalCycleReportService {
/**
* 查询审批周期报表列表分页
*
* @param data 查询条件
* @return 分页结果
*/
PageUtils queryPage(ErfApprovalCycleQueryData data);
}

21
src/main/java/com/xujie/sys/modules/erf/service/ErfSampleCycleReportService.java

@ -0,0 +1,21 @@
package com.xujie.sys.modules.erf.service;
import com.xujie.sys.common.utils.PageUtils;
import com.xujie.sys.modules.erf.data.ErfExpApplyData;
/**
* 样品完成周期报表服务接口
*
* @author System
* @since 2026-02-12
*/
public interface ErfSampleCycleReportService {
/**
* 查询样品完成周期报表列表分页
*
* @param data 查询参数
* @return 分页数据
*/
PageUtils queryPage(ErfExpApplyData data);
}

159
src/main/java/com/xujie/sys/modules/erf/service/impl/ErfApprovalCycleReportServiceImpl.java

@ -0,0 +1,159 @@
package com.xujie.sys.modules.erf.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xujie.sys.common.utils.PageUtils;
import com.xujie.sys.modules.erf.data.ErfApprovalCycleQueryData;
import com.xujie.sys.modules.erf.dto.ErfApprovalCycleReportDto;
import com.xujie.sys.modules.erf.mapper.ErfExpApplyMapper;
import com.xujie.sys.modules.erf.service.ErfApprovalCycleReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* 审批周期报表服务实现类
*
* <p><b>核心功能</b></p>
* <ul>
* <li>查询从申请单发起日到三类经理技术/生产/质量全部审批完成的记录</li>
* <li>计算全部审批完成时间取三类经理中最晚的审批时间</li>
* <li>计算审批周期天数从submit_time到allApproveTime</li>
* <li>支持按审批周期天数范围过滤</li>
* </ul>
*
* @author System
* @since 2026-02-26
*/
@Slf4j
@Service
public class ErfApprovalCycleReportServiceImpl implements ErfApprovalCycleReportService {
@Autowired
private ErfExpApplyMapper erfExpApplyMapper;
@Override
public PageUtils queryPage(ErfApprovalCycleQueryData data) {
log.info("=== 查询审批周期报表列表 ===");
// 分页查询
PageHelper.startPage(data.getPage(), data.getLimit());
List<ErfApprovalCycleReportDto> reportList = erfExpApplyMapper.getApprovalCycleReportList(data);
PageInfo<ErfApprovalCycleReportDto> pageInfo = new PageInfo<>(reportList);
// 计算审批周期及完成状态
reportList.forEach(this::calculateApprovalCycle);
// 按审批完成时间范围过滤post-filter因为allApproveTime在Java中计算
if (data.getAllApproveStartDate() != null || data.getAllApproveEndDate() != null) {
reportList = reportList.stream()
.filter(dto -> {
Date allApproveTime = dto.getAllApproveTime();
if (allApproveTime == null) {
return false;
}
LocalDate approveDate = convertToLocalDate(allApproveTime);
if (data.getAllApproveStartDate() != null) {
LocalDate startDate = convertToLocalDate(data.getAllApproveStartDate());
if (approveDate.isBefore(startDate)) {
return false;
}
}
if (data.getAllApproveEndDate() != null) {
LocalDate endDate = convertToLocalDate(data.getAllApproveEndDate());
if (approveDate.isAfter(endDate)) {
return false;
}
}
return true;
})
.collect(Collectors.toList());
}
// 按审批周期天数范围过滤
if (data.getCycleDaysMin() != null || data.getCycleDaysMax() != null) {
reportList = reportList.stream()
.filter(dto -> {
Integer days = dto.getApprovalCycleDays();
if (days == null) {
return false;
}
boolean matchMin = data.getCycleDaysMin() == null || days >= data.getCycleDaysMin();
boolean matchMax = data.getCycleDaysMax() == null || days <= data.getCycleDaysMax();
return matchMin && matchMax;
})
.collect(Collectors.toList());
}
log.info("查询完成,共{}条记录", reportList.size());
return new PageUtils(reportList, (int) pageInfo.getTotal(), data.getLimit(), data.getPage());
}
/**
* 计算审批周期相关字段
*
* <p>逻辑说明</p>
* <ul>
* <li>allApproveTime = MAX(techApproveTime, prodApproveTime, qualApproveTime)
* 要求三者都不为null才视为全部完成</li>
* <li>approvalCycleDays = DATEDIFF(day, submitTime, allApproveTime)</li>
* </ul>
*
* @param dto 报表DTO
*/
private void calculateApprovalCycle(ErfApprovalCycleReportDto dto) {
Date techTime = dto.getTechApproveTime();
Date prodTime = dto.getProdApproveTime();
Date qualTime = dto.getQualApproveTime();
// 三类经理均已审批完成才认为全部完成
boolean allApproved = (techTime != null && prodTime != null && qualTime != null);
dto.setIsAllApproved(allApproved);
if (allApproved) {
// 取三者中最晚的时间作为全部审批完成时间
Date allApproveTime = List.of(techTime, prodTime, qualTime)
.stream()
.max(Comparator.naturalOrder())
.orElse(null);
dto.setAllApproveTime(allApproveTime);
// 计算审批周期天数
if (dto.getSubmitTime() != null && allApproveTime != null) {
LocalDate submitDate = convertToLocalDate(dto.getSubmitTime());
LocalDate approveDate = convertToLocalDate(allApproveTime);
long days = ChronoUnit.DAYS.between(submitDate, approveDate);
if (days < 1) {
days = 1;
}
dto.setApprovalCycleDays((int) days);
}
} else {
dto.setAllApproveTime(null);
dto.setApprovalCycleDays(null);
}
}
/**
* 将Date转换为LocalDate
*
* @param date Date对象
* @return LocalDate对象
*/
private LocalDate convertToLocalDate(Date date) {
if (date instanceof java.sql.Date) {
return ((java.sql.Date) date).toLocalDate();
}
return date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
}
}

139
src/main/java/com/xujie/sys/modules/erf/service/impl/ErfSampleCycleReportServiceImpl.java

@ -0,0 +1,139 @@
package com.xujie.sys.modules.erf.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xujie.sys.common.utils.PageUtils;
import com.xujie.sys.modules.erf.data.ErfExpApplyData;
import com.xujie.sys.modules.erf.dto.ErfSampleCycleReportDto;
import com.xujie.sys.modules.erf.mapper.ErfExpApplyMapper;
import com.xujie.sys.modules.erf.service.ErfSampleCycleReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;
/**
* 样品完成周期报表服务实现类
*
* <p><b>核心功能</b></p>
* <ul>
* <li>对比期望完成时间和实际完成时间</li>
* <li>计算周期差异提前/准时/延期</li>
* <li>统计样品状态和数量</li>
* </ul>
*
* @author System
* @since 2026-02-12
*/
@Slf4j
@Service
public class ErfSampleCycleReportServiceImpl implements ErfSampleCycleReportService {
@Autowired
private ErfExpApplyMapper erfExpApplyMapper;
@Override
public PageUtils queryPage(ErfExpApplyData data) {
log.info("=== 查询样品完成周期报表列表 ===");
// 分页查询
PageHelper.startPage(data.getPage(), data.getLimit());
List<ErfExpApplyData> applyList = erfExpApplyMapper.searchExpApplyList(data);
PageInfo<ErfExpApplyData> pageInfo = new PageInfo<>(applyList);
// 转换为报表DTO
List<ErfSampleCycleReportDto> reportList = applyList.stream()
.map(this::convertToReportDto)
.collect(Collectors.toList());
// 过滤周期差异范围如果有设置
if (data.getCycleDifferenceMin() != null || data.getCycleDifferenceMax() != null) {
reportList = reportList.stream()
.filter(dto -> {
Integer diff = dto.getCycleDifference();
if (diff == null) {
return false;
}
boolean matchMin = data.getCycleDifferenceMin() == null || diff >= data.getCycleDifferenceMin();
boolean matchMax = data.getCycleDifferenceMax() == null || diff <= data.getCycleDifferenceMax();
return matchMin && matchMax;
})
.collect(Collectors.toList());
}
log.info("查询完成,共{}条记录", reportList.size());
return new PageUtils(reportList, reportList.size(), data.getLimit(), data.getPage());
}
/**
* 转换为报表DTO
*
* @param data 申请单数据
* @return 报表DTO
*/
private ErfSampleCycleReportDto convertToReportDto(ErfExpApplyData data) {
ErfSampleCycleReportDto dto = new ErfSampleCycleReportDto();
// 基本信息
dto.setApplyNo(data.getApplyNo());
dto.setTitle(data.getTitle());
dto.setExperimentType(data.getExperimentType());
dto.setBuNo(data.getBuNo());
dto.setBuName(data.getBuDesc());
dto.setCreatorName(data.getCreatorName());
dto.setStatus(data.getStatus());
dto.setCreateTime(data.getCreateTime());
// 时间信息
dto.setExpectedFinishDate(data.getExpectedFinishDate());
dto.setActualFinishDate(data.getActualFinishDate());
// 计算周期差异
if (data.getExpectedFinishDate() != null && data.getActualFinishDate() != null) {
LocalDate expectedDate = convertToLocalDate(data.getExpectedFinishDate());
LocalDate actualDate = convertToLocalDate(data.getActualFinishDate());
// 计算天数差异实际 - 期望
long daysDiff = ChronoUnit.DAYS.between(expectedDate, actualDate);
dto.setCycleDifference((int) daysDiff);
// 判断是否延期
dto.setIsDelayed(daysDiff > 0);
}
// 样品状态和数量
dto.setFinalStatus(data.getFinalStatus());
dto.setFinalQuantity(data.getFinalQuantity());
// 样品状态描述
if ("NORMAL".equals(data.getFinalStatus())) {
dto.setFinalStatusDesc("正常入库");
} else if ("SCRAPPED".equals(data.getFinalStatus())) {
dto.setFinalStatusDesc("报废");
} else {
dto.setFinalStatusDesc("未确认");
}
return dto;
}
/**
* 将Date转换为LocalDate
*
* @param date Date对象
* @return LocalDate对象
*/
private LocalDate convertToLocalDate(java.util.Date date) {
if (date instanceof java.sql.Date) {
return ((java.sql.Date) date).toLocalDate();
}
return date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
}
}

162
src/main/resources/mapper/erf/ErfExpApplyMapper.xml

@ -99,6 +99,21 @@
<if test="data.productType != null and data.productType != ''">
AND product_type LIKE '%' + #{data.productType} + '%'
</if>
<if test="data.creatorName != null and data.creatorName != ''">
AND creator_name LIKE '%' + #{data.creatorName} + '%'
</if>
<if test="data.expectedFinishStartDate != null">
AND CAST(expected_finish_date AS DATE) &gt;= #{data.expectedFinishStartDate}
</if>
<if test="data.expectedFinishEndDate != null">
AND CAST(expected_finish_date AS DATE) &lt;= #{data.expectedFinishEndDate}
</if>
<if test="data.actualFinishStartDate != null">
AND CAST(actual_finish_date AS DATE) &gt;= #{data.actualFinishStartDate}
</if>
<if test="data.actualFinishEndDate != null">
AND CAST(actual_finish_date AS DATE) &lt;= #{data.actualFinishEndDate}
</if>
</where>
ORDER BY create_time DESC
</select>
@ -268,6 +283,153 @@
AND order_ref6 = #{orderRef6}
</select>
<!-- 审批周期报表结果映射 -->
<resultMap id="ApprovalCycleResultMap" type="com.xujie.sys.modules.erf.dto.ErfApprovalCycleReportDto">
<result column="apply_no" property="applyNo"/>
<result column="bu_no" property="buNo"/>
<result column="buDesc" property="buName"/>
<result column="experiment_type" property="experimentType"/>
<result column="title" property="title"/>
<result column="creator_name" property="creatorName"/>
<result column="status" property="status"/>
<result column="create_time" property="createTime"/>
<result column="submit_time" property="submitTime"/>
<result column="tech_manager_name" property="techManagerName"/>
<result column="tech_approve_time" property="techApproveTime"/>
<result column="prod_manager_name" property="prodManagerName"/>
<result column="prod_approve_time" property="prodApproveTime"/>
<result column="qual_manager_name" property="qualManagerName"/>
<result column="qual_approve_time" property="qualApproveTime"/>
</resultMap>
<!-- 查询审批周期报表列表 -->
<!-- 统计从申请单发起日(submit_time)到技术/生产/质量三类经理全部审批完成的周期 -->
<select id="getApprovalCycleReportList" resultMap="ApprovalCycleResultMap">
SELECT
a.apply_no,
a.bu_no,
dbo.get_bu_desc(a.site, a.bu_no) AS buDesc,
a.experiment_type,
a.title,
a.creator_name,
a.status,
a.create_time,
a.submit_time,
-- 技术经理审批(单人,取已批准记录的最晚完成时间)
tech.assignee_name AS tech_manager_name,
tech.complete_time AS tech_approve_time,
-- 生产经理审批(可能多人,合并姓名,取最晚完成时间)
prod.assignee_names AS prod_manager_name,
prod.max_complete_time AS prod_approve_time,
-- 质量经理审批(可能多人,合并姓名,取最晚完成时间)
qual.assignee_names AS qual_manager_name,
qual.max_complete_time AS qual_approve_time
FROM erf_exp_apply a
-- 技术经理审批:取该申请单最新一次审批通过的记录
LEFT JOIN (
SELECT
n1.apply_no,
n1.assignee_name,
n1.complete_time
FROM erf_flow_node_instance n1
INNER JOIN (
SELECT apply_no, MAX(attempt_no) AS max_attempt
FROM erf_flow_node_instance
WHERE node_code = '技术经理审批'
GROUP BY apply_no
) n1a ON n1.apply_no = n1a.apply_no AND n1.attempt_no = n1a.max_attempt
WHERE n1.node_code = '技术经理审批'
AND n1.status = '已批准'
) tech ON a.apply_no = tech.apply_no
-- 生产经理审批:取最新一次attempt中所有已批准的记录,合并姓名,取最晚完成时间
-- 使用 STUFF+FOR XML PATH 兼容 SQL Server 2017 以下版本
LEFT JOIN (
SELECT
p.apply_no,
STUFF((
SELECT '、' + p2.assignee_name
FROM erf_flow_node_instance p2
WHERE p2.node_code = '生产经理审批'
AND p2.status = '已批准'
AND p2.apply_no = p.apply_no
AND p2.attempt_no = (
SELECT MAX(p3.attempt_no)
FROM erf_flow_node_instance p3
WHERE p3.apply_no = p.apply_no
AND p3.node_code = '生产经理审批'
)
FOR XML PATH('')
), 1, 1, '') AS assignee_names,
MAX(p.complete_time) AS max_complete_time
FROM erf_flow_node_instance p
INNER JOIN (
SELECT apply_no, MAX(attempt_no) AS max_attempt
FROM erf_flow_node_instance
WHERE node_code = '生产经理审批'
GROUP BY apply_no
) pa ON p.apply_no = pa.apply_no AND p.attempt_no = pa.max_attempt
WHERE p.node_code = '生产经理审批'
AND p.status = '已批准'
GROUP BY p.apply_no
) prod ON a.apply_no = prod.apply_no
-- 质量经理审批:取最新一次attempt中所有已批准的记录,合并姓名,取最晚完成时间
LEFT JOIN (
SELECT
q.apply_no,
STUFF((
SELECT '、' + q2.assignee_name
FROM erf_flow_node_instance q2
WHERE q2.node_code = '质量经理审批'
AND q2.status = '已批准'
AND q2.apply_no = q.apply_no
AND q2.attempt_no = (
SELECT MAX(q3.attempt_no)
FROM erf_flow_node_instance q3
WHERE q3.apply_no = q.apply_no
AND q3.node_code = '质量经理审批'
)
FOR XML PATH('')
), 1, 1, '') AS assignee_names,
MAX(q.complete_time) AS max_complete_time
FROM erf_flow_node_instance q
INNER JOIN (
SELECT apply_no, MAX(attempt_no) AS max_attempt
FROM erf_flow_node_instance
WHERE node_code = '质量经理审批'
GROUP BY apply_no
) qa ON q.apply_no = qa.apply_no AND q.attempt_no = qa.max_attempt
WHERE q.node_code = '质量经理审批'
AND q.status = '已批准'
GROUP BY q.apply_no
) qual ON a.apply_no = qual.apply_no
<where>
-- 只查询已下达(有发起日)的申请单
a.submit_time IS NOT NULL
<if test="data.applyNo != null and data.applyNo != ''">
AND a.apply_no LIKE '%' + #{data.applyNo} + '%'
</if>
<if test="data.buNo != null and data.buNo != ''">
AND a.bu_no = #{data.buNo}
</if>
<if test="data.experimentType != null and data.experimentType != ''">
AND a.experiment_type = #{data.experimentType}
</if>
<if test="data.creatorName != null and data.creatorName != ''">
AND a.creator_name LIKE '%' + #{data.creatorName} + '%'
</if>
<if test="data.submitStartDate != null">
AND CAST(a.submit_time AS DATE) &gt;= #{data.submitStartDate}
</if>
<if test="data.submitEndDate != null">
AND CAST(a.submit_time AS DATE) &lt;= #{data.submitEndDate}
</if>
<if test="data.status != null and data.status != ''">
AND a.status = #{data.status}
</if>
</where>
ORDER BY a.submit_time DESC
</select>
<!-- 复制附件 -->
<insert id="copyAttachment">
INSERT INTO sys_oss

Loading…
Cancel
Save