溯源统计

This commit is contained in:
顾君禹
2025-09-15 16:03:36 +08:00
parent 4daa5a8637
commit 23d1b95425
7 changed files with 165 additions and 29 deletions

View File

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodePageReqVO; import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodePageReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodePageWithStatsRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeRespVO; import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeSaveReqVO; import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeSaveReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO; import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO;
@@ -23,7 +24,6 @@ import org.springframework.web.bind.annotation.*;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -75,29 +75,17 @@ public class TraceabilityCodeController {
} }
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得溯源-溯源码分页") @Operation(summary = "获得溯源-溯源码分页(含统计信息)")
public CommonResult<PageResult<TraceabilityCodeRespVO>> getTraceabilityCodePage(@Valid TraceabilityCodePageReqVO pageReqVO) { public CommonResult<TraceabilityCodePageWithStatsRespVO> getTraceabilityCodePage(@Valid TraceabilityCodePageReqVO pageReqVO) {
PageResult<TraceabilityCodeDO> pageResult = traceabilityCodeService.getTraceabilityCodePage(pageReqVO); TraceabilityCodePageWithStatsRespVO result = traceabilityCodeService.getTraceabilityCodePageWithStats(pageReqVO);
// 转换分页结果中的每个DO对象为RespVO对象 return success(result);
PageResult<TraceabilityCodeRespVO> respPageResult = new PageResult<>();
respPageResult.setList(pageResult.getList().stream()
.map(TraceabilityDataConverter::convertToRespVO)
.collect(Collectors.toList()));
respPageResult.setTotal(pageResult.getTotal());
return success(respPageResult);
} }
@GetMapping("/list") @GetMapping("/list")
@Operation(summary = "获得溯源-溯源码批次集合") @Operation(summary = "获得溯源-溯源码批次集合(含统计信息)")
public CommonResult<PageResult<TraceabilityCodeRespVO>> getTraceabilityCodeList(@Valid TraceabilityCodePageReqVO pageReqVO) { public CommonResult<TraceabilityCodePageWithStatsRespVO> getTraceabilityCodeList(@Valid TraceabilityCodePageReqVO pageReqVO) {
PageResult<TraceabilityCodeDO> pageResult = traceabilityCodeService.getTraceabilityCodeList(pageReqVO); TraceabilityCodePageWithStatsRespVO result = traceabilityCodeService.getTraceabilityCodeListWithStats(pageReqVO);
// 转换分页结果中的每个DO对象为RespVO对象 return success(result);
PageResult<TraceabilityCodeRespVO> respPageResult = new PageResult<>();
respPageResult.setList(pageResult.getList().stream()
.map(TraceabilityDataConverter::convertToRespVO)
.collect(Collectors.toList()));
respPageResult.setTotal(pageResult.getTotal());
return success(respPageResult);
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")

View File

@@ -169,6 +169,7 @@ public class TraceabilityCodeRespVO {
@Schema(description = "创建时间") @Schema(description = "创建时间")
@ExcelProperty("创建时间") @ExcelProperty("创建时间")
private LocalDateTime createTime; private LocalDateTime createTime;
private String creator;
private String codeOutBatch; private String codeOutBatch;
private Long scanCodeCount; private Long scanCodeCount;

View File

@@ -59,6 +59,6 @@ public class EnvironmentIndicatorsDO extends BaseDO {
* 说明 * 说明
*/ */
private String description; private String description;
private String tenantId;
} }

View File

@@ -7,8 +7,12 @@ import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.Traceab
import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO; import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@@ -83,6 +87,44 @@ public interface TraceabilityCodeMapper extends BaseMapperX<TraceabilityCodeDO>
@Param("codeOutBatch") String codeOutBatch, @Param("codeOutBatch") String codeOutBatch,
@Param("status") Long status); @Param("status") Long status);
/**
* 统计溯源码数量信息
*/
@Select("<script>" +
"SELECT " +
"COUNT(*) as totalAmount, " +
"SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as normalAmount, " +
"SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as wasteAmount " +
"FROM farm_traceability_code " +
"WHERE 1=1 " +
"<if test='tenantId != null'> AND tenant_id = #{tenantId} </if>" +
"<if test='speciesCode != null'> AND species_code = #{speciesCode} </if>" +
"<if test='speciesName != null and speciesName != \"\"'> AND species_name LIKE CONCAT('%', #{speciesName}, '%') </if>" +
"<if test='baseId != null'> AND base_id = #{baseId} </if>" +
"<if test='baseName != null and baseName != \"\"'> AND base_name LIKE CONCAT('%', #{baseName}, '%') </if>" +
"<if test='plotId != null'> AND plot_id = #{plotId} </if>" +
"<if test='plotName != null and plotName != \"\"'> AND plot_name LIKE CONCAT('%', #{plotName}, '%') </if>" +
"<if test='harvestDateStart != null'> AND harvest_date &gt;= #{harvestDateStart} </if>" +
"<if test='harvestDateEnd != null'> AND harvest_date &lt;= #{harvestDateEnd} </if>" +
"<if test='farmingInputCount != null'> AND farming_input_count = #{farmingInputCount} </if>" +
"<if test='productId != null'> AND product_id = #{productId} </if>" +
"<if test='productName != null and productName != \"\"'> AND product_name LIKE CONCAT('%', #{productName}, '%') </if>" +
"<if test='codeOutBatch != null and codeOutBatch != \"\"'> AND code_out_batch = #{codeOutBatch} </if>" +
"</script>")
Map<String, Object> selectStatistics(@Param("tenantId") String tenantId,
@Param("speciesCode") String speciesCode,
@Param("speciesName") String speciesName,
@Param("baseId") String baseId,
@Param("baseName") String baseName,
@Param("plotId") String plotId,
@Param("plotName") String plotName,
@Param("harvestDateStart") String harvestDateStart,
@Param("harvestDateEnd") String harvestDateEnd,
@Param("farmingInputCount") Long farmingInputCount,
@Param("productId") String productId,
@Param("productName") String productName,
@Param("codeOutBatch") String codeOutBatch);
default PageResult<TraceabilityCodeDO> selectPageList(TraceabilityCodePageReqVO reqVO) { default PageResult<TraceabilityCodeDO> selectPageList(TraceabilityCodePageReqVO reqVO) {
// 先查询符合条件的最新记录ID列表 // 先查询符合条件的最新记录ID列表
List<TraceabilityCodeDO> latestRecords = selectLatestByCodeOutBatch( List<TraceabilityCodeDO> latestRecords = selectLatestByCodeOutBatch(
@@ -101,12 +143,12 @@ public interface TraceabilityCodeMapper extends BaseMapperX<TraceabilityCodeDO>
reqVO.getCodeOutBatch(), reqVO.getCodeOutBatch(),
reqVO.getStatus() reqVO.getStatus()
); );
// 如果没有记录,直接返回空结果 // 如果没有记录,直接返回空结果
if (latestRecords.isEmpty()) { if (latestRecords.isEmpty()) {
return new PageResult<>(Collections.emptyList(), 0L); return new PageResult<>(Collections.emptyList(), 0L);
} }
// 按CodeOutBatch去重,确保每个批次只保留一条记录(保留最新的) // 按CodeOutBatch去重,确保每个批次只保留一条记录(保留最新的)
Map<String, TraceabilityCodeDO> uniqueBatchMap = latestRecords.stream() Map<String, TraceabilityCodeDO> uniqueBatchMap = latestRecords.stream()
.filter(record -> record.getCodeOutBatch() != null) // 过滤掉批次为空的记录 .filter(record -> record.getCodeOutBatch() != null) // 过滤掉批次为空的记录
@@ -121,10 +163,10 @@ public interface TraceabilityCodeMapper extends BaseMapperX<TraceabilityCodeDO>
return existing.getCreateTime() != null ? existing : replacement; return existing.getCreateTime() != null ? existing : replacement;
} }
)); ));
// 转换为去重后的列表 // 转换为去重后的列表
List<TraceabilityCodeDO> uniqueRecords = new ArrayList<>(uniqueBatchMap.values()); List<TraceabilityCodeDO> uniqueRecords = new ArrayList<>(uniqueBatchMap.values());
// 按创建时间倒序排序 // 按创建时间倒序排序
uniqueRecords.sort((a, b) -> { uniqueRecords.sort((a, b) -> {
if (a.getCreateTime() == null && b.getCreateTime() == null) return 0; if (a.getCreateTime() == null && b.getCreateTime() == null) return 0;
@@ -132,12 +174,12 @@ public interface TraceabilityCodeMapper extends BaseMapperX<TraceabilityCodeDO>
if (b.getCreateTime() == null) return -1; if (b.getCreateTime() == null) return -1;
return b.getCreateTime().compareTo(a.getCreateTime()); return b.getCreateTime().compareTo(a.getCreateTime());
}); });
// 提取ID列表 // 提取ID列表
List<String> ids = uniqueRecords.stream() List<String> ids = uniqueRecords.stream()
.map(TraceabilityCodeDO::getId) .map(TraceabilityCodeDO::getId)
.collect(Collectors.toList()); .collect(Collectors.toList());
// 根据ID列表进行分页查询,获取完整的记录信息 // 根据ID列表进行分页查询,获取完整的记录信息
return selectPage(reqVO, new LambdaQueryWrapperX<TraceabilityCodeDO>() return selectPage(reqVO, new LambdaQueryWrapperX<TraceabilityCodeDO>()
.in(TraceabilityCodeDO::getId, ids) .in(TraceabilityCodeDO::getId, ids)

View File

@@ -1,7 +1,9 @@
package cn.iocoder.yudao.module.farm.service.environmentindicators; package cn.iocoder.yudao.module.farm.service.environmentindicators;
import cn.hutool.core.util.IdUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.module.farm.controller.admin.environmentindicators.vo.EnvironmentIndicatorsPageReqVO; import cn.iocoder.yudao.module.farm.controller.admin.environmentindicators.vo.EnvironmentIndicatorsPageReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.environmentindicators.vo.EnvironmentIndicatorsSaveReqVO; import cn.iocoder.yudao.module.farm.controller.admin.environmentindicators.vo.EnvironmentIndicatorsSaveReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.environmentindicators.EnvironmentIndicatorsDO; import cn.iocoder.yudao.module.farm.dal.dataobject.environmentindicators.EnvironmentIndicatorsDO;
@@ -13,6 +15,7 @@ import org.springframework.validation.annotation.Validated;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.ENVIRONMENT_INDICATORS_NOT_EXISTS; import static cn.iocoder.yudao.module.farm.enums.ErrorCodeConstants.ENVIRONMENT_INDICATORS_NOT_EXISTS;
/** /**
@@ -29,8 +32,10 @@ public class EnvironmentIndicatorsServiceImpl implements EnvironmentIndicatorsSe
@Override @Override
public Integer createEnvironmentIndicators(EnvironmentIndicatorsSaveReqVO createReqVO) { public Integer createEnvironmentIndicators(EnvironmentIndicatorsSaveReqVO createReqVO) {
LoginUser user = getLoginUser();
// 插入 // 插入
EnvironmentIndicatorsDO environmentIndicators = BeanUtils.toBean(createReqVO, EnvironmentIndicatorsDO.class); EnvironmentIndicatorsDO environmentIndicators = BeanUtils.toBean(createReqVO, EnvironmentIndicatorsDO.class);
environmentIndicators.setTenantId(String.valueOf(user.getTenantId()));
environmentIndicatorsMapper.insert(environmentIndicators); environmentIndicatorsMapper.insert(environmentIndicators);
// 返回 // 返回

View File

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.farm.service.traceabilitycode;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodePageReqVO; import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodePageReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodePageWithStatsRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeSaveReqVO; import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeSaveReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO; import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
@@ -63,4 +64,20 @@ public interface TraceabilityCodeService {
TraceabilityCodeDO scanTraceabilityCode(String id); TraceabilityCodeDO scanTraceabilityCode(String id);
PageResult<TraceabilityCodeDO> getTraceabilityCodeList(@Valid TraceabilityCodePageReqVO pageReqVO); PageResult<TraceabilityCodeDO> getTraceabilityCodeList(@Valid TraceabilityCodePageReqVO pageReqVO);
/**
* 获得溯源-溯源码分页(含统计信息)
*
* @param pageReqVO 分页查询
* @return 溯源-溯源码分页(含统计信息)
*/
TraceabilityCodePageWithStatsRespVO getTraceabilityCodePageWithStats(@Valid TraceabilityCodePageReqVO pageReqVO);
/**
* 获得溯源-溯源码批次集合(含统计信息)
*
* @param pageReqVO 分页查询
* @return 溯源-溯源码批次集合(含统计信息)
*/
TraceabilityCodePageWithStatsRespVO getTraceabilityCodeListWithStats(@Valid TraceabilityCodePageReqVO pageReqVO);
} }

