maven
5 天以前 8a0d57c6edb61940cdce72862548f30aae1380c9
yys 员工工资生成逻辑
已添加19个文件
已修改5个文件
1064 ■■■■■ 文件已修改
src/main/java/com/ruoyi/project/system/mapper/SysUserDeptMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/BankController.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/StaffSalaryDetailController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/StaffSalaryMainController.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/controller/TaxCalculator.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/mapper/BankMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/mapper/SchemeApplicableStaffMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/mapper/StaffSalaryDetailMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/mapper/StaffSalaryMainMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/pojo/Bank.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/pojo/StaffSalaryDetail.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/pojo/StaffSalaryMain.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/BankService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/StaffSalaryDetailService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/StaffSalaryMainService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/BankServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffSalaryDetailServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffSalaryMainServiceImpl.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/staff/BankMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/staff/SchemeApplicableStaffMapper.xml 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/staff/StaffSalaryDetailMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/staff/StaffSalaryMainMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysUserDeptMapper.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/mapper/SysUserDeptMapper.java
@@ -7,9 +7,12 @@
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface SysUserDeptMapper extends BaseMapper<SysUserDept> {
    List<SysUserDeptVo> userLoginFacotryList(@Param("userDeptVo") SysUserDeptVo userDeptVo);
    List<Map<String, Object>> setSchemeApplicableStaffUserInfo(@Param("ids") List<Long> ids);
}
src/main/java/com/ruoyi/staff/controller/BankController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
package com.ruoyi.staff.controller;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.staff.pojo.Bank;
import com.ruoyi.staff.service.BankService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * <p>
 * é“¶è¡Œç®¡ç†è¡¨ å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 03:40:54
 */
@Api(tags = "银行管理表")
@RestController
@RequestMapping("/bank")
public class BankController {
    @Autowired
    private BankService bankService;
    @GetMapping("/list")
    public AjaxResult list() {
        return AjaxResult.success(bankService.list());
    }
    @PostMapping("/add")
    @ApiOperation("新增银行管理表")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "银行管理表", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody Bank bank) {
        return AjaxResult.success(bankService.save(bank));
    }
    @PostMapping("/update")
    @ApiOperation("更新银行管理表")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "银行管理表", businessType = BusinessType.UPDATE)
    public AjaxResult update(@RequestBody Bank bank) {
        return AjaxResult.success(bankService.updateById(bank));
    }
    @DeleteMapping("/delete")
    @ApiOperation("删除银行管理表")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "银行管理表", businessType = BusinessType.DELETE)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        return AjaxResult.success(bankService.removeBatchByIds(ids));
    }
}
src/main/java/com/ruoyi/staff/controller/StaffSalaryDetailController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.staff.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„明细表 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:24:35
 */
@RestController
@RequestMapping("/staffSalaryDetail")
public class StaffSalaryDetailController {
}
src/main/java/com/ruoyi/staff/controller/StaffSalaryMainController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
package com.ruoyi.staff.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.staff.pojo.StaffSalaryMain;
import com.ruoyi.staff.service.StaffSalaryMainService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„主表 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:22:05
 */
@Api(tags = "员工工资主表")
@RestController
@RequestMapping("/staffSalaryMain")
public class StaffSalaryMainController {
    @Autowired
    private StaffSalaryMainService staffSalaryMainService;
    @GetMapping("/listPage")
    @ApiOperation("员工工资主表分页查询")
    public AjaxResult listPage(Page page, StaffSalaryMain staffSalaryMain) {
        return staffSalaryMainService.listPage(page, staffSalaryMain);
    }
    @ApiOperation("通过部门ids获取用户信息计算每个员工的工资")
    @PostMapping("/calculateSalary")
    public AjaxResult calculateSalary(@RequestBody List<Long> ids) {
        return staffSalaryMainService.calculateSalary(ids);
    }
    @PostMapping("/add")
    @ApiOperation("新建工资表")
    @Log(title = "新建工资表", businessType = BusinessType.INSERT)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody StaffSalaryMain staffSalaryMain) {
        return staffSalaryMainService.add(staffSalaryMain);
    }
    @PostMapping("/update")
    @ApiOperation("修改工资表")
    @Log(title = "修改工资表", businessType = BusinessType.UPDATE)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateStaffSalaryMain(@RequestBody StaffSalaryMain staffSalaryMain) {
        return staffSalaryMainService.updateStaffSalaryMain(staffSalaryMain);
    }
    @DeleteMapping("/delete")
    @ApiOperation("删除工资表")
    @Log(title = "删除工资表", businessType = BusinessType.DELETE)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        return staffSalaryMainService.delete(ids);
    }
}
src/main/java/com/ruoyi/staff/controller/TaxCalculator.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
package com.ruoyi.staff.controller;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
/**
 * æœˆåº¦ä¸ªç¨Žè®¡ç®—工具类(仅需月度收入、社保个人、公积金个人三个参数)
 */
