工单看板-统计

This commit is contained in:
attiya 2026-01-08 16:18:46 +08:00
parent 510403e30c
commit 47b38537b4
8 changed files with 317 additions and 60 deletions

View File

@ -1,7 +1,13 @@
package com.cdzy.operations.mapper;
import com.cdzy.operations.model.dto.EbikeBikeOrderDayCountDto;
import com.cdzy.operations.model.dto.EbikeBikeOrderMonthCountDto;
import com.cdzy.operations.model.dto.EbikeBikeOrderWeekCountDto;
import com.mybatisflex.core.BaseMapper;
import com.cdzy.operations.model.entity.EbikeBikeOrder;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* 工单信息 映射层
@ -11,4 +17,24 @@ import com.cdzy.operations.model.entity.EbikeBikeOrder;
*/
public interface EbikeBikeOrderMapper extends BaseMapper<EbikeBikeOrder> {
/**
* 员工月单量统计
* @param receiverId 员工ID
* @return 列表
*/
List<EbikeBikeOrderMonthCountDto> monthCount(@RequestParam Long receiverId);
/**
* 员工周单量统计
* @param receiverId 员工ID
* @return 列表
*/
List<EbikeBikeOrderWeekCountDto> weekCount(@RequestParam Long receiverId);
/**
* 员工日单量统计
* @param receiverId 员工ID
* @return 列表
*/
List<EbikeBikeOrderDayCountDto> dayCount(@RequestParam Long receiverId);
}

View File

@ -0,0 +1,45 @@
package com.cdzy.operations.model.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
/**
* 工单信息 实体类
*
* @author attiya
* @since 2025-11-24
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EbikeBikeOrderDayCountDto implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 工单类型1 巡检工单 2 换电工单 3 调度工单 4 维修工单
*/
private String orderType;
/**
* 处理人ID
*/
private Long receiverId;
/**
* 当日完成量
*/
private Integer todayCount;
/**
* 昨天完成量
*/
private Integer yesterdayCount;
}

View File

@ -0,0 +1,45 @@
package com.cdzy.operations.model.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
/**
* 工单信息 实体类
*
* @author attiya
* @since 2025-11-24
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EbikeBikeOrderMonthCountDto implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 工单类型1 巡检工单 2 换电工单 3 调度工单 4 维修工单
*/
private String orderType;
/**
* 处理人ID
*/
private Long receiverId;
/**
* 本月完成量
*/
private Integer thisMonthCount;
/**
* 上月完成量
*/
private Integer lastMonthCount;
}

View File

@ -0,0 +1,45 @@
package com.cdzy.operations.model.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
/**
* 工单信息 实体类
*
* @author attiya
* @since 2025-11-24
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EbikeBikeOrderWeekCountDto implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 工单类型1 巡检工单 2 换电工单 3 调度工单 4 维修工单
*/
private String orderType;
/**
* 处理人ID
*/
private Long receiverId;
/**
* 本周完成量
*/
private Integer thisWeekCount;
/**
* 上周完成量
*/
private Integer lastWeekCount;
}

View File

@ -1,22 +1,12 @@
package com.cdzy.operations.model.dto;
import com.cdzy.operations.handler.PointDeserializer;
import com.cdzy.operations.handler.PointSerializer;
import com.cdzy.operations.handler.PointTypeHandler;
import com.cdzy.operations.model.entity.EbikeOrderPart;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.RelationOneToMany;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.locationtech.jts.geom.Point;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
@ -34,52 +24,18 @@ public class EbikeOrderBulletinBoardInfo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 本月与上月单量统计
*/
List<EbikeBikeOrderMonthCountDto> monthCountList;
/**
* 工单ID
* 本周与上周单量统计
*/
private Long orderId;
List<EbikeBikeOrderWeekCountDto> weekCountList;
/**
* 工单类型
* 今日与昨日单量统计
*/
private Integer orderType;
/**
* 车辆编号
*/
private String bikeCode;
/**
* 定位
*/
@Column(typeHandler = PointTypeHandler.class)
@JsonSerialize(using = PointSerializer.class)
@JsonDeserialize(using = PointDeserializer.class)
private Point location;
private LocalDateTime createdAt;
/**
* 故障内容
*/
private String remark;
/**
* SN
*/
private String ecuSn;
/**
* 电量
*/
private Integer soc;
/**
* 故障部位
*/
@RelationOneToMany(selfField = "orderId", targetField = "orderId")
private List<EbikeOrderPart> parts;
List<EbikeBikeOrderDayCountDto> dayCountList;
}

