maven
20 小时以前 61b1802b1b26fc35c07fd09edc4ff2ff8ade6688
Merge remote-tracking branch 'origin/dev_New' into dev_New
已添加23个文件
已修改5个文件
1168 ■■■■■ 文件已修改
src/main/java/com/ruoyi/ScheduleTask.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeAccidentController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeTrainingController.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeTrainingDetailsController.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeTrainingFileController.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/dto/SafeTrainingDetailsDto.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/dto/SafeTrainingDto.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/mapper/SafeTrainingDetailsMapper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/mapper/SafeTrainingFileMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/mapper/SafeTrainingMapper.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/pojo/SafeTraining.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/pojo/SafeTrainingDetails.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/pojo/SafeTrainingFile.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/SafeTrainingDetailsService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/SafeTrainingFileService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/SafeTrainingService.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeHiddenServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingDetailsServiceImpl.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingFileServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingServiceImpl.java 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeAccidentMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeTrainingDetailsMapper.xml 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeTrainingFileMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeTrainingMapper.xml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/safe-training-details.docx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/safe-training.docx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/ScheduleTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.ruoyi;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.project.system.domain.SysNotice;
import com.ruoyi.project.system.mapper.SysNoticeMapper;
import com.ruoyi.safe.mapper.SafeTrainingMapper;
import com.ruoyi.safe.pojo.SafeTraining;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@Component
//定时任务汇总
public class ScheduleTask {
    @Autowired
    private SafeTrainingMapper safeTrainingMapper;
    @Autowired
    private SysNoticeMapper noticeMapper;
    //定时任务(15分钟执行一次--判断培训计划数据,状态做变更)
    @Scheduled(cron = "0 0/15 * * * ?")
    public void testScheduleTask() {
        List<SafeTraining> safeTrainings = safeTrainingMapper.selectList(Wrappers.<SafeTraining>lambdaQuery().ne(SafeTraining::getState, 2));
        if (safeTrainings.size() > 0) {
            for (SafeTraining safeTraining : safeTrainings) {
                //根据时间判断培训状态
                String trainingDate = safeTraining.getTrainingDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                LocalDateTime openingTime = LocalDateTime.parse((trainingDate + safeTraining.getOpeningTime()), DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));
                LocalDateTime endTime = LocalDateTime.parse((trainingDate + safeTraining.getEndTime()), DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));
                if (LocalDateTime.now().isBefore(openingTime)) {
                    //未开始
                    safeTraining.setState(0);
                } else if (LocalDateTime.now().isAfter(endTime)) {
                    //已结束
                    safeTraining.setState(2);
                } else {
                    //进行中
                    safeTraining.setState(1);
                }
                safeTrainingMapper.updateById(safeTraining);
            }
        }
    }
    //已读数据做一个定时任务(每月1号1点清理一次上个月已读数据)
    @Scheduled(cron = "0 0 1 1 * ?")
    public void cleanReadData() {
        noticeMapper.delete(Wrappers.<SysNotice>lambdaQuery()
                .eq(SysNotice::getStatus,"1")
                .lt(SysNotice::getCreateTime, LocalDateTime.now()));
    }
}
src/main/java/com/ruoyi/project/system/mapper/SysDeptMapper.java
@@ -1,19 +1,22 @@
package com.ruoyi.project.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.project.system.domain.SysDept;
/**
 * éƒ¨é—¨ç®¡ç† æ•°æ®å±‚
 *
 *
 * @author ruoyi
 */
