zhuo
2025-02-24 aa6487d1279f4c8fa36d52b1399944203849eb00
人员培训计划移植
已修改2个文件
已添加29个文件
3240 ■■■■ 文件已修改
cnas-personnel/src/main/java/com/ruoyi/personnel/controller/PersonBasicInfoController.java 454 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/controller/PersonTrainingController.java 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonBasicInfoDetailsDto.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonBasicInfoWorkDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingDetailedDto.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingDto.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingRecordDto.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingRecordListDto.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingRecordSubmitDto.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/TrainingRecordExportDto.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/TrainingRecordPersonDetailedDto.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/excel/PersonTrainingDetailedListener.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/excel/PersonTrainingDetailedUpload.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/mapper/PersonTrainingDetailedFileMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/mapper/PersonTrainingDetailedMapper.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/mapper/PersonTrainingMapper.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/mapper/PersonTrainingRecordMapper.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/pojo/PersonTraining.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/pojo/PersonTrainingDetailed.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/pojo/PersonTrainingDetailedFile.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/pojo/PersonTrainingRecord.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/service/PersonTrainingDetailedService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/service/PersonTrainingRecordService.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/service/PersonTrainingService.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/service/impl/PersonBasicInfoServiceImpl.java 676 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/service/impl/PersonTrainingDetailedServiceImpl.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/service/impl/PersonTrainingRecordServiceImpl.java 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/service/impl/PersonTrainingServiceImpl.java 429 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/resources/mapper/PersonBasicInfoMapper.xml 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/resources/mapper/PersonTrainingMapper.xml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/resources/mapper/PersonTrainingRecordMapper.xml 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/src/main/java/com/ruoyi/personnel/controller/PersonBasicInfoController.java
@@ -1,225 +1,229 @@
//package com.ruoyi.personnel.controller;
//
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.ruoyi.personnel.service.AnnexService;
//import com.ruoyi.personnel.service.PersonBasicInfoFileService;
//import com.ruoyi.personnel.service.PersonBasicInfoService;
//import com.ruoyi.personnel.service.PersonBasicInfoWorkService;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//import org.springframework.web.multipart.MultipartFile;
//
//import javax.annotation.Resource;
//import javax.servlet.http.HttpServletResponse;
//import java.util.List;
//import java.util.Map;
//
///**
// * <p>
// *  å‰ç«¯æŽ§åˆ¶å™¨
// * </p>
// *
// * @author æ±Ÿè‹éµ·é›ç½‘络科技有限公司
// * @since 2024-08-30 09:19:57
// */
//@Api(tags = "人员-人员基本信息")
//@RestController
//@RequestMapping("/personBasicInfo")
//public class PersonBasicInfoController {
//
//    @Resource
//    private PersonBasicInfoService personBasicInfoService;
//
//    @Resource
//    private PersonBasicInfoFileService personBasicInfoFileService;
//    @Resource
//    private PersonBasicInfoWorkService personBasicInfoWorkService;
//
//    @Resource
//    private AnnexService annexService;
//
//
//    @ValueClassify("人员基本信息")
//    @ApiOperation(value = "查询CNAS人员侧边栏")
//    @GetMapping("/selectCNSAPersonTree")
//    public Result<List<DepartmentDto>> selectCNSAPersonTree() {
//        return Result.success(personBasicInfoService.selectCNSAPersonTree());
//    }
//
//    @ValueClassify("人员基本信息")
//    @ApiOperation(value = "获取CNAS人员基本信息")
//    @GetMapping("/getCNASPersonnelInfo")
//    public Result getCNASPersonnelInfo(Integer userId) {
//        return Result.success(personBasicInfoService.getCNASPersonnelInfo(userId));
//    }
//
//    @ValueClassify("人员基本信息")
//    @ApiOperation(value = "保存CNAS人员基本信息")
//    @PostMapping("/saveCNASPersonnelInfo")
//    public Result saveCNASPersonnelInfo(@RequestBody PersonBasicInfoDto personBasicInfoDto) {
//        personBasicInfoService.saveCNASPersonnelInfo(personBasicInfoDto);
//        return Result.success();
//    }
//
//    @ApiOperation(value = "人员明细分页查询")
//    @ValueClassify("人员基本信息")
//    @GetMapping("basicInformationOfPersonnelSelectPage")
//    public Result<IPage<Map<String, Object>>> basicInformationOfPersonnelSelectPage(Page<List<PersonBasicInfoDetailsDto>> page, String name, Integer departmentId) {
//        return Result.success(personBasicInfoService.basicInformationOfPersonnelSelectPage(page, name, departmentId));
//    }
//
//    // ä¸Šä¼ æ–‡ä»¶æŽ¥å£
//    @ApiOperation(value = "上传文件接口")
//    @PostMapping("/saveCNASFile")
//    public Result saveFile(@RequestPart("file") MultipartFile file) {
//        String s = FileSaveUtil.uploadWordFile(file);
//        return Result.success("上传成功", s);
//    }
//
//    @GetMapping("/getAnnexByUserId")
//    public Result<List<Annex>> getAnnexByUserId(Integer userId) {
//        List<Annex> list = annexService.list(new LambdaQueryWrapper<Annex>().eq(Annex::getUserId, userId));
//        return Result.success(list);
//    }
//
//    // åˆ é™¤æ–‡ä»¶
//    @DeleteMapping("/deleteCNASFile")
//    public Result saveFile(String fileName) {
//        String[] split = fileName.split(",");
//        for (String s : split) {
//            FileSaveUtil.DeleteFile(s);
//        }
//        return Result.success();
//
//    }
//
//    /**
//     * äººå‘˜åŸºæœ¬ä¿¡æ¯é™„件新增
//     */
//    @PostMapping("/addAnnex")
//    public Result addAnnex(@RequestBody Annex annex) {
//        annexService.save(annex);
//        return Result.success();
//    }
//
//    @GetMapping("/getAnnex")
//    public Result<Annex> getAnnex(Integer id) {
//        return Result.success(annexService.getById(id));
//    }
//    /**
//     * äººå‘˜åŸºæœ¬ä¿¡æ¯é™„件删除
//     */
//    @DeleteMapping("/deleteAnnex/{id}")
//    public Result deleteAnnex(@PathVariable("id") Integer id) {
//        annexService.removeById(id);
//        return Result.success();
//    }
//
//    /**
//     * äººå‘˜åŸºæœ¬ä¿¡æ¯é™„件修改
//     *
//     */
//    @PostMapping("/updateAnnex")
//    public Result updateAnnex(@RequestBody Annex annex) {
//        annexService.updateById(annex);
//        return Result.success();
//    }
//
//    @ApiOperation(value = "导出人员基本信息")
//    @PostMapping("/exportPersonBasicInfo")
//    public void exportPersonBasicInfo(@RequestBody Map<String, Object> data, HttpServletResponse response) throws Exception {
//        UserPageDto userPageDto = JackSonUtil.unmarshal(JackSonUtil.marshal(data.get("entity")), UserPageDto.class);
//        personBasicInfoService.exportPersonBasicInfo(userPageDto,response);
//    }
//
//    @ApiOperation(value = "下载人员档案卡")
//    @GetMapping("/exportPersonBasicInfoById")
//    public Result exportPersonBasicInfoById(Integer id, HttpServletResponse response) {
//        return Result.success(personBasicInfoService.exportPersonBasicInfoById(id,response));
//    }
//
//    /**
//     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件新增
//     * @param userId
//     * @param file
//     * @return
//     */
//    @ApiOperation(value = "人员培训基本信息附件新增")
//    @PostMapping("/uploadBasicInfoFile")
//    public Result<?> uploadBasicInfoFile(Integer userId, MultipartFile file) {
//        return Result.success(personBasicInfoService.uploadBasicInfoFile(userId, file));
//    }
//
//
//    /**
//     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件列表
//     * @return
//     */
//    @ApiOperation(value = "人员培训基本信息附件列表")
//    @GetMapping("/getBasicInfoFileList")
//    public Result<List<PersonBasicInfoFile>> getBasicInfoFileList(Integer userId){
//        return Result.success(personBasicInfoFileService.list(Wrappers.<PersonBasicInfoFile>lambdaQuery()
//                .eq(PersonBasicInfoFile::getUserId, userId)));
//    }
//
//    /**
//     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件删除
//     * @return
//     */
//    @ApiOperation(value = "人员培训基本信息附件删除")
//    @GetMapping("/delBasicInfoFileList")
//    public Result delBasicInfoFileList(Integer basicInfoFileId){
//        return Result.success(personBasicInfoFileService.removeById(basicInfoFileId));
//    }
//
//    /**
//     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†æ–°å¢ž
//     * @return
//     */
//    @ApiOperation(value = "人员培训基本信息工作经历新增")
//    @PostMapping("/addBasicInfoWork")
//    public Result<?> addBasicInfoWork(@RequestBody PersonBasicInfoWork basicInfoWork) {
//        if (basicInfoWork.getUserId() == null) {
//            throw new ErrorException("缺少人员id");
//        }
//        basicInfoWork.setUserId(basicInfoWork.getUserId());
//        return Result.success(personBasicInfoWorkService.save(basicInfoWork));
//    }
//
//
//    /**
//     * äººå‘˜å·¥ä½œç»åŽ†åˆ—è¡¨
//     * @return
//     */
//    @ApiOperation(value = "人员工作经历列表")
//    @GetMapping("/getBasicInfoWorkList")
//    public Result<List<PersonBasicInfoWork>> getBasicInfoWorkList(Integer userId){
//        return Result.success(personBasicInfoWorkService.list(Wrappers.<PersonBasicInfoWork>lambdaQuery()
//                .eq(PersonBasicInfoWork::getUserId, userId)));
//    }
//
//    /**
//     * äººå‘˜å·¥ä½œç»åŽ†åˆ é™¤
//     * @return
//     */
//    @ApiOperation(value = "人员工作经历删除")
//    @GetMapping("/delBasicInfoWorkList")
//    public Result delBasicInfoWorkList(Integer basicInfoWorkId){
//        return Result.success(personBasicInfoWorkService.removeById(basicInfoWorkId));
//    }
//
//    /**
//     * äººå‘˜åŸºæœ¬ä¿¡æ¯é™„件删除
//     * @return
//     */
//    @ApiOperation(value = "人员工作经历修改")
//    @PostMapping("/updateBasicInfoWorkList")
//    public Result updateBasicInfoWorkList(@RequestBody PersonBasicInfoWork basicInfoWork){
//        return Result.success(personBasicInfoWorkService.updateById(basicInfoWork));
//    }
//}
package com.ruoyi.personnel.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.common.core.domain.entity.DepartmentDto;
import com.ruoyi.common.utils.FileSaveUtil;
import com.ruoyi.framework.exception.ErrorException;
import com.ruoyi.personnel.dto.PersonBasicInfoDetailsDto;
import com.ruoyi.personnel.dto.PersonBasicInfoDto;
import com.ruoyi.personnel.dto.UserPageDto;
import com.ruoyi.personnel.pojo.Annex;
import com.ruoyi.personnel.pojo.PersonBasicInfoFile;
import com.ruoyi.personnel.pojo.PersonBasicInfoWork;
import com.ruoyi.personnel.service.AnnexService;
import com.ruoyi.personnel.service.PersonBasicInfoFileService;
import com.ruoyi.personnel.service.PersonBasicInfoService;
import com.ruoyi.personnel.service.PersonBasicInfoWorkService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/**
 * <p>
 *  å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author æ±Ÿè‹éµ·é›ç½‘络科技有限公司
 * @since 2024-08-30 09:19:57
 */
