From a2d1636333fc785f84de829a096f0aa210560102 Mon Sep 17 00:00:00 2001
From: chenhj <1263187585@qq.com>
Date: 星期三, 21 一月 2026 17:54:01 +0800
Subject: [PATCH] 出库记录

---
 src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java |  145 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 145 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java
new file mode 100644
index 0000000..13a440c
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java
@@ -0,0 +1,145 @@
+package com.ruoyi.staff.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.enums.StaffLeaveReason;
+import com.ruoyi.staff.dto.StaffLeaveDto;
+import com.ruoyi.staff.mapper.StaffLeaveMapper;
+import com.ruoyi.staff.mapper.StaffOnJobMapper;
+import com.ruoyi.staff.pojo.StaffLeave;
+import com.ruoyi.staff.service.AnalyticsService;
+import com.ruoyi.staff.vo.MonthlyTurnoverRateVo;
+import com.ruoyi.staff.vo.TotalTurnoverRateVo;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+@AllArgsConstructor
+@Service
+public class AnalyticsServiceImpl extends ServiceImpl<StaffLeaveMapper, StaffLeave> implements AnalyticsService {
+    @Autowired
+    private StaffLeaveMapper staffLeaveMapper;
+
+    @Autowired
+    private StaffOnJobMapper staffOnJobMapper;
+
+    @Override
+    public List<StaffLeaveDto> staffLeaveReasonAnalytics() {
+        List<StaffLeaveDto> result = staffLeaveMapper.staffLeaveReasonAnalytics();
+        result.forEach(dto -> {
+            String reasonCode = dto.getReason();
+            StaffLeaveReason reasonEnum = StaffLeaveReason.getByCode(reasonCode);
+            if (reasonEnum != null) {
+                dto.setReasonText(reasonEnum.getInfo());
+            } else {
+                dto.setReasonText("鏈煡鍘熷洜");
+            }
+        });
+        return result;
+    }
+
+    @Override
+    public List<MonthlyTurnoverRateVo> getMonthlyTurnoverRateFor12Months() {
+        List<MonthlyTurnoverRateVo> result = new ArrayList<>();
+        LocalDate now = LocalDate.now();
+        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
+
+        // 璁$畻杩�12涓湀鐨勬暟鎹�
+        for (int i = 11; i >= 0; i--) {
+            LocalDate currentMonth = now.minusMonths(i);
+            LocalDate monthStart = currentMonth.withDayOfMonth(1);
+            LocalDate monthEnd = currentMonth.withDayOfMonth(currentMonth.lengthOfMonth());
+
+            MonthlyTurnoverRateVo vo = new MonthlyTurnoverRateVo();
+            vo.setMonth(currentMonth.format(monthFormatter));
+            vo.setMonthStartDate(monthStart);
+            vo.setMonthEndDate(monthEnd);
+
+            // 鏈堝垵鍛樺伐鏁帮紙涓婃湀鏈湪鑱屽憳宸ユ暟锛�
+            LocalDate lastMonthEnd = monthStart.minusDays(1);
+            Integer beginMonthStaffCount = staffOnJobMapper.countOnJobStaffByDate(lastMonthEnd);
+            vo.setBeginMonthStaffCount(beginMonthStaffCount != null ? beginMonthStaffCount : 0);
+
+            // 鏈堟湯鍛樺伐鏁�
+            Integer endMonthStaffCount = staffOnJobMapper.countOnJobStaffByDate(monthEnd);
+            vo.setEndMonthStaffCount(endMonthStaffCount != null ? endMonthStaffCount : 0);
+
+            // 鏈堝害鍏ヨ亴鍛樺伐鏁�
+            Integer newHireCount = staffOnJobMapper.countNewHireByMonth(monthStart, monthEnd);
+            vo.setNewHireCount(newHireCount != null ? newHireCount : 0);
+
+            // 鏈堝害绂昏亴鍛樺伐鏁�
+            Integer leaveCount = staffLeaveMapper.countLeaveByMonth(monthStart, monthEnd);
+            vo.setLeaveCount(leaveCount != null ? leaveCount : 0);
+
+            // 璁$畻娴佸け鐜囷細娴佸け鐜� = 鏈堝害绂昏亴鍛樺伐鏁� / 鏈堝垵鍛樺伐鏁� * 100%
+            Double turnoverRate = 0.0;
+            if (vo.getBeginMonthStaffCount() > 0) {
+                turnoverRate = (double) vo.getLeaveCount() / vo.getBeginMonthStaffCount() * 100;
+                // 淇濈暀涓や綅灏忔暟
+                turnoverRate = Math.round(turnoverRate * 100.0) / 100.0;
+            }
+            vo.setTurnoverRate(turnoverRate);
+
+            // 璁$畻娴佸姩鐜囷細娴佸姩鐜� = (鏈堝害鍏ヨ亴鍛樺伐鏁� + 鏈堝害绂昏亴鍛樺伐鏁�) / 鏈堝垵鍛樺伐鏁� * 100%
+            Double flowRate = 0.0;
+            if (vo.getBeginMonthStaffCount() > 0) {
+                flowRate = (double) (vo.getNewHireCount() + vo.getLeaveCount()) / vo.getBeginMonthStaffCount() * 100;
+                // 淇濈暀涓や綅灏忔暟
+                flowRate = Math.round(flowRate * 100.0) / 100.0;
+            }
+            vo.setFlowRate(flowRate);
+
+            result.add(vo);
+        }
+
+        return result;
+    }
+
+    @Override
+    public TotalTurnoverRateVo getTotalStatistic() {
+        TotalTurnoverRateVo result = new TotalTurnoverRateVo();
+        LocalDate now = LocalDate.now();
+
+        // 鑾峰彇褰撳墠鍦ㄨ亴鍛樺伐鏁�
+        Integer currentOnJobCount = staffOnJobMapper.countOnJobStaffByDate(now);
+        result.setCurrentOnJobCount(currentOnJobCount);
+
+        // 鑾峰彇鏈湀鐨勫紑濮嬪拰缁撴潫鏃ユ湡
+        LocalDate monthStartDate = now.withDayOfMonth(1);
+        LocalDate monthEndDate = now.withDayOfMonth(now.lengthOfMonth());
+
+        // 鑾峰彇鏈堝垵鍛樺伐鏁帮紙鍗充笂鏈堟湯鍛樺伐鏁帮級
+        Integer beginMonthStaffCount = staffOnJobMapper.countOnJobStaffByDate(monthStartDate.minusDays(1));
+
+        // 鑾峰彇鏈湀鏂板叆鑱屽憳宸ユ暟
+        Integer newHireCount = staffOnJobMapper.countNewHireByMonth(monthStartDate, monthEndDate);
+
+        // 鑾峰彇鏈湀绂昏亴鍛樺伐鏁�
+        Integer leaveCount = staffLeaveMapper.countLeaveByMonth(monthStartDate, monthEndDate);
+
+        // 璁$畻鎬绘祦鍔ㄧ巼 = (鍏ヨ亴浜烘暟 + 绂昏亴浜烘暟) / 鏈堝垵鍛樺伐鏁� * 100%
+        Double totalFlowRate = 0.0;
+        if (beginMonthStaffCount > 0) {
+            totalFlowRate = (double) (newHireCount + leaveCount) / beginMonthStaffCount * 100;
+            // 淇濈暀涓や綅灏忔暟
+            totalFlowRate = Math.round(totalFlowRate * 100.0) / 100.0;
+        }
+        result.setTotalFlowRate(totalFlowRate);
+
+        // 璁$畻鎬绘祦澶辩巼 = 绂昏亴浜烘暟 / 鏈堝垵鍛樺伐鏁� * 100%
+        Double totalTurnoverRate = 0.0;
+        if (beginMonthStaffCount > 0) {
+            totalTurnoverRate = (double) leaveCount / beginMonthStaffCount * 100;
+            // 淇濈暀涓や綅灏忔暟
+            totalTurnoverRate = Math.round(totalTurnoverRate * 100.0) / 100.0;
+        }
+        result.setTotalTurnoverRate(totalTurnoverRate);
+
+        return result;
+    }
+}

--
Gitblit v1.9.3