@Mapper
public interface SysDeptMapper
{
    /**
     * æŸ¥è¯¢éƒ¨é—¨ç®¡ç†æ•°æ®
     *
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return éƒ¨é—¨ä¿¡æ¯é›†åˆ
     */
@@ -21,7 +24,7 @@
    /**
     * æ ¹æ®è§’色ID查询部门树信息
     *
     *
     * @param roleId è§’色ID
     * @param deptCheckStrictly éƒ¨é—¨æ ‘选择项是否关联显示
     * @return é€‰ä¸­éƒ¨é—¨åˆ—表
@@ -30,7 +33,7 @@
    /**
     * æ ¹æ®éƒ¨é—¨ID查询信息
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return éƒ¨é—¨ä¿¡æ¯
     */
@@ -38,7 +41,7 @@
    /**
     * æ ¹æ®ID查询所有子部门
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return éƒ¨é—¨åˆ—表
     */
@@ -46,7 +49,7 @@
    /**
     * æ ¹æ®ID查询所有子部门(正常状态)
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return å­éƒ¨é—¨æ•°
     */
@@ -54,7 +57,7 @@
    /**
     * æ˜¯å¦å­˜åœ¨å­èŠ‚ç‚¹
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
@@ -62,7 +65,7 @@
    /**
     * æŸ¥è¯¢éƒ¨é—¨æ˜¯å¦å­˜åœ¨ç”¨æˆ·
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
@@ -70,7 +73,7 @@
    /**
     * æ ¡éªŒéƒ¨é—¨åç§°æ˜¯å¦å”¯ä¸€
     *
     *
     * @param deptName éƒ¨é—¨åç§°
     * @param parentId çˆ¶éƒ¨é—¨ID
     * @return ç»“æžœ
@@ -79,7 +82,7 @@
    /**
     * æ–°å¢žéƒ¨é—¨ä¿¡æ¯
     *
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
@@ -87,7 +90,7 @@
    /**
     * ä¿®æ”¹éƒ¨é—¨ä¿¡æ¯
     *
     *
     * @param dept éƒ¨é—¨ä¿¡æ¯
     * @return ç»“æžœ
     */
@@ -95,14 +98,14 @@
    /**
     * ä¿®æ”¹æ‰€åœ¨éƒ¨é—¨æ­£å¸¸çŠ¶æ€
     *
     *
     * @param deptIds éƒ¨é—¨ID组
     */
    public void updateDeptStatusNormal(Long[] deptIds);
    /**
     * ä¿®æ”¹å­å…ƒç´ å…³ç³»
     *
     *
     * @param depts å­å…ƒç´ 
     * @return ç»“æžœ
     */
@@ -110,7 +113,7 @@
    /**
     * åˆ é™¤éƒ¨é—¨ç®¡ç†ä¿¡æ¯
     *
     *
     * @param deptId éƒ¨é—¨ID
     * @return ç»“æžœ
     */
src/main/java/com/ruoyi/project/system/service/impl/SysNoticeServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.project.system.service.impl;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -22,6 +23,7 @@
import com.ruoyi.project.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.ruoyi.project.system.domain.SysNotice;
import com.ruoyi.project.system.mapper.SysNoticeMapper;
@@ -210,4 +212,5 @@
        sysNotice.setTenantId(tenantId);
        return sysNotice;
    }
}
src/main/java/com/ruoyi/safe/controller/SafeAccidentController.java
@@ -48,7 +48,7 @@
    @ApiOperation("删除事故上报记录")
    @DeleteMapping("/{ids}")
    public R delSafeCertification(@RequestBody List<Integer> ids) {
    public R delSafeAccident(@RequestBody List<Integer> ids) {
        return R.ok(safeAccidentService.removeBatchByIds(ids));
    }
src/main/java/com/ruoyi/safe/controller/SafeTrainingController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package com.ruoyi.safe.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeAccident;
import com.ruoyi.safe.pojo.SafeTraining;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.service.SafeAccidentService;
import com.ruoyi.safe.service.SafeTrainingDetailsService;
import com.ruoyi.safe.service.SafeTrainingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
@RestController
@RequestMapping("/safeTraining")
@Api(tags = "安全生产--安全培训考核")
public class SafeTrainingController {
    @Autowired
    private SafeTrainingService safeTrainingService;
    @Autowired
    private SafeTrainingDetailsService safeTrainingDetailsService;
    @GetMapping("/page")
    @ApiOperation("分页查询")
    public R page(Page page, SafeTrainingDto safeTrainingDto) {
        return R.ok(safeTrainingService.pageSafeTraining(page, safeTrainingDto));
    }
    @ApiOperation("新增/编辑安全培训考核")
    @PostMapping()
    public R addOrUpdate(@RequestBody SafeTraining safeTraining) {
        return R.ok(safeTrainingService.addOrUpdate(safeTraining));
    }
    @ApiOperation("签到")
    @PostMapping ("/sign")
    public R sign(@RequestBody SafeTrainingDetails safeTrainingDetails) {
        return R.ok(safeTrainingDetailsService.save(safeTrainingDetails));
    }
    @ApiOperation("结果明细查询")
    @GetMapping ("/getSafeTraining")
    public R getSafeTraining(Long id) {
        return R.ok(safeTrainingService.getSafeTraining(id));
    }
    @ApiOperation("结果明细保存")
    @PostMapping ("/saveSafeTraining")
    public R saveSafeTraining(@RequestBody SafeTrainingDto safeTrainingDto) {
        return R.ok(safeTrainingService.saveSafeTraining(safeTrainingDto));
    }
    @ApiOperation("删除安全培训考核")
    @DeleteMapping("/{ids}")
    public R delSafeTraining(@RequestBody List<Integer> ids) {
        return R.ok(safeTrainingService.delSafeTraining(ids));
    }
    @ApiOperation("导出")
    @PostMapping ("/export")
    public void export(HttpServletResponse response, @RequestBody SafeTraining safeTraining) {
        safeTrainingService.export(response,safeTraining.getId());
    }
}
src/main/java/com/ruoyi/safe/controller/SafeTrainingDetailsController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
package com.ruoyi.safe.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTraining;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.service.SafeTrainingDetailsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
@RestController
@RequestMapping("/safeTrainingDetails")
@Api(tags = "安全生产--安全培训考核--记录详情")
public class SafeTrainingDetailsController {
    @Autowired
    private SafeTrainingDetailsService safeTrainingDetailsService;
    @GetMapping("/page")
    @ApiOperation("分页查询")
    public R page(Page page, SafeTrainingDetails safeTrainingDetails) {
        return R.ok(safeTrainingDetailsService.pageDetails(page, safeTrainingDetails));
    }
    @ApiOperation("导出")
    @PostMapping("/export")
    public void export(HttpServletResponse response, @RequestBody SafeTrainingDetails safeTrainingDetails) {
        safeTrainingDetailsService.export(response,safeTrainingDetails.getUserId());
    }
}
src/main/java/com/ruoyi/safe/controller/SafeTrainingFileController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
package com.ruoyi.safe.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.safe.pojo.SafeHiddenFile;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.ruoyi.safe.service.SafeTrainingFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
@RestController
@RequestMapping("/safeTrainingFile")
@Api(tags = "安全生产--安全培训考核--附件")
public class SafeTrainingFileController {
    @Resource
    private SafeTrainingFileService safeTrainingFileService;
    /**
     * æ–°å¢ž
     * @param safeHiddenFile
     * @return
     */
    @PostMapping("/add")
    @ApiOperation("新增")
    public R add(@RequestBody SafeTrainingFile safeHiddenFile) {
        return R.ok(safeTrainingFileService.save(safeHiddenFile));
    }
    /**
     * åˆ é™¤
     * @param ids
     * @return
     */
    @DeleteMapping("/del")
    @ApiOperation("删除")
    public R delSafeHiddenFile(@RequestBody List<Integer> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return R.fail("请选择至少一条数据");
        }
        //删除检验附件
        return R.ok(safeTrainingFileService.removeBatchByIds(ids));
    }
    /**
     *分页查询
     * @param page
     * @param safeTrainingFile
     * @return
     */
    @GetMapping("/listPage")
    @ApiOperation("分页查询")
    public R listPage(Page page, SafeTrainingFile safeTrainingFile) {
        return R.ok(safeTrainingFileService.page(page, Wrappers.<SafeTrainingFile>lambdaQuery().eq(SafeTrainingFile::getSafeTrainingId,safeTrainingFile.getSafeTrainingId())));
    }
}
src/main/java/com/ruoyi/safe/dto/SafeTrainingDetailsDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.safe.dto;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
public class SafeTrainingDetailsDto extends SafeTrainingDetails {
    @ApiModelProperty("培训人员编号")
    private String userName;
    @ApiModelProperty("培训人员名称")
    private String nickName;
    @ApiModelProperty("手机号码")
    private String phonenumber;
}
src/main/java/com/ruoyi/safe/dto/SafeTrainingDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.safe.dto;
import com.ruoyi.safe.pojo.SafeTraining;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
public class SafeTrainingDto extends SafeTraining {
    @ApiModelProperty("报名人数")
    private Integer nums;
    @ApiModelProperty("评价人")
    private String assessmentUserName;
    @ApiModelProperty("附件集合")
    private List<SafeTrainingFile> safeTrainingFileList;
    @ApiModelProperty("培训记录人员详情集合")
    private List<SafeTrainingDetailsDto> safeTrainingDetailsDtoList;
}
src/main/java/com/ruoyi/safe/mapper/SafeTrainingDetailsMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.safe.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.dto.SafeTrainingDetailsDto;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
@Mapper
public interface SafeTrainingDetailsMapper extends BaseMapper<SafeTrainingDetails> {
    List<SafeTrainingDetailsDto> getSafeTraining(@Param("id") Long id);
    IPage<SafeTrainingDetails> pageDetails(Page page, @Param("c") SafeTrainingDetails safeTrainingDetails);
}
src/main/java/com/ruoyi/safe/mapper/SafeTrainingFileMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.safe.mapper;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
@Mapper
public interface SafeTrainingFileMapper extends BaseMapper<SafeTrainingFile> {
}
src/main/java/com/ruoyi/safe/mapper/SafeTrainingMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.ruoyi.safe.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTraining;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
@Mapper
public interface SafeTrainingMapper extends BaseMapper<SafeTraining> {
    IPage<SafeTrainingDto> pageSafeTraining(Page page, @Param("c") SafeTrainingDto safeTrainingDto);
    SafeTrainingDto getSafeTraining(@Param("id") Long id);
}
src/main/java/com/ruoyi/safe/pojo/SafeTraining.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,123 @@
package com.ruoyi.safe.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
@Getter
@Setter
@TableName("safe_training")
@ApiModel(value = "SafeTraining对象", description = "安全生产--安全培训考核")
public class SafeTraining implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("课程编号")
    private String courseCode;
    @ApiModelProperty("培训目标")
    private String trainingObjectives;
    @ApiModelProperty("培训内容")
    private String trainingContent;
    @ApiModelProperty("培训方式")
    private String trainingMode;
    @ApiModelProperty("状态(0:未开始1:进行中;2:已结束)")
    private Integer state;
    @ApiModelProperty("参加对象")
    private String participants;
    @ApiModelProperty("培训地点")
    private String placeTraining;
    @ApiModelProperty("培训讲师")
    private String trainingLecturer;
    @ApiModelProperty("培训日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @NotBlank(message = "培训日期不能为空")
    private LocalDate trainingDate;
    @ApiModelProperty("开始时间(时分秒)")
    @NotBlank(message = "开始时间不能为空")
    private String openingTime;
    @ApiModelProperty("结束时间(时分秒)")
    @NotBlank(message = "结束时间不能为空")
    private String endTime;
    @ApiModelProperty("课题学分")
    private String projectCredits;
    @ApiModelProperty("课时")
    private Double classHour;
    @ApiModelProperty("考核方式")
    private String assessmentMethod;
    @ApiModelProperty("本次培训综合评价")
    private String comprehensiveAssessment;
    @ApiModelProperty("备注")
    private String remarks;
    @ApiModelProperty("评价人id")
    private Integer assessmentUserId;
    @ApiModelProperty("评价时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate assessmentDate;
    @ApiModelProperty("培训摘要")
    private String trainingAbstract;
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT)
    private Integer tenantId;
}
src/main/java/com/ruoyi/safe/pojo/SafeTrainingDetails.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
package com.ruoyi.safe.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
@Getter
@Setter
@TableName("safe_training_details")
@ApiModel(value = "SafeTrainingDetails对象", description = "安全生产--安全培训考核--记录详情")
public class SafeTrainingDetails implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("用户表格(user)主键")
    @NotBlank(message = "用户id不能为空")
    private Long userId;
    @ApiModelProperty("关联安全培训考核id")
    private Integer safeTrainingId;
    @ApiModelProperty("考核结果")
    private String examinationResults;
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT)
    private Integer tenantId;
    @ApiModelProperty("培训日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @TableField(exist = false)
    private LocalDate trainingDate;
    @ApiModelProperty("课程编号")
    @TableField(exist = false)
    private String courseCode;
    @ApiModelProperty("培训内容")
    @TableField(exist = false)
    private String trainingContent;
    @ApiModelProperty("培训课时")
    @TableField(exist = false)
    private Double classHour;
    @ApiModelProperty("课题学分")
    @TableField(exist = false)
    private String projectCredits;
    @ApiModelProperty("备注")
    @TableField(exist = false)
    private String remarks;
}
src/main/java/com/ruoyi/safe/pojo/SafeTrainingFile.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,57 @@
package com.ruoyi.safe.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
@Getter
@Setter
@TableName("safe_training_file")
@ApiModel(value = "SafeTrainingFile对象", description = "安全生产--安全培训考核--附件")
public class SafeTrainingFile implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("关联安全培训考核id")
    private Integer safeTrainingId;
    private String name;
    private String url;
    private Object fileSize;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT)
    private Integer tenantId;
}
src/main/java/com/ruoyi/safe/service/SafeTrainingDetailsService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.safe.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletResponse;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
public interface SafeTrainingDetailsService extends IService<SafeTrainingDetails> {
    IPage<SafeTrainingDetails> pageDetails(Page page, SafeTrainingDetails safeTrainingDetails);
    void export(HttpServletResponse response, Long userId);
}
src/main/java/com/ruoyi/safe/service/SafeTrainingFileService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.safe.service;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
public interface SafeTrainingFileService extends IService<SafeTrainingFile> {
}
src/main/java/com/ruoyi/safe/service/SafeTrainingService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.ruoyi.safe.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTraining;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
public interface SafeTrainingService extends IService<SafeTraining> {
    IPage<SafeTrainingDto> pageSafeTraining(Page page, SafeTrainingDto safeTrainingDto);
    int addOrUpdate(SafeTraining safeTraining);
    SafeTrainingDto getSafeTraining(Long id);
    int saveSafeTraining(SafeTrainingDto safeTrainingDto);
    int delSafeTraining(List<Integer> ids);
    void export(HttpServletResponse response, Long id);
}
src/main/java/com/ruoyi/safe/service/impl/SafeHiddenServiceImpl.java
@@ -47,7 +47,7 @@
    @Override
    public int add(SafeHidden safeHidden) {
        safeHiddenMapper.insert(safeHidden);
        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
        String no = "YH" + String.format("%s%03d", datePrefix, safeHidden.getId());
        safeHidden.setHiddenCode(no);
        safeHiddenMapper.updateById(safeHidden);
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingDetailsServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package com.ruoyi.safe.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.safe.dto.SafeTrainingDetailsDto;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.mapper.SafeTrainingDetailsMapper;
import com.ruoyi.safe.service.SafeTrainingDetailsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--记录详情 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:15
 */
@Service
public class SafeTrainingDetailsServiceImpl extends ServiceImpl<SafeTrainingDetailsMapper, SafeTrainingDetails> implements SafeTrainingDetailsService {
    @Autowired
    private SafeTrainingDetailsMapper safeTrainingDetailsMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    public IPage<SafeTrainingDetails> pageDetails(Page page, SafeTrainingDetails safeTrainingDetails) {
        return safeTrainingDetailsMapper.pageDetails(page, safeTrainingDetails);
    }
    @Override
    public void export(HttpServletResponse response, Long userId) {
        SafeTrainingDetails safeTrainingDetails = new SafeTrainingDetails();
        safeTrainingDetails.setUserId(userId);
        SysUser sysUser = sysUserMapper.selectUserById(userId);
        List<SafeTrainingDetails> safeTrainingDetailsList = safeTrainingDetailsMapper.pageDetails(new Page(1, -1), safeTrainingDetails).getRecords();
        InputStream inputStream = this.getClass().getResourceAsStream("/static/safe-training-details.docx");
        Configure configure = Configure.builder()
                .bind("safeTrainingDetailsList", new HackLoopTableRenderPolicy())
                .build();
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("user", sysUser);
                    put("safeTrainingDetailsList", safeTrainingDetailsList);
                }});
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode(
                    "培训与考核记录", "UTF-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
    }
}
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingFileServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.safe.service.impl;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.ruoyi.safe.mapper.SafeTrainingFileMapper;
import com.ruoyi.safe.service.SafeTrainingFileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核--附件 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:23
 */