public class TaxCalculator {
    // æœˆåº¦å…å¾é¢ï¼ˆ5000元)
    private static final BigDecimal MONTHLY_EXEMPTION = new BigDecimal("5000");
    // æœˆåº¦ä¸ªç¨Žç¨ŽçŽ‡è¡¨ï¼š[应纳税所得额上限, ç¨Žçއ, é€Ÿç®—扣除数]
    private static final List<TaxBracket> MONTHLY_TAX_BRACKETS = new ArrayList<>();
    // é™æ€åˆå§‹åŒ–税率表(按月度换算,对应全年表/12)
    static {
        MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("3000"),  new BigDecimal("0.03"),  new BigDecimal("0")));
        MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("12000"), new BigDecimal("0.10"),  new BigDecimal("210")));
        MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("25000"), new BigDecimal("0.20"),  new BigDecimal("1410")));
        MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("35000"), new BigDecimal("0.25"),  new BigDecimal("2660")));
        MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("55000"), new BigDecimal("0.30"),  new BigDecimal("4410")));
        MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("80000"), new BigDecimal("0.35"),  new BigDecimal("7160")));
        MONTHLY_TAX_BRACKETS.add(new TaxBracket(new BigDecimal("999999"), new BigDecimal("0.45"), new BigDecimal("15160")));
    }
    // ç¨ŽçŽ‡è¡¨å†…éƒ¨ç±»
    private static class TaxBracket {
        final BigDecimal max;       // è¯¥æ¡£ä½åº”纳税所得额上限
        final BigDecimal rate;      // ç¨Žçއ
        final BigDecimal deduction; // é€Ÿç®—扣除数
        TaxBracket(BigDecimal max, BigDecimal rate, BigDecimal deduction) {
            this.max = max;
            this.rate = rate;
            this.deduction = deduction;
        }
    }
    /**
     * è®¡ç®—单月个人所得税(仅需三个参数)
     * @param monthlyIncome æœˆåº¦æ”¶å…¥ï¼ˆç¨Žå‰ï¼‰
     * @param socialSecurity ç¤¾ä¿ä¸ªäººç¼´çº³é‡‘额
     * @param fund å…¬ç§¯é‡‘个人缴纳金额
     * @return æœˆåº¦åº”缴个税(保留2位小数)
     */
    public static BigDecimal calculateMonthlyTax(
            BigDecimal monthlyIncome,
            BigDecimal socialSecurity,
            BigDecimal fund
    ) {
        // 1. ç©ºå€¼/负数处理:参数为null或负数时按0计算
        monthlyIncome = (monthlyIncome == null || monthlyIncome.compareTo(BigDecimal.ZERO) < 0) ? BigDecimal.ZERO : monthlyIncome;
        socialSecurity = (socialSecurity == null || socialSecurity.compareTo(BigDecimal.ZERO) < 0) ? BigDecimal.ZERO : socialSecurity;
        fund = (fund == null || fund.compareTo(BigDecimal.ZERO) < 0) ? BigDecimal.ZERO : fund;
        // 2. è®¡ç®—月度应纳税所得额 = æœˆåº¦æ”¶å…¥ - 5000免征额 - ç¤¾ä¿ä¸ªäºº - å…¬ç§¯é‡‘个人
        BigDecimal taxableIncome = monthlyIncome
                .subtract(MONTHLY_EXEMPTION)
                .subtract(socialSecurity)
                .subtract(fund);
        // 3. åº”纳税所得额≤0时,个税为0
        if (taxableIncome.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        }
        // 4. åŒ¹é…ç¨ŽçŽ‡æ¡£ä½è®¡ç®—ä¸ªç¨Ž
        for (TaxBracket bracket : MONTHLY_TAX_BRACKETS) {
            if (taxableIncome.compareTo(bracket.max) <= 0) {
                return taxableIncome.multiply(bracket.rate)
                        .subtract(bracket.deduction)
                        .setScale(2, RoundingMode.HALF_UP);
            }
        }
        // 5. è¶…过最高档位(80000元)的情况
        TaxBracket lastBracket = MONTHLY_TAX_BRACKETS.get(MONTHLY_TAX_BRACKETS.size() - 1);
        return taxableIncome.multiply(lastBracket.rate)
                .subtract(lastBracket.deduction)
                .setScale(2, RoundingMode.HALF_UP);
    }
    // æµ‹è¯•示例
    public static void main(String[] args) {
        // ç¤ºä¾‹1:月收入10000,社保个人800,公积金个人500
        BigDecimal income1 = new BigDecimal("10000");
        BigDecimal social1 = new BigDecimal("800");
        BigDecimal fund1 = new BigDecimal("500");
        BigDecimal tax1 = calculateMonthlyTax(income1, social1, fund1);
        System.out.println("月收入10000,社保800,公积金500,个税:" + tax1 + " å…ƒ"); // è®¡ç®—结果:111.00 å…ƒ
        // ç¤ºä¾‹2:月收入5000,社保500,公积金200
        BigDecimal income2 = new BigDecimal("5000");
        BigDecimal social2 = new BigDecimal("500");
        BigDecimal fund2 = new BigDecimal("200");
        BigDecimal tax2 = calculateMonthlyTax(income2, social2, fund2);
        System.out.println("月收入5000,社保500,公积金200,个税:" + tax2 + " å…ƒ"); // è®¡ç®—结果:0.00 å…ƒ
    }
}
src/main/java/com/ruoyi/staff/mapper/BankMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.staff.mapper;
import com.ruoyi.staff.pojo.Bank;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * é“¶è¡Œç®¡ç†è¡¨ Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 03:40:54
 */
