From 2d107e5c57fccb1ae1bfcc8b59389fbd0e2c67a5 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 29 四月 2026 15:44:02 +0800
Subject: [PATCH] feat(staff): 添加在职员工导入功能

---
 src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java |  374 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 357 insertions(+), 17 deletions(-)

diff --git a/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
index 8aaa840..841247a 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
@@ -5,55 +5,395 @@
 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.exception.base.BaseException;
+import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
-import com.ruoyi.staff.mapper.StaffJoinLeaveRecordMapper;
+import com.ruoyi.dto.WordDateDto;
+import com.ruoyi.project.system.domain.SysDept;
+import com.ruoyi.project.system.domain.SysPost;
+import com.ruoyi.project.system.mapper.SysDeptMapper;
+import com.ruoyi.project.system.mapper.SysPostMapper;
+import com.ruoyi.staff.dto.StaffOnJobImportDto;
+import com.ruoyi.staff.dto.StaffOnJobDto;
+import com.ruoyi.staff.mapper.StaffContractMapper;
+import com.ruoyi.staff.mapper.StaffLeaveMapper;
 import com.ruoyi.staff.mapper.StaffOnJobMapper;
-import com.ruoyi.staff.pojo.StaffJoinLeaveRecord;
+import com.ruoyi.staff.pojo.StaffContract;
+import com.ruoyi.staff.pojo.StaffLeave;
 import com.ruoyi.staff.pojo.StaffOnJob;
-import com.ruoyi.staff.service.IStaffJoinLeaveRecordService;
 import com.ruoyi.staff.service.IStaffOnJobService;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
 import lombok.AllArgsConstructor;
-import org.springframework.stereotype.Service;
 
-import javax.annotation.Resource;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
+
 import javax.servlet.http.HttpServletResponse;