@Api(tags = "人员-人员基本信息")
@RestController
@RequestMapping("/personBasicInfo")
public class PersonBasicInfoController {
    @Resource
    private PersonBasicInfoService personBasicInfoService;
    @Resource
    private PersonBasicInfoFileService personBasicInfoFileService;
    @Resource
    private PersonBasicInfoWorkService personBasicInfoWorkService;
    @Resource
    private AnnexService annexService;
    @ApiOperation(value = "查询CNAS人员侧边栏")
    @GetMapping("/selectCNSAPersonTree")
    public Result<List<DepartmentDto>> selectCNSAPersonTree() {
        return Result.success(personBasicInfoService.selectCNSAPersonTree());
    }
    @ApiOperation(value = "获取CNAS人员基本信息")
    @GetMapping("/getCNASPersonnelInfo")
    public Result getCNASPersonnelInfo(Integer userId) {
        return Result.success(personBasicInfoService.getCNASPersonnelInfo(userId));
    }
    @ApiOperation(value = "保存CNAS人员基本信息")
    @PostMapping("/saveCNASPersonnelInfo")
    public Result saveCNASPersonnelInfo(@RequestBody PersonBasicInfoDto personBasicInfoDto) {
        personBasicInfoService.saveCNASPersonnelInfo(personBasicInfoDto);
        return Result.success();
    }
    @ApiOperation(value = "人员明细分页查询")
    @GetMapping("basicInformationOfPersonnelSelectPage")
    public Result<IPage<Map<String, Object>>> basicInformationOfPersonnelSelectPage(Page<List<PersonBasicInfoDetailsDto>> page, String name, Integer departmentId) {
        return Result.success(personBasicInfoService.basicInformationOfPersonnelSelectPage(page, name, departmentId));
    }
    // ä¸Šä¼ æ–‡ä»¶æŽ¥å£
    @ApiOperation(value = "上传文件接口")
    @PostMapping("/saveCNASFile")
    public Result saveFile(@RequestPart("file") MultipartFile file) {
        String s = FileSaveUtil.uploadWordFile(file);
        return Result.success("上传成功", s);
    }
    @GetMapping("/getAnnexByUserId")
    public Result<List<Annex>> getAnnexByUserId(Integer userId) {
        List<Annex> list = annexService.list(new LambdaQueryWrapper<Annex>().eq(Annex::getUserId, userId));
        return Result.success(list);
    }
    // åˆ é™¤æ–‡ä»¶
    @DeleteMapping("/deleteCNASFile")
    public Result saveFile(String fileName) {
        String[] split = fileName.split(",");
        for (String s : split) {
            FileSaveUtil.DeleteFile(s);
        }
        return Result.success();
    }
    /**
     * äººå‘˜åŸºæœ¬ä¿¡æ¯é™„件新增
     */
    @PostMapping("/addAnnex")
    public Result addAnnex(@RequestBody Annex annex) {
        annexService.save(annex);
        return Result.success();
    }
    @GetMapping("/getAnnex")
    public Result<Annex> getAnnex(Integer id) {
        return Result.success(annexService.getById(id));
    }
    /**
     * äººå‘˜åŸºæœ¬ä¿¡æ¯é™„件删除
     */
    @DeleteMapping("/deleteAnnex")
    public Result deleteAnnex(Integer id) {
        annexService.removeById(id);
        return Result.success();
    }
    /**
     * äººå‘˜åŸºæœ¬ä¿¡æ¯é™„件修改
     *
     */
    @PostMapping("/updateAnnex")
    public Result updateAnnex(@RequestBody Annex annex) {
        annexService.updateById(annex);
        return Result.success();
    }
    @ApiOperation(value = "导出人员基本信息")
    @GetMapping("/exportPersonBasicInfo")
    public void exportPersonBasicInfo(UserPageDto userPageDto, HttpServletResponse response) throws Exception {
        personBasicInfoService.exportPersonBasicInfo(userPageDto,response);
    }
    @ApiOperation(value = "下载人员档案卡")
    @GetMapping("/exportPersonBasicInfoById")
    public Result exportPersonBasicInfoById(Integer id, HttpServletResponse response) {
        return Result.success(personBasicInfoService.exportPersonBasicInfoById(id,response));
    }
    /**
     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件新增
     * @param userId
     * @param file
     * @return
     */
    @ApiOperation(value = "人员培训基本信息附件新增")
    @PostMapping("/uploadBasicInfoFile")
    public Result<?> uploadBasicInfoFile(Integer userId, MultipartFile file) {
        return Result.success(personBasicInfoService.uploadBasicInfoFile(userId, file));
    }
    /**
     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件列表
     * @return
     */
    @ApiOperation(value = "人员培训基本信息附件列表")
    @GetMapping("/getBasicInfoFileList")
    public Result<List<PersonBasicInfoFile>> getBasicInfoFileList(Integer userId){
        return Result.success(personBasicInfoFileService.list(Wrappers.<PersonBasicInfoFile>lambdaQuery()
                .eq(PersonBasicInfoFile::getUserId, userId)));
    }
    /**
     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件删除
     * @return
     */
    @ApiOperation(value = "人员培训基本信息附件删除")
    @GetMapping("/delBasicInfoFileList")
    public Result delBasicInfoFileList(Integer basicInfoFileId){
        return Result.success(personBasicInfoFileService.removeById(basicInfoFileId));
    }
    /**
     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†æ–°å¢ž
     * @return
     */
    @ApiOperation(value = "人员培训基本信息工作经历新增")
    @PostMapping("/addBasicInfoWork")
    public Result<?> addBasicInfoWork(@RequestBody PersonBasicInfoWork basicInfoWork) {
        if (basicInfoWork.getUserId() == null) {
            throw new ErrorException("缺少人员id");
        }
        basicInfoWork.setUserId(basicInfoWork.getUserId());
        return Result.success(personBasicInfoWorkService.save(basicInfoWork));
    }
    /**
     * äººå‘˜å·¥ä½œç»åŽ†åˆ—è¡¨
     * @return
     */
    @ApiOperation(value = "人员工作经历列表")
    @GetMapping("/getBasicInfoWorkList")
    public Result<List<PersonBasicInfoWork>> getBasicInfoWorkList(Integer userId){
        return Result.success(personBasicInfoWorkService.list(Wrappers.<PersonBasicInfoWork>lambdaQuery()
                .eq(PersonBasicInfoWork::getUserId, userId)));
    }
    /**
     * äººå‘˜å·¥ä½œç»åŽ†åˆ é™¤
     * @return
     */
    @ApiOperation(value = "人员工作经历删除")
    @GetMapping("/delBasicInfoWorkList")
    public Result delBasicInfoWorkList(Integer basicInfoWorkId){
        return Result.success(personBasicInfoWorkService.removeById(basicInfoWorkId));
    }
    /**
     * äººå‘˜åŸºæœ¬ä¿¡æ¯é™„件删除
     * @return
     */
    @ApiOperation(value = "人员工作经历修改")
    @PostMapping("/updateBasicInfoWorkList")
    public Result updateBasicInfoWorkList(@RequestBody PersonBasicInfoWork basicInfoWork){
        return Result.success(personBasicInfoWorkService.updateById(basicInfoWork));
    }
}
cnas-personnel/src/main/java/com/ruoyi/personnel/controller/PersonTrainingController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,246 @@
package com.ruoyi.personnel.controller;
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.ruoyi.common.core.domain.Result;
import com.ruoyi.common.numgen.NumberGenerator;
import com.ruoyi.personnel.dto.PersonTrainingDetailedDto;
import com.ruoyi.personnel.dto.PersonTrainingDto;
import com.ruoyi.personnel.dto.PersonTrainingRecordDto;
import com.ruoyi.personnel.dto.PersonTrainingRecordSubmitDto;
import com.ruoyi.personnel.mapper.PersonTrainingDetailedFileMapper;
import com.ruoyi.personnel.pojo.PersonTraining;
import com.ruoyi.personnel.pojo.PersonTrainingDetailed;
import com.ruoyi.personnel.pojo.PersonTrainingDetailedFile;
import com.ruoyi.personnel.pojo.PersonTrainingRecord;
import com.ruoyi.personnel.service.PersonTrainingDetailedService;
import com.ruoyi.personnel.service.PersonTrainingRecordService;
import com.ruoyi.personnel.service.PersonTrainingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * <p>
 * åŸ¹è®­è®¡åˆ’ å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-11 01:11:49
 */
@Api(tags = "人员 - åŸ¹è®­è®¡åˆ’")
@RestController
@RequestMapping("/personTraining")
public class PersonTrainingController {
    @Autowired
    private PersonTrainingService personTrainingService;
    @Autowired
    private PersonTrainingDetailedService personTrainingDetailedService;
    @Autowired
    private PersonTrainingRecordService personTrainingRecordService;
    @Autowired
    private PersonTrainingDetailedFileMapper personTrainingDetailedFileMapper;
    @Autowired
    private NumberGenerator<PersonTrainingDetailed> numberGenerator;
    @ApiOperation(value = "培训计划 å¯¼å…¥")
    @PostMapping("personTrainingImport")
    public Result<?> personTrainingImport(@RequestPart("file") MultipartFile file, PersonTraining training) {
        personTrainingService.personTrainingImport(file, training);
        return Result.success();
    }
    @ApiOperation(value = "培训计划 åˆ é™¤")
    @DeleteMapping("personTrainingDelete")
    public Result<?> personTrainingDelete(@RequestParam("id") Integer id) {
        personTrainingService.personTrainingDelete(id);
        return Result.success();
    }
    @ApiOperation(value = "培训计划 æŸ¥è¯¢")
    @GetMapping("personTrainingSelect")
    public Result<IPage<PersonTrainingDto>> personTrainingSelect(Page page, String compilerName, String departmentId) {
        IPage<PersonTrainingDto> iPage = personTrainingService.personTrainingSelect(page, compilerName, departmentId);
        return Result.success(iPage);
    }
    @ApiOperation(value = "年度培训计划 å®¡æ ¸")
    @PostMapping("reviewAnnualPersonnelTraining")
    public Result<?> reviewAnnualPersonnelTraining(@RequestBody PersonTraining training) {
        personTrainingService.reviewAnnualPersonnelTraining(training);
        return Result.success();
    }
    @ApiOperation(value = "培训计划 æ‰¹å‡†")
    @PostMapping("approveAnnualPersonnelTraining")
    public Result<?> approveAnnualPersonnelTraining(@RequestBody PersonTraining training) {
        personTrainingService.approveAnnualPersonnelTraining(training);
        return Result.success();
    }
    @ApiOperation(value = "年度计划明细表 æ–°å¢ž/编辑")
    @PostMapping("addOrUpdatePersonTrainingDetailed")
    public Result<?> addOrUpdatePersonTrainingDetailed(@RequestBody PersonTrainingDetailed personTrainingDetailed) {
        if (ObjectUtils.isEmpty(personTrainingDetailed.getId())) {
            personTrainingDetailed.setState(3);
        }
        personTrainingDetailedService.saveOrUpdate(personTrainingDetailed);
        return Result.success();
    }
    @ApiOperation(value = "年度计划明细表 æ‰¹é‡åˆ é™¤")
    @DeleteMapping("deleteAnnualPlanDetailTable")
    public Result<?> deleteAnnualPlanDetailTable(String ids) {
        personTrainingDetailedService.deleteAnnualPlanDetailTable(ids);
        return Result.success();
    }
    @ApiOperation(value = "年度计划明细表 æŸ¥è¯¢")
    @GetMapping("queryTheAnnualPlanDetailsTable")
    public Result<IPage<PersonTrainingDetailedDto>> queryTheAnnualPlanDetailsTable(Page page,
                                                                                   String trainingLecturerName, String courseCode,
                                                                                   String trainingDate, Integer id, Integer userId) {
        IPage<PersonTrainingDetailedDto> iPage = personTrainingDetailedService.queryTheAnnualPlanDetailsTable(page,
                trainingLecturerName, courseCode, trainingDate, id, userId);
        return Result.success(iPage);
    }
    @ApiOperation(value = "培训与考核记录 æŸ¥è¯¢")
    @GetMapping("trainingAndAssessmentRecordsPage")
    public Result<List<PersonTrainingRecordDto>> trainingAndAssessmentRecordsPage(Integer trainingDetailedId,
                                                                                   String userName) {
        List<PersonTrainingRecordDto> list = personTrainingRecordService.trainingAndAssessmentRecordsPage(trainingDetailedId, userName);
        return Result.success(list);
    }
    @ApiOperation(value = "培训与考核记录 æ–°å¢žäººå‘˜")
    @PostMapping("newPersonnelAddedToTrainingRecords")
    public Result<?> newPersonnelAddedToTrainingRecords(@RequestBody List<PersonTrainingRecord> personTrainingRecord) {
        personTrainingRecordService.saveBatch(personTrainingRecord);
        return Result.success();
    }
    @ApiOperation(value = "培训与考核记录 è®¤é¢†")
    @PostMapping("claimOfTrainingAndAssessmentRecords")
    public Result<?> claimOfTrainingAndAssessmentRecords(@RequestParam("claimAndClaim") Boolean claimAndClaim,
                                                         @RequestParam("courseId") Integer courseId) {
        personTrainingRecordService.claimOfTrainingAndAssessmentRecords(claimAndClaim, courseId);
        return Result.success();
    }
    @ApiOperation(value = "培训与考核记录 æäº¤/撤销")
    @PostMapping("trainingAndAssessmentRecordsAdded")
    public Result<?> trainingAndAssessmentRecordsAdded(@RequestBody PersonTrainingRecordSubmitDto personTrainingRecordSubmitDto) {
        personTrainingRecordService.trainingAndAssessmentRecordsAdded(personTrainingRecordSubmitDto);
        return Result.success();
    }
    @ApiOperation(value = "培训与考核记录 è¯„ä»·")
    @PostMapping("trainingAndAssessmentRecordsEvaluate")
    public Result<?> trainingAndAssessmentRecordsEvaluate(@RequestBody PersonTrainingRecordSubmitDto personTrainingRecordSubmitDto) {
        personTrainingDetailedService.update(Wrappers.<PersonTrainingDetailed>lambdaUpdate()
                .eq(PersonTrainingDetailed::getId, personTrainingRecordSubmitDto.getTrainingDetailedId())
                .set(PersonTrainingDetailed::getComprehensiveAssessment, personTrainingRecordSubmitDto.getComprehensiveAssessment())
                .set(PersonTrainingDetailed::getAssessmentDate, personTrainingRecordSubmitDto.getAssessmentDate())
                .set(PersonTrainingDetailed::getState, personTrainingRecordSubmitDto.getState()));
        return Result.success();
    }
    @ApiOperation(value = "培训与考核记录 åˆ é™¤")
    @DeleteMapping("deleteTrainingAndAssessmentRecords")
    public Result<?> deleteTrainingAndAssessmentRecords(String ids) {
        personTrainingRecordService.deleteTrainingAndAssessmentRecords(ids);
        return Result.success();
    }
    @PostMapping("outOfFocusPreservation")
    public Result<?> outOfFocusPreservation(@RequestBody PersonTrainingRecord personTrainingRecord) {
        personTrainingRecordService.updateById(personTrainingRecord);
        return Result.success();
    }
    /**
     * å¯¼å‡ºäººå‘˜åŸ¹è®­è®¡åˆ’
     * @return
     */
    @ApiOperation(value = "导出人员培训计划")
    @GetMapping("/exportPersonTraining")
    public void exportPersonTraining(Integer id, HttpServletResponse response){
        personTrainingService.exportPersonTraining(id, response);
    }
    /**
     * å¯¼å‡ºäººå‘˜åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½•
     * @return
     */
    @ApiOperation(value = "导出人员培训与考核记录")
    @GetMapping("/exportPersonTrainingRecord")
    public void exportPersonTrainingRecord(Integer id, HttpServletResponse response){
        personTrainingService.exportPersonTrainingRecord(id, response);
    }
    /**
     * äººå‘˜åŸ¹è®­è¯¦æƒ…附件新增
     * @param trainingDetailedId
     * @param file
     * @return
     */
    @ApiOperation(value = "人员培训详情附件新增")
    @PostMapping("/uploadTrainingDetailedFile")
    public Result<?> uploadTrainingDetailedFile(Integer trainingDetailedId, MultipartFile file) {
        return Result.success(personTrainingService.uploadTrainingDetailedFile(trainingDetailedId, file));
    }
    /**
     * äººå‘˜åŸ¹è®­è¯¦æƒ…附件列表
     * @return
     */
    @ApiOperation(value = "人员培训详情附件列表")
    @GetMapping("/getTrainingDetailedFileList")
    public Result<List<PersonTrainingDetailedFile>> getTrainingDetailedFileList(Integer trainingDetailedId){
        return Result.success(personTrainingDetailedFileMapper.selectList(Wrappers.<PersonTrainingDetailedFile>lambdaQuery()
                .eq(PersonTrainingDetailedFile::getTrainingDetailedId, trainingDetailedId)));
    }
    /**
     * äººå‘˜åŸ¹è®­è¯¦æƒ…附件删除
     * @return
     */
    @ApiOperation(value = "人员培训详情附件删除")
    @GetMapping("/delTrainingDetailedFileList")
    public Result delTrainingDetailedFileList(Integer detailedFileId){
        return Result.success(personTrainingDetailedFileMapper.deleteById(detailedFileId));
    }
    /**
     * æŸ¥è¯¢ä»Šå¹´äººå‘˜åŸ¹è®­ä¿¡æ¯
     * @return
     */
    @ApiOperation(value = "查询今年人员培训信息")
    @GetMapping("/getThisYearTrainingDetailed")
    public Result<List<PersonTrainingDetailed>> getThisYearTrainingDetailed(){
        return Result.success(personTrainingService.getThisYearTrainingDetailed());
    }
}
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonBasicInfoDetailsDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
package com.ruoyi.personnel.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
 * Author: yuan
 * Date: 2024-12-13 æ˜ŸæœŸäº” 13:52:52
 * Description:
 */