@Mapper
public interface BankMapper extends BaseMapper<Bank> {
}
src/main/java/com/ruoyi/staff/mapper/SchemeApplicableStaffMapper.java
@@ -2,7 +2,11 @@
import com.ruoyi.staff.pojo.SchemeApplicableStaff;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.staff.pojo.SchemeInsuranceDetail;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -14,5 +18,17 @@
 */
@Mapper
public interface SchemeApplicableStaffMapper extends BaseMapper<SchemeApplicableStaff> {
    /**
     * æ ¹æ®äººå‘˜ID查询对应的社保方案(核心方法)
     * @param staffId äººå‘˜ID
     * @return è¯¥äººå‘˜é€‚用的所有社保方案列表
     */
    List<SchemeApplicableStaff> selectSchemeByStaffId(@Param("staffId") Long staffId);
    /**
     * æ ¹æ®ç¤¾ä¿æ–¹æ¡ˆID查询对应的明细列表
     * @param schemeId ç¤¾ä¿æ–¹æ¡ˆID
     * @return æ–¹æ¡ˆæ˜Žç»†åˆ—表
     */
    List<SchemeInsuranceDetail> selectDetailBySchemeId(@Param("schemeId") Long schemeId);
}
src/main/java/com/ruoyi/staff/mapper/StaffSalaryDetailMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.staff.mapper;
import com.ruoyi.staff.pojo.StaffSalaryDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„明细表 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:24:35
 */
@Mapper
public interface StaffSalaryDetailMapper extends BaseMapper<StaffSalaryDetail> {
}
src/main/java/com/ruoyi/staff/mapper/StaffSalaryMainMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.staff.mapper;
import com.ruoyi.staff.pojo.StaffSalaryMain;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„主表 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:22:05
 */
@Mapper
public interface StaffSalaryMainMapper extends BaseMapper<StaffSalaryMain> {
}
src/main/java/com/ruoyi/staff/pojo/Bank.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.ruoyi.staff.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
 * <p>
 * é“¶è¡Œç®¡ç†è¡¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 03:40:54
 */
@Getter
@Setter
@TableName("bank")
@ApiModel(value = "Bank对象", description = "银行管理表")
public class Bank implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("银行名称")
    private String bankName;
}
src/main/java/com/ruoyi/staff/pojo/StaffSalaryDetail.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
package com.ruoyi.staff.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„明细表
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:24:35
 */