View File

@ -760,7 +760,18 @@ public class EbikeBikeOrderServiceImpl extends ServiceImpl<EbikeBikeOrderMapper,
@Override
public EbikeOrderBulletinBoardInfo bulletinBoard() {
return null;
long staffId = StpUtil.getLoginIdAsLong();
//对比纬度:
//TODO:对比对象待确定
//完成单量统计统计纬度
List<EbikeBikeOrderMonthCountDto> monthCountDtos = ebikeBikeOrderMapper.monthCount(staffId);
List<EbikeBikeOrderWeekCountDto> weekCountDtos = ebikeBikeOrderMapper.weekCount(staffId);
List<EbikeBikeOrderDayCountDto> dayCountDtos = ebikeBikeOrderMapper.dayCount(staffId);
return EbikeOrderBulletinBoardInfo.builder()
.monthCountList(monthCountDtos)
.weekCountList(weekCountDtos)
.dayCountList(dayCountDtos)
.build();
}
@Override

View File

@ -0,0 +1,109 @@
<?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.cdzy.operations.mapper.EbikeBikeOrderMapper">
<select id="monthCount" resultType="com.cdzy.operations.model.dto.EbikeBikeOrderMonthCountDto">
<![CDATA[
SELECT #{receiverId} as receiverId,
CASE aot.order_type
WHEN 1 THEN '巡检工单'
WHEN 2 THEN '换电工单'
WHEN 3 THEN '调度工单'
WHEN 4 THEN '维修工单'
END as orderType,
COALESCE(COUNT(CASE
WHEN DATE_TRUNC('month', ebo.handle_at) = DATE_TRUNC('month', CURRENT_DATE)
THEN 1
END), 0) as thisMonthCount,
COALESCE(COUNT(CASE
WHEN DATE_TRUNC('month', ebo.handle_at) =
DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month')
THEN 1
END), 0) as lastMonthCount
FROM generate_series(1, 4) as aot(order_type)
LEFT JOIN ebike_bike_order ebo ON aot.order_type = ebo.order_type
AND ebo.handle_state = 2
AND ebo.handle_at IS NOT NULL
AND ebo.is_deleted = false
AND ebo.receiver_id = #{receiverId}
AND ebo.handle_at >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month')
AND ebo.handle_at < DATE_TRUNC('month', CURRENT_DATE) + INTERVAL '1 month'
GROUP BY aot.order_type
ORDER BY aot.order_type;
]]>
</select>
<select id="dayCount" resultType="com.cdzy.operations.model.dto.EbikeBikeOrderDayCountDto">
<![CDATA[
SELECT #{receiverId} as receiverId,
CASE aot.order_type
WHEN 1 THEN '巡检工单'
WHEN 2 THEN '换电工单'
WHEN 3 THEN '调度工单'
WHEN 4 THEN '维修工单'
END as orderType,
COALESCE(COUNT(CASE
WHEN DATE (ebo.handle_at) = CURRENT_DATE
THEN 1
END), 0) as todayCount,
COALESCE(COUNT(CASE
WHEN DATE (ebo.handle_at) = CURRENT_DATE - INTERVAL '1 day'
THEN 1
END), 0) as yesterdayCount
FROM generate_series(1, 4) as aot(order_type)
LEFT JOIN ebike_bike_order ebo ON aot.order_type = ebo.order_type
AND ebo.handle_state = 2
AND ebo.handle_at IS NOT NULL
AND ebo.is_deleted = false
AND ebo.receiver_id = #{receiverId}
AND ebo.handle_at >= CURRENT_DATE -
INTERVAL '1 day'
AND ebo.handle_at
< CURRENT_DATE + INTERVAL '1 day'
GROUP BY aot.order_type
ORDER BY aot.order_type;
]]>
</select>
<select id="weekCount" resultType="com.cdzy.operations.model.dto.EbikeBikeOrderWeekCountDto">
<![CDATA[
WITH week_range AS (
SELECT
DATE_TRUNC('week', CURRENT_DATE) as current_week_start,
DATE_TRUNC('week', CURRENT_DATE) + INTERVAL '1 week' as current_week_end,
DATE_TRUNC('week', CURRENT_DATE - INTERVAL '1 week') as last_week_start
)
SELECT #{receiverId} as receiverId,
CASE aot.order_type
WHEN 1 THEN '巡检工单'
WHEN 2 THEN '换电工单'
WHEN 3 THEN '调度工单'
WHEN 4 THEN '维修工单'
END as orderType,
COALESCE(COUNT(CASE
WHEN ebo.handle_at >= wr.current_week_start
AND ebo.handle_at < wr.current_week_end
THEN 1
END), 0) as thisWeekCount,
COALESCE(COUNT(CASE
WHEN ebo.handle_at >= wr.last_week_start
AND ebo.handle_at < wr.current_week_start
THEN 1
END), 0) as lastWeekCount
FROM generate_series(1, 4) as aot(order_type)
CROSS JOIN week_range wr
LEFT JOIN ebike_bike_order ebo ON aot.order_type = ebo.order_type
AND ebo.handle_state = 2
AND ebo.handle_at IS NOT NULL
AND ebo.is_deleted = false
AND ebo.receiver_id = #{receiverId}
AND ebo.handle_at >= wr.last_week_start
AND ebo.handle_at < wr.current_week_end
GROUP BY aot.order_type
ORDER BY aot.order_type;
]]>
</select>
</mapper>

