zouyu
2 天以前 2ea3b36a810adcb639f4d3c72c860f722f601927
绩效管理:人员能力功能模块
已添加21个文件
已修改3个文件
1541 ■■■■■ 文件已修改
inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyInspectItemConfigController.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyLevelEvaluateRecordController.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/dto/StaffCompetencyLevelEvaluateRecordDTO.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyInspectItemConfigMapper.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyLevelEvaluateRecordMapper.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyInspectItemConfig.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyLevelEvaluateRecord.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/StaffAttendanceTrackingRecordService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyInspectItemConfigService.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyLevelEvaluateRecordService.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyInspectItemConfigServiceImpl.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyLevelEvaluateRecordServiceImpl.java 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyInspectItemConfigVO.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyLevelEvaluateRecordVO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffConfigHeaderVO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/vo/TestUserVO.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/mapper/StaffCompetencyInspectItemConfigMapper.xml 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/mapper/StaffCompetencyLevelEvaluateRecordMapper.xml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/StaffSkillLevelType.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/EasyExcelUtils.java 311 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/FullCustomAutoWidthHandler.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/HeaderContentRowHeightHandler.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyInspectItemConfigController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,114 @@
package com.ruoyi.inspect.controller;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig;
import com.ruoyi.inspect.service.StaffCompetencyInspectItemConfigService;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * äººå‘˜èƒ½åŠ›-检验项配置
 */
