diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerContingenPlanController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerContingenPlanController.java index 5971ef68..2c9d0f77 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerContingenPlanController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerContingenPlanController.java @@ -40,7 +40,7 @@ public class CustomerContingenPlanController extends BaseController { /** * 查询客户服务-应急预案列表 */ - @SaCheckPermission("system:contingenPlan:list") + // @SaCheckPermission("system:contingenPlan:list") @GetMapping("/list") public TableDataInfo list(CustomerContingenPlanBo bo, PageQuery pageQuery) { return customerContingenPlanService.queryPageList(bo, pageQuery); diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerServeceController.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerServeceController.java index 40761a81..87a52429 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerServeceController.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/controller/CustomerServeceController.java @@ -3,7 +3,7 @@ package org.dromara.property.controller; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.web.core.BaseController; -import org.dromara.property.domain.vo.ServeceCustomerCountVo; +import org.dromara.property.domain.vo.ServiceWorkOrderAnalysisVo; import org.dromara.property.service.IServiceWorkOrdersService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController; /** * @Author:yuyongle * @Date:2025/7/21 15:25 - * @Description:客户服务控制器 + * @Description:工单看板控制器 **/ @Validated @RequiredArgsConstructor @@ -25,7 +25,7 @@ public class CustomerServeceController extends BaseController { * 查询客户服务工单看板统计 */ @GetMapping("/counts") - public R counts() { + public R counts() { return R.ok(serviceWorkOrdersService.counts()); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/CustomerFeedbacks.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/CustomerFeedbacks.java index 7ac186e2..8de2dee7 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/CustomerFeedbacks.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/CustomerFeedbacks.java @@ -57,6 +57,10 @@ public class CustomerFeedbacks extends TenantEntity { */ private String feedbackImg; + /** + * 是否转至工单 + */ + private Long orderId; /** * 是否转至工单 */ diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrders.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrders.java index 5fe92a6b..fb90a2d4 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrders.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/ServiceWorkOrders.java @@ -42,7 +42,7 @@ public class ServiceWorkOrders extends TenantEntity { /** * 工单类型 */ - private Long type; + private Long type; /** * 状态 diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CustomerFeedbacksBo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CustomerFeedbacksBo.java index 6bb5d29f..6228455d 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CustomerFeedbacksBo.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/bo/CustomerFeedbacksBo.java @@ -59,7 +59,7 @@ public class CustomerFeedbacksBo extends BaseEntity { /** * 反馈图片 */ - @NotBlank(message = "反馈图片不能为空", groups = { AddGroup.class, EditGroup.class }) + // @NotBlank(message = "反馈图片不能为空", groups = { AddGroup.class, EditGroup.class }) private String feedbackImg; /** @@ -68,7 +68,7 @@ public class CustomerFeedbacksBo extends BaseEntity { private String isWorkOrder; /** - * 状态(1待处理2处理中3处理完成) + * 状态(0待处理1处理中2处理完成) */ private String status; diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServeceCustomerCountVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServeceCustomerCountVo.java deleted file mode 100644 index 62a9e9ad..00000000 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServeceCustomerCountVo.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.dromara.property.domain.vo; - -import lombok.Data; -import lombok.experimental.Accessors; - -import java.io.Serializable; - -/** - * @Author:yuyongle - * @Date:2025/7/21 15:29 - * @Description:客户服务工单统计看板 - **/ -@Data -@Accessors(chain = true) -public class ServeceCustomerCountVo implements Serializable { - /** - * 工单总数 - */ - private Integer workOrdersTotal; - /** - * 未派工单总数 - */ - private Integer notWorkOrdersTotal; - /** - * 未半结超时工单 - */ - private Integer novertimeOrdersTotal; - /** - * 处理中工单 - */ - private Integer InHandOrdersTotal; - /** - * 当月工单超时率 - */ - private Double novertimeOrdersRate; - /** - * 当月工单数 - */ - private Integer monthOrdersTotal; - /** - * 超时工单数 - */ - private Integer outTimeOrdersTotal; - /** - * 当月满意度 - */ - private Double monthoSatisfaction; - /** - * 满意数 - */ - private Integer satisfaction; -} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrderAnalysisVo.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrderAnalysisVo.java new file mode 100644 index 00000000..dad2ec70 --- /dev/null +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/domain/vo/ServiceWorkOrderAnalysisVo.java @@ -0,0 +1,115 @@ +package org.dromara.property.domain.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +@Accessors(chain = true) +@Data +public class ServiceWorkOrderAnalysisVo { + /** + * 工单看板当前周折线图 + */ + @Data + @Accessors(chain = true) + public static class LineChartVo { + private String date; + private String dayOfWeek; + private long count; + + public LineChartVo(String date, String dayOfWeek, long count) { + this.date = date; + this.dayOfWeek = dayOfWeek; + this.count = count; + } + + } + + /** + * 工单看板饼型图 + */ + @Data + @Accessors(chain = true) + public static class PieChartVo { + private String type; // 工单类型 + private Long quantity; // 工单类型 + private double percentage; // 占比 + + public PieChartVo(String type, Long quantity, double percentage) { + this.type = type; + this.quantity = quantity; + this.percentage = percentage; + } + + // Getters and Setters + } + + // Builder Pattern for ServiceWorkOrderAnalysisVo + @Data + @Accessors(chain = true) + public static class ServiceWorkOrderCount { + private int workOrdersTotal; + private int notWorkOrdersTotal; + private int novertimeOrdersTotal; + private int inHandOrdersTotal; + private double novertimeOrdersRate; + private int monthOrdersTotal; + private int outTimeOrdersTotal; + private double monthoSatisfaction; + private int satisfaction; + private List recentWeekWorkOrders; + private List workOrderTypeDistribution; + + // Setters + public ServiceWorkOrderCount setWorkOrdersTotal(int workOrdersTotal) { + this.workOrdersTotal = workOrdersTotal; + return this; + } + // ...其他Setter... + + public ServiceWorkOrderCount setRecentWeekWorkOrders(List recentWeekWorkOrders) { + this.recentWeekWorkOrders = recentWeekWorkOrders; + return this; + } + + public ServiceWorkOrderCount setWorkOrderTypeDistribution(List workOrderTypeDistribution) { + this.workOrderTypeDistribution = workOrderTypeDistribution; + return this; + } + + public ServiceWorkOrderAnalysisVo build() { + ServiceWorkOrderAnalysisVo vo = new ServiceWorkOrderAnalysisVo(); + vo.workOrdersTotal = this.workOrdersTotal; + vo.notWorkOrdersTotal = this.notWorkOrdersTotal; + vo.novertimeOrdersTotal = this.novertimeOrdersTotal; + vo.inHandOrdersTotal = this.inHandOrdersTotal; + vo.novertimeOrdersRate = this.novertimeOrdersRate; + vo.monthOrdersTotal = this.monthOrdersTotal; + vo.outTimeOrdersTotal = this.outTimeOrdersTotal; + vo.monthoSatisfaction = this.monthoSatisfaction; + vo.satisfaction = this.satisfaction; + vo.recentWeekWorkOrders = this.recentWeekWorkOrders; + vo.workOrderTypeDistribution = this.workOrderTypeDistribution; + return vo; + } + } + + private int workOrdersTotal; + private int notWorkOrdersTotal; + private int novertimeOrdersTotal; + private int inHandOrdersTotal; + private double novertimeOrdersRate; + private int monthOrdersTotal; + private int outTimeOrdersTotal; + private double monthoSatisfaction; + private int satisfaction; + private List recentWeekWorkOrders; + private List workOrderTypeDistribution; + + // Constructor is private to enforce use of builder pattern + public ServiceWorkOrderAnalysisVo() { + } + + // Getters... +} diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersService.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersService.java index f9dc1d63..aa992bdb 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersService.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/IServiceWorkOrdersService.java @@ -3,7 +3,7 @@ package org.dromara.property.service; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.property.domain.bo.ServiceWorkOrdersBo; -import org.dromara.property.domain.vo.ServeceCustomerCountVo; +import org.dromara.property.domain.vo.ServiceWorkOrderAnalysisVo; import org.dromara.property.domain.vo.ServiceWorkOrdersInfoVo; import org.dromara.property.domain.vo.ServiceWorkOrdersVo; @@ -72,6 +72,6 @@ public interface IServiceWorkOrdersService { * 工单服务看板 * @return */ - ServeceCustomerCountVo counts(); + ServiceWorkOrderAnalysisVo counts(); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerContingenPlanServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerContingenPlanServiceImpl.java index da55aaf3..d13415b8 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerContingenPlanServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerContingenPlanServiceImpl.java @@ -47,7 +47,12 @@ public class CustomerContingenPlanServiceImpl implements ICustomerContingenPlanS */ @Override public CustomerContingenPlanVo queryById(Long id) { - return baseMapper.selectVoById(id); + CustomerContingenPlanVo customerContingenPlanVo = baseMapper.selectVoById(id); + ResidentPerson residentPerson = residentPersonMapper.selectById(customerContingenPlanVo.getInitiat()); + customerContingenPlanVo.setInitiatName(ObjectUtil.isNotEmpty(residentPerson)?residentPerson.getUserName():null); + ResidentPerson dutyPerson = residentPersonMapper.selectById(customerContingenPlanVo.getDutyPersion()); + customerContingenPlanVo.setDutyPersionName(ObjectUtil.isNotEmpty(residentPerson)?dutyPerson.getUserName():null); + return customerContingenPlanVo; } /** @@ -65,10 +70,10 @@ public class CustomerContingenPlanServiceImpl implements ICustomerContingenPlanS if (CollUtil.isNotEmpty(residentPeoplelist)) { result.getRecords().stream().forEach(s -> { ResidentPerson residentInitiatVo = residentPeoplelist.stream() - .filter(vo -> vo.getId() != null && String.valueOf(vo.getId()).equals(s.getInitiat())).findFirst().orElse(null); + .filter(vo -> vo.getId() != null && vo.getId().equals(s.getInitiat())).findFirst().orElse(null); s.setInitiatName(ObjectUtil.isNotEmpty(residentInitiatVo)?residentInitiatVo.getUserName():null); ResidentPerson residentDutyVo = residentPeoplelist.stream() - .filter(vo -> vo.getId() != null && String.valueOf(vo.getId()).equals(s.getDutyPersion())).findFirst().orElse(null); + .filter(vo -> vo.getId() != null && vo.getId().equals(s.getDutyPersion())).findFirst().orElse(null); s.setDutyPersionName(ObjectUtil.isNotEmpty(residentDutyVo)?residentDutyVo.getUserName():null); }); } diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerNoticesServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerNoticesServiceImpl.java index f2e5f01b..c3dbfb45 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerNoticesServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/CustomerNoticesServiceImpl.java @@ -1,5 +1,7 @@ package org.dromara.property.service.impl; +import cn.hutool.core.util.ObjectUtil; +import org.apache.dubbo.config.annotation.DubboReference; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -9,6 +11,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.property.mapper.ResidentPersonMapper; +import org.dromara.resource.api.RemoteMessageService; import org.springframework.stereotype.Service; import org.dromara.property.domain.bo.CustomerNoticesBo; import org.dromara.property.domain.vo.CustomerNoticesVo; @@ -16,9 +20,11 @@ import org.dromara.property.domain.CustomerNotices; import org.dromara.property.mapper.CustomerNoticesMapper; import org.dromara.property.service.ICustomerNoticesService; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Collection; +import java.util.stream.Collectors; /** * 客户服务-通知公告Service业务层处理 @@ -32,6 +38,9 @@ import java.util.Collection; public class CustomerNoticesServiceImpl implements ICustomerNoticesService { private final CustomerNoticesMapper baseMapper; + private final ResidentPersonMapper residentPersonMapper; + @DubboReference + private RemoteMessageService remoteMessageService; /** * 查询客户服务-通知公告 @@ -97,6 +106,16 @@ public class CustomerNoticesServiceImpl implements ICustomerNoticesService { boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); + if(bo.getIsAll().equals("0")){ + remoteMessageService.publishAll(bo.getTitle()); + } + if(bo.getIsAll().equals("1") && ObjectUtil.isNotEmpty(bo.getNoticePersion())){ + String[] noticePersion = bo.getNoticePersion().split(","); + List userIdList = Arrays.stream(noticePersion) + .map(Long::valueOf) + .collect(Collectors.toList()); + remoteMessageService.publishMessage(userIdList,bo.getTitle()); + } } return flag; } @@ -110,7 +129,7 @@ public class CustomerNoticesServiceImpl implements ICustomerNoticesService { @Override public Boolean updateByBo(CustomerNoticesBo bo) { CustomerNotices update = MapstructUtils.convert(bo, CustomerNotices.class); - validEntityBeforeSave(update); + validEntityBeforeUpdate(update); return baseMapper.updateById(update) > 0; } @@ -120,7 +139,12 @@ public class CustomerNoticesServiceImpl implements ICustomerNoticesService { private void validEntityBeforeSave(CustomerNotices entity){ //TODO 做一些数据校验,如唯一约束 } - + /** + * 修改前的数据校验 + */ + private void validEntityBeforeUpdate(CustomerNotices entity){ + //TODO 做一些数据校验,如唯一约束 + } /** * 校验并批量删除客户服务-通知公告信息 * diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/MeetBookingServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/MeetBookingServiceImpl.java index a0a71154..9ae00baa 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/MeetBookingServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/MeetBookingServiceImpl.java @@ -1,6 +1,7 @@ package org.dromara.property.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -78,30 +79,25 @@ public class MeetBookingServiceImpl implements IMeetBookingService { public TableDataInfo queryPageList(MeetBookingBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - - List units = result.getRecords().stream() - .map(vo -> vo.getUnit()) - .distinct() - .collect(Collectors.toList()); - List persons = result.getRecords().stream() - .map(vo -> vo.getPerson()) - .distinct() - .collect(Collectors.toList()); - List residentUnitVolist = residentUnitMapper.selectVoByIds(units); - List residentPersonsVolist = residentPersonMapper.selectVoByIds(persons); + List residentUnitVolist = residentUnitMapper.selectVoList(); + List residentPersonsVolist = residentPersonMapper.selectVoList(); List meetBookingVoList = new ArrayList<>(); result.getRecords().stream().forEach(s -> { - ResidentUnitVo residentUnitVo = residentUnitVolist.stream() - .filter(vo -> vo.getId() != null && String.valueOf(vo.getId()).equals(s.getUnit())).findFirst().orElse(null); - s.setUnitName(residentUnitVo.getName()); - ResidentPersonVo residentPersonVo = residentPersonsVolist.stream() - .filter(vo -> vo.getId() != null && String.valueOf(vo.getId()).equals(s.getPerson())).findFirst().orElse(null); - s.setPersonName(residentPersonVo.getUserName()); - s.setPhone(residentPersonVo.getPhone()); + if (CollUtil.isNotEmpty(residentUnitVolist)) { + ResidentUnitVo residentUnitVo = residentUnitVolist.stream() + .filter(vo -> vo.getId() != null && String.valueOf(vo.getId()).equals(s.getUnit())).findFirst().orElse(null); + s.setUnitName(ObjectUtil.isNotEmpty(residentUnitVo) ? residentUnitVo.getName() : null); + } + if (CollUtil.isNotEmpty(residentPersonsVolist)) { + ResidentPersonVo residentPersonVo = residentPersonsVolist.stream() + .filter(vo -> vo.getId() != null && String.valueOf(vo.getId()).equals(s.getPerson())).findFirst().orElse(null); + s.setPersonName(ObjectUtil.isNotEmpty(residentPersonVo) ? residentPersonVo.getUserName() : null); + s.setPhone(ObjectUtil.isNotEmpty(residentPersonVo) ? residentPersonVo.getPhone() : null); + } meetBookingVoList.add(s); }); - return TableDataInfo.build(new Page().setRecords(meetBookingVoList)); + return TableDataInfo.build(new Page().setRecords(meetBookingVoList).setTotal(result.getTotal())); } /** diff --git a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java index 921918c5..116bb6ee 100644 --- a/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java +++ b/ruoyi-modules/Property/src/main/java/org/dromara/property/service/impl/ServiceWorkOrdersServiceImpl.java @@ -5,7 +5,6 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; -import cn.idev.excel.event.Order; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -49,6 +48,7 @@ import java.util.stream.Collectors; public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { private final ServiceWorkOrdersMapper baseMapper; + private final ServiceWorkOrdersTypeMapper serviceWorkOrdersTypeMapper; private final ServiceWorkOrdersTypeMapper typesMapper; private final ResidentPersonMapper residentPersonMapper; private final ServiceWorkOrdersRecordMapper workOrdersRecordMapper; @@ -248,13 +248,15 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { /** * 工单服务看板 + * * @return */ @Override - public ServeceCustomerCountVo counts() { + public ServiceWorkOrderAnalysisVo counts() { List serviceWorkOrdersList = baseMapper.selectList(new QueryWrapper<>()); - // 总工单数 + // 原有逻辑不变... + // 总工单数 int workOrdersTotal = serviceWorkOrdersList.size(); // 待派送工单(status = "0") @@ -293,7 +295,7 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { .filter(order -> order.getServiceEvalua() != null && order.getServiceEvalua()>= 4) .count(); - // 当月满意度(当月工单中满意的占比) + // 当月满意度(当月工单中满意的占比) int monthSatisfactionCount = (int) serviceWorkOrdersList.stream() .filter(order -> currentMonth.equals(order.getCreateTime()) && order.getServiceEvalua() != null @@ -302,8 +304,14 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { double monthoSatisfaction = monthOrdersTotal == 0 ? 0.0 : (double) monthSatisfactionCount / monthOrdersTotal * 100; + ServiceWorkOrderAnalysisVo serviceWorkOrderAnalysisVo =new ServiceWorkOrderAnalysisVo(); + // 获取近一周的工单统计 + List recentWeekData = getRecentWeekWorkOrders(serviceWorkOrdersList); - return new ServeceCustomerCountVo() + // 计算工单类型分布 + List workOrderTypeDistribution = calculateWorkOrderTypeDistribution(serviceWorkOrdersList); + + return new ServiceWorkOrderAnalysisVo.ServiceWorkOrderCount() .setWorkOrdersTotal(workOrdersTotal) .setNotWorkOrdersTotal(notWorkOrdersTotal) .setNovertimeOrdersTotal(novertimeOrdersTotal) @@ -312,6 +320,66 @@ public class ServiceWorkOrdersServiceImpl implements IServiceWorkOrdersService { .setMonthOrdersTotal(monthOrdersTotal) .setOutTimeOrdersTotal(outTimeOrdersTotal) .setMonthoSatisfaction(monthoSatisfaction) - .setSatisfaction(satisfaction); + .setSatisfaction(satisfaction) + .setRecentWeekWorkOrders(recentWeekData) + .setWorkOrderTypeDistribution(workOrderTypeDistribution) + .build(); + } + + // 近一周工单统计方法 + private List getRecentWeekWorkOrders(List serviceWorkOrdersList) { + LocalDate today = LocalDate.now(); + List dateList = new ArrayList<>(); + for (int i = 6; i >= 0; i--) { + dateList.add(today.minusDays(i)); + } + + Map workOrdersByDate = serviceWorkOrdersList.stream() + .filter(order -> { + try { + LocalDate createTime = LocalDate.parse((CharSequence) order.getCreateTime()); + return !createTime.isBefore(today.minusDays(7)); + } catch (Exception e) { + return false; + } + }) + .collect(Collectors.groupingBy( + order -> LocalDate.parse((CharSequence) order.getCreateTime()).format(DateTimeFormatter.ISO_LOCAL_DATE), + Collectors.counting() + )); + + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + DateTimeFormatter dayOfWeekFormatter = DateTimeFormatter.ofPattern("E"); + + List result = new ArrayList<>(); + for (LocalDate date : dateList) { + String dateStr = date.format(dateFormatter); + String dayOfWeek = date.format(dayOfWeekFormatter); + result.add(new ServiceWorkOrderAnalysisVo.LineChartVo(dateStr, dayOfWeek, workOrdersByDate.getOrDefault(dateStr, 0L))); + } + + return result; + } + + // 计算工单类型分布 + private List calculateWorkOrderTypeDistribution(List serviceWorkOrdersList) { + // 按 typeId 分组统计数量 + Map workOrderTypeCounts = serviceWorkOrdersList.stream() + .collect(Collectors.groupingBy(ServiceWorkOrders::getType, Collectors.counting())); + + long total = serviceWorkOrdersList.size(); + List result = new ArrayList<>(); + + for (Map.Entry entry : workOrderTypeCounts.entrySet()) { + Long typeId = entry.getKey(); + Long count = entry.getValue(); + // 查询类型名称 + ServiceWorkOrdersType serviceWorkOrdersType = serviceWorkOrdersTypeMapper.selectById(typeId); + String typeName = serviceWorkOrdersType != null ? serviceWorkOrdersType.getOrderTypeName() : "未知类型"; + // 计算占比(保留两位小数) + double percentage = Math.round(((double) count / total) * 10000) / 100.0; + result.add(new ServiceWorkOrderAnalysisVo.PieChartVo(typeName, count, percentage)); + } + return result; } }