View File

@ -1,23 +1,43 @@
package com.cdzy.operations;
import com.cdzy.operations.utils.RedisUtil;
import com.cdzy.operations.mapper.EbikeBikeOrderMapper;
import com.cdzy.operations.model.dto.EbikeBikeOrderDayCountDto;
import com.cdzy.operations.model.dto.EbikeBikeOrderMonthCountDto;
import com.cdzy.operations.model.dto.EbikeBikeOrderWeekCountDto;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.concurrent.TimeUnit;
import java.util.List;
@SpringBootTest
class EbikeOperationsApplicationTests {
@Resource
RedisUtil redisUtil;
private EbikeBikeOrderMapper orderMapper;
@Test
void contextLoads() {
redisUtil.saveDispatchOrder(360977412682211328L,null,10L, TimeUnit.SECONDS);
// redisUtil.releaseDispatchLock("bike:dispatch:lock:360967408603103232");
void monthCount() {
List<EbikeBikeOrderMonthCountDto> monthCountDtos = orderMapper.monthCount(320131029184712704L);
for (EbikeBikeOrderMonthCountDto monthCountDto : monthCountDtos) {
System.out.println(monthCountDto);
}
}
@Test
void dayCount() {
List<EbikeBikeOrderDayCountDto> dayCountDtos = orderMapper.dayCount(320131029184712704L);
for (EbikeBikeOrderDayCountDto dayCountDto : dayCountDtos) {
System.out.println(dayCountDto);
}
}
@Test
void weekCount() {
List<EbikeBikeOrderWeekCountDto> weekCountDtos = orderMapper.weekCount(320131029184712704L);
for (EbikeBikeOrderWeekCountDto weekCountDto : weekCountDtos) {
System.out.println(weekCountDto);
}
}