@Getter
@Setter
@TableName("staff_salary_detail")
@ApiModel(value = "StaffSalaryDetail对象", description = "员工工资明细表")
public class StaffSalaryDetail implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("主键ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("关联工资主表ID")
    private Long mainId;
    @ApiModelProperty("关联staff_on_job表主键ID")
    private Long staffOnJobId;
    @ApiModelProperty("员工姓名")
    private String staffName;
    @ApiModelProperty("职位名称")
    private String postName;
    @ApiModelProperty("部门名称")
    private String deptName;
    @ApiModelProperty("基本工资")
    private BigDecimal basicSalary;
    @ApiModelProperty("计件工资")
    private BigDecimal pieceSalary;
    @ApiModelProperty("计时工资")
    private BigDecimal hourlySalary;
    @ApiModelProperty("其他收入")
    private BigDecimal otherIncome;
    @ApiModelProperty("社保个人")
    private BigDecimal socialPersonal;
    @ApiModelProperty("公积金个人")
    private BigDecimal fundPersonal;
    @ApiModelProperty("其他支出")
    private BigDecimal otherDeduct;
    @ApiModelProperty("工资个税")
    private BigDecimal salaryTax;
    @ApiModelProperty("应发工资")
    private BigDecimal grossSalary;
    @ApiModelProperty("应扣工资")
    private BigDecimal deductSalary;
    @ApiModelProperty("实发工资")
    private BigDecimal netSalary;
    @ApiModelProperty("备注")
    private String remark;
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty("创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Long createUser;
    @ApiModelProperty("修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty("修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;
}
src/main/java/com/ruoyi/staff/pojo/StaffSalaryMain.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
package com.ruoyi.staff.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„主表
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:22:05
 */
@Getter
@Setter
@TableName("staff_salary_main")
@ApiModel(value = "StaffSalaryMain对象", description = "员工工资主表")
public class StaffSalaryMain implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableField(exist = false)
    private List<StaffSalaryDetail> staffSalaryDetailList;
    @ApiModelProperty("主键ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("审核人Id")
    private Long auditUserId;
    @ApiModelProperty("审核人名称")
    private String auditUserName;
    @ApiModelProperty("工资主题")
    private String salaryTitle;
    @ApiModelProperty("关联部门ID,多个用逗号分隔")
    private String deptIds;
    @ApiModelProperty("工资月份,格式:yyyy-MM")
    private String salaryMonth;
    @ApiModelProperty("备注")
    private String remark;
    @ApiModelProperty("状态:1-草稿 2-审核未通过 3-待审核 4-待发放 5-已发放")
    private Integer status;
    @ApiModelProperty("工资总额")
    private BigDecimal totalSalary;
    @ApiModelProperty("支付银行")
    private String payBank;
    @TableField(exist = false)
    @ApiModelProperty("创建人")
    private String createUserName;
    @ApiModelProperty("发放时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8",shape = JsonFormat.Shape.STRING)
    private LocalDateTime payTime;
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8",shape = JsonFormat.Shape.STRING)
    private LocalDateTime createTime;
    @ApiModelProperty("创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Long createUser;
    @ApiModelProperty("修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty("修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;
}
src/main/java/com/ruoyi/staff/service/BankService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.staff.service;
import com.ruoyi.staff.pojo.Bank;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * é“¶è¡Œç®¡ç†è¡¨ æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 03:40:54
 */
public interface BankService extends IService<Bank> {
}
src/main/java/com/ruoyi/staff/service/StaffSalaryDetailService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.staff.service;
import com.ruoyi.staff.pojo.StaffSalaryDetail;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„明细表 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:24:35
 */
public interface StaffSalaryDetailService extends IService<StaffSalaryDetail> {
}
src/main/java/com/ruoyi/staff/service/StaffSalaryMainService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.staff.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.staff.pojo.StaffSalaryMain;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„主表 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:22:05
 */
public interface StaffSalaryMainService extends IService<StaffSalaryMain> {
    AjaxResult listPage(Page page, StaffSalaryMain staffSalaryMain);
    AjaxResult add(StaffSalaryMain staffSalaryMain);
    AjaxResult updateStaffSalaryMain(StaffSalaryMain staffSalaryMain);
    AjaxResult delete(List<Long> ids);
    AjaxResult calculateSalary(List<Long> ids);
}
src/main/java/com/ruoyi/staff/service/impl/BankServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.staff.service.impl;
import com.ruoyi.staff.pojo.Bank;
import com.ruoyi.staff.mapper.BankMapper;
import com.ruoyi.staff.service.BankService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * é“¶è¡Œç®¡ç†è¡¨ æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 03:40:54
 */
@Service
public class BankServiceImpl extends ServiceImpl<BankMapper, Bank> implements BankService {
}
src/main/java/com/ruoyi/staff/service/impl/SchemeApplicableStaffServiceImpl.java
@@ -10,19 +10,24 @@
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.mapper.SysUserDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.staff.controller.TaxCalculator;
import com.ruoyi.staff.dto.StaffOnJobDto;
import com.ruoyi.staff.mapper.SchemeInsuranceDetailMapper;
import com.ruoyi.staff.mapper.StaffOnJobMapper;
import com.ruoyi.staff.pojo.SchemeApplicableStaff;
import com.ruoyi.staff.mapper.SchemeApplicableStaffMapper;
import com.ruoyi.staff.pojo.SchemeInsuranceDetail;
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.staff.service.IStaffOnJobService;
import com.ruoyi.staff.service.SchemeApplicableStaffService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -50,6 +55,9 @@
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private StaffOnJobMapper staffOnJobMapper;
    @Override
@@ -88,22 +96,19 @@
    public void setSchemeApplicableStaffUserInfo(SchemeApplicableStaff schemeApplicableStaff) {
        // é€šè¿‡éƒ¨é—¨èŽ·å–äººå‘˜id
        List<SysUserDept> sysUserDepts = sysUserDeptMapper.selectList(new LambdaQueryWrapper<SysUserDept>()
                .in(SysUserDept::getDeptId, schemeApplicableStaff.getDeptIds()));
        if(CollectionUtils.isEmpty(sysUserDepts)){
        String[] split = schemeApplicableStaff.getDeptIds().split(",");
        List<StaffOnJob> staffOnJobs = staffOnJobMapper.selectList(new LambdaQueryWrapper<StaffOnJob>()
                .in(StaffOnJob::getSysDeptId, Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList())));
        if(CollectionUtils.isEmpty(staffOnJobs)){
            throw new IllegalArgumentException("部门下无员工");
        }
        List<SysUser> sysUsers = sysUserMapper.selectUserByIds(sysUserDepts.stream().map(SysUserDept::getUserId).collect(Collectors.toList()));
        if(CollectionUtils.isEmpty(sysUsers)){
            throw new IllegalArgumentException("部门下无员工");
        }
        schemeApplicableStaff.setStaffIds(sysUsers
        schemeApplicableStaff.setStaffIds(staffOnJobs
                .stream()
                .map(SysUser::getUserId)
                .map(StaffOnJob::getId)
                .filter(Objects::nonNull)         // è¿‡æ»¤æŽ‰ null å€¼
                .map(String::valueOf)
                .collect(Collectors.joining( ",")));
        schemeApplicableStaff.setStaffNames(sysUsers.stream().map(SysUser::getNickName).collect(Collectors.joining(",")));
        schemeApplicableStaff.setStaffNames(staffOnJobs.stream().map(StaffOnJob::getStaffName).collect(Collectors.joining(",")));
    }
    @Override
@@ -150,4 +155,113 @@
                .in(SchemeInsuranceDetail::getSchemeId, ids));
        return AjaxResult.success(delete);
    }
    /**
     * é€šè¿‡å‘˜å·¥id计算社保方案
     * @param id
     */
    public void calculateByEmployeeId(Integer id,Map<String, Object> map) {
        // 1. å…¥å‚校验
        if (id == null) {
            return; // æˆ–返回空列表,根据业务需求调整
        }
        Long staffId = id.longValue();
        // ç¤¾ä¿é‡‘额
        BigDecimal schemeAmount = new BigDecimal("0.00");
        // å…¬ç§¯é‡‘金额
        BigDecimal gjj = new BigDecimal("0.00");
        // åŸºæœ¬å·¥èµ„
        BigDecimal basicSalary = new BigDecimal("0.00");
        map.put("gjj", gjj); // å…¬ç§¯é‡‘
        map.put("schemeAmount", schemeAmount); // ç¤¾ä¿é‡‘额
        map.put("basicSalary", basicSalary); // åŸºæœ¬å·¥èµ„
        // ä¸ªç¨Žé‡‘额
        BigDecimal salaryTax = new BigDecimal("0.00");
        map.put("salaryTax", salaryTax);
        // è®¡ä»¶å·¥èµ„
        BigDecimal pieceSalary = new BigDecimal("0.00");
        map.put("pieceSalary", pieceSalary);
        // è®¡æ—¶å·¥èµ„
        BigDecimal hourlySalary = new BigDecimal("0.00");
        map.put("hourlySalary", hourlySalary);
        // å…¶ä»–æ”¶å…¥
        BigDecimal otherIncome = new BigDecimal("0.00");
        map.put("otherIncome", otherIncome);
        // å…¶ä»–支出
        BigDecimal otherDeduct = new BigDecimal("0.00");
        map.put("otherDeduct", otherDeduct);
        // åº”发工资
        BigDecimal grossSalary = new BigDecimal("0.00");
        map.put("grossSalary", grossSalary);
        // åº”扣工资
        BigDecimal deductSalary = new BigDecimal("0.00");
        map.put("deductSalary", deductSalary);
        // å®žå‘工资
        BigDecimal netSalary = new BigDecimal("0.00");
        map.put("netSalary", netSalary);
        // è°ƒç”¨åŸºæœ¬å·¥èµ„
        StaffOnJob staffOnJobDto = staffOnJobMapper.selectById(staffId);
        if(staffOnJobDto == null){
            return;
        }
        basicSalary = staffOnJobDto.getBasicSalary();
        map.put("basicSalary", basicSalary);
        // åº”发工资
        map.put("grossSalary", basicSalary);
        // ä¸ªç¨Žé‡‘额(无社保版)
        BigDecimal bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, schemeAmount, gjj);
        map.put("salaryTax", bigDecimal);
        // 2. æŸ¥è¯¢è¯¥äººå‘˜å¯¹åº”的社保方案
        List<SchemeApplicableStaff> schemeList = schemeApplicableStaffMapper.selectSchemeByStaffId(staffId);
        if (CollectionUtils.isEmpty(schemeList)) {
            return; // æ— åŒ¹é…æ–¹æ¡ˆï¼Œè¿”回空列表
        }
        // 3. ä¸ºæ¯ä¸ªæ–¹æ¡ˆå…³è”明细列表
        for (SchemeApplicableStaff scheme : schemeList) {
            List<SchemeInsuranceDetail> detailList = schemeApplicableStaffMapper.selectDetailBySchemeId(scheme.getId());
            // æ ¹æ®æ˜Žç»†åˆ—表计算社保缴费金额
            if(CollectionUtils.isEmpty(detailList)){
                continue;
            }
            for (SchemeInsuranceDetail detail : detailList) {
                if("住房公积金".equals(detail.getInsuranceType())){
                    gjj = gjj.add(calculateByEmployeeIdType(detail.getInsuranceType(),gjj, staffOnJobDto, detail));
                }else{
                    schemeAmount = schemeAmount.add(calculateByEmployeeIdType(detail.getInsuranceType(),schemeAmount, staffOnJobDto, detail));
                }
            }
        }
        map.put("schemeAmount", schemeAmount);
        map.put("gjj", gjj);
        // ä¸ªç¨Žé‡‘额(社保版)
        bigDecimal = TaxCalculator.calculateMonthlyTax(basicSalary, schemeAmount, gjj);
        map.put("salaryTax", bigDecimal);
        // åº”扣工资
        map.put("deductSalary", bigDecimal.add(gjj).add(schemeAmount));
        // å®žå‘工资
        map.put("netSalary", basicSalary.subtract(bigDecimal).subtract(gjj).subtract(schemeAmount));
    }
    /**
     * è®¡ç®—
     * @param type
     * @param bigDecimal
     * @param staffOnJobDto
     * @param detail
     * @return
     */
    public BigDecimal calculateByEmployeeIdType(String type,BigDecimal bigDecimal, StaffOnJob staffOnJobDto,SchemeInsuranceDetail detail) {
        // åˆ¤æ–­æ˜¯å¦è°ƒç”¨åŸºæœ¬å·¥èµ„
        if (detail.getUseBasicSalary() == 1) {
            BigDecimal divide = detail.getPaymentBase().multiply(detail.getPersonalRatio()).divide(new BigDecimal("100"), 2);
            bigDecimal = bigDecimal.add(divide);
        }else{
            // è°ƒç”¨åŸºæœ¬å·¥èµ„
            BigDecimal multiply = staffOnJobDto.getBasicSalary().multiply(detail.getPersonalRatio().divide(new BigDecimal("100"), 2));
            bigDecimal = bigDecimal.add(multiply);
        }
        bigDecimal = bigDecimal.add(detail.getPersonalFixed());
        return bigDecimal;
    }
}
src/main/java/com/ruoyi/staff/service/impl/StaffSalaryDetailServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.staff.service.impl;
import com.ruoyi.staff.pojo.StaffSalaryDetail;
import com.ruoyi.staff.mapper.StaffSalaryDetailMapper;
import com.ruoyi.staff.service.StaffSalaryDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„明细表 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:24:35
 */
@Service
public class StaffSalaryDetailServiceImpl extends ServiceImpl<StaffSalaryDetailMapper, StaffSalaryDetail> implements StaffSalaryDetailService {
}
src/main/java/com/ruoyi/staff/service/impl/StaffSalaryMainServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,142 @@
package com.ruoyi.staff.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.domain.SysUserDept;
import com.ruoyi.project.system.mapper.SysUserDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.staff.mapper.StaffSalaryDetailMapper;
import com.ruoyi.staff.pojo.SchemeApplicableStaff;
import com.ruoyi.staff.pojo.StaffSalaryDetail;
import com.ruoyi.staff.pojo.StaffSalaryMain;
import com.ruoyi.staff.mapper.StaffSalaryMainMapper;
import com.ruoyi.staff.service.StaffSalaryDetailService;
import com.ruoyi.staff.service.StaffSalaryMainService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
 * <p>
 * å‘˜å·¥å·¥èµ„主表 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-03-06 01:22:05
 */
@Service
public class StaffSalaryMainServiceImpl extends ServiceImpl<StaffSalaryMainMapper, StaffSalaryMain> implements StaffSalaryMainService {
    @Autowired
    private StaffSalaryMainMapper staffSalaryMainMapper;
    @Autowired
    private StaffSalaryDetailService staffSalaryDetailService;
    @Autowired
    private StaffSalaryDetailMapper staffSalaryDetailMapper;
    @Autowired
    private SchemeApplicableStaffServiceImpl schemeApplicableStaffService;
    @Autowired
    private SysUserDeptMapper sysUserDeptMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    public AjaxResult listPage(Page page, StaffSalaryMain staffSalaryMain) {
        LambdaQueryWrapper<StaffSalaryMain> staffSalaryMainLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(staffSalaryMain != null){
            if(StringUtils.isNotEmpty(staffSalaryMain.getSalaryTitle())){
                staffSalaryMainLambdaQueryWrapper.like(StaffSalaryMain::getSalaryTitle, staffSalaryMain.getSalaryTitle());
            }
            if(StringUtils.isNotEmpty(staffSalaryMain.getSalaryMonth())){
                staffSalaryMainLambdaQueryWrapper.like(StaffSalaryMain::getSalaryMonth, staffSalaryMain.getSalaryMonth());
            }
            if(staffSalaryMain.getStatus() != null){
                staffSalaryMainLambdaQueryWrapper.eq(StaffSalaryMain::getStatus, staffSalaryMain.getStatus());
            }
        }
        Page<StaffSalaryMain> page1 = staffSalaryMainMapper.selectPage(page, staffSalaryMainLambdaQueryWrapper);
        page1.getRecords().forEach(main -> {
            List<StaffSalaryDetail> staffSalaryDetailList = staffSalaryDetailMapper.selectList(new LambdaQueryWrapper<StaffSalaryDetail>().eq(StaffSalaryDetail::getMainId, main.getId()));
            main.setStaffSalaryDetailList(staffSalaryDetailList);
        });
        return AjaxResult.success(page1);
    }
    @Override
    public AjaxResult add(StaffSalaryMain staffSalaryMain) {
        staffSalaryMainMapper.insert(staffSalaryMain);
        staffSalaryMain.getStaffSalaryDetailList().forEach(detail -> {
            detail.setMainId(staffSalaryMain.getId());
        });
        staffSalaryDetailService.saveBatch(staffSalaryMain.getStaffSalaryDetailList());
        return AjaxResult.success("新增成功");
    }
    @Override
    public AjaxResult updateStaffSalaryMain(StaffSalaryMain staffSalaryMain) {
        if(staffSalaryMain == null){
            return AjaxResult.error("参数错误");
        }
        StaffSalaryMain staffSalaryMain1 = staffSalaryMainMapper.selectById(staffSalaryMain.getId());
        if(staffSalaryMain1 == null){
            return AjaxResult.error("参数错误");
        }
        // å¾…审核不可编辑
        if(staffSalaryMain1.getStatus() > 2){
            return AjaxResult.error("待审核不可编辑");
        }
        staffSalaryMainMapper.updateById(staffSalaryMain);
        staffSalaryDetailMapper.delete(new LambdaQueryWrapper<StaffSalaryDetail>().eq(StaffSalaryDetail::getMainId, staffSalaryMain.getId()));
        staffSalaryMain.getStaffSalaryDetailList().forEach(detail -> {
            detail.setMainId(staffSalaryMain.getId());
        });
        staffSalaryDetailService.saveBatch(staffSalaryMain.getStaffSalaryDetailList());
        return AjaxResult.success("修改成功");
    }
    @Override
    public AjaxResult delete(List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return AjaxResult.error("参数错误");
        }
        staffSalaryMainMapper.deleteBatchIds(ids);
        staffSalaryDetailMapper.delete(new LambdaQueryWrapper<StaffSalaryDetail>().in(StaffSalaryDetail::getMainId, ids));
        return AjaxResult.success("删除成功");
    }
    @Override
    public AjaxResult calculateSalary(List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return AjaxResult.error("参数错误");
        }
        List<Map<String, Object>> longs = setSchemeApplicableStaffUserInfo(ids); // é€šè¿‡éƒ¨é—¨ids获取用户信息
        if(CollectionUtils.isEmpty(longs)){
            return AjaxResult.error("无员工");
        }
        for (Map<String, Object> id : longs) {
            schemeApplicableStaffService.calculateByEmployeeId((Integer) id.get("id"),id);
        }
        return AjaxResult.success(longs);
    }
    public List<Map<String, Object>> setSchemeApplicableStaffUserInfo(List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return new ArrayList<>();
        }
        // é€šè¿‡éƒ¨é—¨èŽ·å–äººå‘˜id
        return sysUserDeptMapper.setSchemeApplicableStaffUserInfo(ids);
    }
}
src/main/resources/mapper/staff/BankMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
<?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.ruoyi.staff.mapper.BankMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.staff.pojo.Bank">
        <id column="id" property="id" />
        <result column="bank_name" property="bankName" />
    </resultMap>
