分析页统计:1、小板数据源name完善,宽高厚小数点0移除,用x连接;2、x轴日类型修改;3、小板排名前10逻辑错误修复;

This commit is contained in:
gaoqr
2024-08-15 18:26:47 +08:00
parent 982be46985
commit 4428dbedc3
6 changed files with 178 additions and 86 deletions
@@ -86,4 +86,11 @@ public class OrderStatisticsController {
public CommonResult<Map<String,Object>> getPlateArea(@Valid OrderStatisticsReqVO reqVO) {
return success(orderStatisticsService.getOrderPlateAreaGroup(reqVO));
}
@GetMapping("/bigPlateCount/group")
@Operation(summary = "大板数量分组统计")
public CommonResult<Map<String, Object>> getBigPlateCount(@Valid OrderStatisticsReqVO reqVO) {
return success(null);
}
}
@@ -61,40 +61,32 @@ public class OrderGoodsPlateRespVO implements Comparable<OrderGoodsPlateRespVO>
@Override
public int compareTo(@NotNull OrderGoodsPlateRespVO other) {
// 解析 date 字符串为年、月、周
String[] partsThis = orderDate.split("-");
String[] partsOther = other.orderDate.split("-");
if (orderDate != null && other.orderDate != null) {
// 解析 date 字符串为年、月、周
String[] partsThis = orderDate.split("-");
String[] partsOther = other.orderDate.split("-");
// 比较年份
int yearComparison = Integer.compare(Integer.parseInt(partsThis[0]), Integer.parseInt(partsOther[0]));
if (yearComparison != 0) {
return yearComparison;
}
// 比较月份
if (partsThis.length > 1 && partsOther.length > 1) {
int monthComparison = Integer.compare(Integer.parseInt(partsThis[1]), Integer.parseInt(partsOther[1]));
if (monthComparison != 0) {
return monthComparison;
// 比较年份
int yearComparison = Integer.compare(Integer.parseInt(partsThis[0]), Integer.parseInt(partsOther[0]));
if (yearComparison != 0) {
return yearComparison;
}
}
// 比较周/日
if (partsThis.length > 2 && partsOther.length > 2) {
int weekComparison = Integer.compare(Integer.parseInt(partsThis[2]), Integer.parseInt(partsOther[2]));
if (weekComparison != 0) {
return weekComparison;
// 比较月份
if (partsThis.length + partsOther.length > 2) {
int monthComparison = Integer.compare(Integer.parseInt(partsThis[1]), Integer.parseInt(partsOther[1]));
if (monthComparison != 0) {
return monthComparison;
}
}
}
// 比较数量
if (orderCount != null && other.orderCount != null) {
return orderCount.compareTo(other.orderCount);
}
// 比较面积
if (orderArea != null && other.orderArea != null) {
return orderArea.compareTo(other.orderArea);
// 比较周/日
if (partsThis.length + partsOther.length > 4) {
int weekComparison = Integer.compare(Integer.parseInt(partsThis[2]), Integer.parseInt(partsOther[2]));
if (weekComparison != 0) {
return weekComparison;
}
}
}
return 0;
}
@@ -21,6 +21,9 @@ public class OptimizeBoardModelDO extends ESDocument {
@Schema(description = "排单ID")
private Long planId;
@Schema(description ="排单优化的大板数里")
private Long placeBoardNumber;
@Schema(description = "生产单id")
private Long orderId;
@@ -18,19 +18,37 @@ import java.util.List;
@Mapper
public interface OrderPlateStatisticsMapper extends BaseMapperX<PlateDO> {
/**
* 基于生产单时间分组统计小板数量
* 基于商品id分组的小板数量列表
*
* @param reqVO
* @return
*/
List<OrderGoodsPlateRespVO> selectPlateAnalysisListByCount(@Param("req") OrderStatisticsReqVO reqVO);
List<OrderGoodsPlateRespVO> selectPlateCountList(@Param("req") OrderStatisticsReqVO reqVO);
/**
* 基于生产单时间分组统计小板面积
* 基于订单日期分组的前10小板数量分组
* @param goodsIdList
* @param reqVO
* @return
*/
List<OrderGoodsPlateRespVO> selectTopTenPlateCountListGroupByOrderDate(@Param("goodsIds") List<Long> goodsIdList, @Param("req") OrderStatisticsReqVO reqVO);
/**
* 基于商品id分组的小板面积列表
* @param reqVO
* @return
*/
List<OrderGoodsPlateRespVO> selectPlateAreaList(@Param("req") OrderStatisticsReqVO reqVO);
/**
* 基于订单日期分组的前10小板面积分组
*
* @param reqVO
* @return
*/
List<OrderGoodsPlateRespVO> selectPlateAnalysisListByArea(@Param("req") OrderStatisticsReqVO reqVO);
List<OrderGoodsPlateRespVO> selectTopTenPlateAreaListGroupByOrderDate(@Param("goodsIds") List<Long> goodsIdList, @Param("req") OrderStatisticsReqVO reqVO);
}
@@ -12,6 +12,9 @@ import com.cf.imes.module.executor.dal.mysql.order.OrderStatisticsMapper;
import com.cf.imes.module.executor.dal.mysql.plan.PlanMapper;
import com.cf.imes.module.executor.dal.mysql.plate.OrderPlateStatisticsMapper;
import com.cf.imes.module.executor.enums.OrderStatisticsUnit;
import com.cf.imes.module.system.api.dict.DictDataApi;
import com.cf.imes.module.system.api.dict.dto.DictDataRespDTO;
import com.cf.imes.module.system.enums.DictTypeConstants;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -47,6 +50,9 @@ public class OrderStatisticsServiceImpl implements OrderStatisticsService {
@Resource
private OrderPlateStatisticsMapper orderPlateStatisticsMapper;
@Resource
private DictDataApi dictDataApi;
// 常用的字段key
private static final String DATELIST_FIELD_NAME = "dateList";
private static final String SERIES_FIELD_NAME = "series";
@@ -200,22 +206,33 @@ public class OrderStatisticsServiceImpl implements OrderStatisticsService {
// 所有的日期集合
List<String> dateList = getDateList(reqVO);
List<OrderGoodsPlateRespVO> orderGoodsPlateRespVOList = orderPlateStatisticsMapper.selectPlateAnalysisListByCount(reqVO);
// 基于相同的orderDate分组
Map<String, List<OrderGoodsPlateRespVO>> orderGoodsPlateRespMap = orderGoodsPlateRespVOList.stream()
// 查询时间段内数量最多的小板,排序列出数量前10的goods_id
List<Long> topTenCountGoodsId = orderPlateStatisticsMapper.selectPlateCountList(reqVO).stream()
.sorted(Comparator.comparingLong(OrderGoodsPlateRespVO::getOrderCount).reversed())
.map(OrderGoodsPlateRespVO::getGoodsId)
.limit(10)
.collect(Collectors.toList());
// 前十goods_id基于时间分组
Map<String, List<OrderGoodsPlateRespVO>> orderGoodsPlateRespMap = orderPlateStatisticsMapper.selectTopTenPlateCountListGroupByOrderDate(topTenCountGoodsId, reqVO).stream()
.sorted(Comparator.naturalOrder())
.collect(Collectors.groupingBy(OrderGoodsPlateRespVO::getOrderDate, LinkedHashMap::new, Collectors.toList()));
// 获取所有商品map
Map<Long, OrderGoodsPlateRespVO> goodsMap = orderGoodsPlateRespMap.values().stream()
.flatMap(List::stream)
.collect(Collectors.toMap(
OrderGoodsPlateRespVO::getGoodsId,
vo -> vo,
(oldValue, newValue) -> oldValue
));
// 获取所有商品{goodsId:respvo},根据top10排序
Map<Long, OrderGoodsPlateRespVO> goodsMap = new LinkedHashMap<>();
for (Long id : topTenCountGoodsId) {
List<OrderGoodsPlateRespVO> list = orderGoodsPlateRespMap.values().stream()
.flatMap(List::stream)
.filter(vo -> vo.getGoodsId().equals(id))
.collect(Collectors.toList());
if (!list.isEmpty()) {
// goodsId相同,其他属性任取
goodsMap.put(id, list.get(0));
}
}
// 遍历订单状态所有枚举值
// 遍历所有goods_id
List<Map<String, Object>> series = new ArrayList<>();
for (Map.Entry<Long, OrderGoodsPlateRespVO> entry : goodsMap.entrySet()) {
Map<String, Object> seriesItem = new HashMap<>();
@@ -228,10 +245,10 @@ public class OrderStatisticsServiceImpl implements OrderStatisticsService {
List<OrderGoodsPlateRespVO> orderGoodsPlateRespVOS = orderGoodsPlateRespMap.get(dateStr);
int count = 0;
if (orderGoodsPlateRespVOS != null) {
count = orderGoodsPlateRespVOS.stream()
Optional<OrderGoodsPlateRespVO> matchingRespVO = orderGoodsPlateRespVOS.stream()
.filter(respVO -> Objects.equals(entry.getKey(), respVO.getGoodsId()))
.map(OrderGoodsPlateRespVO::getOrderCount)
.findFirst().orElse(0);
.findFirst();
count = matchingRespVO.map(OrderGoodsPlateRespVO::getOrderCount).orElse(0);
}
sumArr[index++] = count;
}
@@ -240,9 +257,12 @@ public class OrderStatisticsServiceImpl implements OrderStatisticsService {
seriesItem.put("id", entry.getKey());
// 材质-商品名称-颜色-纹理-宽-高-厚-品牌
OrderGoodsPlateRespVO orderGoodsPlateRespVO = entry.getValue();
// 获取纹路描述
DictDataRespDTO grainDTO = dictDataApi.getDictData(DictTypeConstants.GRAIN_TYPE, String.valueOf(orderGoodsPlateRespVO.getTexture())).getData();
String texture = ObjectUtil.isNotNull(grainDTO) ? grainDTO.getLabel() : "";
seriesItem.put("name", orderGoodsPlateRespVO.getMaterial() + "-" + orderGoodsPlateRespVO.getGoodsName() +
"-" + orderGoodsPlateRespVO.getColor() + "-" + orderGoodsPlateRespVO.getTexture() + "-" + orderGoodsPlateRespVO.getWidth() +
"-" + orderGoodsPlateRespVO.getHeight() + "-" + orderGoodsPlateRespVO.getThickness() + "-" + orderGoodsPlateRespVO.getBrand());
"-" + orderGoodsPlateRespVO.getColor() + "-" + texture + "-" + stripTrailingZeros(orderGoodsPlateRespVO.getWidth()) +
"×" + stripTrailingZeros(orderGoodsPlateRespVO.getHeight()) + "×" + stripTrailingZeros(orderGoodsPlateRespVO.getThickness()) + "-" + orderGoodsPlateRespVO.getBrand());
series.add(seriesItem);
}
resultMap.put(DATELIST_FIELD_NAME, dateList.stream().map(date -> generateDateRangeAxis(date, reqVO.getUnit())).toList());
@@ -257,22 +277,33 @@ public class OrderStatisticsServiceImpl implements OrderStatisticsService {
// 所有的日期集合
List<String> dateList = getDateList(reqVO);
List<OrderGoodsPlateRespVO> orderGoodsPlateRespVOList = orderPlateStatisticsMapper.selectPlateAnalysisListByArea(reqVO);
// 基于相同的orderDate分组
Map<String, List<OrderGoodsPlateRespVO>> orderGoodsPlateRespMap = orderGoodsPlateRespVOList.stream()
// 查询时间段内面积最多的小板,排序列出前10面积的goods_id
List<Long> topTenCountGoodsId = orderPlateStatisticsMapper.selectPlateAreaList(reqVO).stream()
.sorted(Comparator.comparing(OrderGoodsPlateRespVO::getOrderArea).reversed())
.map(OrderGoodsPlateRespVO::getGoodsId)
.limit(10)
.collect(Collectors.toList());
// 前十goods_id基于时间分组
Map<String, List<OrderGoodsPlateRespVO>> orderGoodsPlateRespMap = orderPlateStatisticsMapper.selectTopTenPlateAreaListGroupByOrderDate(topTenCountGoodsId, reqVO).stream()
.sorted(Comparator.naturalOrder())
.collect(Collectors.groupingBy(OrderGoodsPlateRespVO::getOrderDate, LinkedHashMap::new, Collectors.toList()));
// 获取所有商品map
Map<Long, OrderGoodsPlateRespVO> goodsMap = orderGoodsPlateRespMap.values().stream()
.flatMap(List::stream)
.collect(Collectors.toMap(
OrderGoodsPlateRespVO::getGoodsId,
vo -> vo,
(oldValue, newValue) -> newValue
));
// 获取所有商品{goodsId:respvo},根据top10排序
Map<Long, OrderGoodsPlateRespVO> goodsMap = new LinkedHashMap<>();
for (Long id : topTenCountGoodsId) {
List<OrderGoodsPlateRespVO> list = orderGoodsPlateRespMap.values().stream()
.flatMap(List::stream)
.filter(vo -> vo.getGoodsId().equals(id))
.collect(Collectors.toList());
if (!list.isEmpty()) {
// goodsId相同,其他属性任取
goodsMap.put(id, list.get(0));
}
}
// 遍历订单状态所有枚举值
// 遍历所有goods_id
List<Map<String, Object>> series = new ArrayList<>();
for (Map.Entry<Long, OrderGoodsPlateRespVO> entry : goodsMap.entrySet()) {
Map<String, Object> seriesItem = new HashMap<>();
@@ -287,7 +318,7 @@ public class OrderStatisticsServiceImpl implements OrderStatisticsService {
if (orderGoodsPlateRespVOS != null) {
area = orderGoodsPlateRespVOS.stream()
.filter(respVO -> Objects.equals(entry.getKey(), respVO.getGoodsId()))
.map(OrderGoodsPlateRespVO::getOrderArea)
.map(vo -> vo.getOrderArea().stripTrailingZeros())
.findFirst().orElse(new BigDecimal(0));
}
areaArr[index++] = area;
@@ -297,9 +328,12 @@ public class OrderStatisticsServiceImpl implements OrderStatisticsService {
seriesItem.put("id", entry.getKey());
// 材质-商品名称-颜色-纹理-宽-高-厚-品牌
OrderGoodsPlateRespVO orderGoodsPlateRespVO = entry.getValue();
// 获取纹路描述
DictDataRespDTO grainDTO = dictDataApi.getDictData(DictTypeConstants.GRAIN_TYPE, String.valueOf(orderGoodsPlateRespVO.getTexture())).getData();
String texture = ObjectUtil.isNotNull(grainDTO) ? grainDTO.getLabel() : "";
seriesItem.put("name", orderGoodsPlateRespVO.getMaterial() + "-" + orderGoodsPlateRespVO.getGoodsName() +
"-" + orderGoodsPlateRespVO.getColor() + "-" + orderGoodsPlateRespVO.getTexture() + "-" + orderGoodsPlateRespVO.getWidth() +
"-" + orderGoodsPlateRespVO.getHeight() + "-" + orderGoodsPlateRespVO.getThickness() + "-" + orderGoodsPlateRespVO.getBrand());
"-" + orderGoodsPlateRespVO.getColor() + "-" + texture + "-" + stripTrailingZeros(orderGoodsPlateRespVO.getWidth()) +
"×" + stripTrailingZeros(orderGoodsPlateRespVO.getHeight()) + "×" + stripTrailingZeros(orderGoodsPlateRespVO.getThickness()) + "-" + orderGoodsPlateRespVO.getBrand());
series.add(seriesItem);
}
resultMap.put(DATELIST_FIELD_NAME, dateList.stream().map(date -> generateDateRangeAxis(date, reqVO.getUnit())).toList());
@@ -435,11 +469,25 @@ public class OrderStatisticsServiceImpl implements OrderStatisticsService {
newDateStrBuffer.append("").append(dateSplit[2]).append("");
break;
case DAY:
newDateStrBuffer.append(dateSplit[2]).append("");
newDateStrBuffer.append(dateSplit[2]);
break;
default:
}
return newDateStrBuffer.toString();
}
/**
* 移除尾数的0600.000 -> 600
*
* @param data
* @return
*/
private String stripTrailingZeros(BigDecimal data) {
if (ObjectUtil.isNotNull(data)) {
return data.stripTrailingZeros().toPlainString();
} else {
return "";
}
}
}
@@ -1,7 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.cf.imes.module.executor.dal.mysql.plate.OrderPlateStatisticsMapper">
<select id="selectPlateAnalysisListByCount" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderGoodsPlateRespVO">
<select id="selectPlateCountList" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderGoodsPlateRespVO">
select g.goods_id,
count(a.id) as orderCount
from order_goods g
left join order_plate a ON g.id = a.goods_id and a.deleted = 0
left join orders o ON o.id = a.order_id and o.deleted = 0
where g.deleted = 0
and o.order_date between #{req.createTime[0]} and #{req.createTime[1]}
group by g.goods_id
having orderCount > 0
order by null;
</select>
<select id="selectTopTenPlateCountListGroupByOrderDate" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderGoodsPlateRespVO">
SELECT g.goods_id,
MIN(g.material) AS material,
MIN(g.brand) AS brand,
@@ -26,20 +39,32 @@
,CONCAT(YEAR(o.order_date), '-', MONTH(o.order_date), '-', DAY(o.order_date)) as orderDate
</if>
FROM order_goods g
LEFT JOIN order_plate a ON g.id = a.goods_id
LEFT JOIN orders o ON o.id = a.order_id
WHERE a.deleted = 0
LEFT JOIN order_plate a ON g.id = a.goods_id and a.deleted = 0
LEFT JOIN orders o ON o.id = a.order_id and o.deleted = 0
WHERE g.deleted = 0
AND o.order_date BETWEEN #{req.createTime[0]} AND #{req.createTime[1]}
and g.goods_id in
<foreach item="goodsId" collection="goodsIds" open="(" separator="," close=")">
#{goodsId}
</foreach>
GROUP BY
g.goods_id,orderDate
HAVING
orderCount > 0
ORDER BY
orderCount DESC
LIMIT 10;
g.goods_id,orderDate;
</select>
<select id="selectPlateAnalysisListByArea"
<select id="selectPlateAreaList" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderGoodsPlateRespVO">
select g.goods_id,
SUM(a.area) AS orderArea
from order_goods g
left join order_plate a ON g.id = a.goods_id and a.deleted = 0
left join orders o ON o.id = a.order_id and o.deleted = 0
where g.deleted = 0
and o.order_date between #{req.createTime[0]} and #{req.createTime[1]}
group by g.goods_id
having orderArea > 0
order by null;
</select>
<select id="selectTopTenPlateAreaListGroupByOrderDate"
resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderGoodsPlateRespVO">
SELECT g.goods_id,
MIN(g.material) AS material,
@@ -65,16 +90,15 @@
,CONCAT(YEAR(o.order_date), '-', MONTH(o.order_date), '-', DAY(o.order_date)) as orderDate
</if>
FROM order_goods g
LEFT JOIN order_plate a ON g.id = a.goods_id
LEFT JOIN orders o ON o.id = a.order_id
WHERE a.deleted = 0
LEFT JOIN order_plate a ON g.id = a.goods_id and a.deleted = 0
LEFT JOIN orders o ON o.id = a.order_id and o.deleted = 0
WHERE g.deleted = 0
AND o.order_date BETWEEN #{req.createTime[0]} AND #{req.createTime[1]}
and g.goods_id in
<foreach item="goodsId" collection="goodsIds" open="(" separator="," close=")">
#{goodsId}
</foreach>
GROUP BY
g.goods_id,orderDate
HAVING
orderArea > 0
ORDER BY
orderArea DESC
LIMIT 10;
g.goods_id,orderDate;
</select>
</mapper>