-import java.util.List;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 @AllArgsConstructor
 @Service
 public class StaffOnJobServiceImpl extends ServiceImpl<StaffOnJobMapper, StaffOnJob>  implements IStaffOnJobService {
 
-
+    @Autowired
     private StaffOnJobMapper staffOnJobMapper;
+    @Autowired
+    private SysPostMapper sysPostMapper;
+    @Autowired
+    private SysDeptMapper sysDeptMapper;
 
-    private StaffJoinLeaveRecordMapper staffJoinLeaveRecordMapper;
+    @Autowired
+    private StaffContractMapper staffContractMapper;
+    @Autowired
+    private StaffLeaveMapper staffLeaveMapper;
+
 
     //鍦ㄨ亴鍛樺伐鍙拌处鍒嗛〉鏌ヨ
     @Override
-    public IPage<StaffOnJob> staffOnJobListPage(Page page, StaffOnJob staffOnJob) {
+    public IPage<StaffOnJobDto> staffOnJobListPage(Page page, StaffOnJob staffOnJob) {
         return staffOnJobMapper.staffOnJobListPage(page,staffOnJob);
+    }
+
+    //鏂板鍏ヨ亴
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int add(StaffOnJobDto staffOnJobPrams) {
+        String[] ignoreProperties = {"id"};//鎺掗櫎id灞炴��
+        // 鍒ゆ柇缂栧彿鏄惁瀛樺湪
+        List<StaffOnJob> staffOnJobs = staffOnJobMapper.selectList(Wrappers.<StaffOnJob>lambdaQuery().eq(StaffOnJob::getStaffNo, staffOnJobPrams.getStaffNo()));
+        if (staffOnJobs.size()>0){
+            throw new BaseException("缂栧彿涓�"+staffOnJobPrams.getStaffNo()+"鐨勫憳宸ュ凡缁忓瓨鍦�,鏃犳硶鏂板!!!");
+        }
+        // 鍒涘缓鍏ヨ亴鏁版嵁
+        staffOnJobPrams.setContractExpireTime(staffOnJobPrams.getContractEndTime());
+        staffOnJobPrams.setStaffState(1);
+        staffOnJobMapper.insert(staffOnJobPrams);
+
+        // 鍒涘缓鍚堝悓璁板綍
+        StaffContract staffContract = new StaffContract();
+        staffContract.setStaffOnJobId(staffOnJobPrams.getId());
+        staffContract.setContractTerm(staffOnJobPrams.getContractTerm());
+        staffContract.setContractStartTime(staffOnJobPrams.getContractStartTime());
+        staffContract.setContractEndTime(staffOnJobPrams.getContractEndTime());
+        return staffContractMapper.insert(staffContract);
+    }
+
+    //鏇存柊鍏ヨ亴淇℃伅
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int update(Long id, StaffOnJobDto staffOnJobParams) {
+        // 鍒ゆ柇瀵硅薄鏄惁瀛樺湪
+        StaffOnJob job = staffOnJobMapper.selectById(id);
+        if (job == null){
+            throw new BaseException("缂栧彿涓�"+staffOnJobParams.getStaffNo()+"鐨勫憳宸ヤ笉瀛樺湪,鏃犳硶鏇存柊!!!");
+        }
+
+        String[] ignoreProperties = {"id"};//鎺掗櫎鏇存柊灞炴��
+
+        // 鑾峰彇鏈�鏂板悎鍚屾暟鎹紝骞朵笖鏇存柊
+        StaffContract contract = staffContractMapper.selectOne(Wrappers.<StaffContract>lambdaQuery()
+                .eq(StaffContract::getStaffOnJobId, id)
+                .last("limit 1")
+                .orderByDesc(StaffContract::getId));
+        if (contract != null){
+            BeanUtils.copyProperties(staffOnJobParams,contract,ignoreProperties);
+            staffContractMapper.updateById(contract);
+        }
+
+        // 鏇存柊鍛樺伐鏁版嵁
+        staffOnJobParams.setContractExpireTime(staffOnJobParams.getContractEndTime());
+        return staffOnJobMapper.updateById(staffOnJobParams);
+    }
+
+    //鍒犻櫎鍏ヨ亴
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int delStaffOnJobs(List<Integer> ids) {
+        // 鍒犻櫎鍏ヨ亴鏁版嵁
+        staffOnJobMapper.deleteBatchIds(ids);
+        // 鍒犻櫎绂昏亴鏁版嵁
+        staffLeaveMapper.delete(Wrappers.<StaffLeave>lambdaQuery().in(StaffLeave::getStaffOnJobId, ids));
+        // 鍒犻櫎鍚堝悓鏁版嵁
+        return staffContractMapper.delete(Wrappers.<StaffContract>lambdaQuery().in(StaffContract::getStaffOnJobId, ids));
+    }
+
+    // 缁鍚堝悓
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int renewContract(Long id, StaffContract staffContract) {
+        // 鍒ゆ柇瀵硅薄鏄惁瀛樺湪
+        StaffOnJob job = staffOnJobMapper.selectById(id);
+        if (job == null){
+            throw new BaseException("璇ュ憳宸ヤ笉瀛樺湪,鏃犳硶鏇存柊!!!");
+        }
+
+        // 澧炲姞鍚堝悓
+        StaffContract newStaffContract = new StaffContract();
+        newStaffContract.setStaffOnJobId(id);
+        newStaffContract.setContractTerm(staffContract.getContractTerm());
+        newStaffContract.setContractStartTime(staffContract.getContractStartTime());
+        newStaffContract.setContractEndTime(staffContract.getContractEndTime());
+        staffContractMapper.insert(newStaffContract);
+
+        // 鏇存柊鍛樺伐鍚堝悓杩囨湡鏃堕棿
+        job.setContractExpireTime(staffContract.getContractEndTime());
+        staffOnJobMapper.updateById(job);
+        return 0;
     }
 
     //鍦ㄨ亴鍛樺伐璇︽儏
     @Override
-    public List<StaffJoinLeaveRecord> staffOnJobDetail(String staffNo) {
-        return staffJoinLeaveRecordMapper.selectList(Wrappers.<StaffJoinLeaveRecord>lambdaQuery()
-                .eq(StaffJoinLeaveRecord::getStaffState,1)
-                .eq(StaffJoinLeaveRecord::getStaffNo,staffNo));
+    public StaffOnJobDto staffOnJobDetail(Long id) {
+        StaffOnJob staffOnJob  = staffOnJobMapper.selectById(id);
+        if (staffOnJob == null) {
+            throw new IllegalArgumentException("璇ュ憳宸ヤ笉瀛樺湪");
+        }
+
+        StaffOnJobDto staffOnJobDto = new StaffOnJobDto();
+        BeanUtils.copyProperties(staffOnJob, staffOnJobDto);
+        // 鏌ヨ宀椾綅鍚嶇О
+        if (staffOnJob.getSysPostId() != null) {
+            SysPost post = sysPostMapper.selectPostById(staffOnJob.getSysPostId().longValue());
+            if (post != null) {
+                staffOnJobDto.setPostName(post.getPostName());
+            }
+        }
+
+        // 鏌ヨ鍚堝悓淇℃伅
+        StaffContract contract = staffContractMapper.selectOne(Wrappers.<StaffContract>lambdaQuery()
+                .eq(StaffContract::getStaffOnJobId, staffOnJob.getId())
+                .last("limit 1")
+                .orderByDesc(StaffContract::getId));
+        if (contract != null){
+            staffOnJobDto.setContractTerm(contract.getContractTerm());
+            staffOnJobDto.setContractStartTime(contract.getContractStartTime());
+            staffOnJobDto.setContractEndTime(contract.getContractEndTime());
+        }
+        return staffOnJobDto;
     }
 
     //鍦ㄨ亴鍛樺伐瀵煎嚭
     @Override
     public void staffOnJobExport(HttpServletResponse response, StaffOnJob staffOnJob) {
-        List<StaffOnJob> staffOnJobs = staffOnJobMapper.staffOnJobList(staffOnJob);
-        ExcelUtil<StaffOnJob> util = new ExcelUtil<StaffOnJob>(StaffOnJob.class);
+        List<StaffOnJobDto> staffOnJobs = staffOnJobMapper.staffOnJobList(staffOnJob);
+        ExcelUtil<StaffOnJobDto> util = new ExcelUtil<StaffOnJobDto>(StaffOnJobDto.class);
         util.exportExcel(response, staffOnJobs, "鍦ㄨ亴鍛樺伐鍙拌处瀵煎嚭");
     }
 
     @Override
-    public List<StaffJoinLeaveRecord> staffOnJobList() {
-        return staffJoinLeaveRecordMapper.staffOnJobList();
+    public List<StaffOnJobDto> staffOnJobList(StaffOnJob staffOnJob) {
+        return staffOnJobMapper.staffOnJobList(staffOnJob);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean importData(MultipartFile file) {
+        try {
+            ExcelUtil<StaffOnJobImportDto> util = new ExcelUtil<>(StaffOnJobImportDto.class);
+            List<StaffOnJobImportDto> staffOnJobs = util.importExcel(file.getInputStream());
+            if (CollectionUtils.isEmpty(staffOnJobs)) {
+                throw new BaseException("妯℃澘閿欒鎴栧鍏ユ暟鎹负绌�");
+            }
+
+            Map<String, SysPost> postMap = buildPostMap();
+            Map<String, SysDept> deptMap = buildDeptMap();
+            Set<String> importedStaffNos = new HashSet<>();
+            for (int i = 0; i < staffOnJobs.size(); i++) {
+                StaffOnJobDto staffOnJobDto = buildImportStaff(staffOnJobs.get(i), i + 2, postMap, deptMap, importedStaffNos);
+                add(staffOnJobDto);
+            }
+            return true;
+        } catch (Exception e) {
+            if (e instanceof BaseException) {
+                throw (BaseException) e;
+            }
+            throw new BaseException("瀵煎叆澶辫触锛岃妫�鏌ユā鏉挎牸寮忔槸鍚︽纭�");
+        }
+    }
+
+    private StaffOnJobDto buildImportStaff(StaffOnJobImportDto row, int rowNum, Map<String, SysPost> postMap,
+                                           Map<String, SysDept> deptMap, Set<String> importedStaffNos) {
+        String staffNo = normalizeValue(row.getStaffNo());
+        String postName = normalizeValue(row.getPostName());
+        String deptName = normalizeValue(row.getDeptName());
+
+        if (StringUtils.isBlank(staffNo)) {
+            throw new BaseException("绗�" + rowNum + "琛屽憳宸ョ紪鍙蜂笉鑳戒负绌�");
+        }
+        if (!importedStaffNos.add(staffNo)) {
+            throw new BaseException("绗�" + rowNum + "琛屽憳宸ョ紪鍙烽噸澶嶏細" + staffNo);
+        }
+        if (StringUtils.isBlank(normalizeValue(row.getStaffName()))) {
+            throw new BaseException("绗�" + rowNum + "琛屽憳宸ュ鍚嶄笉鑳戒负绌�");
+        }
+        if (StringUtils.isBlank(postName)) {
+            throw new BaseException("绗�" + rowNum + "琛屽矖浣嶄笉鑳戒负绌�");
+        }
+        if (StringUtils.isBlank(deptName)) {
+            throw new BaseException("绗�" + rowNum + "琛岄儴闂ㄤ笉鑳戒负绌�");
+        }
+        if (row.getContractStartTime() == null) {
+            throw new BaseException("绗�" + rowNum + "琛屽悎鍚屽紑濮嬫棩鏈熶笉鑳戒负绌�");
+        }
+        if (row.getContractEndTime() == null) {
+            throw new BaseException("绗�" + rowNum + "琛屽悎鍚岀粨鏉熸棩鏈熶笉鑳戒负绌�");
+        }
+
+        SysPost post = postMap.get(postName);
+        if (post == null) {
+            throw new BaseException("绗�" + rowNum + "琛屽矖浣嶄笉瀛樺湪鎴栧凡鍋滅敤锛�" + postName);
+        }
+        SysDept dept = deptMap.get(deptName);
+        if (dept == null) {
+            throw new BaseException("绗�" + rowNum + "琛岄儴闂ㄤ笉瀛樺湪鎴栧凡鍋滅敤锛�" + deptName);
+        }
+
+        StaffOnJobDto staffOnJobDto = new StaffOnJobDto();
+        BeanUtils.copyProperties(row, staffOnJobDto);
+        staffOnJobDto.setStaffNo(staffNo);
+        staffOnJobDto.setStaffName(normalizeValue(row.getStaffName()));
+        staffOnJobDto.setSex(normalizeValue(row.getSex()));
+        staffOnJobDto.setNativePlace(normalizeValue(row.getNativePlace()));
+        staffOnJobDto.setAdress(normalizeValue(row.getAdress()));
+        staffOnJobDto.setFirstStudy(normalizeValue(row.getFirstStudy()));
+        staffOnJobDto.setProfession(normalizeValue(row.getProfession()));
+        staffOnJobDto.setAge(normalizeValue(row.getAge()));
+        staffOnJobDto.setPhone(normalizeValue(row.getPhone()));
+        staffOnJobDto.setEmergencyContact(normalizeValue(row.getEmergencyContact()));
+        staffOnJobDto.setEmergencyContactPhone(normalizeValue(row.getEmergencyContactPhone()));
+        staffOnJobDto.setContractTerm(normalizeValue(row.getContractTerm()));
+        staffOnJobDto.setSysPostId(post.getPostId().intValue());
+        staffOnJobDto.setSysDeptId(dept.getDeptId().intValue());
+        return staffOnJobDto;
+    }
+
+    private Map<String, SysPost> buildPostMap() {
+        SysPost query = new SysPost();
+        query.setStatus("0");
+        return buildUniqueMap(sysPostMapper.selectPostList(query), SysPost::getPostName, "宀椾綅");
+    }
+
+    private Map<String, SysDept> buildDeptMap() {
+        SysDept query = new SysDept();
+        query.setStatus("0");
+        return buildUniqueMap(sysDeptMapper.selectDeptList(query), SysDept::getDeptName, "閮ㄩ棬");
+    }
+
+    private <T> Map<String, T> buildUniqueMap(List<T> dataList, Function<T, String> nameGetter, String fieldName) {
+        Map<String, List<T>> groupedMap = dataList.stream()
+                .filter(Objects::nonNull)
+                .filter(item -> StringUtils.isNotBlank(normalizeValue(nameGetter.apply(item))))
+                .collect(Collectors.groupingBy(item -> normalizeValue(nameGetter.apply(item))));
+
+        List<String> duplicateNames = groupedMap.entrySet().stream()
+                .filter(entry -> entry.getValue().size() > 1)
+                .map(Map.Entry::getKey)
+                .sorted()
+                .collect(Collectors.toList());
+        if (!duplicateNames.isEmpty()) {
+            throw new BaseException("绯荤粺涓瓨鍦ㄩ噸鍚�" + fieldName + "锛屾棤娉曞鍏ワ細" + String.join("銆�", duplicateNames));
+        }
+
+        return groupedMap.entrySet().stream()
+                .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().get(0)));
+    }
+
+    private String normalizeValue(String value) {
+        return value == null ? null : value.trim();
+    }
+
+
+    @Override
+    public String exportCopy(HttpServletResponse response, StaffOnJob staffOnJob) throws Exception {
+        String url = "/javaWork/product-inventory-management/file/prod/" + staffOnJob.getStaffName() + "-鍔冲姩鍚堝悓涔�.docx";
+        Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
+        // 璁剧疆妯℃澘鏂囦欢鎵�鍦ㄧ洰褰曪紙缁濆璺緞锛屼緥濡傦細/templates/锛�
+        cfg.setClassForTemplateLoading(StaffOnJobServiceImpl.class, "/static");
+        cfg.setDefaultEncoding("UTF-8");
+        //2.瀹氫箟闇�瑕佸~鍏呯殑鍙橀噷
+        // 鈶� 鏋勯�犲憳宸ヤ俊鎭紙瀹為檯椤圭洰涓彲浠庢暟鎹簱/Excel璇诲彇锛�
+        WordDateDto staff = new WordDateDto();
+        BeanUtils.copyProperties(staffOnJob, staff);
+        // 閫氳繃鍚堝悓骞撮檺锛屽悎鍚屽埌鏈熸棩鏈熻绠楀悎鍚屽紑濮嬫棩鏈燂紝鍦ㄨ幏鍙栧紑濮嬫棩鏈燂紝缁撴潫鏃ユ湡鐨勫勾鏈堟棩鏁板瓧
+        // 鍚堝悓鍒版湡鏃ユ湡 - 鍚堝悓骞撮檺锛圖ate绫诲瀷锛�
+        // 1. 灏咲ate杞崲涓篒nstant锛堟椂闂存埑锛�
+        Instant instant = staff.getContractExpireTime().toInstant();
+
+        // 涔熷彲浠ユ寚瀹氬叿浣撴椂鍖猴紝渚嬪Asia/Shanghai锛�
+        LocalDate localDate = instant.atZone(ZoneId.of("Asia/Shanghai")).toLocalDate();  // 鍚堝悓缁撴潫鏃堕棿
+        LocalDate localDate1 = localDate.minusYears(Integer.parseInt(staff.getContractTerm()));// 鍚堝悓寮�濮嬫椂闂�
+
+        // 绛捐鏃ユ湡杞崲lcoaldate
+        LocalDate localDate2 = staff.getSignDate().toInstant().atZone(ZoneId.of("Asia/Shanghai")).toLocalDate();
+
+        // 璇曠敤鏃ユ湡杞崲lcoaldate
+        LocalDate localDate3 = staff.getTrialStartDate().toInstant().atZone(ZoneId.of("Asia/Shanghai")).toLocalDate();
+        LocalDate localDate4 = staff.getTrialEndDate().toInstant().atZone(ZoneId.of("Asia/Shanghai")).toLocalDate();
+
+        staff.setQyear(localDate2.getYear() + "");
+        staff.setQmoth(localDate2.getMonthValue() + "");
+        staff.setQday(localDate2.getDayOfMonth() + "");
+        if(staff.getDateSelect().equals("A")){
+            staff.setSyear(localDate1.getYear() + "");
+            staff.setSmoth(localDate1.getMonthValue() + "");
+            staff.setSday(localDate1.getDayOfMonth() + "");
+            staff.setEyear(localDate.getDayOfMonth() + "");
+            staff.setEmoth(localDate.getDayOfMonth() + "");
+            staff.setEday(localDate.getDayOfMonth() + "");
+
+            staff.setStyear(localDate3.getYear() + "");
+            staff.setStmoth(localDate3.getMonthValue() + "");
+            staff.setStday(localDate3.getDayOfMonth() + "");
+            staff.setSeyear(localDate4.getYear() + "");
+            staff.setSemoth(localDate4.getMonthValue() + "");
+            staff.setSeday(localDate4.getDayOfMonth() + "");
+        }else if (staff.getDateSelect().equals("B")){
+
+            staff.setBsyear(localDate1.getYear() + "");
+            staff.setBsmoth(localDate1.getMonthValue() + "");
+            staff.setBsday(localDate1.getDayOfMonth() + "");
+
+            staff.setBstyear(localDate3.getYear() + "");
+            staff.setBstmoth(localDate3.getMonthValue() + "");
+            staff.setBstday(localDate3.getDayOfMonth() + "");
+            staff.setBseyear(localDate4.getYear() + "");
+            staff.setBsemoth(localDate4.getMonthValue() + "");
+            staff.setBseday(localDate4.getDayOfMonth() + "");
+        }else if (staff.getDateSelect().equals("C")){
+            staff.setCsyear(localDate1.getYear() + "");
+            staff.setCsmoth(localDate1.getMonthValue() + "");
+            staff.setCsday(localDate1.getDayOfMonth() + "");
+        }
+
+        Map<String,Object> data = new HashMap<>();
+        data.put("item",staff);
+        //3.鍔犺浇XML 妯℃澘
+        Template template = cfg.getTemplate("鍔冲姩鍚堝悓涔�.xml");
+        //4.鐢熸垚濉厖鍚庣殑 XML 鍐呭
+        StringWriter out = new StringWriter();
+        template.process(data, out);
+        String filledXml = out.toString();
+        //5.灏哫ML鍐呭鍐欏叆浜や欢骞舵敼涓�.docx 鏍煎紡
+        File outputFile = new File(url);
+        try(FileOutputStream fos = new FileOutputStream(outputFile);
+            OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8)) {
+            osw.write(filledXml);
+        }
+        return url;
+    }
+
+
 
 }

--
Gitblit v1.9.3