View File

@@ -8,9 +8,12 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodePageReqVO; import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodePageReqVO;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodePageWithStatsRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeRespVO;
import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeSaveReqVO; import cn.iocoder.yudao.module.farm.controller.admin.traceabilitycode.vo.TraceabilityCodeSaveReqVO;
import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO; import cn.iocoder.yudao.module.farm.dal.dataobject.traceabilitycode.TraceabilityCodeDO;
import cn.iocoder.yudao.module.farm.dal.mysql.traceabilitycode.TraceabilityCodeMapper; import cn.iocoder.yudao.module.farm.dal.mysql.traceabilitycode.TraceabilityCodeMapper;
import cn.iocoder.yudao.module.farm.framework.util.TraceabilityDataConverter;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -18,6 +21,8 @@ import org.springframework.validation.annotation.Validated;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
@@ -296,4 +301,82 @@ public class TraceabilityCodeServiceImpl implements TraceabilityCodeService {
// 这里我们不需要实际转换,因为DO对象保持Long类型用于数据库存储 // 这里我们不需要实际转换,因为DO对象保持Long类型用于数据库存储
// 转换将在VO层进行,确保前端接收到的是Boolean类型 // 转换将在VO层进行,确保前端接收到的是Boolean类型
} }
@Override
public TraceabilityCodePageWithStatsRespVO getTraceabilityCodePageWithStats(TraceabilityCodePageReqVO pageReqVO) {
// 获取分页数据
PageResult<TraceabilityCodeDO> pageResult = getTraceabilityCodePage(pageReqVO);
// 获取统计信息
Map<String, Object> statisticsMap = traceabilityCodeMapper.selectStatistics(
pageReqVO.getTenantId(),
pageReqVO.getSpeciesCode(),
pageReqVO.getSpeciesName(),
pageReqVO.getBaseId(),
pageReqVO.getBaseName(),
pageReqVO.getPlotId(),
pageReqVO.getPlotName(),
pageReqVO.getHarvestDateStart(),
pageReqVO.getHarvestDateEnd(),
pageReqVO.getFarmingInputCount(),
pageReqVO.getProductId(),
pageReqVO.getProductName(),
pageReqVO.getCodeOutBatch()
);
// 转换统计信息
TraceabilityCodePageWithStatsRespVO.StatisticsInfo statistics = new TraceabilityCodePageWithStatsRespVO.StatisticsInfo(
((Number) statisticsMap.get("totalAmount")).longValue(),
((Number) statisticsMap.get("normalAmount")).longValue(),
((Number) statisticsMap.get("wasteAmount")).longValue()
);
// 转换分页结果为VO
PageResult<TraceabilityCodeRespVO> respPageResult = new PageResult<>();
respPageResult.setList(pageResult.getList().stream()
.map(TraceabilityDataConverter::convertToRespVO)
.collect(Collectors.toList()));
respPageResult.setTotal(pageResult.getTotal());
return new TraceabilityCodePageWithStatsRespVO(respPageResult, statistics);
}
@Override
public TraceabilityCodePageWithStatsRespVO getTraceabilityCodeListWithStats(TraceabilityCodePageReqVO pageReqVO) {
// 获取分页数据
PageResult<TraceabilityCodeDO> pageResult = getTraceabilityCodeList(pageReqVO);
// 获取统计信息
Map<String, Object> statisticsMap = traceabilityCodeMapper.selectStatistics(
pageReqVO.getTenantId(),
pageReqVO.getSpeciesCode(),
pageReqVO.getSpeciesName(),
pageReqVO.getBaseId(),
pageReqVO.getBaseName(),
pageReqVO.getPlotId(),
pageReqVO.getPlotName(),
pageReqVO.getHarvestDateStart(),
pageReqVO.getHarvestDateEnd(),
pageReqVO.getFarmingInputCount(),
pageReqVO.getProductId(),
pageReqVO.getProductName(),
pageReqVO.getCodeOutBatch()
);
// 转换统计信息
TraceabilityCodePageWithStatsRespVO.StatisticsInfo statistics = new TraceabilityCodePageWithStatsRespVO.StatisticsInfo(
((Number) statisticsMap.get("totalAmount")).longValue(),
((Number) statisticsMap.get("normalAmount")).longValue(),
((Number) statisticsMap.get("wasteAmount")).longValue()
);
// 转换分页结果为VO
PageResult<TraceabilityCodeRespVO> respPageResult = new PageResult<>();
respPageResult.setList(pageResult.getList().stream()
.map(TraceabilityDataConverter::convertToRespVO)
.collect(Collectors.toList()));
respPageResult.setTotal(pageResult.getTotal());
return new TraceabilityCodePageWithStatsRespVO(respPageResult, statistics);
}
} }