From 2ea3b36a810adcb639f4d3c72c860f722f601927 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期一, 30 三月 2026 16:17:29 +0800
Subject: [PATCH] 绩效管理:人员能力功能模块

---
 inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyInspectItemConfig.java                      |   74 ++
 inspect-server/src/main/java/com/ruoyi/inspect/vo/TestUserVO.java                                              |   33 +
 inspect-server/src/main/java/com/ruoyi/inspect/service/StaffAttendanceTrackingRecordService.java               |    2 
 inspect-server/src/main/resources/mapper/StaffCompetencyLevelEvaluateRecordMapper.xml                          |   46 +
 ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/EasyExcelUtils.java                                    |  311 +++++++++++
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyLevelEvaluateRecordServiceImpl.java |  187 +++++++
 inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyInspectItemConfigController.java      |  114 ++++
 inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyInspectItemConfigService.java            |   30 +
 inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyLevelEvaluateRecordService.java          |   21 
 ruoyi-common/src/main/java/com/ruoyi/common/enums/StaffSkillLevelType.java                                     |   32 +
 ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/FullCustomAutoWidthHandler.java                        |   72 ++
 inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyLevelEvaluateRecord.java                    |   64 ++
 inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyInspectItemConfigVO.java                      |   16 
 inspect-server/src/main/java/com/ruoyi/inspect/dto/StaffCompetencyLevelEvaluateRecordDTO.java                  |   28 +
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyInspectItemConfigServiceImpl.java   |  146 +++++
 ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml                                                |    1 
 inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyLevelEvaluateRecordMapper.java            |   31 +
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java      |   22 
 inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyLevelEvaluateRecordVO.java                    |   22 
 inspect-server/src/main/resources/mapper/StaffCompetencyInspectItemConfigMapper.xml                            |  133 +++++
 inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyInspectItemConfigMapper.java              |   46 +
 ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/HeaderContentRowHeightHandler.java                     |   36 +
 inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyLevelEvaluateRecordController.java    |   51 +
 inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffConfigHeaderVO.java                                     |   23 
 24 files changed, 1,535 insertions(+), 6 deletions(-)

diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyInspectItemConfigController.java b/inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyInspectItemConfigController.java
new file mode 100644
index 0000000..b8d1cab
--- /dev/null
+++ b/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));
+    }
+
+
+
+}
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyLevelEvaluateRecordController.java b/inspect-server/src/main/java/com/ruoyi/inspect/controller/StaffCompetencyLevelEvaluateRecordController.java
new file mode 100644
index 0000000..cc82bb9
--- /dev/null
+++ b/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);
+    }
+
+}
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/dto/StaffCompetencyLevelEvaluateRecordDTO.java b/inspect-server/src/main/java/com/ruoyi/inspect/dto/StaffCompetencyLevelEvaluateRecordDTO.java
new file mode 100644
index 0000000..63d2b22
--- /dev/null
+++ b/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;
+
+}
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyInspectItemConfigMapper.java b/inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyInspectItemConfigMapper.java
new file mode 100644
index 0000000..8c3ff96
--- /dev/null
+++ b/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 閽堝琛ㄣ�恠taff_competency_inspect_item_config(浜哄憳鑳藉姏-妫�楠岄」閰嶇疆琛�)銆戠殑鏁版嵁搴撴搷浣淢apper
+* @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();
+}
+
+
+
+
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyLevelEvaluateRecordMapper.java b/inspect-server/src/main/java/com/ruoyi/inspect/mapper/StaffCompetencyLevelEvaluateRecordMapper.java
new file mode 100644
index 0000000..aded2f0
--- /dev/null
+++ b/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 閽堝琛ㄣ�恠taff_competency_level_evaluate_record(浜哄憳鑳藉姏绛夌骇璇勫畾琛�)銆戠殑鏁版嵁搴撴搷浣淢apper
+* @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);
+
+}
+
+
+
+
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyInspectItemConfig.java b/inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyInspectItemConfig.java
new file mode 100644
index 0000000..9aab1f3
--- /dev/null
+++ b/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;
+}
\ No newline at end of file
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyLevelEvaluateRecord.java b/inspect-server/src/main/java/com/ruoyi/inspect/pojo/StaffCompetencyLevelEvaluateRecord.java
new file mode 100644
index 0000000..6a96b39
--- /dev/null
+++ b/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;
+}
\ No newline at end of file
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/StaffAttendanceTrackingRecordService.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/StaffAttendanceTrackingRecordService.java
index f0476ff..6d7a9cf 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/service/StaffAttendanceTrackingRecordService.java
+++ b/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);
+
 }
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyInspectItemConfigService.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyInspectItemConfigService.java
new file mode 100644
index 0000000..fb9b4ab
--- /dev/null
+++ b/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 閽堝琛ㄣ�恠taff_competency_inspect_item_config(浜哄憳鑳藉姏-妫�楠岄」閰嶇疆琛�)銆戠殑鏁版嵁搴撴搷浣淪ervice
+* @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);
+}
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyLevelEvaluateRecordService.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/StaffCompetencyLevelEvaluateRecordService.java
new file mode 100644
index 0000000..a65125c
--- /dev/null
+++ b/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 閽堝琛ㄣ�恠taff_competency_level_evaluate_record(浜哄憳鑳藉姏绛夌骇璇勫畾琛�)銆戠殑鏁版嵁搴撴搷浣淪ervice
+* @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);
+}
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
index 104239e..99d2aaf 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffAttendanceTrackingRecordServiceImpl.java
+++ b/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 @@
                  * 姝e父锛氬綋鍓嶇彮娆$粨鏉熷悗绗竴娆″嚭闂ㄦ椂闂�
                  * 寮傚父(鏃╅��)锛氭棤褰撳墠鐝缁撴潫鍒颁笅涓�鐝寮�濮嬪墠鐨勫嚭闂ㄨ褰曞苟涓旀渶鍚庝竴娆″嚭闂ㄥ湪褰撳墠鐝鏃堕棿鑼冨洿鍐咃紝鍙栧綋鍓嶇彮娆℃渶鍚庝竴娆″嚭闂ㄦ椂闂�
                  */