</mapper>
src/main/resources/mapper/staff/SchemeApplicableStaffMapper.xml
@@ -2,19 +2,39 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.staff.mapper.SchemeApplicableStaffMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.staff.pojo.SchemeApplicableStaff">
        <id column="id" property="id" />
        <result column="title" property="title" />
        <result column="dept_ids" property="deptIds" />
        <result column="staff_names" property="staffNames" />
        <result column="staff_ids" property="staffIds" />
        <result column="insurance_types" property="insuranceTypes" />
        <result column="remark" property="remark" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="create_user" property="createUser" />
        <result column="update_user" property="updateUser" />
    </resultMap>
    <!-- åŸºç¡€å­—段查询 -->
    <sql id="schemeColumns">
        id, title, dept_ids, staff_names, staff_ids,
        insurance_types, remark, create_time, update_time,
        create_user, update_user
    </sql>
    <!-- æ ¹æ®äººå‘˜ID查询社保方案 -->
    <select id="selectSchemeByStaffId" resultType="com.ruoyi.staff.pojo.SchemeApplicableStaff">
        SELECT
        <include refid="schemeColumns"/>
        FROM
        scheme_applicable_staff
        WHERE
        1 = 1
        <!-- æ ¸å¿ƒï¼šåŒ¹é…staff_ids中包含目标人员ID的记录 -->
        AND FIND_IN_SET(#{staffId}, staff_ids)
        <!-- å¯é€‰ï¼šå¢žåŠ æœ‰æ•ˆçŠ¶æ€è¿‡æ»¤ï¼ˆå¦‚æžœè¡¨ä¸­æœ‰çŠ¶æ€å­—æ®µï¼‰ -->
        <!-- AND status = 1 -->
        ORDER BY
        create_time DESC
    </select>
    <!-- æŸ¥è¯¢æ–¹æ¡ˆå¯¹åº”的明细 -->
    <select id="selectDetailBySchemeId" resultType="com.ruoyi.staff.pojo.SchemeInsuranceDetail">
        SELECT
            id, scheme_id, insurance_type, payment_base,
            use_basic_salary, personal_ratio, personal_fixed,
            create_time, update_time, create_user, update_user
        FROM
            scheme_insurance_detail
        WHERE
            scheme_id = #{schemeId}
    </select>
</mapper>
src/main/resources/mapper/staff/StaffSalaryDetailMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
<?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.ruoyi.staff.mapper.StaffSalaryDetailMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.staff.pojo.StaffSalaryDetail">
        <id column="id" property="id" />
        <result column="main_id" property="mainId" />
        <result column="staff_on_job_id" property="staffOnJobId" />
        <result column="staff_name" property="staffName" />
        <result column="post_name" property="postName" />
        <result column="dept_name" property="deptName" />
        <result column="basic_salary" property="basicSalary" />
        <result column="piece_salary" property="pieceSalary" />
        <result column="hourly_salary" property="hourlySalary" />
        <result column="other_income" property="otherIncome" />
        <result column="social_personal" property="socialPersonal" />
        <result column="fund_personal" property="fundPersonal" />
        <result column="other_deduct" property="otherDeduct" />
        <result column="salary_tax" property="salaryTax" />
        <result column="gross_salary" property="grossSalary" />
        <result column="deduct_salary" property="deductSalary" />
        <result column="net_salary" property="netSalary" />
        <result column="remark" property="remark" />
        <result column="create_time" property="createTime" />
        <result column="create_user" property="createUser" />
        <result column="update_time" property="updateTime" />
        <result column="update_user" property="updateUser" />
    </resultMap>
</mapper>
src/main/resources/mapper/staff/StaffSalaryMainMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
<?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.ruoyi.staff.mapper.StaffSalaryMainMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.staff.pojo.StaffSalaryMain">
        <id column="id" property="id" />
        <result column="salary_title" property="salaryTitle" />
        <result column="dept_ids" property="deptIds" />
        <result column="salary_month" property="salaryMonth" />
        <result column="remark" property="remark" />
        <result column="status" property="status" />
        <result column="create_time" property="createTime" />
        <result column="create_user" property="createUser" />
        <result column="update_time" property="updateTime" />
        <result column="update_user" property="updateUser" />
    </resultMap>
</mapper>
src/main/resources/mapper/system/SysUserDeptMapper.xml
@@ -3,7 +3,23 @@
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.project.system.mapper.SysUserDeptMapper">
    <select id="setSchemeApplicableStaffUserInfo" resultType="java.util.Map">
        SELECT
        T1.id as id,
        T1.staff_no as staffNo,
        T1.staff_name as staffName,
        T2.dept_id as deptId,
        T2.dept_name as deptName
        FROM
        staff_on_job T1
        LEFT JOIN sys_dept T2 ON T1.sys_dept_id = T2.dept_id
        <where>
            T1.sys_dept_id in<foreach collection="ids" item="id" separator="," close=")" open="(">#{id}</foreach>
        </where>
        GROUP BY
        T1.id
    </select>
    <select id="userLoginFacotryList" resultType="com.ruoyi.project.system.domain.vo.SysUserDeptVo">
        SELECT
            T1.user_id,