@Service
public class SafeTrainingFileServiceImpl extends ServiceImpl<SafeTrainingFileMapper, SafeTrainingFile> implements SafeTrainingFileService {
}
src/main/java/com/ruoyi/safe/service/impl/SafeTrainingServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,179 @@
package com.ruoyi.safe.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
import com.ruoyi.production.pojo.ProductOrder;
import com.ruoyi.production.pojo.ProductWorkOrder;
import com.ruoyi.project.system.domain.SysNotice;
import com.ruoyi.safe.dto.SafeTrainingDetailsDto;
import com.ruoyi.safe.dto.SafeTrainingDto;
import com.ruoyi.safe.mapper.SafeTrainingDetailsMapper;
import com.ruoyi.safe.mapper.SafeTrainingFileMapper;
import com.ruoyi.safe.pojo.SafeTraining;
import com.ruoyi.safe.mapper.SafeTrainingMapper;
import com.ruoyi.safe.pojo.SafeTrainingDetails;
import com.ruoyi.safe.pojo.SafeTrainingFile;
import com.ruoyi.safe.service.SafeTrainingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--安全培训考核 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-29 10:54:06
 */
@Service
public class SafeTrainingServiceImpl extends ServiceImpl<SafeTrainingMapper, SafeTraining> implements SafeTrainingService {
    @Autowired
    private SafeTrainingMapper safeTrainingMapper;
    @Autowired
    private SafeTrainingFileMapper safeTrainingFileMapper;
    @Autowired
    private SafeTrainingDetailsMapper safeTrainingDetailsMapper;
    @Override
    public IPage<SafeTrainingDto> pageSafeTraining(Page page, SafeTrainingDto safeTrainingDto) {
        return safeTrainingMapper.pageSafeTraining(page, safeTrainingDto);
    }
    @Override
    public int addOrUpdate(SafeTraining safeTraining) {
        if (ObjectUtils.isNull(safeTraining.getId())) {
            String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
            // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§è¯¾ç¨‹ç¼–号
            QueryWrapper<SafeTraining> queryWrapper = new QueryWrapper<>();
            queryWrapper.likeRight("course_code", datePrefix)
                    .orderByDesc("course_code")
                    .last("LIMIT 1");
            SafeTraining lastSafeTraining = safeTrainingMapper.selectOne(queryWrapper);
            int sequenceNumber = 1; // é»˜è®¤åºå·
            if (lastSafeTraining != null && lastSafeTraining.getCourseCode() != null) {
                String lastNo = lastSafeTraining.getCourseCode().toString();
                if (lastNo.startsWith(datePrefix)) {
                    String seqStr = lastNo.substring(datePrefix.length());
                    try {
                        sequenceNumber = Integer.parseInt(seqStr) + 1;
                    } catch (NumberFormatException e) {
                        sequenceNumber = 1;
                    }
                }
            }
            // ç”Ÿæˆå®Œæ•´çš„课程编号
            String no = "KC-" + String.format("%s%03d", datePrefix, sequenceNumber);
            safeTraining.setCourseCode(no);
        }
        //根据时间判断培训状态
        String trainingDate = safeTraining.getTrainingDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDateTime openingTime = LocalDateTime.parse((trainingDate + safeTraining.getOpeningTime()), DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));
        LocalDateTime endTime = LocalDateTime.parse((trainingDate + safeTraining.getEndTime()), DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));
        if (LocalDateTime.now().isBefore(openingTime)) {
            //未开始
            safeTraining.setState(0);
        } else if (LocalDateTime.now().isAfter(endTime)) {
            //已结束
            safeTraining.setState(2);
        } else {
            //进行中
            safeTraining.setState(1);
        }
        //新增或更新
        saveOrUpdate(safeTraining);
        return 0;
    }
    @Override
    public SafeTrainingDto getSafeTraining(Long id) {
        //主表数据
        SafeTrainingDto safeTrainingDto = safeTrainingMapper.getSafeTraining(id);
        //附件
        List<SafeTrainingFile> safeTrainingFiles = safeTrainingFileMapper.selectList(Wrappers.<SafeTrainingFile>lambdaQuery().eq(SafeTrainingFile::getSafeTrainingId, id));
        safeTrainingDto.setSafeTrainingFileList(safeTrainingFiles);
        //培训记录详情
        List<SafeTrainingDetailsDto> safeTrainingDetailsDto = safeTrainingDetailsMapper.getSafeTraining(id);
        safeTrainingDto.setSafeTrainingDetailsDtoList(safeTrainingDetailsDto);
        return safeTrainingDto;
    }
    @Override
    public int saveSafeTraining(SafeTrainingDto safeTrainingDto) {
        //更新主表
        safeTrainingMapper.updateById(safeTrainingDto);
        //更新培训记录详情
        safeTrainingDto.getSafeTrainingDetailsDtoList().forEach(safeTrainingDetailsDto -> {
            safeTrainingDetailsMapper.updateById(safeTrainingDetailsDto);
        });
        return 0;
    }
    @Override
    public int delSafeTraining(List<Integer> ids) {
        //删除主表
        safeTrainingMapper.deleteBatchIds(ids);
        //删除附件
        safeTrainingFileMapper.delete(Wrappers.<SafeTrainingFile>lambdaQuery().in(SafeTrainingFile::getSafeTrainingId, ids));
        //删除培训记录
        safeTrainingDetailsMapper.delete(Wrappers.<SafeTrainingDetails>lambdaQuery().in(SafeTrainingDetails::getSafeTrainingId, ids));
        return 0;
    }
    @Override
    public void export(HttpServletResponse response, Long id) {
        SafeTrainingDto safeTrainingDto = safeTrainingMapper.getSafeTraining(id);
        List<SafeTrainingDetailsDto> safeTrainingDetailsDtoList = safeTrainingDetailsMapper.getSafeTraining(id);
        InputStream inputStream = this.getClass().getResourceAsStream("/static/safe-training.docx");
        Configure configure = Configure.builder()
                .bind("safeTrainingDetailsDtoList", new HackLoopTableRenderPolicy())
                .build();
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("safeTrainingDto", safeTrainingDto);
                    put("safeTrainingDetailsDtoList", safeTrainingDetailsDtoList);
                }});
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode(
                    safeTrainingDto.getCourseCode() + "培训与考核计划", "UTF-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
    }
}
src/main/resources/mapper/safe/SafeAccidentMapper.xml
@@ -35,13 +35,13 @@
            and sa.accident_code like concat('%', #{c.accidentCode}, '%')
        </if>
        <if test="c.accidentName != null and c.accidentName != ''">
            and sa.accident_name like concat('%', #{accidentName}, '%')
            and sa.accident_name like concat('%', #{c.accidentName}, '%')
        </if>
        <if test="c.accidentType != null and c.accidentType != ''">
            and sa.accident_type like concat('%', #{accidentType}, '%')
            and sa.accident_type like concat('%', #{c.accidentType}, '%')
        </if>
        <if test="c.accidentGrade != null and c.accidentGrade != ''">
            and sa.accident_grade like concat('%', #{accidentGrade}, '%')
            and sa.accident_grade like concat('%', #{c.accidentGrade}, '%')
        </if>
    </select>
src/main/resources/mapper/safe/SafeTrainingDetailsMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
<?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.safe.mapper.SafeTrainingDetailsMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.safe.pojo.SafeTrainingDetails">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="safe_training_id" property="safeTrainingId"/>
        <result column="examination_results" property="examinationResults"/>
        <result column="create_time" property="createTime"/>
        <result column="create_user" property="createUser"/>
        <result column="update_time" property="updateTime"/>
        <result column="update_user" property="updateUser"/>
        <result column="tenant_id" property="tenantId"/>
    </resultMap>
    <select id="getSafeTraining" resultType="com.ruoyi.safe.dto.SafeTrainingDetailsDto">
        select std.*,
               su.user_name,
               su.nick_name,
               su.phonenumber
        from safe_training_details std
                 left join sys_user su on std.user_id = su.user_id
        where std.safe_training_id = #{id}
    </select>
    <select id="pageDetails" resultType="com.ruoyi.safe.pojo.SafeTrainingDetails">
        select std.*,
               st.*
        from safe_training_details std
                 left join safe_training st on std.safe_training_id = st.id
        where std.user_id = #{c.userId}
        <if test="c.trainingDate != null">
            and st.training_date = #{c.trainingDate}
        </if>
    </select>
</mapper>
src/main/resources/mapper/safe/SafeTrainingFileMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.safe.mapper.SafeTrainingFileMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.safe.pojo.SafeTrainingFile">
        <id column="id" property="id" />
        <result column="safe_training_id" property="safeTrainingId" />
        <result column="name" property="name" />
        <result column="url" property="url" />
        <result column="file_size" property="fileSize" />
        <result column="create_time" property="createTime" />
        <result column="create_user" property="createUser" />
        <result column="update_time" property="updateTime" />
        <result column="update_user" property="updateUser" />
        <result column="tenant_id" property="tenantId" />
    </resultMap>
</mapper>
src/main/resources/mapper/safe/SafeTrainingMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
<?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.safe.mapper.SafeTrainingMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.safe.pojo.SafeTraining">
        <id column="id" property="id" />
        <result column="course_code" property="courseCode" />
        <result column="training_objectives" property="trainingObjectives" />
        <result column="training_content" property="trainingContent" />
        <result column="training_mode" property="trainingMode" />
        <result column="state" property="state" />
        <result column="participants" property="participants" />
        <result column="place_training" property="placeTraining" />
        <result column="training_lecturer" property="trainingLecturer" />
        <result column="training_date" property="trainingDate" />
        <result column="opening_time" property="openingTime" />
        <result column="end_time" property="endTime" />
        <result column="project_credits" property="projectCredits" />
        <result column="class_hour" property="classHour" />
        <result column="assessment_method" property="assessmentMethod" />
        <result column="comprehensive_assessment" property="comprehensiveAssessment" />
        <result column="remarks" property="remarks" />
        <result column="assessment_user_id" property="assessmentUserId" />
        <result column="assessment_date" property="assessmentDate" />
        <result column="training_abstract" property="trainingAbstract" />
        <result column="create_time" property="createTime" />
        <result column="create_user" property="createUser" />
        <result column="update_time" property="updateTime" />
        <result column="update_user" property="updateUser" />
        <result column="tenant_id" property="tenantId" />
    </resultMap>
    <select id="pageSafeTraining" resultType="com.ruoyi.safe.dto.SafeTrainingDto">
        select st.*,
               su.nick_name assessmentUserName,
                count(std.id) nums
        from safe_training st
        left join safe_training_details std on std.safe_training_id = st.id
        left join sys_user su on st.assessment_user_id = su.user_id
        where 1=1
        <if test="c.placeTraining != null and c.placeTraining != ''">
            and st.place_training like concat('%', #{c.placeTraining}, '%')
        </if>
        <if test="c.trainingDate != null and c.trainingDate != ''">
            and st.training_date = #{c.trainingDate}
        </if>
        <if test="c.state != null and c.state != ''">
            and st.state like concat('%', #{c.state}, '%')
        </if>
    </select>
    <select id="getSafeTraining" resultType="com.ruoyi.safe.dto.SafeTrainingDto">
         select st.*,
                su.nick_name assessmentUserName
         from safe_training st
                  left join sys_user su on st.assessment_user_id = su.user_id
         where st.id=#{id}
    </select>
</mapper>
src/main/resources/static/safe-training-details.docx
Binary files differ
src/main/resources/static/safe-training.docx
Binary files differ