From 655540c20b01a599ce47ef3ec9c4aa3e4537e70f Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Mon, 8 Sep 2025 15:33:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(oa):=20=E6=96=B0=E5=A2=9E=E5=B7=A5?= =?UTF-8?q?=E8=B5=84=E6=95=B0=E6=8D=AE=E7=9C=8B=E6=9D=BF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加新工资看板相关的 VO 类 - 实现新工资看板的数据获取接口和业务逻辑 - 优化原有工资看板的代码结构 - 新增月度支出、工资构成、趋势分析等图表数据查询- 增加社保公积金统计和单位、部门统计功能 --- .../controller/SalaryDashboardController.java | 23 +- .../domain/vo/dashboard/DeptSalaryStatVo.java | 46 +++ .../domain/vo/dashboard/InsuranceStatVo.java | 31 ++ .../domain/vo/dashboard/MonthlyExpenseVo.java | 31 ++ .../oa/domain/vo/dashboard/NewCardDataVo.java | 66 +++++ .../domain/vo/dashboard/NewCardMetricsVo.java | 36 +++ .../domain/vo/dashboard/NewChartDataVo.java | 31 ++ .../vo/dashboard/NewSalaryDashboardVo.java | 30 ++ .../vo/dashboard/SalaryStructureVo.java | 26 ++ .../vo/dashboard/SalaryTrendPointVo.java | 31 ++ .../oa/domain/vo/dashboard/SalaryTrendVo.java | 47 +++ .../oa/domain/vo/dashboard/UnitStatVo.java | 51 ++++ .../oa/mapper/SalaryDashboardMapper.java | 56 ++++ .../oa/service/ISalaryDashboardService.java | 11 +- .../impl/SalaryDashboardServiceImpl.java | 207 +++++++++++++ .../mapper/oa/SalaryDashboardMapper.xml | 273 ++++++++++++++++++ 16 files changed, 993 insertions(+), 3 deletions(-) create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/DeptSalaryStatVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/InsuranceStatVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/MonthlyExpenseVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewCardDataVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewCardMetricsVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewChartDataVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewSalaryDashboardVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryStructureVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryTrendPointVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryTrendVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/UnitStatVo.java diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SalaryDashboardController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SalaryDashboardController.java index 06abefb..728ecb8 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SalaryDashboardController.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/SalaryDashboardController.java @@ -1,10 +1,10 @@ package com.ruoyi.oa.controller; -import com.ruoyi.common.core.AjaxResult; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.R; import com.ruoyi.oa.domain.vo.SalaryDashboardVo; +import com.ruoyi.oa.domain.vo.dashboard.NewSalaryDashboardVo; import com.ruoyi.oa.service.ISalaryDashboardService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -12,6 +12,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +/** + * 工资数据看板控制器 + */ @RestController @RequestMapping("/oa/salary/dashboard") public class SalaryDashboardController extends BaseController { @@ -19,8 +22,11 @@ public class SalaryDashboardController extends BaseController { @Autowired private ISalaryDashboardService salaryDashboardService; + /** + * 获取原有工资数据看板数据 + */ @GetMapping - public RgetDashboardData( + public R getDashboardData( @RequestParam(required = true) Long payYear, @RequestParam(required = true) Long payMonth ) { @@ -28,4 +34,17 @@ public class SalaryDashboardController extends BaseController { salaryDashboardService.getDashboardData(payYear, payMonth) ); } + + /** + * 获取新工资数据看板数据(基于新的工资表结构) + */ + @GetMapping("/new") + public R getNewDashboardData( + @RequestParam(required = true) String salaryPeriod + ) { + return R.ok( + salaryDashboardService.getNewDashboardData(salaryPeriod) + ); + } + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/DeptSalaryStatVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/DeptSalaryStatVo.java new file mode 100644 index 0000000..78934aa --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/DeptSalaryStatVo.java @@ -0,0 +1,46 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 部门工资统计VO + */ +@Data +public class DeptSalaryStatVo { + /** + * 部门名称 + */ + private String deptName; + + /** + * 员工数量 + */ + private Integer employeeCount; + + /** + * 总实发工资 + */ + private BigDecimal totalNetSalary; + + /** + * 总应发工资 + */ + private BigDecimal totalGrossSalary; + + /** + * 人均实发工资 + */ + private BigDecimal avgNetSalary; + + /** + * 人均应发工资 + */ + private BigDecimal avgGrossSalary; + + /** + * 同比增长率 + */ + private BigDecimal yearOnYearGrowthRate; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/InsuranceStatVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/InsuranceStatVo.java new file mode 100644 index 0000000..d83ee36 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/InsuranceStatVo.java @@ -0,0 +1,31 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 社保公积金统计VO + */ +@Data +public class InsuranceStatVo { + /** + * 项目名称 + */ + private String itemName; + + /** + * 个人缴纳总额 + */ + private BigDecimal personalTotal; + + /** + * 企业缴纳总额 + */ + private BigDecimal enterpriseTotal; + + /** + * 合计 + */ + private BigDecimal total; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/MonthlyExpenseVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/MonthlyExpenseVo.java new file mode 100644 index 0000000..0c1564f --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/MonthlyExpenseVo.java @@ -0,0 +1,31 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 月度支出VO + */ +@Data +public class MonthlyExpenseVo { + /** + * 月份 + */ + private Integer month; + + /** + * 实发工资总额 + */ + private BigDecimal totalNetSalary; + + /** + * 应发工资总额 + */ + private BigDecimal totalGrossSalary; + + /** + * 单位总支出 + */ + private BigDecimal totalUnitExpense; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewCardDataVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewCardDataVo.java new file mode 100644 index 0000000..a169559 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewCardDataVo.java @@ -0,0 +1,66 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 新工资看板卡片数据VO + */ +@Data +public class NewCardDataVo { + /** + * 总实发工资 + */ + private BigDecimal totalNetSalary; + + /** + * 较上月总实发工资增长率 + */ + private BigDecimal lastMonthNetSalaryRate; + + /** + * 总应发工资 + */ + private BigDecimal totalGrossSalary; + + /** + * 较上月总应发工资增长率 + */ + private BigDecimal lastMonthGrossSalaryRate; + + /** + * 单位总支出 + */ + private BigDecimal totalUnitExpense; + + /** + * 较上月单位总支出增长率 + */ + private BigDecimal lastMonthUnitExpenseRate; + + /** + * 人均实发工资 + */ + private BigDecimal avgNetSalary; + + /** + * 较上月人均实发工资增长率 + */ + private BigDecimal lastMonthAvgNetSalaryRate; + + /** + * 同比增长率(与去年同期相比) + */ + private BigDecimal yearOnYearGrowthRate; + + /** + * 员工总数 + */ + private Integer totalEmployeeCount; + + /** + * 单位数量 + */ + private Integer unitCount; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewCardMetricsVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewCardMetricsVo.java new file mode 100644 index 0000000..69cf18b --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewCardMetricsVo.java @@ -0,0 +1,36 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 新工资看板卡片指标VO + */ +@Data +public class NewCardMetricsVo { + /** + * 总实发工资 + */ + private BigDecimal totalNetSalary; + + /** + * 总应发工资 + */ + private BigDecimal totalGrossSalary; + + /** + * 单位总支出 + */ + private BigDecimal totalUnitExpense; + + /** + * 员工数量 + */ + private Integer employeeCount; + + /** + * 单位数量 + */ + private Integer unitCount; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewChartDataVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewChartDataVo.java new file mode 100644 index 0000000..e0e0d4b --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewChartDataVo.java @@ -0,0 +1,31 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.util.List; + +/** + * 新工资看板图表数据VO + */ +@Data +public class NewChartDataVo { + /** + * 月度支出数据(柱状图) + */ + private List monthlyExpenses; + + /** + * 工资构成分析(饼图) + */ + private List salaryStructures; + + /** + * 趋势分析(折线图) + */ + private SalaryTrendVo trendData; + + /** + * 社保公积金统计(柱状图) + */ + private List insuranceStats; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewSalaryDashboardVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewSalaryDashboardVo.java new file mode 100644 index 0000000..c982b18 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/NewSalaryDashboardVo.java @@ -0,0 +1,30 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import com.ruoyi.common.core.page.TableDataInfo; +import lombok.Data; + +/** + * 新工资数据看板VO + */ +@Data +public class NewSalaryDashboardVo { + /** + * 卡片数据 + */ + private NewCardDataVo cardData; + + /** + * 图表数据 + */ + private NewChartDataVo chartData; + + /** + * 单位统计表格数据 + */ + private TableDataInfo unitStats; + + /** + * 部门统计表格数据 + */ + private TableDataInfo deptStats; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryStructureVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryStructureVo.java new file mode 100644 index 0000000..76aa620 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryStructureVo.java @@ -0,0 +1,26 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 工资构成VO + */ +@Data +public class SalaryStructureVo { + /** + * 项目名称 + */ + private String itemName; + + /** + * 总金额 + */ + private BigDecimal totalAmount; + + /** + * 占比 + */ + private BigDecimal percentage; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryTrendPointVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryTrendPointVo.java new file mode 100644 index 0000000..b4694e3 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryTrendPointVo.java @@ -0,0 +1,31 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 工资趋势点VO + */ +@Data +public class SalaryTrendPointVo { + /** + * 月份 + */ + private Integer month; + + /** + * 总实发工资 + */ + private BigDecimal totalNetSalary; + + /** + * 总应发工资 + */ + private BigDecimal totalGrossSalary; + + /** + * 人均实发工资 + */ + private BigDecimal avgNetSalary; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryTrendVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryTrendVo.java new file mode 100644 index 0000000..73df751 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/SalaryTrendVo.java @@ -0,0 +1,47 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * 工资趋势VO + */ +@Data +public class SalaryTrendVo { + /** + * 月份列表 + */ + private List months; + + /** + * 实发工资趋势 + */ + private List netSalaryTrend; + + /** + * 应发工资趋势 + */ + private List grossSalaryTrend; + + /** + * 人均实发工资趋势 + */ + private List avgNetSalaryTrend; + + public SalaryTrendVo(List points) { + this.months = new ArrayList<>(); + this.netSalaryTrend = new ArrayList<>(); + this.grossSalaryTrend = new ArrayList<>(); + this.avgNetSalaryTrend = new ArrayList<>(); + + for (SalaryTrendPointVo point : points) { + this.months.add(point.getMonth()); + this.netSalaryTrend.add(point.getTotalNetSalary()); + this.grossSalaryTrend.add(point.getTotalGrossSalary()); + this.avgNetSalaryTrend.add(point.getAvgNetSalary()); + } + } +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/UnitStatVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/UnitStatVo.java new file mode 100644 index 0000000..4193f27 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/dashboard/UnitStatVo.java @@ -0,0 +1,51 @@ +package com.ruoyi.oa.domain.vo.dashboard; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 单位统计VO + */ +@Data +public class UnitStatVo { + /** + * 单位名称 + */ + private String unitName; + + /** + * 员工数量 + */ + private Integer employeeCount; + + /** + * 总实发工资 + */ + private BigDecimal totalNetSalary; + + /** + * 总应发工资 + */ + private BigDecimal totalGrossSalary; + + /** + * 单位总支出 + */ + private BigDecimal totalUnitExpense; + + /** + * 人均实发工资 + */ + private BigDecimal avgNetSalary; + + /** + * 同比增长率 + */ + private BigDecimal yearOnYearGrowthRate; + + /** + * 工资期间 + */ + private String salaryPeriod; +} \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SalaryDashboardMapper.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SalaryDashboardMapper.java index 3777da3..d8075ce 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SalaryDashboardMapper.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/SalaryDashboardMapper.java @@ -1,6 +1,7 @@ package com.ruoyi.oa.mapper; import com.ruoyi.oa.domain.vo.*; +import com.ruoyi.oa.domain.vo.dashboard.*; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -18,4 +19,59 @@ public interface SalaryDashboardMapper { List queryLineChartData(@Param("year") Long year); List queryDepartmentStats(@Param("year") Long year, @Param("month") Long month); + /** + * 查询卡片指标数据 + * + * @param salaryPeriod 工资期间 + * @return 卡片指标数据 + */ + NewCardMetricsVo queryNewCardMetrics(@Param("salaryPeriod") String salaryPeriod); + + /** + * 查询月度支出数据 + * + * @param year 年份 + * @return 月度支出列表 + */ + List queryMonthlyExpenses(@Param("year") Integer year); + + /** + * 查询工资构成数据 + * + * @param salaryPeriod 工资期间 + * @return 工资构成列表 + */ + List querySalaryStructures(@Param("salaryPeriod") String salaryPeriod); + + /** + * 查询工资趋势数据 + * + * @param year 年份 + * @return 工资趋势点列表 + */ + List querySalaryTrendData(@Param("year") Integer year); + + /** + * 查询社保公积金统计数据 + * + * @param salaryPeriod 工资期间 + * @return 社保公积金统计列表 + */ + List queryInsuranceStats(@Param("salaryPeriod") String salaryPeriod); + + /** + * 查询单位统计数据 + * + * @param salaryPeriod 工资期间 + * @return 单位统计列表 + */ + List queryUnitStats(@Param("salaryPeriod") String salaryPeriod); + + /** + * 查询部门统计数据 + * + * @param salaryPeriod 工资期间 + * @return 部门统计列表 + */ + List queryDeptSalaryStats(@Param("salaryPeriod") String salaryPeriod); } \ No newline at end of file diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISalaryDashboardService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISalaryDashboardService.java index d5d540f..04e257e 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISalaryDashboardService.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/ISalaryDashboardService.java @@ -1,8 +1,17 @@ package com.ruoyi.oa.service; -import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.oa.domain.vo.SalaryDashboardVo; +import com.ruoyi.oa.domain.vo.dashboard.NewSalaryDashboardVo; public interface ISalaryDashboardService { SalaryDashboardVo getDashboardData(Long payYear, Long payMonth); + /** + * 获取新工资数据看板数据 + * + * @param salaryPeriod 工资期间,格式如:2023-08 + * @return 数据看板VO + */ + NewSalaryDashboardVo getNewDashboardData(String salaryPeriod); + + } diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SalaryDashboardServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SalaryDashboardServiceImpl.java index 7f5bc1f..b4e8ddf 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SalaryDashboardServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SalaryDashboardServiceImpl.java @@ -2,6 +2,7 @@ package com.ruoyi.oa.service.impl; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.oa.domain.vo.*; +import com.ruoyi.oa.domain.vo.dashboard.*; import com.ruoyi.oa.mapper.SalaryDashboardMapper; import com.ruoyi.oa.service.ISalaryDashboardService; import org.springframework.beans.factory.annotation.Autowired; @@ -154,4 +155,210 @@ public class SalaryDashboardServiceImpl implements ISalaryDashboardService { return chartData; } + + @Override + public NewSalaryDashboardVo getNewDashboardData(String salaryPeriod) { + NewSalaryDashboardVo dashboardVo = new NewSalaryDashboardVo(); + + // 1. 获取卡片数据 + dashboardVo.setCardData(getNewCardData(salaryPeriod)); + + // 2. 获取图表数据 + String[] periodParts = salaryPeriod.split("-"); + Integer year = Integer.valueOf(periodParts[0]); + dashboardVo.setChartData(getNewChartData(salaryPeriod, year)); + + // 3. 获取单位统计表格数据 + List unitStats = dashboardMapper.queryUnitStats(salaryPeriod); + TableDataInfo unitTableData = new TableDataInfo<>(unitStats, unitStats.size()); + dashboardVo.setUnitStats(unitTableData); + + // 4. 获取部门统计表格数据 + List deptStats = dashboardMapper.queryDeptSalaryStats(salaryPeriod); + TableDataInfo deptTableData = new TableDataInfo<>(deptStats, deptStats.size()); + dashboardVo.setDeptStats(deptTableData); + + return dashboardVo; + } + + + + /** + * 获取新卡片数据 + */ + private NewCardDataVo getNewCardData(String salaryPeriod) { + NewCardDataVo cardData = new NewCardDataVo(); + + // 初始化所有数值为0,避免NPE + cardData.setTotalNetSalary(BigDecimal.ZERO); + cardData.setLastMonthNetSalaryRate(BigDecimal.ZERO); + cardData.setTotalGrossSalary(BigDecimal.ZERO); + cardData.setLastMonthGrossSalaryRate(BigDecimal.ZERO); + cardData.setTotalUnitExpense(BigDecimal.ZERO); + cardData.setLastMonthUnitExpenseRate(BigDecimal.ZERO); + cardData.setAvgNetSalary(BigDecimal.ZERO); + cardData.setLastMonthAvgNetSalaryRate(BigDecimal.ZERO); + cardData.setYearOnYearGrowthRate(BigDecimal.ZERO); + cardData.setTotalEmployeeCount(0); + cardData.setUnitCount(0); + + // 获取当月数据 + NewCardMetricsVo currentMonthMetrics = dashboardMapper.queryNewCardMetrics(salaryPeriod); + if (currentMonthMetrics == null) { + return cardData; // 如果当月没有数据,直接返回零值 + } + + // 设置当月数据 + cardData.setTotalNetSalary(currentMonthMetrics.getTotalNetSalary() != null ? + currentMonthMetrics.getTotalNetSalary() : BigDecimal.ZERO); + cardData.setTotalGrossSalary(currentMonthMetrics.getTotalGrossSalary() != null ? + currentMonthMetrics.getTotalGrossSalary() : BigDecimal.ZERO); + cardData.setTotalUnitExpense(currentMonthMetrics.getTotalUnitExpense() != null ? + currentMonthMetrics.getTotalUnitExpense() : BigDecimal.ZERO); + cardData.setTotalEmployeeCount(currentMonthMetrics.getEmployeeCount() != null ? + currentMonthMetrics.getEmployeeCount() : 0); + cardData.setUnitCount(currentMonthMetrics.getUnitCount() != null ? + currentMonthMetrics.getUnitCount() : 0); + + // 计算人均实发工资 + if (currentMonthMetrics.getEmployeeCount() != null && + currentMonthMetrics.getEmployeeCount() > 0 && + currentMonthMetrics.getTotalNetSalary() != null) { + try { + BigDecimal avgNetSalary = currentMonthMetrics.getTotalNetSalary() + .divide(new BigDecimal(currentMonthMetrics.getEmployeeCount()), 2, RoundingMode.HALF_UP); + cardData.setAvgNetSalary(avgNetSalary); + } catch (Exception e) { + cardData.setAvgNetSalary(BigDecimal.ZERO); + } + } + + // 计算上月对比数据 + String lastMonthPeriod = getLastMonthPeriod(salaryPeriod); + NewCardMetricsVo lastMonthMetrics = dashboardMapper.queryNewCardMetrics(lastMonthPeriod); + + if (lastMonthMetrics != null) { + // 计算实发工资增长率 + if (lastMonthMetrics.getTotalNetSalary() != null && + lastMonthMetrics.getTotalNetSalary().compareTo(BigDecimal.ZERO) != 0) { + try { + BigDecimal netSalaryGrowth = currentMonthMetrics.getTotalNetSalary() + .subtract(lastMonthMetrics.getTotalNetSalary()) + .divide(lastMonthMetrics.getTotalNetSalary(), 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal("100")); + cardData.setLastMonthNetSalaryRate(netSalaryGrowth); + } catch (Exception e) { + cardData.setLastMonthNetSalaryRate(BigDecimal.ZERO); + } + } + + // 计算应发工资增长率 + if (lastMonthMetrics.getTotalGrossSalary() != null && + lastMonthMetrics.getTotalGrossSalary().compareTo(BigDecimal.ZERO) != 0) { + try { + BigDecimal grossSalaryGrowth = currentMonthMetrics.getTotalGrossSalary() + .subtract(lastMonthMetrics.getTotalGrossSalary()) + .divide(lastMonthMetrics.getTotalGrossSalary(), 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal("100")); + cardData.setLastMonthGrossSalaryRate(grossSalaryGrowth); + } catch (Exception e) { + cardData.setLastMonthGrossSalaryRate(BigDecimal.ZERO); + } + } + + // 计算单位总支出增长率 + if (lastMonthMetrics.getTotalUnitExpense() != null && + lastMonthMetrics.getTotalUnitExpense().compareTo(BigDecimal.ZERO) != 0) { + try { + BigDecimal unitExpenseGrowth = currentMonthMetrics.getTotalUnitExpense() + .subtract(lastMonthMetrics.getTotalUnitExpense()) + .divide(lastMonthMetrics.getTotalUnitExpense(), 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal("100")); + cardData.setLastMonthUnitExpenseRate(unitExpenseGrowth); + } catch (Exception e) { + cardData.setLastMonthUnitExpenseRate(BigDecimal.ZERO); + } + } + } + + // 计算同比增长率(与去年同期相比) + String lastYearPeriod = getLastYearPeriod(salaryPeriod); + NewCardMetricsVo lastYearMetrics = dashboardMapper.queryNewCardMetrics(lastYearPeriod); + + if (lastYearMetrics != null && + lastYearMetrics.getEmployeeCount() != null && + lastYearMetrics.getEmployeeCount() > 0 && + lastYearMetrics.getTotalNetSalary() != null) { + try { + BigDecimal lastYearAvgSalary = lastYearMetrics.getTotalNetSalary() + .divide(new BigDecimal(lastYearMetrics.getEmployeeCount()), 2, RoundingMode.HALF_UP); + if (lastYearAvgSalary.compareTo(BigDecimal.ZERO) != 0 && + cardData.getAvgNetSalary() != null) { + BigDecimal yearGrowth = cardData.getAvgNetSalary() + .subtract(lastYearAvgSalary) + .divide(lastYearAvgSalary, 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal("100")); + cardData.setYearOnYearGrowthRate(yearGrowth); + } + } catch (Exception e) { + cardData.setYearOnYearGrowthRate(BigDecimal.ZERO); + } + } + + return cardData; + } + + /** + * 获取新图表数据 + */ + private NewChartDataVo getNewChartData(String salaryPeriod, Integer year) { + NewChartDataVo chartData = new NewChartDataVo(); + + // 1. 获取月度支出数据 + List monthlyExpenses = dashboardMapper.queryMonthlyExpenses(year); + chartData.setMonthlyExpenses(monthlyExpenses != null ? monthlyExpenses : new ArrayList<>()); + + // 2. 获取工资构成数据 + List salaryStructures = dashboardMapper.querySalaryStructures(salaryPeriod); + chartData.setSalaryStructures(salaryStructures != null ? salaryStructures : new ArrayList<>()); + + // 3. 获取趋势数据 + List trendData = dashboardMapper.querySalaryTrendData(year); + chartData.setTrendData(new SalaryTrendVo(trendData != null ? trendData : new ArrayList<>())); + + // 4. 获取社保公积金统计数据 + List insuranceStats = dashboardMapper.queryInsuranceStats(salaryPeriod); + chartData.setInsuranceStats(insuranceStats != null ? insuranceStats : new ArrayList<>()); + + return chartData; + } + + /** + * 获取上月期间 + */ + private String getLastMonthPeriod(String salaryPeriod) { + String[] parts = salaryPeriod.split("-"); + int year = Integer.parseInt(parts[0]); + int month = Integer.parseInt(parts[1]); + + if (month == 1) { + year--; + month = 12; + } else { + month--; + } + + return String.format("%d-%02d", year, month); + } + + /** + * 获取去年同期 + */ + private String getLastYearPeriod(String salaryPeriod) { + String[] parts = salaryPeriod.split("-"); + int year = Integer.parseInt(parts[0]) - 1; + int month = Integer.parseInt(parts[1]); + + return String.format("%d-%02d", year, month); + } } \ No newline at end of file diff --git a/ruoyi-oa/src/main/resources/mapper/oa/SalaryDashboardMapper.xml b/ruoyi-oa/src/main/resources/mapper/oa/SalaryDashboardMapper.xml index 0135a65..7480db1 100644 --- a/ruoyi-oa/src/main/resources/mapper/oa/SalaryDashboardMapper.xml +++ b/ruoyi-oa/src/main/resources/mapper/oa/SalaryDashboardMapper.xml @@ -140,4 +140,277 @@ ORDER BY totalExpenditure DESC + + + + + + + + + + + + + + + + + + + + \ No newline at end of file