@Api("人员能力-检验项配置")
@RestController
@RequestMapping("/staffCompetencyInspectItemConfig")
public class StaffCompetencyInspectItemConfigController {
    @Autowired
    private StaffCompetencyInspectItemConfigService configService;
    /**
     * èŽ·å–æ£€éªŒé¡¹ç‚¹åˆ—è¡¨
     */
    @GetMapping("/list")
    public Result list(StaffCompetencyInspectItemConfig config)
    {
        List<StaffCompetencyInspectItemConfig> configs = configService.selectConfigList(config);
        return Result.success(configs);
    }
    /**
     * æŸ¥è¯¢æ£€éªŒé¡¹ç‚¹åˆ—表(排除节点)
     */
    @GetMapping("/list/exclude/{configId}")
    public Result excludeChild(@PathVariable(value = "configId", required = false) Long configId)
    {
        StaffCompetencyInspectItemConfig itemConfig = new StaffCompetencyInspectItemConfig();
        itemConfig.setIsEnable(Boolean.TRUE);
        List<StaffCompetencyInspectItemConfig> configs = configService.selectConfigList(itemConfig);
        configs.removeIf(c -> c.getParentId().intValue() == configId  || ArrayUtils.contains(StringUtils.split(c.getAncestors(), ","), configId + ""));
        return Result.success(configs);
    }
    /**
     * æ ¹æ®æ£€éªŒé¡¹ç‚¹ç¼–号获取详细信息
     */
    @GetMapping(value = "/{configId}")
    public Result getInfo(@PathVariable Long configId)
    {
        return Result.success(configService.selectConfigById(configId));
    }
    /**
     * æ–°å¢žæ£€éªŒé¡¹ç‚¹
     */
    @Log(title = "人员能力-检验项配置", businessType = BusinessType.INSERT)
    @PostMapping
    public Result add(@Validated @RequestBody StaffCompetencyInspectItemConfig config)
    {
        if (!configService.checkItemNameUnique(config))
        {
            return Result.fail("新增检验项点'" + config.getItemName() + "'失败,项点名称已存在");
        }
        return Result.success(configService.insertConfig(config));
    }
    /**
     * ä¿®æ”¹æ£€éªŒé¡¹ç‚¹
     */
    @Log(title = "人员能力-检验项配置", businessType = BusinessType.UPDATE)
    @PutMapping
    public Result edit(@Validated @RequestBody StaffCompetencyInspectItemConfig config)
    {
        Long configId = config.getId();
        if (!configService.checkItemNameUnique(config))
        {
            return Result.fail("修改检验项点'" + config.getItemName() + "'失败,项点名称已存在");
        }
        else if (config.getParentId().equals(configId))
        {
            return Result.fail("修改检验项点'" + config.getItemName() + "'失败,上级项点不能是自己");
        }
        else if (!config.getIsEnable() && configService.selectNormalChildrenConfigById(configId) > 0)
        {
            return Result.fail("该检验项点包含未停用的子项点!");
        }
        return Result.success(configService.updateConfig(config));
    }
    /**
     * åˆ é™¤éƒ¨é—¨
     */
    @Log(title = "人员能力-检验项配置", businessType = BusinessType.DELETE)
    @DeleteMapping("/{configId}")
    public Result remove(@PathVariable Long configId)
    {
        if (configService.hasChildByConfigId(configId))
        {
            return Result.fail("存在下级检验项点,不允许删除");
        }
        return Result.success(configService.deleteConfigById(configId));
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyLevelEvaluateRecordController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.ruoyi.inspect.controller;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.inspect.dto.StaffCompetencyLevelEvaluateRecordDTO;
import com.ruoyi.inspect.service.StaffCompetencyLevelEvaluateRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
/**
 * äººå‘˜èƒ½åŠ›-等级评定
 */
@Api("人员能力-等级评定")
@RestController
@RequestMapping("/StaffCompetencyLevelEvaluateRecord")
public class StaffCompetencyLevelEvaluateRecordController {
    @Autowired
    private StaffCompetencyLevelEvaluateRecordService recordService;
    /**
     * èŽ·å–ç”¨æˆ·ç­‰çº§è¯„å®šåˆ—è¡¨
     */
    @ApiModelProperty("获取用户等级评定列表")
    @GetMapping("/getPageList")
    public Result getPageList(StaffCompetencyLevelEvaluateRecordDTO record){
        return Result.success(recordService.getPageList(record));
    }
    /**
     * ä¿®æ”¹ç”¨æˆ·ç­‰çº§
     */
    @ApiModelProperty("修改用户等级")
    @PostMapping("/changeLevel")
    public Result changeLevel(@RequestBody StaffCompetencyLevelEvaluateRecordDTO recordDTO){
        return Result.success(recordService.saveOrUpdate(recordDTO));
    }
    /**
     * å¯¼å‡ºäººå‘˜èƒ½åŠ›åˆ—è¡¨
     */
    @ApiModelProperty("导出人员能力列表")
    @GetMapping("/exportRecords")
    public void exportRecords(HttpServletResponse response,StaffCompetencyLevelEvaluateRecordDTO recordDTO){
        recordService.exportRecords(response,recordDTO);
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/dto/StaffCompetencyLevelEvaluateRecordDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.inspect.dto;
import com.ruoyi.inspect.pojo.StaffCompetencyLevelEvaluateRecord;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class StaffCompetencyLevelEvaluateRecordDTO extends StaffCompetencyLevelEvaluateRecord {
    /**
     * å·¥å·/人员名称
     */
    @ApiModelProperty("工号/人员名称")
    private String keyword;
    /**
     * å²—位
     */
    @ApiModelProperty("岗位")
    private String postName;
    /**
     * è§’色id
     */
    @ApiModelProperty("角色id")
    private Long roleId;
}
inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyInspectItemConfigMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.ruoyi.inspect.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig;
import com.ruoyi.inspect.vo.StaffCompetencyInspectItemConfigVO;
import com.ruoyi.inspect.vo.StaffConfigHeaderVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 27233
* @description é’ˆå¯¹è¡¨ã€staff_competency_inspect_item_config(人员能力-检验项配置表)】的数据库操作Mapper
* @createDate 2026-03-26 17:16:51
* @Entity com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig
*/
@Mapper
public interface StaffCompetencyInspectItemConfigMapper extends BaseMapper<StaffCompetencyInspectItemConfig> {
    List<StaffCompetencyInspectItemConfig> selectConfigList(@Param("config") StaffCompetencyInspectItemConfig config);
    StaffCompetencyInspectItemConfig checkDeptNameUnique(@Param("itemName") String itemName, @Param("parentId") Long parentId);
    StaffCompetencyInspectItemConfigVO selectConfigById(@Param("configId") Long configId);
    int insertConfig(@Param("config") StaffCompetencyInspectItemConfig config);
    int updateConfig(@Param("config") StaffCompetencyInspectItemConfig config);
    int updateConfigStatusNormal(@Param("configIds") List<Long> configIds);
    List<StaffCompetencyInspectItemConfig> selectChildrenConfigById(@Param("configId") Long configId);
    int updateConfigChildren(@Param("children") List<StaffCompetencyInspectItemConfig> children);
    int hasChildByConfigId(@Param("configId") Long configId);
    int selectNormalChildrenConfigById(@Param("configId")Long configId);
    List<StaffConfigHeaderVO> selectConfigHeader();
}
inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyLevelEvaluateRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.ruoyi.inspect.mapper;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.inspect.dto.StaffCompetencyLevelEvaluateRecordDTO;
import com.ruoyi.inspect.pojo.StaffCompetencyLevelEvaluateRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.inspect.vo.StaffCompetencyLevelEvaluateRecordVO;
import com.ruoyi.inspect.vo.TestUserVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 27233
* @description é’ˆå¯¹è¡¨ã€staff_competency_level_evaluate_record(人员能力等级评定表)】的数据库操作Mapper
* @createDate 2026-03-26 17:16:56
* @Entity com.ruoyi.inspect.pojo.StaffCompetencyLevelEvaluateRecord
*/
@Mapper
public interface StaffCompetencyLevelEvaluateRecordMapper extends BaseMapper<StaffCompetencyLevelEvaluateRecord> {
    List<StaffCompetencyLevelEvaluateRecordVO> selectCompetencyLevelEvaluateRecord();
    List<TestUserVO> selectTestUserList(@Param("dto") StaffCompetencyLevelEvaluateRecordDTO dto);
}
inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyInspectItemConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
package com.ruoyi.inspect.pojo;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import lombok.Data;
/**
 * äººå‘˜èƒ½åŠ›-检验项配置表
 * @TableName staff_competency_inspect_item_config
 */
@TableName(value ="staff_competency_inspect_item_config")
@Data
public class StaffCompetencyInspectItemConfig implements Serializable {
    /**
     * ä¸»é”®id
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * çˆ¶çº§id
     */
    private Long parentId;
    /**
     * ç¥–级列表
     */
    private String ancestors;
    /**
     * æ£€éªŒé¡¹åç§°
     */
    private String itemName;
    /**
     * æŽ’序
     */
    private Integer sort;
    /**
     * æ˜¯å¦å¯ç”¨
     */
    private Boolean isEnable;
    /**
     * åˆ›å»ºäºº
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * æ›´æ–°äºº
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * æ›´æ–°æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyLevelEvaluateRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
package com.ruoyi.inspect.pojo;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import lombok.Data;
/**
 * äººå‘˜èƒ½åŠ›ç­‰çº§è¯„å®šè¡¨
 * @TableName staff_competency_level_evaluate_record
 */
@TableName(value ="staff_competency_level_evaluate_record")
@Data
public class StaffCompetencyLevelEvaluateRecord implements Serializable {
    /**
     * ä¸»é”®id
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * ç”¨æˆ·id
     */
    private Integer userId;
    /**
     * æ£€éªŒé¡¹é…ç½®id
     */
    private Long itemConfigId;
    /**
     * è¯„定等级
     */
    private String level;
    /**
     * åˆ›å»ºäºº
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * æ›´æ–°äºº
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * æ›´æ–°æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
inspect-server/src/main/java/com/ruoyi/inspect/service/StaffAttendanceTrackingRecordService.java
@@ -6,7 +6,6 @@
import com.ruoyi.inspect.dto.StaffAttendanceDTO;
import com.ruoyi.inspect.pojo.StaffAttendanceTrackingRecord;
import com.ruoyi.inspect.vo.StaffAttendanceVO;
import com.ruoyi.inspect.vo.StaffClockInVO;
import com.ruoyi.performance.dto.PerformanceShiftMapDto;
import java.time.LocalDateTime;
@@ -28,4 +27,5 @@
    PerformanceShiftMapDto checkDutyDate(StaffAttendanceDTO staffAttendanceDTO);
    boolean saveOrUpdateRecord(StaffAttendanceDTO staffAttendanceDTO);
}
inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyInspectItemConfigService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.ruoyi.inspect.service;
import com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author 27233
* @description é’ˆå¯¹è¡¨ã€staff_competency_inspect_item_config(人员能力-检验项配置表)】的数据库操作Service
* @createDate 2026-03-26 17:16:51
*/
public interface StaffCompetencyInspectItemConfigService extends IService<StaffCompetencyInspectItemConfig> {
    List<StaffCompetencyInspectItemConfig> selectConfigList(StaffCompetencyInspectItemConfig config);
    StaffCompetencyInspectItemConfig selectConfigById(Long configId);
    boolean checkItemNameUnique(StaffCompetencyInspectItemConfig config);
    int insertConfig(StaffCompetencyInspectItemConfig config);
    int updateConfig(StaffCompetencyInspectItemConfig config);
    boolean hasChildByConfigId(Long configId);
    int deleteConfigById(Long configId);
    int selectNormalChildrenConfigById(Long configId);
}
inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyLevelEvaluateRecordService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ruoyi.inspect.service;
import com.ruoyi.inspect.dto.StaffCompetencyLevelEvaluateRecordDTO;
import com.ruoyi.inspect.pojo.StaffCompetencyLevelEvaluateRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/**
* @author 27233
* @description é’ˆå¯¹è¡¨ã€staff_competency_level_evaluate_record(人员能力等级评定表)】的数据库操作Service
* @createDate 2026-03-26 17:16:56
*/
public interface StaffCompetencyLevelEvaluateRecordService extends IService<StaffCompetencyLevelEvaluateRecord> {
    List<Map<String,Object>> getPageList(StaffCompetencyLevelEvaluateRecordDTO record);
    void exportRecords(HttpServletResponse response, StaffCompetencyLevelEvaluateRecordDTO recordDTO);
}
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
@@ -36,6 +36,7 @@
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@@ -170,6 +171,8 @@
                 * æ­£å¸¸ï¼šå½“前班次结束后第一次出门时间
                 * å¼‚常(早退):无当前班次结束到下一班次开始前的出门记录并且最后一次出门在当前班次时间范围内,取当前班次最后一次出门时间
                 */
                //当前时间
                LocalDateTime now  = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
                // å½“前班次开始天0点时间
                LocalDateTime startDateTime = LocalDateTime.of(p.getWorkTime().toLocalDate(), LocalTime.MIN);
                // å½“前班次结束天24点时间
@@ -224,7 +227,7 @@
                                    && s.getSwingTime().isBefore(nextShiftStartDateTime))
                            .min(Comparator.comparing(StaffAttendanceTrackingRecord::getSwingTime))
                            .orElse(new StaffAttendanceTrackingRecord());
                    if (BeanUtil.isEmpty(exitRecord)) {
                    if (BeanUtil.isEmpty(exitRecord) && !now.isBefore(currentShiftEndDateTime)) {
                        exitRecord = exitRecords.stream()
                                .filter(s -> (s.getSwingTime().isAfter(currentShiftStartDateTime)
                                        && s.getSwingTime().isBefore(currentShiftEndDateTime)))
@@ -258,9 +261,13 @@
                vo.setCreateTime(recordList.get(0).getCreateTime());
                vo.setUpdateUser(recordList.get(0).getUpdateUser());
                vo.setUpdateTime(recordList.get(0).getUpdateTime());
                vo.setResult(ClockInState.ABNORMAL.getValue());
                if(ObjectUtils.allNotNull(vo.getWorkClockInState(),vo.getOffClockInState())){
                    vo.setResult(Integer.min(vo.getWorkClockInState(),vo.getOffClockInState()));
                //当前时间在下班时间过后才判断考勤结果
                if(!now.isBefore(currentShiftEndDateTime)){
                    if(ObjectUtils.allNotNull(vo.getWorkClockInState(),vo.getOffClockInState())){
                        vo.setResult(Integer.min(vo.getWorkClockInState(),vo.getOffClockInState()));
                    }else{
                        vo.setResult(ClockInState.ABNORMAL.getValue());
                    }
                }
                // è®¡ç®—缺勤时长
                if (ObjectUtils.allNotNull(vo.getActualWorkHours(), vo.getPlannedWorkHours())) {
@@ -373,7 +380,12 @@
        long pages = getPages(size,total);
        int startIndex = Math.toIntExact((current - 1) * size >= total ? (pages - 1) * size : (current - 1) * size);
        int endIndex = Math.toIntExact(Math.min(current * size, total));
        List<StaffAttendanceVO> records = resultList.subList(startIndex, endIndex);
        List<StaffAttendanceVO> records;
        if(resultList.isEmpty()){
            records = new ArrayList<>();
        }else{
            records = resultList.subList(startIndex, endIndex);
        }
        resultPage.setRecords(records);
        resultPage.setTotal(total);
        resultPage.setSize(size);
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyInspectItemConfigServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,146 @@
package com.ruoyi.inspect.service.impl;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.inspect.mapper.StaffCompetencyInspectItemConfigMapper;
import com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig;
import com.ruoyi.inspect.service.StaffCompetencyInspectItemConfigService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author 27233
* @description é’ˆå¯¹è¡¨ã€staff_competency_inspect_item_config(人员能力-检验项配置表)】的数据库操作Service实现
* @createDate 2026-03-26 17:16:51
*/
@Service
public class StaffCompetencyInspectItemConfigServiceImpl extends ServiceImpl<StaffCompetencyInspectItemConfigMapper, StaffCompetencyInspectItemConfig>
    implements StaffCompetencyInspectItemConfigService{
    @Override
    public List<StaffCompetencyInspectItemConfig> selectConfigList(StaffCompetencyInspectItemConfig config) {
        return baseMapper.selectConfigList(config);
    }
    @Override
    public StaffCompetencyInspectItemConfig selectConfigById(Long configId) {
        return baseMapper.selectConfigById(configId);
    }
    @Override
    public boolean checkItemNameUnique(StaffCompetencyInspectItemConfig config) {
        Long configId = ObjectUtils.isEmpty(config.getId()) ? -1L : config.getId();
        StaffCompetencyInspectItemConfig info = baseMapper.checkDeptNameUnique(config.getItemName(), config.getParentId());
        if (StringUtils.isNotNull(info) && info.getId().longValue() != configId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
    @Override
    public int insertConfig(StaffCompetencyInspectItemConfig config) {
        StaffCompetencyInspectItemConfig info = baseMapper.selectConfigById(config.getParentId());
        if(ObjectUtils.isEmpty(config.getParentId())){
            StaffCompetencyInspectItemConfig itemConfig = baseMapper.selectOne(Wrappers.<StaffCompetencyInspectItemConfig>lambdaQuery().orderByAsc(StaffCompetencyInspectItemConfig::getParentId).last("limit 1"));
            if(ObjectUtils.isNotEmpty(itemConfig)){
                config.setParentId(itemConfig.getParentId()-1L);
            }else{
                config.setParentId(0L);
            }
        }
        // å¦‚果父节点不为正常状态,则不允许新增子节点
        if (ObjectUtils.isNotEmpty(info) && !info.getIsEnable())
        {
            throw new ServiceException("检验项点停用,不允许新增");
        }
        if(Long.compare(config.getParentId(),0)<1){
            config.setAncestors(config.getParentId().toString());
        }else{
            config.setAncestors(info.getAncestors() + "," + config.getParentId());
        }
        return baseMapper.insertConfig(config);
    }
    @Override
    public int updateConfig(StaffCompetencyInspectItemConfig config) {
        StaffCompetencyInspectItemConfig newParentConfig = baseMapper.selectConfigById(config.getParentId());
        StaffCompetencyInspectItemConfig oldConfig = baseMapper.selectConfigById(config.getId());
        if (StringUtils.isNotNull(newParentConfig) && StringUtils.isNotNull(oldConfig))
        {
            String newAncestors = newParentConfig.getAncestors() + "," + newParentConfig.getId();
            String oldAncestors = oldConfig.getAncestors();
            config.setAncestors(newAncestors);
            updateConfigChildren(config.getId(), newAncestors, oldAncestors);
        }
        int result = baseMapper.updateConfig(config);
        if (config.getIsEnable() && Long.compare(config.getParentId(),0)==1)
        {
            // å¦‚果该检验项点是启用状态,则启用该检验项点的所有上级项点
            updateParentConfigStatusNormal(config);
        }
        return result;
    }
    /**
     * ä¿®æ”¹è¯¥æ£€éªŒé¡¹ç‚¹çš„父级项点状态
     *
     * @param config å½“前检验项点
     */
    private void updateParentConfigStatusNormal(StaffCompetencyInspectItemConfig config)
    {
        String ancestors = config.getAncestors();
        List<Long> configIds = Arrays.stream(Convert.toLongArray(ancestors)).filter(f->Long.compare(f,0)>0).collect(Collectors.toList());
        baseMapper.updateConfigStatusNormal(configIds);
    }
    /**
     * ä¿®æ”¹å­å…ƒç´ å…³ç³»
     *
     * @param configId è¢«ä¿®æ”¹çš„æ£€éªŒé¡¹ç‚¹ID
     * @param newAncestors æ–°çš„父ID集合
     * @param oldAncestors æ—§çš„父ID集合
     */
    public void updateConfigChildren(Long configId, String newAncestors, String oldAncestors)
    {
        List<StaffCompetencyInspectItemConfig> children = baseMapper.selectChildrenConfigById(configId);
        for (StaffCompetencyInspectItemConfig child : children)
        {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (!children.isEmpty())
        {
            baseMapper.updateConfigChildren(children);
        }
    }
    @Override
    public boolean hasChildByConfigId(Long configId) {
        int result = baseMapper.hasChildByConfigId(configId);
        return result > 0;
    }
    @Override
    public int deleteConfigById(Long configId) {
        return baseMapper.deleteById(configId);
    }
    @Override
    public int selectNormalChildrenConfigById(Long configId) {
        return baseMapper.selectNormalChildrenConfigById(configId);
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyLevelEvaluateRecordServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,187 @@
package com.ruoyi.inspect.service.impl;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.StaffSkillLevelType;
import com.ruoyi.common.utils.excel.EasyExcelUtils;
import com.ruoyi.common.utils.excel.FullCustomAutoWidthHandler;
import com.ruoyi.common.utils.excel.HeaderContentRowHeightHandler;
import com.ruoyi.inspect.dto.StaffCompetencyLevelEvaluateRecordDTO;
import com.ruoyi.inspect.mapper.StaffCompetencyInspectItemConfigMapper;
import com.ruoyi.inspect.mapper.StaffCompetencyLevelEvaluateRecordMapper;
import com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig;
import com.ruoyi.inspect.pojo.StaffCompetencyLevelEvaluateRecord;
import com.ruoyi.inspect.service.StaffCompetencyLevelEvaluateRecordService;
import com.ruoyi.inspect.vo.StaffConfigHeaderVO;
import com.ruoyi.inspect.vo.TestUserVO;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author 27233
* @description é’ˆå¯¹è¡¨ã€staff_competency_level_evaluate_record(人员能力等级评定表)】的数据库操作Service实现
* @createDate 2026-03-26 17:16:56
*/
@Service
public class StaffCompetencyLevelEvaluateRecordServiceImpl extends ServiceImpl<StaffCompetencyLevelEvaluateRecordMapper, StaffCompetencyLevelEvaluateRecord>
    implements StaffCompetencyLevelEvaluateRecordService{
    @Autowired
    private StaffCompetencyInspectItemConfigMapper configMapper;
    private final static Long roleId = 4L;
    /**
     * æŸ¥è¯¢æ£€æµ‹äººå‘˜åˆ—表
     * @param record
     * @return
     */
    private List<TestUserVO> getTestUserList(StaffCompetencyLevelEvaluateRecordDTO record){
        record.setRoleId(roleId);
        return baseMapper.selectTestUserList(record);
    }
    @Override
    public List<Map<String, Object>> getPageList(StaffCompetencyLevelEvaluateRecordDTO record) {
        List<Map<String, Object>> hashMaps = new ArrayList<>();
        //查询检验项点配置列表,转换为键值对
        StaffCompetencyInspectItemConfig itemConfig = new StaffCompetencyInspectItemConfig();
        itemConfig.setIsEnable(Boolean.TRUE);
        List<StaffCompetencyInspectItemConfig> configs = configMapper.selectConfigList(itemConfig);
        Map<String,Object> configMaps = transformConfigList(configs);
        //查询检测人员列表
        List<TestUserVO> testUserList = getTestUserList(record);
        List<Integer> userIds = testUserList.stream().map(TestUserVO::getUserId).collect(Collectors.toList());
        //查询人员能力考评列表
        List<StaffCompetencyLevelEvaluateRecord> recordVos = baseMapper.selectList(Wrappers.<StaffCompetencyLevelEvaluateRecord>lambdaQuery().in(!userIds.isEmpty(),StaffCompetencyLevelEvaluateRecord::getUserId,userIds));
        if(testUserList.isEmpty())return Collections.emptyList();
        testUserList.forEach(u->{
            HashMap<String, Object> map = new HashMap<>();
            map.put("userName",u.getUserName());
            map.put("userId",u.getUserId());
            map.put("account",u.getAccount());
            map.put("postName",u.getPostName());
            List<StaffCompetencyLevelEvaluateRecord> userRecords = recordVos.stream().filter(f -> Objects.equals(f.getUserId(), u.getUserId())).collect(Collectors.toList());
            map.putAll(configMaps);
            if(!userRecords.isEmpty()){
                userRecords.forEach(ur->{
                    map.put(ur.getItemConfigId().toString(),ur);
                });
            }
            hashMaps.add(map);
        });
        return hashMaps;
    }
    @Override
    public void exportRecords(HttpServletResponse response, StaffCompetencyLevelEvaluateRecordDTO recordDTO) {
        response.reset();
        try {
            //1.组装数据
            List<List<String>> dataList = new ArrayList<>();
            List<TestUserVO> testUserList = getTestUserList(recordDTO);
            List<Integer> userIds = testUserList.stream().map(TestUserVO::getUserId).collect(Collectors.toList());
            //查询人员能力考评列表
            List<StaffCompetencyLevelEvaluateRecord> recordVos = baseMapper.selectList(Wrappers.<StaffCompetencyLevelEvaluateRecord>lambdaQuery().in(!userIds.isEmpty(),StaffCompetencyLevelEvaluateRecord::getUserId,userIds));
            //查询启用的检验项点配置列表
            List<StaffConfigHeaderVO> headerVOS = configMapper.selectConfigHeader();
            for (int i = 0; i < testUserList.size(); i++) {
                TestUserVO u = testUserList.get(i);
                List<String> rowData = new ArrayList<>();
                rowData.add(String.valueOf(i+1));
                rowData.add(u.getUserName());
                rowData.add(u.getPostName());
                //过滤当前人员的能力考评记录
                List<StaffCompetencyLevelEvaluateRecord> currentUserRecords = recordVos.stream().filter(f -> ObjectUtils.equals(f.getUserId(), u.getUserId())).collect(Collectors.toList());
                headerVOS.forEach(head->{
                    StaffCompetencyLevelEvaluateRecord record = currentUserRecords.stream().filter(f -> ObjectUtils.equals(f.getItemConfigId(), head.getChildrenId())).findFirst().orElse(null);
                    if(ObjectUtils.isEmpty(record)){
                        rowData.add("");
                    }else{
                        rowData.add(StaffSkillLevelType.getIconByValue(record.getLevel()));
                    }
                });
                dataList.add(rowData);
            }
            //2.导出
            String fileName = "中天耐丝质量部检验员能力矩阵图"+ ExcelTypeEnum.XLSX;
            fileName =  URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            // é…ç½®ç‰¹æ®Šåˆ—规则:第0列最大20字符,第2列最大25字符
            Map<Integer, Integer> columnRules = new HashMap<>();
            columnRules.put(0, 15);
            columnRules.put(1, 24);
            EasyExcel.write(response.getOutputStream())
                    .head(getExportTableHeader(headerVOS))
                    .registerWriteHandler(new FullCustomAutoWidthHandler(columnRules, 15, 4))
                    .registerWriteHandler(new HeaderContentRowHeightHandler(35,20,4))
                    .registerWriteHandler(EasyExcelUtils.getStyleStrategy(IndexedColors.GREY_25_PERCENT))
                    .sheet("Sheet 1")
                    .doWrite(dataList);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    private List<List<String>> getExportTableHeader(List<StaffConfigHeaderVO> configHeaderVOList){
        List<List<String>> headerList = new ArrayList<>();
        List<String> row1 = new ArrayList<>();
        row1.add("中天耐丝质量部检验员能力矩阵图");
        row1.add("不了解:○;基本了解:●;熟练掌握:☆;精通:★");
        row1.add("序号");
        row1.add("序号");
        List<String> row2 = new ArrayList<>();
        row2.add("中天耐丝质量部检验员能力矩阵图");
        row2.add("不了解:○;基本了解:●;熟练掌握:☆;精通:★");
        row2.add("姓名");
        row2.add("姓名");
        List<String> row3 = new ArrayList<>();
        row3.add("中天耐丝质量部检验员能力矩阵图");
        row3.add("不了解:○;基本了解:●;熟练掌握:☆;精通:★");
        row3.add("岗位");
        row3.add("岗位");
        headerList.add(row1);
        headerList.add(row2);
        headerList.add(row3);
        configHeaderVOList.forEach(f->{
            List<String> configRow = new ArrayList<>();
            configRow.add("中天耐丝质量部检验员能力矩阵图");
            configRow.add("不了解:○;基本了解:●;熟练掌握:☆;精通:★");
            configRow.add(f.getItemName());
            configRow.add(f.getChildrenItemName());
            headerList.add(configRow);
        });
        return headerList;
    }
    /**
     * å°†é…ç½®åˆ—表转换从键值对
     * @param configs  é…ç½®åˆ—表
     * @return
     */
    private Map<String, Object> transformConfigList(List<StaffCompetencyInspectItemConfig> configs) {
        Map<String, Object> hashMap = new HashMap<>();
        if(!configs.isEmpty()){
            configs.stream().filter(f->f.getParentId()>0).forEach(f->hashMap.put(f.getId().toString(),new StaffCompetencyLevelEvaluateRecord()));
        }
        return hashMap;
    }
}
inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyInspectItemConfigVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.inspect.vo;
import com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class StaffCompetencyInspectItemConfigVO extends StaffCompetencyInspectItemConfig {
    /**
     * çˆ¶çº§é¡¹ç‚¹åç§°
     */
    @ApiModelProperty("父级项点名称")
    private String parentName;
}
inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyLevelEvaluateRecordVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.inspect.vo;
import com.ruoyi.inspect.pojo.StaffCompetencyLevelEvaluateRecord;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class StaffCompetencyLevelEvaluateRecordVO extends StaffCompetencyLevelEvaluateRecord {
    /**
     * äººå‘˜åç§°
     */
    @ApiModelProperty("人员名称")
    private String userName;
    /**
     * å²—位
     */
    @ApiModelProperty("岗位")
    private String postName;
}
inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffConfigHeaderVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.inspect.vo;
import lombok.Data;
@Data
public class StaffConfigHeaderVO {
    /**
     * çˆ¶é¡¹åç§°
     */
    private String itemName;
    /**
     * å­é¡¹åç§°
     */
    private String childrenItemName;
    /**
     * å­é¡¹id
     */
    private Long childrenId;
}
inspect-server/src/main/java/com/ruoyi/inspect/vo/TestUserVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.ruoyi.inspect.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class TestUserVO {
    /**
     * ç”¨æˆ·id
     */
    @ApiModelProperty("用户id")
    private Integer userId;
    /**
     * å·¥å·
     */
    @ApiModelProperty("工号")
    private String account;
    /**
     * ç”¨æˆ·åç§°
     */
    @ApiModelProperty("用户名称")
    private String userName;
    /**
     * å²—位名称
     */
    @ApiModelProperty("岗位名称")
    private String postName;
}
inspect-server/src/main/resources/mapper/StaffCompetencyInspectItemConfigMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,133 @@
<?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.inspect.mapper.StaffCompetencyInspectItemConfigMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="parentId" column="parent_id" jdbcType="BIGINT"/>
            <result property="ancestors" column="ancestors" jdbcType="VARCHAR"/>
            <result property="itemName" column="item_name" jdbcType="VARCHAR"/>
            <result property="sort" column="sort" jdbcType="INTEGER"/>
            <result property="isEnable" column="is_enable" jdbcType="BIT"/>
            <result property="createUser" column="create_user" jdbcType="INTEGER"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateUser" column="update_user" jdbcType="INTEGER"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,parent_id,ancestors,item_name,
        sort,is_enable,create_user,
        create_time,update_user,update_time
    </sql>
    <sql id="selectConfigVo">
        select id,parent_id,ancestors,item_name,
               sort,is_enable,create_user,
               create_time,update_user,update_time
        from staff_competency_inspect_item_config
    </sql>
    <insert id="insertConfig">
        insert into staff_competency_inspect_item_config(
        <if test="config.parentId != null and config.parentId != 0">parent_id,</if>
        <if test="config.ancestors != null and config.ancestors != ''">ancestors,</if>
        <if test="config.itemName != null and config.itemName != ''">item_name,</if>
        <if test="config.sort != null">sort,</if>
        <if test="config.isEnable != null">is_enable</if>
        )values(
        <if test="config.parentId != null and config.parentId != 0">#{config.parentId},</if>
        <if test="config.ancestors != null and config.ancestors != ''">#{config.ancestors},</if>
        <if test="config.itemName != null and config.itemName != ''">#{config.itemName},</if>
        <if test="config.sort != null">#{config.sort},</if>
        <if test="config.isEnable != null">#{config.isEnable}</if>
        )
    </insert>
    <update id="updateConfig">
        update staff_competency_inspect_item_config
        <set>
            <if test="config.parentId != null and config.parentId != 0">parent_id = #{config.parentId},</if>
            <if test="config.itemName != null and config.itemName != ''">item_name = #{config.itemName},</if>
            <if test="config.ancestors != null and config.ancestors != ''">ancestors = #{config.ancestors},</if>
            <if test="config.sort != null">sort = #{config.sort},</if>
            <if test="config.isEnable != null">is_enable = #{config.isEnable}</if>
        </set>
        where id = #{config.id}
    </update>
    <update id="updateConfigStatusNormal">
        update staff_competency_inspect_item_config set is_enable = 1 where id in
        <foreach collection="configIds" item="configId" open="(" separator="," close=")">
            #{configId}
        </foreach>
    </update>
    <update id="updateConfigChildren">
        update staff_competency_inspect_item_config set ancestors =
        <foreach collection="children" item="item" index="index"
                 separator=" " open="case dept_id" close="end">
            when #{item.id} then #{item.ancestors}
        </foreach>
        where id in
        <foreach collection="children" item="item" index="index"
                 separator="," open="(" close=")">
            #{item.id}
        </foreach>
    </update>
    <select id="selectConfigList" resultType="com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig">
        <include refid="selectConfigVo"/>
        where 1 = 1
        <if test="config.id != null and config.id != 0">
            AND id = #{config.id}
        </if>
        <if test="config.parentId != null and config.parentId != 0">
            AND parent_id = #{config.parentId}
        </if>
        <if test="config.itemName != null and config.itemName != ''">
            AND item_name like concat('%', #{config.itemName}, '%')
        </if>
        <if test="config.isEnable != null">
            AND is_enable = #{config.isEnable}
        </if>
        order by sort
    </select>
    <select id="selectConfigById" resultType="com.ruoyi.inspect.vo.StaffCompetencyInspectItemConfigVO">
        select <include refid="Base_Column_List"/>,
               (select item_name from staff_competency_inspect_item_config where id = parent_id) parent_name
        from staff_competency_inspect_item_config
        where id = #{configId}
    </select>
    <select id="checkDeptNameUnique" resultType="com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig">
        <include refid="selectConfigVo"/>
        where item_name=#{itemName}
        <choose>
            <when test="parentId!=null and parentId!=''">
                and parent_id = #{parentId}
            </when>
            <when test="parentId==null or parentId==''">
                and parent_id &lt;= 0
            </when>
        </choose>
        limit 1
    </select>
    <select id="selectChildrenConfigById" resultType="com.ruoyi.inspect.pojo.StaffCompetencyInspectItemConfig">
        select * from staff_competency_inspect_item_config where find_in_set(#{configId}, ancestors)
    </select>
    <select id="hasChildByConfigId" resultType="java.lang.Integer">
        select count(1) from staff_competency_inspect_item_config
        where parent_id = #{configId} limit 1
    </select>
    <select id="selectNormalChildrenConfigById" resultType="java.lang.Integer">
        select count(*) from staff_competency_inspect_item_config where is_enable = 1  and find_in_set(#{configId}, ancestors)
    </select>
    <select id="selectConfigHeader" resultType="com.ruoyi.inspect.vo.StaffConfigHeaderVO">
        select
            c2.item_name AS item_name,
            c1.item_name AS children_item_name,
            c1.id AS children_id
        from staff_competency_inspect_item_config c1 left join staff_competency_inspect_item_config c2 on c1.parent_id=c2.id
        where c1.is_enable=1
          and c2.id is not null
        order by c1.parent_id,c1.sort
    </select>
</mapper>
inspect-server/src/main/resources/mapper/StaffCompetencyLevelEvaluateRecordMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
<?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.inspect.mapper.StaffCompetencyLevelEvaluateRecordMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.inspect.pojo.StaffCompetencyLevelEvaluateRecord">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="userId" column="user_id" jdbcType="INTEGER"/>
            <result property="itemConfigId" column="item_config_id" jdbcType="BIGINT"/>
            <result property="level" column="level" jdbcType="VARCHAR"/>
            <result property="createUser" column="create_user" jdbcType="INTEGER"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateUser" column="update_user" jdbcType="INTEGER"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,user_id,item_config_id,
        level,create_user,create_time,
        update_user,update_time
    </sql>
    <select id="selectCompetencyLevelEvaluateRecord" resultType="com.ruoyi.inspect.vo.StaffCompetencyLevelEvaluateRecordVO">
    </select>
    <select id="selectTestUserList" resultType="com.ruoyi.inspect.vo.TestUserVO">
        select
            u.id AS user_id,
            u.account AS account,
            u.name AS user_name,
            sp.post_name
        from sys_user_role sur
            left join user u on sur.user_id=u.id
            left join sys_user_post sup on u.id = sup.user_id
            left join sys_post sp on sp.post_id = sup.post_id
        where u.status=0
          and u.del_flag=0
          and sur.role_id=#{dto.roleId}
          <if test="dto.postName!=null and dto.postName!=''">
              AND sp.post_name = #{dto.postName}
          </if>
          <if test="dto.keyword!=null and dto.keyword!=''">
              AND (u.name like concat('%',#{dto.keyword},'%') or u.account like concat('%',#{dto.keyword},'%'))
          </if>
    </select>
</mapper>
ruoyi-common/src/main/java/com/ruoyi/common/enums/StaffSkillLevelType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.common.enums;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
@Getter
public enum StaffSkillLevelType {
    NOTHING("不了解","01nothing","○"),
    BASIC("基本了解","02basic","●"),
    SKILLED("熟练掌握","03skilled","☆"),
    MASTER("精通","master","★");
    private String desc,value,icon;
    StaffSkillLevelType(String desc, String value, String icon) {
        this.desc = desc;
        this.value = value;
        this.icon = icon;
    }
    public static String getIconByValue(String value){
        for (StaffSkillLevelType skillLevelType : StaffSkillLevelType.values()) {
            if(StringUtils.equals(skillLevelType.value, value)){
                return skillLevelType.icon;
            }
        }
        return "";
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/EasyExcelUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,311 @@
package com.ruoyi.common.utils.excel;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
/**
*@author: Zou, Yu
*@description:
*@date: 2023/9/24 0024 13:18
**/
public class EasyExcelUtils {
    /**
     * color枚举: IndexedColors
     * @param color
     * @return
     */
    public static HorizontalCellStyleStrategy getStyleStrategy(IndexedColors color) {
        // å¤´çš„ç­–ç•¥
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // èƒŒæ™¯è®¾ç½®ä¸ºç°è‰²
        headWriteCellStyle.setFillForegroundColor(color.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 14);
        // å­—体样式
        headWriteFont.setFontName("宋体");
        headWriteCellStyle.setWriteFont(headWriteFont);
        // è‡ªåŠ¨æ¢è¡Œ
        headWriteCellStyle.setWrapped(false);
        // æ°´å¹³å¯¹é½æ–¹å¼
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // åž‚直对齐方式
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // å†…容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // è¿™é‡Œéœ€è¦æŒ‡å®š FillPatternType ä¸ºFillPatternType.SOLID_FOREGROUND ä¸ç„¶æ— æ³•显示背景颜色.头默认了 FillPatternType所以可以不指定
//        contentWriteCellStyle.setFillPatternType(FillPatternType.SQUARES);
        // èƒŒæ™¯ç™½è‰²
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // å­—体大小
        contentWriteFont.setFontHeightInPoints((short) 12);
        // å­—体样式
        contentWriteFont.setFontName("宋体");
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // å†…容居中对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //内容垂直居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //边框设置
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        // è¿™ä¸ªç­–略是 å¤´æ˜¯å¤´çš„æ ·å¼ å†…容是内容的样式 å…¶ä»–的策略可以自己实现
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }
    public static HorizontalCellStyleStrategy getStyleFixedStrategy() {
        // å¤´çš„ç­–ç•¥
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // èƒŒæ™¯è®¾ç½®ä¸ºç°è‰²
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 14);
        // å­—体样式
        headWriteFont.setFontName("Calibri");
        headWriteCellStyle.setWriteFont(headWriteFont);
        // è‡ªåŠ¨æ¢è¡Œ
        headWriteCellStyle.setWrapped(false);
        // æ°´å¹³å¯¹é½æ–¹å¼
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // åž‚直对齐方式
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // å†…容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // è¿™é‡Œéœ€è¦æŒ‡å®š FillPatternType ä¸ºFillPatternType.SOLID_FOREGROUND ä¸ç„¶æ— æ³•显示背景颜色.头默认了 FillPatternType所以可以不指定
//        contentWriteCellStyle.setFillPatternType(FillPatternType.SQUARES);
        // èƒŒæ™¯ç™½è‰²
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // å­—体大小
        contentWriteFont.setFontHeightInPoints((short) 12);
        // å­—体样式
        contentWriteFont.setFontName("Calibri");
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // å†…容左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        // è¿™ä¸ªç­–略是 å¤´æ˜¯å¤´çš„æ ·å¼ å†…容是内容的样式 å…¶ä»–的策略可以自己实现
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }
    public static HorizontalCellStyleStrategy getArveStyleStrategy() {
        // å¤´çš„ç­–ç•¥
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // èƒŒæ™¯è®¾ç½®ä¸º
        headWriteCellStyle.setFillForegroundColor(IndexedColors.BLACK.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12);
        // å­—体样式
        headWriteFont.setFontName("Calibri");
        headWriteFont.setColor(IndexedColors.WHITE.getIndex());
        headWriteCellStyle.setWriteFont(headWriteFont);
        headWriteCellStyle.setBorderBottom(BorderStyle.MEDIUM);
        headWriteCellStyle.setLeftBorderColor(IndexedColors.WHITE.getIndex());
        headWriteCellStyle.setRightBorderColor(IndexedColors.WHITE.getIndex());
        // è‡ªåŠ¨æ¢è¡Œ
        headWriteCellStyle.setWrapped(true);
        // æ°´å¹³å¯¹é½æ–¹å¼
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        // åž‚直对齐方式
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // å†…容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // è¿™é‡Œéœ€è¦æŒ‡å®š FillPatternType ä¸ºFillPatternType.SOLID_FOREGROUND ä¸ç„¶æ— æ³•显示背景颜色.头默认了 FillPatternType所以可以不指定
//        contentWriteCellStyle.setFillPatternType(FillPatternType.SQUARES);
        // èƒŒæ™¯ç™½è‰²
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // å­—体大小
        contentWriteFont.setFontHeightInPoints((short) 10);
        // å­—体样式
        contentWriteFont.setFontName("Calibri");
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // è¿™ä¸ªç­–略是 å¤´æ˜¯å¤´çš„æ ·å¼ å†…容是内容的样式 å…¶ä»–的策略可以自己实现
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }
    /**
     * è®¾ç½®response
     * @param response
     * @param targetName
     * @return
     */
    public static OutputStream getResponse(HttpServletResponse response, String targetName) throws IOException {
        String fileName;
        try {
            fileName = String.valueOf(new StringBuilder()
                    .append(targetName)
                    .append("_")
                    .append(DateUtil.today())
                    .append(ExcelTypeEnum.XLSX.getValue()));
            fileName =  URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            return response.getOutputStream();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * æ›¿æ¢æ¨¡æ¿æ ‡è®°
     *
     * @param export     å¯¼å‡ºæ–‡ä»¶å¯¹è±¡
     * @param index      sheet序号
     * @param rows       å•元格行序
     * @param columns    å•元格列序
     * @param replaceMap å¤šä¸ªæ ‡è®°é›†åˆ
     */
    public static void editModelWorkBook(File export, Integer index, Integer rows, Integer columns, Map<String, String> replaceMap) {
        try {
            XSSFWorkbook workBook = new XSSFWorkbook(export);
//            editModelWorkBook(workBook,index,0,0,replaceMap);
            editModelWorkBook(workBook, index, rows, columns, replaceMap);
            workBook.close();
        } catch (IOException | InvalidFormatException e) {
            e.printStackTrace();
        }
    }
    /**
     * æ›¿æ¢æ¨¡æ¿æ ‡è®°
     *
     * @param workBook   excel工作册对象
     * @param index      sheet序号
     * @param rows       å•元格行序
     * @param columns    å•元格列序
     * @param replaceMap å¤šä¸ªæ ‡è®°é›†åˆ
     */
    public static void editModelWorkBook(XSSFWorkbook workBook, Integer index, Integer rows, Integer columns, Map<String, String> replaceMap) {
        XSSFSheet sheet = workBook.getSheetAt(index);
        Row row = sheet.getRow(rows);
        Cell cell = row.getCell(columns);
        String replaceString = cell.toString();
        for (Map.Entry<String, String> entry : replaceMap.entrySet()) {
            replaceString = replaceString.replace(entry.getKey(), entry.getValue());
        }
        cell.setCellValue(replaceString);
        workBook.setSheetName(index, replaceString.replace(":", ""));
    }
    /**
     * æ¨¡æ¿sheet克隆及命名
     *
     * @param temp           ä¸´æ—¶æ–‡ä»¶å¯¹è±¡
     * @param export         å¯¼å‡ºæ–‡ä»¶å¯¹è±¡
     * @param cloneSheetNo   å…‹éš†sheet序列
     * @param rows           å•元格行序
     * @param columns        å•元格列序
     * @param replaceMapList å¤šä¸ªæ ‡è®°é›†åˆ
     */
    public static void writeModelCloneSheet(File temp, File export, Integer cloneSheetNo, Integer rows, Integer columns, List<Map<String, String>> replaceMapList) {
        try {
            XSSFWorkbook workBook = new XSSFWorkbook(temp);
            OutputStream outputStream = new FileOutputStream(export);
            /** å¦‚果你需要6份相同模板的sheet é‚£ä¹ˆä½ åªéœ€è¦å…‹éš†5份即可*/
            for (int index = 0; index < replaceMapList.size() - 1; index++) {
                /** å…‹éš†æ¨¡æ¿æ–‡ä»¶ */
                XSSFSheet sheet = workBook.cloneSheet(cloneSheetNo);
            }
            for (int index = 0; index < replaceMapList.size(); index++) {
                editModelWorkBook(workBook, index, rows, columns, replaceMapList.get(index));
            }
            workBook.write(outputStream);
            outputStream.flush();
            outputStream.close();
            workBook.close();
        } catch (IOException | InvalidFormatException e) {
            e.printStackTrace();
        }
    }
    /**
     * ä¸´æ—¶æ–‡ä»¶å†™å…¥å¯¼å‡ºæ–‡ä»¶
     *
     * @param temp    ä¸´æ—¶æ–‡ä»¶å¯¹è±¡
     * @param export  å¯¼å‡ºæ–‡ä»¶å¯¹è±¡
     * @param index   sheet序号
     * @param rows    å•元格行序
     * @param columns å•元格列序
     * @param isTime  æ˜¯å¦æœ‰æ—¶é—´æ ‡è®°
     */
    public static void writeModelWorkBook(File temp, File export, Integer index, Integer rows, Integer columns, Boolean isTime) {
        try {
            XSSFWorkbook workBook = new XSSFWorkbook(temp);
            OutputStream outputStream = new FileOutputStream(export);
            if (isTime) {
                writeModelWorkBook(workBook, index, rows, columns);
            }
            workBook.write(outputStream);
            outputStream.flush();
            outputStream.close();
            workBook.close();
        } catch (IOException | InvalidFormatException e) {
            e.printStackTrace();
        }
    }
    /**
     * æ›¿æ¢æ—¶é—´æ ‡è®°ï¼ˆyear,month,day)
     *
     * @param workBook excel工作册对象
     * @param index    sheet序号
     * @param rows     å•元格行序
     * @param columns  å•元格列序
     */
    public static void writeModelWorkBook(XSSFWorkbook workBook, Integer index, Integer rows, Integer columns) {
        XSSFSheet xssfSheet = workBook.getSheetAt(index);
        Row row = xssfSheet.getRow(rows);
        Cell cell = row.getCell(columns);
        String cellString = cell.toString();
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        String yearString = cellString.replace("year", String.valueOf(year));
        String monthString = yearString.replace("month", String.valueOf(month));
        String dayString = monthString.replace("day", String.valueOf(day));
        cell.setCellValue(dayString);
    }
    /**
     * é’ˆå¯¹UserModel导出方法
     *
     * @param temp
     * @param export
     * @param isTime
     */
    public static void writeModelWorkBook(File temp, File export, Boolean isTime) {
        writeModelWorkBook(temp, export, 0, 1, 9, isTime);
    }
    public static void writeModelCloneSheet(File temp, File export, List<Map<String, String>> replaceMapList) {
        writeModelCloneSheet(temp, export, 0, 0, 0, replaceMapList);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/FullCustomAutoWidthHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
package com.ruoyi.common.utils.excel;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * å®Œå…¨è‡ªå®šä¹‰è‡ªé€‚应列宽处理器
 */
public class FullCustomAutoWidthHandler implements CellWriteHandler {
    // å­˜å‚¨æ¯åˆ—最大宽度(字符)
    private final Map<Integer, Integer> columnMaxWidth = new HashMap<>();
    // é…ç½®æ¯åˆ—的特殊规则(如第0列最大宽度20)
    private final Map<Integer, Integer> columnMaxWidthRules;
    private final int defaultMaxWidth;
    private final int defaultMinWidth;
    public FullCustomAutoWidthHandler() {
        this(new HashMap<>(), 30, 8);
    }
    public FullCustomAutoWidthHandler(Map<Integer, Integer> columnMaxWidthRules,
                                     int defaultMaxWidth, int defaultMinWidth) {
        this.columnMaxWidthRules = columnMaxWidthRules;
        this.defaultMaxWidth = defaultMaxWidth;
        this.defaultMinWidth = defaultMinWidth;
    }
    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        int columnIndex = cell.getColumnIndex();
        String cellValue = cell.getStringCellValue();
        int contentWidth = calculateStringWidth(cellValue);
        // æ›´æ–°æœ€å¤§å®½åº¦
        columnMaxWidth.put(columnIndex,
                Math.max(columnMaxWidth.getOrDefault(columnIndex, 0), contentWidth));
        // æ‰€æœ‰æ•°æ®å†™å…¥å®ŒæˆåŽè®¾ç½®åˆ—宽(最后一行处理时)
        Sheet sheet = writeSheetHolder.getSheet();
        if (cell.getRowIndex() == sheet.getLastRowNum()) {
            int finalWidth = columnMaxWidth.get(columnIndex);
            // åº”用特殊规则或默认规则
            int maxWidth = columnMaxWidthRules.getOrDefault(columnIndex, defaultMaxWidth);
            finalWidth = Math.min(finalWidth, maxWidth);
            finalWidth = Math.max(finalWidth, defaultMinWidth);
            sheet.setColumnWidth(columnIndex, finalWidth * 256);
        }
    }
    /**
     * è®¡ç®—字符串显示宽度(中文算2字符,英文/数字算1字符)
     */
    private int calculateStringWidth(String value) {
        if (value == null || value.isEmpty()) return 0;
        int width = 0;
        for (char c : value.toCharArray()) {
            width += (c > 255) ? 2 : 1; // ä¸­æ–‡å 2字符,英文占1字符
        }
        return width + 2; // é¢å¤–加2字符的边距,避免内容溢出
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/HeaderContentRowHeightHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package com.ruoyi.common.utils.excel;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Row;
/**
 * è¡¨å¤´ã€å†…容行 è‡ªå®šä¹‰ä¸åŒè¡Œé«˜
 */
public class HeaderContentRowHeightHandler implements RowWriteHandler {
    private final float headerHeight; // è¡¨å¤´è¡Œé«˜ï¼ˆç£…)
    private final float contentHeight; // å†…容行高(磅)
    private final int headerRowCount; // è¡¨å¤´è¡Œæ•°ï¼ˆå±‚级数)
    /**
     * @param headerHeight è¡¨å¤´è¡Œé«˜
     * @param contentHeight å†…容行高
     * @param headerRowCount è¡¨å¤´è¡Œæ•°ï¼ˆåŠ¨æ€è¡¨å¤´çš„å±‚çº§æ•°ï¼‰
     */
    public HeaderContentRowHeightHandler(float headerHeight, float contentHeight, int headerRowCount) {
        this.headerHeight = headerHeight;
        this.contentHeight = contentHeight;
        this.headerRowCount = headerRowCount;
    }
    @Override
    public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer rowIndex, Boolean isHead) {
        // åˆ¤æ–­ï¼šè¡Œç´¢å¼• < è¡¨å¤´è¡Œæ•° â†’ è¡¨å¤´è¡Œ
        if (rowIndex < headerRowCount) {
            row.setHeight((short) (headerHeight * 20));
        } else {
            row.setHeight((short) (contentHeight * 20));
        }
    }
}
ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml
@@ -39,6 +39,7 @@
    <select id="selectPostAll" resultMap="SysPostResult">
        <include refid="selectPostVo"/>
        WHERE status = 0
    </select>
    <select id="selectPostById" parameterType="Long" resultMap="SysPostResult">