+                //褰撳墠鏃堕棿
+                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);
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyInspectItemConfigServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyInspectItemConfigServiceImpl.java
new file mode 100644
index 0000000..77d0028
--- /dev/null
+++ b/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 閽堝琛ㄣ�恠taff_competency_inspect_item_config(浜哄憳鑳藉姏-妫�楠岄」閰嶇疆琛�)銆戠殑鏁版嵁搴撴搷浣淪ervice瀹炵幇
+* @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 琚慨鏀圭殑妫�楠岄」鐐笽D
+     * @param newAncestors 鏂扮殑鐖禝D闆嗗悎
+     * @param oldAncestors 鏃х殑鐖禝D闆嗗悎
+     */
+    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);
+    }
+}
+
+
+
+
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyLevelEvaluateRecordServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/StaffCompetencyLevelEvaluateRecordServiceImpl.java
new file mode 100644
index 0000000..da24625
--- /dev/null
+++ b/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 閽堝琛ㄣ�恠taff_competency_level_evaluate_record(浜哄憳鑳藉姏绛夌骇璇勫畾琛�)銆戠殑鏁版嵁搴撴搷浣淪ervice瀹炵幇
+* @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;
+    }
+}
+
+
+
+
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyInspectItemConfigVO.java b/inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyInspectItemConfigVO.java
new file mode 100644
index 0000000..b4afea0
--- /dev/null
+++ b/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;
+
+}
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyLevelEvaluateRecordVO.java b/inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffCompetencyLevelEvaluateRecordVO.java
new file mode 100644
index 0000000..30dcbd2
--- /dev/null
+++ b/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;
+
+}
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffConfigHeaderVO.java b/inspect-server/src/main/java/com/ruoyi/inspect/vo/StaffConfigHeaderVO.java
new file mode 100644
index 0000000..a4d5098
--- /dev/null
+++ b/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;
+
+}
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/vo/TestUserVO.java b/inspect-server/src/main/java/com/ruoyi/inspect/vo/TestUserVO.java
new file mode 100644
index 0000000..85b4166
--- /dev/null
+++ b/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;
+
+}
diff --git a/inspect-server/src/main/resources/mapper/StaffCompetencyInspectItemConfigMapper.xml b/inspect-server/src/main/resources/mapper/StaffCompetencyInspectItemConfigMapper.xml
new file mode 100644
index 0000000..fa8242f
--- /dev/null
+++ b/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>
diff --git a/inspect-server/src/main/resources/mapper/StaffCompetencyLevelEvaluateRecordMapper.xml b/inspect-server/src/main/resources/mapper/StaffCompetencyLevelEvaluateRecordMapper.xml
new file mode 100644
index 0000000..b2eb5c0
--- /dev/null
+++ b/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>
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/StaffSkillLevelType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/StaffSkillLevelType.java
new file mode 100644
index 0000000..c605d66
--- /dev/null
+++ b/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 "";
+    }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/EasyExcelUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/EasyExcelUtils.java
new file mode 100644
index 0000000..6edc7ae
--- /dev/null
+++ b/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 涓篎illPatternType.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 涓篎illPatternType.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 涓篎illPatternType.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 閭d箞浣犲彧闇�瑕佸厠闅�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();
+        }
+    }
+
+    /**
+     * 鏇挎崲鏃堕棿鏍囪锛坹ear,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);
+    }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/FullCustomAutoWidthHandler.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/FullCustomAutoWidthHandler.java
new file mode 100644
index 0000000..77d23a5
--- /dev/null
+++ b/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瀛楃鐨勮竟璺濓紝閬垮厤鍐呭婧㈠嚭
+    }
+}
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/HeaderContentRowHeightHandler.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/excel/HeaderContentRowHeightHandler.java
new file mode 100644
index 0000000..0167f95
--- /dev/null
+++ b/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));
+        }
+    }
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml
index 085827b..b047ee5 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml
+++ b/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">

--
Gitblit v1.9.3