@Data
public class PersonBasicInfoDetailsDto {
    @ApiModelProperty("用户id")
    private Integer userId;
    @ApiModelProperty("用户姓名")
    private String name;
    @ApiModelProperty("入职时间")
    private String entryTimeStr;
    @ApiModelProperty("实际实习结束")
    private String endPracticalPracticeStr;
    @ApiModelProperty("籍贯")
    private String nativePlace;
    @ApiModelProperty("身份证号")
    private String identityCard;
    @ApiModelProperty("身份证地址")
    private String idAddress;
    @ApiModelProperty("用户手机号")
    private String phone;
    @ApiModelProperty("毕业院校")
    private String graduatedInstitutions1;
    @ApiModelProperty("专业")
    private String major1;
    @ApiModelProperty("毕业时间1")
    private LocalDateTime graduationTime1;
    @ApiModelProperty("最高学历")
    private String officialAcademicRedentials;
    @ApiModelProperty("最高学位")
    private String highestDegree;
    @ApiModelProperty("职称")
    private String professionalTitle;
    // èŒä¸šèƒ½åŠ›
    @ApiModelProperty("紧急联系人")
    private String emergencyContact;
    @ApiModelProperty("紧急联系人电话")
    private String emergencyContactPhone;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonBasicInfoWorkDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.personnel.dto;
import com.ruoyi.personnel.pojo.PersonBasicInfoWork;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @Author zhuo
 * @Date 2025/1/14
 */
@Data
public class PersonBasicInfoWorkDto extends PersonBasicInfoWork {
    @ApiModelProperty("填充使用")
    private String fill;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingDetailedDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.personnel.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.personnel.pojo.PersonTrainingDetailed;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class PersonTrainingDetailedDto extends PersonTrainingDetailed {
    @ApiModelProperty("举办部门名称")
    private String holdingDepartmentName;
    @ApiModelProperty("培训讲师名称")
    private String trainingLecturerName;
    @ApiModelProperty("当前登录人是否认领")
    private Boolean whetherClaim;
    @ApiModelProperty("培训日期")
    private String trainingDateString;
    // å¯¼å‡ºä½¿ç”¨
    @TableField(select = false, exist = false)
    @ApiModelProperty("序号(导出使用)")
    private Integer index;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.personnel.dto;
import com.ruoyi.personnel.pojo.PersonTraining;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "PersonTrainingDto对象", description = "培训计划")
public class PersonTrainingDto extends PersonTraining {
    @ApiModelProperty("编制人姓名")
    private String compilerName;
    @ApiModelProperty("审核人姓名")
    private String reviewerName;
    @ApiModelProperty("批准人姓名")
    private String approverName;
    @ApiModelProperty("创建人姓名")
    private String createUserName;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingRecordDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.personnel.dto;
import com.ruoyi.personnel.pojo.PersonTrainingRecord;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class PersonTrainingRecordDto extends PersonTrainingRecord {
    @ApiModelProperty(value = "姓名")
    private String userName;
    @ApiModelProperty(value = "工号")
    private String account;
    @ApiModelProperty(value = "角色")
    private String roleName;
    @ApiModelProperty(value = "电话号码")
    private String phone;
    @ApiModelProperty(value = "部门")
    private String department;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingRecordListDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package com.ruoyi.personnel.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class PersonTrainingRecordListDto {
    @ApiModelProperty(value = "用户id")
    private Integer userId;
    @ApiModelProperty("员工编号")
    private String account;
    @ApiModelProperty("用户姓名")
    private String name;
    @ApiModelProperty("所在部门")
    private String departLimsName;
    @ApiModelProperty("职称")
    private String professionalTitle;
    @ApiModelProperty("最高学历")
    private String officialAcademicRedentials;
    @ApiModelProperty("入单位时间")
    private LocalDateTime unitTime;
    @ApiModelProperty("入单位时间")
    private String unitTimeSting;
    @ApiModelProperty("专业")
    private String major1;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/PersonTrainingRecordSubmitDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package com.ruoyi.personnel.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDate;
@Data
public class PersonTrainingRecordSubmitDto {
    @ApiModelProperty("年度计划明细ID")
    private Integer trainingDetailedId;
    @ApiModelProperty("培训地点")
    private String placeTraining;
    @ApiModelProperty("培训完成时间")
    private LocalDate openingTime;
    @ApiModelProperty("考核方式")
    private String assessmentMethod;
    @ApiModelProperty("本次培训综合评价")
    private String comprehensiveAssessment;
    @ApiModelProperty("评价人")
    private Integer assessmentUserId;
    @ApiModelProperty("评价时间")
    private LocalDate assessmentDate;
    private Integer state;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/TrainingRecordExportDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.personnel.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @Author zhuo
 * @Date 2024/11/25
 */
@Data
public class TrainingRecordExportDto {
    @ApiModelProperty("用户名称1")
    private String userName1;
    @ApiModelProperty("部门1")
    private String department1;
    @ApiModelProperty("考核结果1")
    private String examinationResults1;
    @ApiModelProperty("用户名称2")
    private String userName2;
    @ApiModelProperty("部门1")
    private String department2;
    @ApiModelProperty("考核结果1")
    private String examinationResults2;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/dto/TrainingRecordPersonDetailedDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.personnel.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class TrainingRecordPersonDetailedDto {
    @ApiModelProperty("培训日期")
    private String trainingDateString;
    @ApiModelProperty("培训日期")
    private String trainingDate;
    @ApiModelProperty("培训内容")
    private String trainingContent;
    @ApiModelProperty("课时")
    private Integer classHour;
    @ApiModelProperty("考核结果")
    private String examinationResults;
    @ApiModelProperty("备注")
    private String remarks;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/excel/PersonTrainingDetailedListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.ruoyi.personnel.excel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ruoyi.personnel.service.PersonTrainingDetailedService;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class PersonTrainingDetailedListener extends AnalysisEventListener<PersonTrainingDetailedUpload> {
    private Integer planId;
    private static final int BATCH_COUNT = 1000;
    List<PersonTrainingDetailedUpload> list = new ArrayList<>();
    private PersonTrainingDetailedService personTrainingDetailedService;
    public PersonTrainingDetailedListener(PersonTrainingDetailedService personTrainingDetailedService) {
        this.personTrainingDetailedService = personTrainingDetailedService;
    }
    @Override
    public void invoke(PersonTrainingDetailedUpload data, AnalysisContext context) {
        list.add(data);
        if (list.size() >= BATCH_COUNT) {
            save();
            list.clear();
        }
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        save();
    }
    private void save() {
        personTrainingDetailedService.importExcel(list, this.planId);
    }
}
cnas-personnel/src/main/java/com/ruoyi/personnel/excel/PersonTrainingDetailedUpload.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package com.ruoyi.personnel.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class PersonTrainingDetailedUpload {
    @ExcelProperty("培训目标")
    private String trainingObjectives;
    @ExcelProperty("培训内容")
    private String trainingContent;
    @ExcelProperty("培训方式")
    private String trainingMode;
    @ExcelProperty("参加对象")
    private String participants;
    @ExcelProperty("举办部门")
    private String holdingDepartment;
    @ExcelProperty("培训讲师")
    private String trainingLecturerName;
    @ExcelProperty("培训时间")
    private String trainingDate;
    @ExcelProperty("课时")
    private Integer classHour;
    @ExcelProperty("备注")
    private String remarks;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/mapper/PersonTrainingDetailedFileMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.personnel.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.personnel.pojo.PersonTrainingDetailedFile;
/**
 * äººå‘˜åŸ¹è®­è®¡åˆ’详情附件表(CnasPersonTrainingDetailedFile)$desc
 *
 * @author makejava
 * @since 2024-12-25 14:18:22
 */
public interface PersonTrainingDetailedFileMapper extends BaseMapper<PersonTrainingDetailedFile> {
}
cnas-personnel/src/main/java/com/ruoyi/personnel/mapper/PersonTrainingDetailedMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package com.ruoyi.personnel.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.mybatis_config.MyBaseMapper;
import com.ruoyi.personnel.dto.PersonTrainingDetailedDto;
import com.ruoyi.personnel.pojo.PersonTrainingDetailed;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
 * åŸ¹è®­è®¡åˆ’详情 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-11 01:46:27
 */
public interface PersonTrainingDetailedMapper extends MyBaseMapper<PersonTrainingDetailed> {
    IPage<PersonTrainingDetailedDto> queryTheAnnualPlanDetailsTable(Page page,
                                                                    String trainingLecturerName,
                                                                    String courseCode, String trainingDate,
                                                                    Integer id,
                                                                    Integer userId,
                                                                    Integer loginUserId);
    /**
     * æ ¹æ®ä¸»è¡¨id查询详情
     * @param trainingId
     * @return
     */
    List<PersonTrainingDetailedDto> selectTrainingList(@Param("trainingId") Integer trainingId);
    /**
     * æŸ¥è¯¢è¯¦ç»†
     * @param id
     * @return
     */
    PersonTrainingDetailedDto selectTrainingDetail(@Param("id") Integer id);
    /**
     * æŸ¥è¯¢ä»Šå¹´äººå‘˜åŸ¹è®­ä¿¡æ¯
     * @return
     */
    List<PersonTrainingDetailed> getThisYearTrainingDetailed();
}
cnas-personnel/src/main/java/com/ruoyi/personnel/mapper/PersonTrainingMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.personnel.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.personnel.dto.PersonTrainingDto;
import com.ruoyi.personnel.pojo.PersonTraining;
/**
 * <p>
 * åŸ¹è®­è®¡åˆ’ Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-11 01:11:49
 */
public interface PersonTrainingMapper extends BaseMapper<PersonTraining> {
    IPage<PersonTrainingDto> personTrainingSelect(Page page, String compilerName, String departLimsId);
}
cnas-personnel/src/main/java/com/ruoyi/personnel/mapper/PersonTrainingRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.ruoyi.personnel.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.personnel.dto.PersonTrainingRecordDto;
import com.ruoyi.personnel.dto.PersonTrainingRecordListDto;
import com.ruoyi.personnel.dto.TrainingRecordPersonDetailedDto;
import com.ruoyi.personnel.pojo.PersonTrainingRecord;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
 * åŸ¹è®­è®°å½• Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-12 04:50:48
 */
public interface PersonTrainingRecordMapper extends BaseMapper<PersonTrainingRecord> {
    List<PersonTrainingRecordDto> trainingAndAssessmentRecordsPage(Integer trainingDetailedId, String userName);
    IPage<PersonTrainingRecordListDto> personnelTrainingPersonnel(Page page, String userName, Integer userId, Integer departLimsId);
    IPage<TrainingRecordPersonDetailedDto> queryPersonnelDetails(Page page, Integer userId);
    /**
     * æ ¹æ®è¯¦æƒ…id查询培训人员
     * @param trainingDetailedId
     * @return
     */
    List<PersonTrainingRecordDto> selectListByTrainingDetailedId(@Param("trainingDetailedId") Integer trainingDetailedId);
    /**
     * æŸ¥è¯¢äººå‘˜ä¿¡æ¯
     * @param userId
     * @return
     */
    PersonTrainingRecordListDto selectUserTraining(@Param("userId") Integer userId);
    /**
     * æ ¹æ®ç”¨æˆ·id查询培训记录
     * @param userId
     * @return
     */
    List<TrainingRecordPersonDetailedDto> selectPersonDetailedDtos(Integer userId);
    /**
     * æ ¹æ®ç”¨æˆ·id和年份查询人员明细 åŸ¹è®­è®°å½•
     * @param page
     * @param userId
     * @param year
     * @return
     */
    IPage<TrainingRecordPersonDetailedDto> queryPersonnelDetailsOfUserIdAndYear(Page page, Integer userId, Integer year);
    /**
     * æ ¹æ®ç”¨æˆ·id和年份查询人员明细 åŸ¹è®­è®°å½•导出
     * @param userId
     * @param trainingDate
     * @return
     */
    List<TrainingRecordPersonDetailedDto> selectPersonDetailedDtosByTrainingDate(Integer userId, Integer year);
}
cnas-personnel/src/main/java/com/ruoyi/personnel/pojo/PersonTraining.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
package com.ruoyi.personnel.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
 * <p>
 * åŸ¹è®­è®¡åˆ’
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-11 01:11:49
 */
@Getter
@Setter
@TableName("cnas_person_training")
@ApiModel(value = "PersonTraining对象", description = "培训计划")
public class PersonTraining implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("主键id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("文件名称")
    private String fileName;
    @ApiModelProperty("计划年份")
    private String planYear;
    @ApiModelProperty("编制人id")
    private Integer compilerId;
    @ApiModelProperty("编制日期")
    private LocalDateTime compilationDate;
    @ApiModelProperty("审核人id")
    private Integer reviewerId;
    @ApiModelProperty("审核日期")
    private LocalDateTime auditDate;
    @ApiModelProperty("审核状态")
    private Integer reviewerStatus;
    @ApiModelProperty("审核备注")
    private String auditRemarks;
    @ApiModelProperty("批准人id")
    private Integer approverId;
    @ApiModelProperty("批准备注")
    private String approvalRemarks;
    @ApiModelProperty("批准状态(1:批准;2:不批准)")
    private Integer approvalStatus;
    @ApiModelProperty("批准日期")
    private LocalDateTime approvalDate;
    @ApiModelProperty("创建日期")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty("创建人id")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty("更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty("更新人id")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/pojo/PersonTrainingDetailed.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
package com.ruoyi.personnel.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
 * <p>
 * åŸ¹è®­è®¡åˆ’详情
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-11 01:46:27
 */
@Getter
@Setter
@TableName("cnas_person_training_detailed")
@ApiModel(value = "PersonTrainingDetailed对象", description = "培训计划详情")
public class PersonTrainingDetailed implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("培训计划")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("培训目标")
    private String trainingObjectives;
    @ApiModelProperty("培训内容")
    private String trainingContent;
    @ApiModelProperty("培训方式")
    private String trainingMode;
    @ApiModelProperty("状态(1:已完成;2:待评价;3: æœªå¼€å§‹)")
    private Integer state;
    @ApiModelProperty("参加对象")
    private String participants;
    @ApiModelProperty("举办部门")
    private String holdingDepartment;
    @ApiModelProperty("培训地点")
    private String placeTraining;
    @ApiModelProperty("培训讲师_id")
    private Integer trainingLecturerId;
    @ApiModelProperty("计划培训日期")
    private String trainingDate;
    @ApiModelProperty("培训完成时间")
    private LocalDate openingTime;
    @ApiModelProperty("课时")
    private Integer classHour;
    @ApiModelProperty("备注")
    private String remarks;
    @ApiModelProperty("培训计划id")
    private Integer planId;
    @ApiModelProperty(value = "创建时间", hidden = true)
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "创建人id", hidden = true)
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "更新人id", hidden = true)
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "更新时间", hidden = true)
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty("考核方式")
    private String assessmentMethod;
    @ApiModelProperty("本次培训综合评价")
    private String comprehensiveAssessment;
    @ApiModelProperty("评价人")
    private Integer assessmentUserId;
    @ApiModelProperty("评价时间")
    private LocalDate assessmentDate;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/pojo/PersonTrainingDetailedFile.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
package com.ruoyi.personnel.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
 * äººå‘˜åŸ¹è®­è®¡åˆ’详情附件表(CnasPersonTrainingDetailedFile)$desc
 *
 * @author makejava
 * @since 2024-12-25 14:18:22
 */
@Data
@TableName("cnas_person_training_detailed_file")
public class PersonTrainingDetailedFile {
    @TableId(type = IdType.AUTO)
    private Integer detailedFileId;
    @ApiModelProperty("人员你培训计划详情id")
    private Integer trainingDetailedId;
    @ApiModelProperty("类型:1图片/2文件")
    private Integer type;
    @ApiModelProperty("附件路径")
    private String fileUrl;
    @ApiModelProperty("附件名称")
    private String fileName;
    @ApiModelProperty("创建人")
    private Integer createUser;
    @ApiModelProperty("创建时间")
    private Date createTime;
    @ApiModelProperty("修改人")
    private Integer updateUser;
    @ApiModelProperty("修改时间")
    private Date updateTime;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/pojo/PersonTrainingRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
package com.ruoyi.personnel.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
 * <p>
 * åŸ¹è®­è®°å½•
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-12 04:50:48
 */
@Getter
@Setter
@TableName("cnas_person_training_record")
@ApiModel(value = "PersonTrainingRecord对象", description = "培训记录")
public class PersonTrainingRecord implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("主键id")
    @TableId(value = "training_record_id", type = IdType.AUTO)
    private Integer trainingRecordId;
    @ApiModelProperty("用户表格(user)主键")
    private Integer userId;
    @ApiModelProperty("培训计划详情 - å­ id")
    private Integer courseId;
    @ApiModelProperty("考核结果")
    private String examinationResults;
}
cnas-personnel/src/main/java/com/ruoyi/personnel/service/PersonTrainingDetailedService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.personnel.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.personnel.dto.PersonTrainingDetailedDto;
import com.ruoyi.personnel.excel.PersonTrainingDetailedUpload;
import com.ruoyi.personnel.pojo.PersonTrainingDetailed;
import java.util.List;
/**
 * <p>
 * åŸ¹è®­è®¡åˆ’详情 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-11 01:46:27
 */
public interface PersonTrainingDetailedService extends IService<PersonTrainingDetailed> {
    void importExcel(List<PersonTrainingDetailedUpload> list, Integer planId);
    void deleteAnnualPlanDetailTable(String ids);
    IPage<PersonTrainingDetailedDto> queryTheAnnualPlanDetailsTable(Page page,
                                                                    String trainingLecturerName,
                                                                    String courseCode, String trainingDate, Integer id, Integer userId);
}
cnas-personnel/src/main/java/com/ruoyi/personnel/service/PersonTrainingRecordService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.ruoyi.personnel.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.personnel.dto.PersonTrainingRecordDto;
import com.ruoyi.personnel.dto.PersonTrainingRecordListDto;
import com.ruoyi.personnel.dto.PersonTrainingRecordSubmitDto;
import com.ruoyi.personnel.dto.TrainingRecordPersonDetailedDto;
import com.ruoyi.personnel.pojo.PersonTrainingRecord;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * <p>
 * åŸ¹è®­è®°å½• æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-12 04:50:48
 */
public interface PersonTrainingRecordService extends IService<PersonTrainingRecord> {
    List<PersonTrainingRecordDto> trainingAndAssessmentRecordsPage(Integer trainingDetailedId, String userName);
    void deleteTrainingAndAssessmentRecords(String ids);
    IPage<PersonTrainingRecordListDto> personnelTrainingPersonnel(Page page,
                                                                  String userName, Integer userId, Integer departLimsId);
    void claimOfTrainingAndAssessmentRecords(Boolean claimAndClaim, Integer courseId);
    /**
     * æ ¹æ®ç”¨æˆ·id和年份查询人员明细 åŸ¹è®­è®°å½•
     * @param page
     * @param userId
     * @param year
     * @return
     */
    IPage<TrainingRecordPersonDetailedDto> queryPersonnelDetailsOfUserIdAndYear(Page page, Integer userId, Integer year);
    /**
     * å¯¼å‡ºäººå‘˜åŸ¹è®­è®°å½•
     * @param userId
     * @param trainingDate
     * @param response
     */
    void exportTrainingRecordAddTrainingDate(Integer userId, Integer trainingDate, HttpServletResponse response);
    /**
     * åŸ¹è®­æäº¤
     * @param personTrainingRecordSubmitDto
     */
    void trainingAndAssessmentRecordsAdded(PersonTrainingRecordSubmitDto personTrainingRecordSubmitDto);
}
cnas-personnel/src/main/java/com/ruoyi/personnel/service/PersonTrainingService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.ruoyi.personnel.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.personnel.dto.PersonTrainingDto;
import com.ruoyi.personnel.pojo.PersonTraining;
import com.ruoyi.personnel.pojo.PersonTrainingDetailed;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * <p>
 * åŸ¹è®­è®¡åˆ’ æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-11 01:11:49
 */
public interface PersonTrainingService extends IService<PersonTraining> {
    IPage<PersonTrainingDto> personTrainingSelect(Page page,
                                                  String compilerName, String departmentId);
    void personTrainingImport(MultipartFile file, PersonTraining training);
    void personTrainingDelete(Integer id);
    void reviewAnnualPersonnelTraining(PersonTraining training);
    void approveAnnualPersonnelTraining(PersonTraining training);
    /**
     * å¯¼å‡ºäººå‘˜åŸ¹è®­è®¡åˆ’
     * @param id
     * @param response
     */
    void exportPersonTraining(Integer id, HttpServletResponse response);
    /**
     * å¯¼å‡ºäººå‘˜åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½•
     * @param id
     * @param response
     */
    void exportPersonTrainingRecord(Integer id, HttpServletResponse response);
    /**
     * äººå‘˜åŸ¹è®­è¯¦æƒ…附件新增
     * @param trainingDetailedId
     * @param file
     * @return
     */
    boolean uploadTrainingDetailedFile(Integer trainingDetailedId, MultipartFile file);
    /**
     * æŸ¥è¯¢ä»Šå¹´äººå‘˜åŸ¹è®­ä¿¡æ¯
     * @return
     */
    List<PersonTrainingDetailed> getThisYearTrainingDetailed();
}
cnas-personnel/src/main/java/com/ruoyi/personnel/service/impl/PersonBasicInfoServiceImpl.java
@@ -1,336 +1,340 @@
//package com.ruoyi.personnel.service.impl;
//
//import com.alibaba.excel.EasyExcel;
//import com.alibaba.excel.ExcelWriter;
//import com.alibaba.excel.write.metadata.WriteSheet;
//import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
//import com.alibaba.fastjson2.JSON;
//import com.alibaba.fastjson2.JSONObject;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.ruoyi.common.core.domain.entity.DepartmentDto;
//import com.ruoyi.common.core.domain.entity.DepartmentLims;
//import com.ruoyi.common.core.domain.entity.User;
//import com.ruoyi.common.utils.QueryWrappers;
//import com.ruoyi.framework.exception.ErrorException;
//import com.ruoyi.personnel.dto.PersonBasicInfoDto;
//import com.ruoyi.personnel.dto.UserPageDto;
//import com.ruoyi.personnel.mapper.AnnexMapper;
//import com.ruoyi.personnel.mapper.PersonBasicInfoFileMapper;
//import com.ruoyi.personnel.mapper.PersonBasicInfoMapper;
//import com.ruoyi.personnel.mapper.PersonBasicInfoWorkMapper;
//import com.ruoyi.personnel.pojo.Annex;
//import com.ruoyi.personnel.pojo.PersonBasicInfo;
//import com.ruoyi.personnel.pojo.PersonBasicInfoFile;
//import com.ruoyi.personnel.pojo.PersonBasicInfoWork;
//import com.ruoyi.personnel.service.PersonBasicInfoService;
//import com.ruoyi.system.mapper.DepartmentLimsMapper;
//import com.ruoyi.system.mapper.UserMapper;
//import org.apache.poi.xwpf.usermodel.XWPFTable;
//import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//import org.springframework.web.multipart.MultipartFile;
//
//import javax.annotation.Resource;
//import javax.servlet.http.HttpServletResponse;
//import java.io.File;
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.OutputStream;
//import java.net.URLEncoder;
//import java.time.LocalDateTime;
//import java.time.format.DateTimeFormatter;
//import java.util.*;
//import java.util.stream.Collectors;
//
///**
// * <p>
// *  æœåŠ¡å®žçŽ°ç±»
// * </p>
// *
// * @author æ±Ÿè‹éµ·é›ç½‘络科技有限公司
// * @since 2024-08-30 09:19:57
// */
//
//@Service
//@Transactional(rollbackFor = Exception.class)
//public class PersonBasicInfoServiceImpl extends ServiceImpl<PersonBasicInfoMapper, PersonBasicInfo> implements PersonBasicInfoService {
//
//    @Autowired
//    private DepartmentLimsMapper departmentMapper;
//    @Value("${file.path}")
//    private String imgUrl;
//    @Value("${wordUrl}")
//    private String wordUrl;
//    @Resource
//    private UserMapper userMapper;
//    @Resource
//    private AnnexMapper annexMapper;
//    @Resource
//    private PersonBasicInfoFileMapper personBasicInfoFileMapper;
//    @Resource
//    private PersonBasicInfoWorkMapper personBasicInfoWorkMapper;
//
//    @Override
//    public List<DepartmentDto> selectCNSAPersonTree() {
//        List<DepartmentDto> departments = departmentMapper.selectDepartment();
//        List<DepartmentDto> limsUser = baseMapper.selectLimsUser();
//        departments.addAll(limsUser);
//        //获取父节点
//        return departments.stream().filter(m -> m.getFatherId() == null).peek(
//                (m) -> m.setChildren(getChildren(m, departments))
//        ).collect(Collectors.toList());
//    }
//
//    @Override
//    public Map<String,Object> getCNASPersonnelInfo(Integer userId) {
//        Map<String, Object> map = new HashMap<>();
//        Map<Integer,List<DepartmentLims>>  childrenMap = new HashMap<>();
//        List<DepartmentLims> deptS = departmentMapper.selectList(null);
//        for (DepartmentLims dept : deptS) {
//            if(!Objects.isNull(dept.getFatherId())) {
//                if(!childrenMap.containsKey(dept.getFatherId())) {
//                        childrenMap.put(dept.getFatherId(),new ArrayList<>());
//                }
//                childrenMap.get(dept.getFatherId()).add(dept);
//            }
//        }
//        // çˆ¶èŠ‚ç‚¹
//        List<DepartmentLims> deptF = new ArrayList<>();
//        for (DepartmentLims dept : deptS) {
//            if(Objects.isNull(dept.getFatherId())) {
//                deptF.add(buildTree(dept,childrenMap));
//            }
//        }
//        map.put("department",deptF);
//        map.put("PersonBasicInfoDto",baseMapper.getCNASPersonnelInfo(userId));
//        map.put("annexList",annexMapper.selectList(new LambdaQueryWrapper<Annex>().eq(Annex::getUserId,userId)));
//        return map;
//    }
//
//    private DepartmentLims buildTree(DepartmentLims departmentLims, Map<Integer,List<DepartmentLims>> childrenMap) {
//        if(childrenMap.containsKey(departmentLims.getId())) {
//            departmentLims.setChildren(childrenMap.get(departmentLims.getId()));
//            for (DepartmentLims departmentLims1 : departmentLims.getChildren()) {
//                buildTree(departmentLims1,childrenMap);
//            }
//        }
//        return departmentLims;
//    }
//
//    @Override
//    public void saveCNASPersonnelInfo(PersonBasicInfoDto personBasicInfoDto) {
//        User user = new User();
//        user.setId(personBasicInfoDto.getUserId());
//        user.setAccount(personBasicInfoDto.getAccount());
//        user.setName(personBasicInfoDto.getName());
//        user.setNameEn(personBasicInfoDto.getNameEn());
//        user.setAge(personBasicInfoDto.getAge());
//        user.setPhone(personBasicInfoDto.getPhone());
//        user.setEmail(personBasicInfoDto.getEmail());
//        user.setSignatureUrl(personBasicInfoDto.getSignatureUrl());
//        user.setPictureUrl(personBasicInfoDto.getPictureUrl());
//        user.setDepartLimsId(personBasicInfoDto.getDepartLimsId());
//        userMapper.updateById(user);
//        PersonBasicInfo personBasicInfo = JSONObject.parseObject(JSON.toJSONString(personBasicInfoDto), PersonBasicInfo.class);
//        PersonBasicInfo one = baseMapper.selectOne(new LambdaQueryWrapper<PersonBasicInfo>()
//                .eq(PersonBasicInfo::getUserId, personBasicInfoDto.getUserId()));
//        if(Objects.isNull(one)) {
//            baseMapper.insert(personBasicInfo);
//        }else {
//            baseMapper.updateById(personBasicInfo);
//        }
//    }
//
//    @Override
//    public IPage<Map<String, Object>> basicInformationOfPersonnelSelectPage(Page page, String name, Integer departmentId) {
//        return baseMapper.selectPersonBasecInfoAndUser(page, name, departmentId);
//    }
//
//    @Override
//    public void exportPersonBasicInfo(UserPageDto userPageDto, HttpServletResponse response) throws Exception {
//        ArrayList<PersonBasicInfoDto> data = new ArrayList<>();
//        List<User> list = userMapper.selectUserDtoPageList(new Page(-1, -1), QueryWrappers.queryWrappers(userPageDto)).getRecords();
//        for (User user : list) {
//            PersonBasicInfoDto personBasicInfoDto = new PersonBasicInfoDto();
//            PersonBasicInfo personBasicInfo = baseMapper.selectOne(Wrappers.<PersonBasicInfo>lambdaQuery().eq(PersonBasicInfo::getUserId, user.getId()));
//            if (ObjectUtils.isNotEmpty(personBasicInfo)) {
//                BeanUtils.copyProperties(personBasicInfo, personBasicInfoDto);
//            }
//            personBasicInfoDto.setName(user.getName());
//            personBasicInfoDto.setAccount(user.getAccount());
//            personBasicInfoDto.setPhone(ObjectUtils.isNotEmpty(user.getPhone()) ? user.getPhone() : " ");
//            data.add(personBasicInfoDto);
//        }
//        response.setContentType("application/vnd.ms-excel");
//        response.setCharacterEncoding("UTF-8");
//        String fileName = URLEncoder.encode("人员基本信息列表导出", "UTF-8");
//        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
//        try {
//            // æ–°å»ºExcelWriter
//            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
//            WriteSheet mainSheet = EasyExcel.writerSheet(0, "人员基本信息导出").head(PersonBasicInfoDto.class).build();
//            excelWriter.write(data, mainSheet);
//            // å…³é—­æµ
//            excelWriter.finish();
//        } catch (IOException e) {
//            throw new RuntimeException("导出失败");
//        }
//    }
//
//    @Override
//    public String exportPersonBasicInfoById(Integer id, HttpServletResponse response) {
//        Map<String, Object> userMap = baseMapper.selectexportPersonBasic(id);
//        User user = userMapper.selectById(id);
//        PersonBasicInfo personBasicInfo = baseMapper.selectOne(Wrappers.<PersonBasicInfo>lambdaQuery().eq(PersonBasicInfo::getUserId, user.getId()));
//        if (ObjectUtils.isEmpty(personBasicInfo)){
//            throw new ErrorException("该用户的基本信息没有录入,暂无法导出");
//        }
//        // è¯ä»¶
//        List<Annex> annexList = annexMapper.selectList(Wrappers.<Annex>lambdaQuery()
//                .eq(Annex::getUserId, id));
//        // å·¥ä½œç»åކ
//        List<PersonBasicInfoWork> personBasicInfoWorks = personBasicInfoWorkMapper.selectList(Wrappers.<PersonBasicInfoWork>lambdaQuery()
//                .eq(PersonBasicInfoWork::getUserId, id));
//
//        List<PersonBasicInfoWorkDto> workList = personBasicInfoWorks.stream().map(basicInfoWork -> {
//            PersonBasicInfoWorkDto personBasicInfoWorkDto = new PersonBasicInfoWorkDto();
//            personBasicInfoWorkDto.setWorkExperience(basicInfoWork.getWorkExperience());
//            personBasicInfoWorkDto.setFill("主要工作经历\nMain work experience∑1");
//            return personBasicInfoWorkDto;
//        }).collect(Collectors.toList());
//
//        // æ£€æŸ¥åˆ—表长度并填充空对象
//        while (annexList.size() < 10) {
//            annexList.add(new Annex());
//        }
//
//        // æ£€æŸ¥åˆ—表长度并填充空对象
//        while (workList.size() < 4) {
//            workList.add(new PersonBasicInfoWorkDto());
//        }
//
//        // èŽ·å–è·¯å¾„
//        InputStream inputStream = this.getClass().getResourceAsStream("/static/person-basic-info.docx");
//        Configure configure = Configure.builder()
//                .bind("annexList", new HackLoopTableRenderPolicy())
//                .bind("workList", new HackLoopTableRenderPolicy())
//                .build();
//        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
//                new HashMap<String, Object>() {{
//                    put("user", userMap);
//                    put("annexList", annexList);
//                    put("workList", workList);
//                }});
//
//        try {
//            response.setContentType("application/msword");
//            String fileName = URLEncoder.encode(
//                    userMap.get("name") + "人员档案", "UTF-8");
//            response.setHeader("Content-disposition",
//                    "attachment;filename=" + fileName + ".docx");
//            OutputStream os = response.getOutputStream();
//            template.write(os);
//            os.flush();
//            os.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new RuntimeException("导出失败");
//        }
//
//        return null;
//    }
//
//    /**
//     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件新增
//     * @param userId
//     * @param file
//     * @return
//     */
//    @Override
//    public boolean uploadBasicInfoFile(Integer userId, MultipartFile file) {
//        if (userId == null) {
//            throw new ErrorException("缺少人员id");
//        }
//
//        String urlString;
//        String pathName;
//        String path;
//        String filename = file.getOriginalFilename();
//        String contentType = file.getContentType();
//        PersonBasicInfoFile personBasicInfoFile = new PersonBasicInfoFile();
//        personBasicInfoFile.setUserId(userId);
//        personBasicInfoFile.setFileName(filename);
//        if (contentType != null && contentType.startsWith("image/")) {
//            // æ˜¯å›¾ç‰‡
//            path = imgUrl;
//            personBasicInfoFile.setType(1);
//        } else {
//            // æ˜¯æ–‡ä»¶
//            path = wordUrl;
//            personBasicInfoFile.setType(2);
//        }
//        try {
//            File realpath = new File(path);
//            if (!realpath.exists()) {
//                realpath.mkdirs();
//            }
//            pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "_" + file.getOriginalFilename();
//            urlString = realpath + "/" + pathName;
//            file.transferTo(new File(urlString));
//            personBasicInfoFile.setFileUrl(pathName);
//            personBasicInfoFileMapper.insert(personBasicInfoFile);
//            return true;
//        } catch (Exception e) {
//            e.printStackTrace();
//            System.err.println("附件上传错误");
//            return false;
//        }
//    }
//
//    /**
//     * é€’归查询子节点
//     * @param root  æ ¹èŠ‚ç‚¹
//     * @param all   æ‰€æœ‰èŠ‚ç‚¹
//     * @return æ ¹èŠ‚ç‚¹ä¿¡æ¯
//     */
//    private List<DepartmentDto> getChildren(DepartmentDto root, List<DepartmentDto> all) {
//        if (ObjectUtils.isNotEmpty(root.getId())) {
//            return all.stream().filter(m -> Objects.equals(m.getFatherId(), root.getId())).peek(
//                    (m) -> m.setChildren(getChildren(m, all))
//            ).collect(Collectors.toList());
//        } else {
//            return Collections.emptyList();
//        }
//    }
//
//    // æ°´å¹³åˆå¹¶å•元格
//    private static void mergeCellsHorizontally(XWPFTable table, int row, int fromCol, int toCol) {
//        for (int i = fromCol; i <= toCol; i++) {
//            if (i == fromCol) {
//                table.getRow(row).getCell(i).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
//            } else {
//                table.getRow(row).getCell(i).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
//            }
//        }
//    }
//
//    // åž‚直合并单元格
//    private static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
//        for (int i = fromRow; i <= toRow; i++) {
//            if (i == fromRow) {
//                table.getRow(i).getCell(col).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
//            } else {
//                table.getRow(i).getCell(col).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
//            }
//        }
//    }
//}
package com.ruoyi.personnel.service.impl;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.core.domain.entity.DepartmentDto;
import com.ruoyi.common.core.domain.entity.DepartmentLims;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.utils.QueryWrappers;
import com.ruoyi.framework.exception.ErrorException;
import com.ruoyi.inspect.util.HackLoopTableRenderPolicy;
import com.ruoyi.personnel.dto.PersonBasicInfoDto;
import com.ruoyi.personnel.dto.PersonBasicInfoWorkDto;
import com.ruoyi.personnel.dto.UserPageDto;
import com.ruoyi.personnel.mapper.AnnexMapper;
import com.ruoyi.personnel.mapper.PersonBasicInfoFileMapper;
import com.ruoyi.personnel.mapper.PersonBasicInfoMapper;
import com.ruoyi.personnel.mapper.PersonBasicInfoWorkMapper;
import com.ruoyi.personnel.pojo.Annex;
import com.ruoyi.personnel.pojo.PersonBasicInfo;
import com.ruoyi.personnel.pojo.PersonBasicInfoFile;
import com.ruoyi.personnel.pojo.PersonBasicInfoWork;
import com.ruoyi.personnel.service.PersonBasicInfoService;
import com.ruoyi.system.mapper.DepartmentLimsMapper;
import com.ruoyi.system.mapper.UserMapper;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
 * <p>
 *  æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author æ±Ÿè‹éµ·é›ç½‘络科技有限公司
 * @since 2024-08-30 09:19:57
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PersonBasicInfoServiceImpl extends ServiceImpl<PersonBasicInfoMapper, PersonBasicInfo> implements PersonBasicInfoService {
    @Autowired
    private DepartmentLimsMapper departmentMapper;
    @Value("${file.path}")
    private String imgUrl;
    @Value("${wordUrl}")
    private String wordUrl;
    @Resource
    private UserMapper userMapper;
    @Resource
    private AnnexMapper annexMapper;
    @Resource
    private PersonBasicInfoFileMapper personBasicInfoFileMapper;
    @Resource
    private PersonBasicInfoWorkMapper personBasicInfoWorkMapper;
    @Override
    public List<DepartmentDto> selectCNSAPersonTree() {
        List<DepartmentDto> departments = departmentMapper.selectDepartment();
        List<DepartmentDto> limsUser = baseMapper.selectLimsUser();
        departments.addAll(limsUser);
        //获取父节点
        return departments.stream().filter(m -> m.getFatherId() == null).peek(
                (m) -> m.setChildren(getChildren(m, departments))
        ).collect(Collectors.toList());
    }
    @Override
    public Map<String,Object> getCNASPersonnelInfo(Integer userId) {
        Map<String, Object> map = new HashMap<>();
        Map<Integer,List<DepartmentLims>>  childrenMap = new HashMap<>();
        List<DepartmentLims> deptS = departmentMapper.selectList(null);
        for (DepartmentLims dept : deptS) {
            if(!Objects.isNull(dept.getFatherId())) {
                if(!childrenMap.containsKey(dept.getFatherId())) {
                        childrenMap.put(dept.getFatherId(),new ArrayList<>());
                }
                childrenMap.get(dept.getFatherId()).add(dept);
            }
        }
        // çˆ¶èŠ‚ç‚¹
        List<DepartmentLims> deptF = new ArrayList<>();
        for (DepartmentLims dept : deptS) {
            if(Objects.isNull(dept.getFatherId())) {
                deptF.add(buildTree(dept,childrenMap));
            }
        }
        map.put("department",deptF);
        map.put("PersonBasicInfoDto",baseMapper.getCNASPersonnelInfo(userId));
        map.put("annexList",annexMapper.selectList(new LambdaQueryWrapper<Annex>().eq(Annex::getUserId,userId)));
        return map;
    }
    private DepartmentLims buildTree(DepartmentLims departmentLims, Map<Integer,List<DepartmentLims>> childrenMap) {
        if(childrenMap.containsKey(departmentLims.getId())) {
            departmentLims.setChildren(childrenMap.get(departmentLims.getId()));
            for (DepartmentLims departmentLims1 : departmentLims.getChildren()) {
                buildTree(departmentLims1,childrenMap);
            }
        }
        return departmentLims;
    }
    @Override
    public void saveCNASPersonnelInfo(PersonBasicInfoDto personBasicInfoDto) {
        User user = new User();
        user.setId(personBasicInfoDto.getUserId());
        user.setAccount(personBasicInfoDto.getAccount());
        user.setName(personBasicInfoDto.getName());
        user.setNameEn(personBasicInfoDto.getNameEn());
        user.setAge(personBasicInfoDto.getAge());
        user.setPhone(personBasicInfoDto.getPhone());
        user.setEmail(personBasicInfoDto.getEmail());
        user.setSignatureUrl(personBasicInfoDto.getSignatureUrl());
        user.setPictureUrl(personBasicInfoDto.getPictureUrl());
        user.setDepartLimsId(personBasicInfoDto.getDepartLimsId());
        userMapper.updateById(user);
        PersonBasicInfo personBasicInfo = JSONObject.parseObject(JSON.toJSONString(personBasicInfoDto), PersonBasicInfo.class);
        PersonBasicInfo one = baseMapper.selectOne(new LambdaQueryWrapper<PersonBasicInfo>()
                .eq(PersonBasicInfo::getUserId, personBasicInfoDto.getUserId()));
        if(Objects.isNull(one)) {
            baseMapper.insert(personBasicInfo);
        }else {
            baseMapper.updateById(personBasicInfo);
        }
    }
    @Override
    public IPage<Map<String, Object>> basicInformationOfPersonnelSelectPage(Page page, String name, Integer departmentId) {
        return baseMapper.selectPersonBasecInfoAndUser(page, name, departmentId);
    }
    @Override
    public void exportPersonBasicInfo(UserPageDto userPageDto, HttpServletResponse response) throws Exception {
        ArrayList<PersonBasicInfoDto> data = new ArrayList<>();
        List<User> list = userMapper.selectList(null);
        for (User user : list) {
            PersonBasicInfoDto personBasicInfoDto = new PersonBasicInfoDto();
            PersonBasicInfo personBasicInfo = baseMapper.selectOne(Wrappers.<PersonBasicInfo>lambdaQuery().eq(PersonBasicInfo::getUserId, user.getId()));
            if (ObjectUtils.isNotEmpty(personBasicInfo)) {
                BeanUtils.copyProperties(personBasicInfo, personBasicInfoDto);
            }
            personBasicInfoDto.setName(user.getName());
            personBasicInfoDto.setAccount(user.getAccount());
            personBasicInfoDto.setPhone(ObjectUtils.isNotEmpty(user.getPhone()) ? user.getPhone() : " ");
            data.add(personBasicInfoDto);
        }
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("UTF-8");
        String fileName = URLEncoder.encode("人员基本信息列表导出", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        try {
            // æ–°å»ºExcelWriter
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
            WriteSheet mainSheet = EasyExcel.writerSheet(0, "人员基本信息导出").head(PersonBasicInfoDto.class).build();
            excelWriter.write(data, mainSheet);
            // å…³é—­æµ
            excelWriter.finish();
        } catch (IOException e) {
            throw new RuntimeException("导出失败");
        }
    }
    @Override
    public String exportPersonBasicInfoById(Integer id, HttpServletResponse response) {
        Map<String, Object> userMap = baseMapper.selectexportPersonBasic(id);
        User user = userMapper.selectById(id);
        PersonBasicInfo personBasicInfo = baseMapper.selectOne(Wrappers.<PersonBasicInfo>lambdaQuery().eq(PersonBasicInfo::getUserId, user.getId()));
        if (ObjectUtils.isEmpty(personBasicInfo)){
            throw new ErrorException("该用户的基本信息没有录入,暂无法导出");
        }
        // è¯ä»¶
        List<Annex> annexList = annexMapper.selectList(Wrappers.<Annex>lambdaQuery()
                .eq(Annex::getUserId, id));
        // å·¥ä½œç»åކ
        List<PersonBasicInfoWork> personBasicInfoWorks = personBasicInfoWorkMapper.selectList(Wrappers.<PersonBasicInfoWork>lambdaQuery()
                .eq(PersonBasicInfoWork::getUserId, id));
        List<PersonBasicInfoWorkDto> workList = personBasicInfoWorks.stream().map(basicInfoWork -> {
            PersonBasicInfoWorkDto personBasicInfoWorkDto = new PersonBasicInfoWorkDto();
            personBasicInfoWorkDto.setWorkExperience(basicInfoWork.getWorkExperience());
            personBasicInfoWorkDto.setFill("主要工作经历\nMain work experience∑1");
            return personBasicInfoWorkDto;
        }).collect(Collectors.toList());
        // æ£€æŸ¥åˆ—表长度并填充空对象
        while (annexList.size() < 10) {
            annexList.add(new Annex());
        }
        // æ£€æŸ¥åˆ—表长度并填充空对象
        while (workList.size() < 4) {
            workList.add(new PersonBasicInfoWorkDto());
        }
        // èŽ·å–è·¯å¾„
        InputStream inputStream = this.getClass().getResourceAsStream("/static/person-basic-info.docx");
        Configure configure = Configure.builder()
                .bind("annexList", new HackLoopTableRenderPolicy())
                .bind("workList", new HackLoopTableRenderPolicy())
                .build();
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("user", userMap);
                    put("annexList", annexList);
                    put("workList", workList);
                }});
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode(
                    userMap.get("name") + "人员档案", "UTF-8");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
        return null;
    }
    /**
     * äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件新增
     * @param userId
     * @param file
     * @return
     */
    @Override
    public boolean uploadBasicInfoFile(Integer userId, MultipartFile file) {
        if (userId == null) {
            throw new ErrorException("缺少人员id");
        }
        String urlString;
        String pathName;
        String path;
        String filename = file.getOriginalFilename();
        String contentType = file.getContentType();
        PersonBasicInfoFile personBasicInfoFile = new PersonBasicInfoFile();
        personBasicInfoFile.setUserId(userId);
        personBasicInfoFile.setFileName(filename);
        if (contentType != null && contentType.startsWith("image/")) {
            // æ˜¯å›¾ç‰‡
            path = imgUrl;
            personBasicInfoFile.setType(1);
        } else {
            // æ˜¯æ–‡ä»¶
            path = wordUrl;
            personBasicInfoFile.setType(2);
        }
        try {
            File realpath = new File(path);
            if (!realpath.exists()) {
                realpath.mkdirs();
            }
            pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "_" + file.getOriginalFilename();
            urlString = realpath + "/" + pathName;
            file.transferTo(new File(urlString));
            personBasicInfoFile.setFileUrl(pathName);
            personBasicInfoFileMapper.insert(personBasicInfoFile);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("附件上传错误");
            return false;
        }
    }
    /**
     * é€’归查询子节点
     * @param root  æ ¹èŠ‚ç‚¹
     * @param all   æ‰€æœ‰èŠ‚ç‚¹
     * @return æ ¹èŠ‚ç‚¹ä¿¡æ¯
     */
    private List<DepartmentDto> getChildren(DepartmentDto root, List<DepartmentDto> all) {
        if (ObjectUtils.isNotEmpty(root.getId())) {
            return all.stream().filter(m -> Objects.equals(m.getFatherId(), root.getId())).peek(
                    (m) -> m.setChildren(getChildren(m, all))
            ).collect(Collectors.toList());
        } else {
            return Collections.emptyList();
        }
    }
    // æ°´å¹³åˆå¹¶å•元格
    private static void mergeCellsHorizontally(XWPFTable table, int row, int fromCol, int toCol) {
        for (int i = fromCol; i <= toCol; i++) {
            if (i == fromCol) {
                table.getRow(row).getCell(i).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                table.getRow(row).getCell(i).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }
    // åž‚直合并单元格
    private static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
        for (int i = fromRow; i <= toRow; i++) {
            if (i == fromRow) {
                table.getRow(i).getCell(col).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                table.getRow(i).getCell(col).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }
}
cnas-personnel/src/main/java/com/ruoyi/personnel/service/impl/PersonTrainingDetailedServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
package com.ruoyi.personnel.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.numgen.NumberGenerator;
import com.ruoyi.framework.exception.ErrorException;
import com.ruoyi.personnel.dto.PersonTrainingDetailedDto;
import com.ruoyi.personnel.excel.PersonTrainingDetailedUpload;
import com.ruoyi.personnel.mapper.PersonTrainingDetailedMapper;
import com.ruoyi.personnel.pojo.PersonTrainingDetailed;
import com.ruoyi.personnel.service.PersonTrainingDetailedService;
import com.ruoyi.system.mapper.UserMapper;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
 * <p>
 * åŸ¹è®­è®¡åˆ’详情 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-11 01:46:27
 */
@Service
@Transactional(rollbackFor = Exception.class)
@AllArgsConstructor
public class PersonTrainingDetailedServiceImpl extends ServiceImpl<PersonTrainingDetailedMapper, PersonTrainingDetailed> implements PersonTrainingDetailedService {
    private UserMapper userMapper;
    @Override
    public void importExcel(List<PersonTrainingDetailedUpload> list, Integer planId) {
        List<PersonTrainingDetailed> personTrainingDetailedList = new ArrayList<>();
        list.forEach(i -> {
            PersonTrainingDetailed personTrainingDetailed = new PersonTrainingDetailed();
            BeanUtils.copyProperties(i, personTrainingDetailed);
            // åŒ¹é…è®²å¸ˆ
            User user = userMapper.selectOne(Wrappers.<User>lambdaQuery()
                    .eq(User::getName, i.getTrainingLecturerName()));
            if (ObjectUtils.isEmpty(user)) {
                throw new ErrorException("未找到该讲师:" + i.getTrainingLecturerName());
            }
            personTrainingDetailed.setTrainingLecturerId(user.getId());
            personTrainingDetailed.setPlanId(planId);
            personTrainingDetailed.setState(3);
            personTrainingDetailed.setTrainingDate(i.getTrainingDate());
            personTrainingDetailedList.add(personTrainingDetailed);
        });
        // æ‰¹é‡æ–°å¢ž
        if (CollectionUtils.isNotEmpty(personTrainingDetailedList)) {
            baseMapper.insertBatchSomeColumn(personTrainingDetailedList);
        }
    }
    @Override
    public void deleteAnnualPlanDetailTable(String ids) {
        String[] split = ids.split(",");
        if (split.length > 0) {
            for (String s : split) {
                baseMapper.deleteById(s);
            }
        }
    }
    @Override
    public IPage<PersonTrainingDetailedDto> queryTheAnnualPlanDetailsTable(Page page, String trainingLecturerName, String courseCode, String trainingDate, Integer id, Integer userId) {
        return baseMapper.queryTheAnnualPlanDetailsTable(page, trainingLecturerName, courseCode, trainingDate, id, userId, null);
    }
}
cnas-personnel/src/main/java/com/ruoyi/personnel/service/impl/PersonTrainingRecordServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,177 @@
package com.ruoyi.personnel.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.core.domain.entity.InformationNotification;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.WxCpUtils;
import com.ruoyi.inspect.util.HackLoopTableRenderPolicy;
import com.ruoyi.personnel.dto.PersonTrainingRecordDto;
import com.ruoyi.personnel.dto.PersonTrainingRecordListDto;
import com.ruoyi.personnel.dto.PersonTrainingRecordSubmitDto;
import com.ruoyi.personnel.dto.TrainingRecordPersonDetailedDto;
import com.ruoyi.personnel.mapper.PersonTrainingRecordMapper;
import com.ruoyi.personnel.pojo.PersonTrainingDetailed;
import com.ruoyi.personnel.pojo.PersonTrainingRecord;
import com.ruoyi.personnel.service.PersonTrainingDetailedService;
import com.ruoyi.personnel.service.PersonTrainingRecordService;
import com.ruoyi.system.mapper.UserMapper;
import com.ruoyi.system.service.InformationNotificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
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 2024-10-12 04:50:48
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class PersonTrainingRecordServiceImpl extends ServiceImpl<PersonTrainingRecordMapper, PersonTrainingRecord> implements PersonTrainingRecordService {
    @Autowired
    private PersonTrainingDetailedService personTrainingDetailedService;
    @Resource
    private InformationNotificationService informationNotificationService;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Resource
    private UserMapper userMapper;
    @Override
    public List<PersonTrainingRecordDto> trainingAndAssessmentRecordsPage(Integer trainingDetailedId, String userName) {
        return baseMapper.trainingAndAssessmentRecordsPage(trainingDetailedId, userName);
    }
    @Override
    public void deleteTrainingAndAssessmentRecords(String ids) {
        String[] split = ids.split(",");
        if (split.length > 0) {
            for (String s : split) {
                baseMapper.deleteById(s);
            }
        }
    }
    @Override
    public IPage<PersonTrainingRecordListDto> personnelTrainingPersonnel(Page page, String userName, Integer userId, Integer departLimsId) {
        return baseMapper.personnelTrainingPersonnel(page, userName, userId, departLimsId);
    }
    @Override
    public void claimOfTrainingAndAssessmentRecords(Boolean claimAndClaim, Integer courseId) {
    }
    @Override
    public IPage<TrainingRecordPersonDetailedDto> queryPersonnelDetailsOfUserIdAndYear(Page page, Integer userId, Integer year) {
        return baseMapper.queryPersonnelDetailsOfUserIdAndYear(page, userId, year);
    }
    @Override
    public void exportTrainingRecordAddTrainingDate(Integer userId, Integer trainingDate, HttpServletResponse response) {
        // æŸ¥è¯¢äººå‘˜äººä¿¡æ¯
        PersonTrainingRecordListDto trainingRecordListDto = baseMapper.selectUserTraining(userId);
        // æŸ¥è¯¢åŸ¹è®­è®°å½•
        List<TrainingRecordPersonDetailedDto> personDetailedDtos = baseMapper.selectPersonDetailedDtosByTrainingDate(userId, trainingDate);
        // èŽ·å–è·¯å¾„
        InputStream inputStream = this.getClass().getResourceAsStream("/static/training-record.docx");
        Configure configure = Configure.builder()
                .bind("personnelDetailsLisat", new HackLoopTableRenderPolicy())
                .build();
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("traning", trainingRecordListDto);
                    put("personnelDetailsLisat", personDetailedDtos);
                }});
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode(
                    "人员培训记录导出", "UTF-8");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
    }
    /**
     * åŸ¹è®­æäº¤
     * @param personTrainingRecordSubmitDto
     */
    @Override
    public void trainingAndAssessmentRecordsAdded(PersonTrainingRecordSubmitDto personTrainingRecordSubmitDto) {
        personTrainingDetailedService.update(Wrappers.<PersonTrainingDetailed>lambdaUpdate()
                .eq(PersonTrainingDetailed::getId, personTrainingRecordSubmitDto.getTrainingDetailedId())
                .set(PersonTrainingDetailed::getAssessmentMethod, personTrainingRecordSubmitDto.getAssessmentMethod())
                .set(PersonTrainingDetailed::getPlaceTraining, personTrainingRecordSubmitDto.getPlaceTraining())
                .set(PersonTrainingDetailed::getOpeningTime, personTrainingRecordSubmitDto.getOpeningTime())
                .set(PersonTrainingDetailed::getAssessmentUserId, personTrainingRecordSubmitDto.getAssessmentUserId())
                .set(PersonTrainingDetailed::getState, personTrainingRecordSubmitDto.getState()));
        // å‘送消息通知
        if (personTrainingRecordSubmitDto.getState().equals(2)) {
            PersonTrainingDetailed personPersonnelCapacity = personTrainingDetailedService.getById(personTrainingRecordSubmitDto.getTrainingDetailedId());
            Integer userId = SecurityUtils.getUserId().intValue();
            User user = userMapper.selectById(userId);
            // æ¶ˆæ¯å‘送
            InformationNotification info = new InformationNotification();
            // å‘送人
            info.setCreateUser(user.getName());
            info.setMessageType("6");
            info.setTheme("CNAS人员培训计划待评价");
            info.setContent("培训内容:" + personPersonnelCapacity.getTrainingContent() + "的人员培训待评价");
            info.setSenderId(userId);
            // æŽ¥æ”¶äºº
            info.setConsigneeId(personTrainingRecordSubmitDto.getAssessmentUserId());
            info.setJumpPath("a6-personnel");
            informationNotificationService.addInformationNotification(info);
            // å‘送企业微信通知
            threadPoolTaskExecutor.execute(() -> {
                // æŸ¥è¯¢æŽ¥æ”¶äºº
                User personnel = userMapper.selectById(personTrainingRecordSubmitDto.getAssessmentUserId());
                String message = "";
                message += "CNAS人员培训计划待评价";
                message += "\n请去资源管理-人员-人员培训计划";
                message += "\n" + "培训内容:" + personPersonnelCapacity.getTrainingContent() + "的人员培训待评价";
                //发送企业微信消息通知
                try {
                    WxCpUtils.inform(personnel.getAccount(), message, null);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
        }
    }
}
cnas-personnel/src/main/java/com/ruoyi/personnel/service/impl/PersonTrainingServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,429 @@
package com.ruoyi.personnel.service.impl;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.Pictures;
import com.ruoyi.common.core.domain.entity.InformationNotification;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.utils.DateImageUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.WxCpUtils;
import com.ruoyi.framework.exception.ErrorException;
import com.ruoyi.inspect.util.HackLoopTableRenderPolicy;
import com.ruoyi.personnel.dto.PersonTrainingDetailedDto;
import com.ruoyi.personnel.dto.PersonTrainingDto;
import com.ruoyi.personnel.dto.PersonTrainingRecordDto;
import com.ruoyi.personnel.dto.TrainingRecordExportDto;
import com.ruoyi.personnel.excel.PersonTrainingDetailedListener;
import com.ruoyi.personnel.excel.PersonTrainingDetailedUpload;
import com.ruoyi.personnel.mapper.PersonTrainingDetailedFileMapper;
import com.ruoyi.personnel.mapper.PersonTrainingDetailedMapper;
import com.ruoyi.personnel.mapper.PersonTrainingMapper;
import com.ruoyi.personnel.mapper.PersonTrainingRecordMapper;
import com.ruoyi.personnel.pojo.PersonTraining;
import com.ruoyi.personnel.pojo.PersonTrainingDetailed;
import com.ruoyi.personnel.pojo.PersonTrainingDetailedFile;
import com.ruoyi.personnel.service.PersonTrainingDetailedService;
import com.ruoyi.personnel.service.PersonTrainingService;
import com.ruoyi.system.mapper.UserMapper;
import com.ruoyi.system.service.InformationNotificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
/**
 * <p>
 * åŸ¹è®­è®¡åˆ’ æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2024-10-11 01:11:49
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PersonTrainingServiceImpl extends ServiceImpl<PersonTrainingMapper, PersonTraining> implements PersonTrainingService {
    @Autowired
    private PersonTrainingDetailedService personTrainingDetailedService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PersonTrainingDetailedMapper personTrainingDetailedMapper;
    @Autowired
    private PersonTrainingRecordMapper personTrainingRecordMapper;
    @Autowired
    private PersonTrainingDetailedFileMapper personTrainingDetailedFileMapper;
    @Resource
    private InformationNotificationService informationNotificationService;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Value("${file.path}")
    private String imgUrl;
    @Value("${wordUrl}")
    private String wordUrl;
    @Override
    public IPage<PersonTrainingDto> personTrainingSelect(Page page, String compilerName, String departmentId) {
        return baseMapper.personTrainingSelect(page, compilerName, departmentId);
    }
    @Override
    public void personTrainingImport(MultipartFile file, PersonTraining training) {
        Integer userId = SecurityUtils.getUserId().intValue();
        // å¹´åº¦è®¡åˆ’父级新增数据
        PersonTraining personSupervisePlan = new PersonTraining();
        String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));
        personSupervisePlan.setFileName(fileName);
        personSupervisePlan.setPlanYear(training.getPlanYear());
        personSupervisePlan.setCompilerId(userId);
        personSupervisePlan.setReviewerId(training.getReviewerId());
        personSupervisePlan.setCompilationDate(LocalDateTime.now());
        baseMapper.insert(personSupervisePlan);
        User user = userMapper.selectById(userId);
        // æ¶ˆæ¯å‘送
        InformationNotification info = new InformationNotification();
        // å‘送人
        info.setCreateUser(user.getName());
        info.setMessageType("6");
        info.setTheme("CNAS培训计划审核通知");
        info.setContent("您有一条培训计划待审核");
        info.setSenderId(userId);
        // æŽ¥æ”¶äºº
        info.setConsigneeId(training.getApproverId());
        info.setJumpPath("a6-personnel");
        informationNotificationService.addInformationNotification(info);
        // å‘送企业微信通知
        threadPoolTaskExecutor.execute(() -> {
            // æŸ¥è¯¢æŽ¥æ”¶äºº
            User personnel = userMapper.selectById(training.getApproverId());
            String message = "";
            message += "CNAS培训计划审核通知";
            message += "\n请去资源管理-人员-培训计划填写";
            message += "\n" + fileName + "的培训计划待审核";
            //发送企业微信消息通知
            try {
                WxCpUtils.inform(personnel.getAccount(), message, null);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        // å¹´åº¦è®¡åˆ’详情 æ–°å¢ž
        try {
            PersonTrainingDetailedListener personSupervisePlanDetailsListener = new PersonTrainingDetailedListener(personTrainingDetailedService);
            personSupervisePlanDetailsListener.setPlanId(personSupervisePlan.getId());
            EasyExcel.read(file.getInputStream(), PersonTrainingDetailedUpload.class, personSupervisePlanDetailsListener).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void personTrainingDelete(Integer id) {
        personTrainingDetailedService.remove(Wrappers.<PersonTrainingDetailed>lambdaQuery()
                .eq(PersonTrainingDetailed::getPlanId, id));
        baseMapper.deleteById(id);
    }
    @Override
    public void reviewAnnualPersonnelTraining(PersonTraining training) {
        PersonTraining personTraining = new PersonTraining();
        personTraining.setId(training.getId());
        personTraining.setApproverId(training.getApproverId());// æ·»åŠ æ‰¹å‡†äºº
        personTraining.setAuditDate(LocalDateTime.now());
        personTraining.setAuditRemarks(training.getAuditRemarks());
        personTraining.setReviewerStatus(training.getReviewerStatus());
        PersonTraining old = baseMapper.selectById(training.getId());
        // æ¶ˆæ¯å‘送
        Integer userId = SecurityUtils.getUserId().intValue();
        User user = userMapper.selectById(userId);
        InformationNotification info = new InformationNotification();
        // å‘送人
        info.setCreateUser(user.getName());
        info.setMessageType("6");
        info.setTheme("CNAS培训计划审核通知");
        info.setContent("您有一条培训计划待批准");
        info.setSenderId(userId);
        // æŽ¥æ”¶äºº
        info.setConsigneeId(training.getApproverId());
        info.setJumpPath("a6-personnel");
        informationNotificationService.addInformationNotification(info);
        // å‘送企业微信通知
        threadPoolTaskExecutor.execute(() -> {
            // æŸ¥è¯¢æŽ¥æ”¶äºº
            User personnel = userMapper.selectById(training.getApproverId());
            String message = "";
            message += "CNAS培训计划批准通知";
            message += "\n请去资源管理-人员-培训计划填写";
            message += "\n" + old.getFileName() + "的培训计划待批准";
            //发送企业微信消息通知
            try {
                WxCpUtils.inform(personnel.getAccount(), message, null);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        baseMapper.updateById(personTraining);
    }
    @Override
    public void approveAnnualPersonnelTraining(PersonTraining training) {
        LambdaUpdateWrapper<PersonTraining> wrapper = Wrappers.<PersonTraining>lambdaUpdate()
                .eq(PersonTraining::getId, training.getId())
                .set(PersonTraining::getApprovalDate, LocalDateTime.now())
                .set(PersonTraining::getApprovalRemarks, training.getApprovalRemarks())
                .set(PersonTraining::getApprovalStatus, training.getApprovalStatus());
        baseMapper.update(new PersonTraining(), wrapper);
    }
    /**
     * å¯¼å‡ºäººå‘˜åŸ¹è®­è®¡åˆ’
     * @param id
     * @param response
     */
    @Override
    public void exportPersonTraining(Integer id, HttpServletResponse response) {
        // æŸ¥è¯¢è¯¦æƒ…
        PersonTraining personTraining = baseMapper.selectById(id);
        //获取提交人的签名地址
        String writeUrl = userMapper.selectById(personTraining.getCompilerId()).getSignatureUrl();
        if (ObjectUtils.isEmpty(writeUrl) || writeUrl.equals("")) {
            throw new ErrorException("找不到检验人的签名");
        }
        //获取复核人的签名地址
        String examineUrl = null;
        if (personTraining.getReviewerId() != null) {
            examineUrl = userMapper.selectById(personTraining.getReviewerId()).getSignatureUrl();
            if (StringUtils.isBlank(examineUrl)) {
                throw new ErrorException("找不到复核人的签名");
            }
        }
        //获取批准人的签名地址
        String ratifyUrl = null;
        if (personTraining.getApproverId() != null) {
            ratifyUrl = userMapper.selectById(personTraining.getApproverId()).getSignatureUrl();
            if (StringUtils.isBlank(ratifyUrl)) {
                throw new ErrorException("找不到复核人的签名");
            }
        }
        // æŸ¥è¯¢è¯¦æƒ…
        List<PersonTrainingDetailedDto> detailedDtos = personTrainingDetailedMapper.selectTrainingList(id);
        int index = 1;
        for (PersonTrainingDetailedDto detailedDto : detailedDtos) {
            detailedDto.setTrainingDateString(detailedDto.getTrainingDate());
            detailedDto.setIndex(index);
            index++;
        }
        // èŽ·å–è·¯å¾„
        InputStream inputStream = this.getClass().getResourceAsStream("/static/person-training.docx");
        String finalExamineUrl = examineUrl;
        String finalRatifyUrl = ratifyUrl;
        Configure configure = Configure.builder()
                .bind("trainingDetailedList", new HackLoopTableRenderPolicy())
                .build();
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("year", personTraining.getPlanYear());
                    put("trainingDetailedList", detailedDtos);
                    put("writeUrl", StringUtils.isNotBlank(writeUrl) ? Pictures.ofLocal(imgUrl + "/" + writeUrl).create() : null);
                    put("examineUrl", StringUtils.isNotBlank(finalExamineUrl) ? Pictures.ofLocal(imgUrl + "/" + finalExamineUrl).create() : null);
                    put("ratifyUrl", StringUtils.isNotBlank(finalRatifyUrl) ? Pictures.ofLocal(imgUrl + "/" + finalRatifyUrl).create() : null);
                    put("writeDateUrl", personTraining.getCompilationDate() != null ?
                            Pictures.ofStream(DateImageUtil.createDateImage(personTraining.getCompilationDate())).create() : null);
                    put("examineDateUrl", personTraining.getAuditDate() != null ?
                            Pictures.ofStream(DateImageUtil.createDateImage(personTraining.getAuditDate())).create() : null);
                    put("ratifyDateUrl", personTraining.getApprovalDate() != null ?
                            Pictures.ofStream(DateImageUtil.createDateImage(personTraining.getApprovalDate())).create() : null);
                }});
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode(
                    "人员培训计划导出", "UTF-8");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
    }
    /**
     * å¯¼å‡ºäººå‘˜åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½•
     * @param id
     * @param response
     */
    @Override
    public void exportPersonTrainingRecord(Integer id, HttpServletResponse response) {
        // æŸ¥è¯¢äººå‘˜åŸ¹è®­æ˜Žç»†
        PersonTrainingDetailedDto detailedDto = personTrainingDetailedMapper.selectTrainingDetail(id);
        // æŸ¥è¯¢åŸ¹è®­çš„人员
        List<PersonTrainingRecordDto> recordDtos = personTrainingRecordMapper.selectListByTrainingDetailedId(id);
        List<TrainingRecordExportDto> exportDtoList = new ArrayList<>();
        TrainingRecordExportDto exportDto = new TrainingRecordExportDto();
        int count = 0;
        for (PersonTrainingRecordDto recordDto : recordDtos) {
            switch (count) {
                case 0:
                    exportDto.setUserName1(recordDto.getUserName());
                    exportDto.setDepartment1(recordDto.getDepartment());
                    exportDto.setExaminationResults1(recordDto.getExaminationResults());
                    count ++;
                    break;
                case 1:
                    exportDto.setUserName2(recordDto.getUserName());
                    exportDto.setDepartment2(recordDto.getDepartment());
                    exportDto.setExaminationResults2(recordDto.getExaminationResults());
                    exportDtoList.add(exportDto);
                    exportDto = new TrainingRecordExportDto();
                    count = 0;
                    break;
            }
        }
        exportDtoList.add(exportDto);
        // è´¨é‡è´Ÿè´£äºº
        String assessmentUserUrl = null;
        if (detailedDto.getAssessmentUserId() != null) {
            assessmentUserUrl = userMapper.selectById(detailedDto.getAssessmentUserId()).getSignatureUrl();
            if (StringUtils.isBlank(assessmentUserUrl)) {
                throw new ErrorException("找不到评价人的签名");
            }
        }
        // èŽ·å–è·¯å¾„
        InputStream inputStream = this.getClass().getResourceAsStream("/static/person-training-record.docx");
        Configure configure = Configure.builder()
                .bind("trainingRecordsList", new HackLoopTableRenderPolicy())
                .build();
        String finalAssessmentUserUrl = assessmentUserUrl;
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("trainingDetail", detailedDto);
                    put("trainingRecordsList", exportDtoList);
                    put("assessmentUserUrl", StringUtils.isNotBlank(finalAssessmentUserUrl) ? Pictures.ofLocal(imgUrl + "/" + finalAssessmentUserUrl).create() : null);
                }});
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode(
                    "培训与考核记录导出", "UTF-8");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出失败");
        }
    }
    /**
     * äººå‘˜åŸ¹è®­è¯¦æƒ…附件新增
     * @param trainingDetailedId
     * @param file
     * @return
     */
    @Override
    public boolean uploadTrainingDetailedFile(Integer trainingDetailedId, MultipartFile file) {
        if (trainingDetailedId == null) {
            throw new ErrorException("缺少验收id");
        }
        String urlString;
        String pathName;
        String path;
        String filename = file.getOriginalFilename();
        String contentType = file.getContentType();
        PersonTrainingDetailedFile detailedFile = new PersonTrainingDetailedFile();
        detailedFile.setTrainingDetailedId(trainingDetailedId);
        detailedFile.setFileName(filename);
        if (contentType != null && contentType.startsWith("image/")) {
            // æ˜¯å›¾ç‰‡
            path = imgUrl;
            detailedFile.setType(1);
        } else {
            // æ˜¯æ–‡ä»¶
            path = wordUrl;
            detailedFile.setType(2);
        }
        try {
            File realpath = new File(path);
            if (!realpath.exists()) {
                realpath.mkdirs();
            }
            pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "_" + file.getOriginalFilename();
            urlString = realpath + "/" + pathName;
            file.transferTo(new File(urlString));
            detailedFile.setFileUrl(pathName);
            personTrainingDetailedFileMapper.insert(detailedFile);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("附件上传错误");
            return false;
        }
    }
    /**
     * æŸ¥è¯¢ä»Šå¹´äººå‘˜åŸ¹è®­ä¿¡æ¯
     * @return
     */
    @Override
    public List<PersonTrainingDetailed> getThisYearTrainingDetailed() {
        return personTrainingDetailedMapper.getThisYearTrainingDetailed();
    }
}
cnas-personnel/src/main/resources/mapper/PersonBasicInfoMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
<?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.personnel.mapper.PersonBasicInfoMapper">
    <select id="selectLimsUser" resultType="com.ruoyi.common.core.domain.entity.DepartmentDto">
        SELECT u.id userId, u.name, SUBSTRING_INDEX(SUBSTRING_INDEX(u.depart_lims_id, ',', -2), ',', 1) AS fatherId
        FROM user u
        where u.is_custom = 0
          and u.depart_lims_id is not null
          and u.depart_lims_id != ''
    </select>
    <select id="getCNASPersonnelInfo" resultType="com.ruoyi.personnel.dto.PersonBasicInfoDto">
        SELECT *
        FROM user u
                 left join cnas_person_basic_info cpbi on cpbi.user_id = u.id
        where u.id = #{userId}
    </select>
    <select id="selectPersonBasecInfoAndUser" resultType="java.util.Map">
        select
            u.id  userId,
            u.`name`  name,
            u.account account,
            DATE_FORMAT(cpbi.group_time, '%Y-%m-%d') groupTime,
            cpbi.native_place nativePlace,
            cpbi.identity_card identityCard,
            cpbi.id_address idAddress,
            u.phone telephone,
            cpbi.graduated_institutions1 graduatedInstitutions1,
            cpbi.major1 major1,
            DATE_FORMAT(cpbi.graduation_time1, '%Y-%m-%d')  graduationTime1,
            cpbi.official_academic_redentials officialAcademicRedentials,
            cpbi.highest_degree highestDegree,
            cpbi.professional_title professionalTitle
        from user u
                 left join cnas_person_basic_info cpbi on cpbi.user_id = u.id
                 left join user u1 on u1.id = u.create_user
        <where>
            FIND_IN_SET(#{departmentId},u.depart_lims_id)
            <if test="name != null and name != ''">
                and u.name like concat('%',#{name},'%')
            </if>
        </where>
    </select>
    <!-- å¯¼å‡ºæŸ¥è¯¢äººå‘˜ä¿¡æ¯ -->
    <select id="selectexportPersonBasic" resultType="java.util.Map">
        select DATE_FORMAT(cpbi.last_update_time, '%Yå¹´%m月%d日') lastUpdateTimeString,
               u.account,
               u.`name`,
               cpbi.sex,
               cpbi.post_name postName,
               u.age,
               DATE_FORMAT(cpbi.working_time, '%Yå¹´%m月')   workingTimeString,
               cpbi.major1,
               DATE_FORMAT(cpbi.graduation_time1, '%Yå¹´%m月')   graduationTime1string,
               cpbi.official_academic_redentials officialAcademicRedentials,
               cpbi.graduated_institutions1 graduatedInstitutions1,
               cpbi.remarks
        from user u
                 left join cnas_person_basic_info cpbi on cpbi.user_id = u.id
        where u.id = #{userId}
    </select>
</mapper>
cnas-personnel/src/main/resources/mapper/PersonTrainingMapper.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.personnel.mapper.PersonTrainingMapper">
    <!-- æ ¹æ®åˆ›å»ºäººçš„部门筛选数据,可是创建人可能未分配部门也需要查看 -->
    <select id="personTrainingSelect" resultType="com.ruoyi.personnel.dto.PersonTrainingDto">
        SELECT
        cpt.*,
        u1.name compiler_name,
        u2.name reviewer_name,
        u3.name approver_name,
        u4.name create_user_name
        FROM
        cnas_person_training cpt
        LEFT JOIN user u1 ON cpt.compiler_id = u1.id
        LEFT JOIN user u2 ON cpt.reviewer_id = u2.id
        LEFT JOIN user u3 ON cpt.approver_id = u3.id
        LEFT JOIN user u4 ON cpt.create_user = u4.id
        <where>
            <if test="departLimsId != null and departLimsId != ''">
                and FIND_IN_SET(#{departLimsId}, u4.depart_lims_id)
            </if>
            <if test="compilerName != null and compilerName != ''">
                and u4.name like concat('%', #{compilerName}, '%')
            </if>
        </where>
        union
        SELECT
        cpt.*,
        u1.name compiler_name,
        u2.name reviewer_name,
        u3.name approver_name,
        u4.name create_user_name
        FROM
        cnas_person_training cpt
        LEFT JOIN user u1 ON cpt.compiler_id = u1.id
        LEFT JOIN user u2 ON cpt.reviewer_id = u2.id
        LEFT JOIN user u3 ON cpt.approver_id = u3.id
        LEFT JOIN user u4 ON cpt.create_user = u4.id
        WHERE
        u4.depart_lims_id is not null and length(u4.depart_lims_id) = 0
        <if test="compilerName != null and compilerName != ''">
            and u4.name like concat('%', #{compilerName}, '%')
        </if>
    </select>
</mapper>
cnas-personnel/src/main/resources/mapper/PersonTrainingRecordMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
<?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.personnel.mapper.PersonTrainingRecordMapper">
    <select id="trainingAndAssessmentRecordsPage" resultType="com.ruoyi.personnel.dto.PersonTrainingRecordDto">
        select cptr.*, u.account, u.name user_name, u.phone, r.name role_name
        from cnas_person_training_record cptr
                 left join user u on u.id = cptr.user_id
                 left join role r on r.id = u.role_id
        where cptr.course_id = #{trainingDetailedId}
        <if test="userName != null and userName != ''">
            and u.name like concat('%', #{userName}, '%')
        </if>
    </select>
    <select id="personnelTrainingPersonnel" resultType="com.ruoyi.personnel.dto.PersonTrainingRecordListDto">
        select u.name, u.account, dl.name depart_lims_name, cpbi.professional_title,
        cpbi.official_academic_redentials, u.id user_id
        from user u
        left join cnas_person_basic_info cpbi on cpbi.user_id = u.id
        left join department_lims dl on dl.id = SUBSTRING_INDEX(SUBSTRING_INDEX(u.depart_lims_id, ',', -2), ',', 1)
        where u.is_custom = 0
        <if test="userName != '' and userName != null and userName != 'null'">
            and u.name like concat('%', #{userName}, '%')
        </if>
        <if test="userId != null and userId != ''">
            and u.id = #{userId}
        </if>
        <if test="departLimsId != null and departLimsId != ''">
            and FIND_IN_SET(#{departLimsId}, u.depart_lims_id)
        </if>
    </select>
    <select id="queryPersonnelDetails" resultType="com.ruoyi.personnel.dto.TrainingRecordPersonDetailedDto">
        select cptd.training_date, cptd.training_content, cptd.class_hour, cptr.examination_results, cptd.remarks
        from cnas_person_training_record cptr
                 inner join cnas_person_training_detailed cptd on cptd.id = cptr.course_id
        <where>
            <if test="userId != null and userId != ''">
                and cptr.user_id = #{userId}
            </if>
        </where>
    </select>
    <!-- æ ¹æ®è¯¦æƒ…id查询培训信息 -->
    <select id="selectListByTrainingDetailedId" resultType="com.ruoyi.personnel.dto.PersonTrainingRecordDto">
        select cptr.*,
               u.name  userName,
               dl.name department
        from cnas_person_training_record cptr
                 left join user u on u.id = cptr.user_id
                 left join department_lims dl on find_in_set(dl.id, u.depart_lims_id) and dl.id != 1
        where cptr.course_id = #{trainingDetailedId}
    </select>
    <!-- æ ¹æ®id查询人员信息 -->
    <select id="selectUserTraining" resultType="com.ruoyi.personnel.dto.PersonTrainingRecordListDto">
        select u.name,
               u.account,
               dl.name                                    depart_lims_name,
               cpbi.professional_title,
               cpbi.official_academic_redentials,
               cpbi.unit_time,
               cpbi.major1,
               u.id                                       user_id,
               DATE_FORMAT(cpbi.unit_time, '%Y-%m-%d') AS unitTimeSting
        from user u
                 left join cnas_person_basic_info cpbi on cpbi.user_id = u.id
                 left join department_lims dl on dl.id = SUBSTRING_INDEX(SUBSTRING_INDEX(u.depart_lims_id, ',', -2), ',', 1)
        where u.is_custom = 0
        and u.id = #{userId}
    </select>
    <!-- æ ¹æ®ç”¨æˆ·id查询人员记录 -->
    <select id="selectPersonDetailedDtos" resultType="com.ruoyi.personnel.dto.TrainingRecordPersonDetailedDto">
        select cptd.training_date,
               cptd.training_content,
               cptd.class_hour,
               cptr.examination_results,
               cptd.remarks,
               DATE_FORMAT(cptd.training_date, '%Y-%m-%d') AS trainingDateString
        from cnas_person_training_record cptr
                 inner join cnas_person_training_detailed cptd on cptd.id = cptr.course_id
            and cptr.user_id = #{userId}
        <where>
            <if test="year!= null and year!= ''">
                and YEAR(cptd.training_date) = ${year}
            </if>
        </where>
    </select>
    <!--根据用户id和年份查询人员明细 åŸ¹è®­è®°å½•-->
    <select id="queryPersonnelDetailsOfUserIdAndYear"
            resultType="com.ruoyi.personnel.dto.TrainingRecordPersonDetailedDto">
        select cptd.training_date, cptd.training_content, cptd.class_hour, cptr.examination_results, cptd.remarks
        from cnas_person_training_record cptr
        inner join cnas_person_training_detailed cptd on cptd.id = cptr.course_id
        <where>
            <if test="userId != null and userId != ''">
                and cptr.user_id = #{userId}
            </if>
            <if test="year!= null and year!= ''">
                and YEAR(cptd.training_date) = ${year}
            </if>
        </where>
    </select>
    <!-- æ ¹æ®ç”¨æˆ·id和年份查询人员明细 åŸ¹è®­è®°å½•导出 -->
    <select id="selectPersonDetailedDtosByTrainingDate"
            resultType="com.ruoyi.personnel.dto.TrainingRecordPersonDetailedDto">
        select cptd.training_date,
        cptd.training_content,
        cptd.class_hour,
        cptr.examination_results,
        cptd.remarks,
        DATE_FORMAT(cptd.training_date, '%Y-%m-%d') AS trainingDateString
        from cnas_person_training_record cptr
        inner join cnas_person_training_detailed cptd on cptd.id = cptr.course_id
        and cptr.user_id = #{userId}
        <where>
            <if test="year!= null and year!= ''">
                and YEAR(cptd.training_date) = ${year}
            </if>
        </where>
    </select>
</mapper>