From dcc8bb8f47544cbad6e6440640dcdaa946086013 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 06 五月 2026 17:31:54 +0800
Subject: [PATCH] feat(staff): 员工模块新增民族出生日期入职日期字段

---
 src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java                    |   25 ++
 src/main/java/com/ruoyi/staff/dto/StaffOnJobImportDto.java            |   53 ++---
 doc/员工模块-前端联调文档-20260506.md                                           |  127 ++++++++++++++
 src/main/resources/mapper/stock/StockOutRecordMapper.xml              |    3 
 src/main/resources/mapper/staff/StaffOnJobMapper.xml                  |    8 
 src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java |  244 +++++++++++++++-----------
 doc/20260506_staff_on_job_add_nation_birth_entry_date.sql             |   19 ++
 src/main/resources/mapper/stock/StockInventoryMapper.xml              |    3 
 src/main/resources/mapper/stock/StockInRecordMapper.xml               |    3 
 9 files changed, 347 insertions(+), 138 deletions(-)

diff --git a/doc/20260506_staff_on_job_add_nation_birth_entry_date.sql b/doc/20260506_staff_on_job_add_nation_birth_entry_date.sql
new file mode 100644
index 0000000..826ad9f
--- /dev/null
+++ b/doc/20260506_staff_on_job_add_nation_birth_entry_date.sql
@@ -0,0 +1,19 @@
+ALTER TABLE staff_on_job
+    ADD COLUMN nation VARCHAR(32) NULL COMMENT '姘戞棌' AFTER sex;
+
+ALTER TABLE staff_on_job
+    ADD COLUMN birth_date DATE NULL COMMENT '鍑虹敓鏃ユ湡' AFTER nation;
+
+ALTER TABLE staff_on_job
+    ADD COLUMN entry_date DATE NULL COMMENT '鍏ヨ亴鏃ユ湡' AFTER emergency_contact_phone;
+
+UPDATE staff_on_job
+SET nation = native_place
+WHERE (nation IS NULL OR nation = '')
+  AND native_place IS NOT NULL
+  AND native_place <> '';
+
+UPDATE staff_on_job
+SET entry_date = DATE(create_time)
+WHERE entry_date IS NULL
+  AND create_time IS NOT NULL;
diff --git "a/doc/\345\221\230\345\267\245\346\250\241\345\235\227-\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243-20260506.md" "b/doc/\345\221\230\345\267\245\346\250\241\345\235\227-\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243-20260506.md"
new file mode 100644
index 0000000..fe77ca4
--- /dev/null
+++ "b/doc/\345\221\230\345\267\245\346\250\241\345\235\227-\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243-20260506.md"
@@ -0,0 +1,127 @@
+# 鍛樺伐妯″潡鍓嶇鑱旇皟鏂囨。锛�2026-05-06锛�
+
+## 1. 鏈鍙樻洿鑼冨洿
+
+妯″潡锛歚鍛樺伐鍙拌处 / 鍏ヨ亴淇℃伅`  
+鎺ュ彛鍓嶇紑锛歚/staff/staffOnJob`
+
+鏂板/璋冩暣鍚庣殑鍏ヨ亴琛ㄥ崟瀛楁锛�
+
+1. 鍛樺伐缂栧彿 `staffNo`
+2. 濮撳悕 `staffName`
+3. 鎬у埆 `sex`
+4. 姘戞棌 `nation`
+5. 鍑虹敓鏃ユ湡 `birthDate`
+6. 韬唤璇佸彿 `identityCard`
+7. 鐜颁綇鍧� `adress`
+8. 鑱旂郴鐢佃瘽 `phone`
+9. 绱ф�ヨ仈绯讳汉鐢佃瘽 `emergencyContactPhone`
+10. 鍏ヨ亴鏃ユ湡 `entryDate`
+11. 宀椾綅 `sysPostId`
+12. 閮ㄩ棬 `sysDeptId`
+13. 鍚堝悓骞撮檺 `contractTerm`锛堝師閫昏緫涓嶅彉锛�
+14. 鍚堝悓寮�濮嬫棩鏈� `contractStartTime`锛堝師閫昏緫涓嶅彉锛�
+15. 鍚堝悓缁撴潫鏃ユ湡 `contractEndTime`锛堝師閫昏緫涓嶅彉锛�
+
+## 2. 鏁版嵁搴撳彉鏇�
+
+鍏堟墽琛� SQL锛�
+
+`doc/20260506_staff_on_job_add_nation_birth_entry_date.sql`
+
+鏂板鍒楋細
+
+1. `nation`锛堟皯鏃忥級
+2. `birth_date`锛堝嚭鐢熸棩鏈燂級
+3. `entry_date`锛堝叆鑱屾棩鏈燂級
+
+鍏煎澶勭悊锛�
+
+1. `nation` 浼氬洖濉巻鍙� `native_place`
+2. `entry_date` 浼氬洖濉巻鍙� `create_time` 鐨勬棩鏈熼儴鍒�
+
+## 3. 鎺ュ彛娓呭崟锛堟牳蹇冭仈璋冿級
+
+### 3.1 鏂板鍏ヨ亴
+
+- `POST /staff/staffOnJob`
+- `Content-Type: application/json`
+
+璇锋眰绀轰緥锛�
+
+```json
+{
+  "staffNo": "YG20260506001",
+  "staffName": "寮犱笁",
+  "sex": "鐢�",
+  "nation": "姹夋棌",
+  "birthDate": "1995-06-08",
+  "identityCard": "320XXXXXXXXXXXXX",
+  "adress": "鍗楅�氬競宕囧窛鍖篨XX璺�",
+  "phone": "13800000000",
+  "emergencyContactPhone": "13900000000",
+  "entryDate": "2026-05-06",
+  "sysPostId": 12,
+  "sysDeptId": 6,
+  "contractTerm": "3",
+  "contractStartTime": "2026-05-06",
+  "contractEndTime": "2029-05-05"
+}
+```
+
+璇存槑锛�
+
+1. `staffNo` 鍞竴锛岄噸澶嶄細鎶ラ敊
+2. 濡傛灉 `entryDate` 涓嶄紶锛屽悗绔細鍥為��浣跨敤 `contractStartTime`
+3. 鏂板鏃朵細鍚屾鍐欏叆涓�鏉″悎鍚岃褰曪紙`staff_contract`锛�
+
+### 3.2 缂栬緫鍏ヨ亴淇℃伅
+
+- `PUT /staff/staffOnJob/{id}`
+
+璇锋眰浣撲笌鏂板涓�鑷达紱鍚庣浼氭寜璺緞鍙傛暟 `{id}` 鏇存柊锛屼笉渚濊禆 body 閲岀殑 `id`銆�
+
+### 3.3 璇︽儏
+
+- `GET /staff/staffOnJob/{id}`
+
+杩斿洖浼氬寘鍚細
+
+1. 鍛樺伐鍩虹瀛楁锛堝惈 `nation`銆乣birthDate`銆乣entryDate`锛�
+2. 鏈�鏂板悎鍚屽瓧娈碉紙`contractTerm`銆乣contractStartTime`銆乣contractEndTime`锛�
+3. `postName`銆乣deptName`
+
+### 3.4 鍒嗛〉鍒楄〃
+
+- `GET /staff/staffOnJob/listPage`
+
+甯哥敤鏌ヨ鍙傛暟锛�
+
+1. `staffState`
+2. `staffName`
+3. `entryDateStart`
+4. `entryDateEnd`
+
+璇存槑锛�  
+`entryDateStart/entryDateEnd` 鐜板湪鎸夊叆鑱屾棩鏈熻繃婊わ紙`entry_date`锛夛紝涓嶅啀鎸夊悎鍚屽埌鏈熸棩鏈熻繃婊ゃ��
+
+## 4. 鍏煎绛栫暐锛堝墠绔彲鐩存帴鐢級
+
+1. 鏂拌〃鍗曠洿鎺ヤ娇鐢� `nation` 瀛楁鍗冲彲
+2. 鍚庣浠嶄細缁存姢 `nativePlace` 鍏煎鍘嗗彶鍔熻兘锛堝绂昏亴妯″潡鑱旀煡锛�
+3. 鍘嗗彶鏁版嵁鑻� `nation` 涓虹┖锛屾帴鍙d細鍥炲~鏄剧ず涓烘棫 `nativePlace` 鍊�
+
+## 5. 瀵煎叆妯℃澘鍙樻洿
+
+`/staff/staffOnJob/downloadTemplate` 瀵煎叆妯℃澘瀛楁宸叉寜鏂板彛寰勮皟鏁达紝涓昏鍖呭惈锛�
+
+1. 鍛樺伐缂栧彿銆佸鍚嶃�佹�у埆銆佹皯鏃忋�佸嚭鐢熸棩鏈熴�佽韩浠借瘉鍙�
+2. 鐜颁綇鍧�銆佽仈绯荤數璇濄�佺揣鎬ヨ仈绯讳汉鐢佃瘽銆佸叆鑱屾棩鏈�
+3. 宀椾綅銆侀儴闂ㄣ�佸悎鍚屽勾闄愩�佸悎鍚屽紑濮嬫棩鏈熴�佸悎鍚岀粨鏉熸棩鏈�
+
+## 6. 鍓嶇鑱旇皟娉ㄦ剰鐐�
+
+1. 鏃ユ湡瀛楁缁熶竴浼� `yyyy-MM-dd`
+2. 宀椾綅/閮ㄩ棬浼� ID锛歚sysPostId`銆乣sysDeptId`
+3. 鏂板鍜岀紪杈戦兘瑕佷紶鍚堝悓涓夊瓧娈碉紙鍚堝悓閫昏緫涓嶅彉锛�
+4. `staffNo` 闇�瑕佸墠绔厛鍋氬敮涓�鎬ф彁绀猴紙鍚庣涔熶細鍏滃簳鏍¢獙锛�
diff --git a/src/main/java/com/ruoyi/staff/dto/StaffOnJobImportDto.java b/src/main/java/com/ruoyi/staff/dto/StaffOnJobImportDto.java
index 9d7e574..d3e7e39 100644
--- a/src/main/java/com/ruoyi/staff/dto/StaffOnJobImportDto.java
+++ b/src/main/java/com/ruoyi/staff/dto/StaffOnJobImportDto.java
@@ -5,7 +5,6 @@
 import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 
-import java.math.BigDecimal;
 import java.util.Date;
 
 @Data
@@ -14,53 +13,53 @@
     @Excel(name = "鍛樺伐缂栧彿", cellType = Excel.ColumnType.STRING, sort = 1)
     private String staffNo;
 
-    @Excel(name = "鍛樺伐濮撳悕", sort = 2)
+    @Excel(name = "濮撳悕", sort = 2)
     private String staffName;
 
-    @Excel(name = "鎬у埆", sort = 3, combo = {"鐢�", "濂�"})
+    @Excel(name = "鎬у埆", sort = 3, combo = {"male", "female"})
     private String sex;
 
-    @Excel(name = "绫嶈疮", sort = 4)
-    private String nativePlace;
+    @Excel(name = "姘戞棌", sort = 4)
+    private String nation;
 
-    @Excel(name = "宀椾綅", sort = 5, prompt = "璇峰~鍐欑郴缁熶腑宸插瓨鍦ㄧ殑宀椾綅鍚嶇О")
-    private String postName;
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "鍑虹敓鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd", sort = 5)
+    private Date birthDate;
 
-    @Excel(name = "閮ㄩ棬", sort = 6, prompt = "璇峰~鍐欑郴缁熶腑宸插瓨鍦ㄧ殑閮ㄩ棬鍚嶇О")
-    private String deptName;
+    @Excel(name = "韬唤璇佸彿", cellType = Excel.ColumnType.STRING, sort = 6)
+    private String identityCard;
 
     @Excel(name = "鐜颁綇鍧�", sort = 7)
     private String adress;
 
-    @Excel(name = "绗竴瀛﹀巻", sort = 8)
-    private String firstStudy;
-
-    @Excel(name = "涓撲笟", sort = 9)
-    private String profession;
-
-    @Excel(name = "骞撮緞", sort = 11)
-    private String age;
-
-    @Excel(name = "鑱旂郴鐢佃瘽", cellType = Excel.ColumnType.STRING, sort = 12)
+    @Excel(name = "鑱旂郴鐢佃瘽", cellType = Excel.ColumnType.STRING, sort = 8)
     private String phone;
 
-    @Excel(name = "绱ф�ヨ仈绯讳汉", sort = 13)
-    private String emergencyContact;
-
-    @Excel(name = "绱ф�ヨ仈绯讳汉鑱旂郴鐢佃瘽", cellType = Excel.ColumnType.STRING, sort = 14)
+    @Excel(name = "绱ф�ヨ仈绯讳汉鐢佃瘽", cellType = Excel.ColumnType.STRING, sort = 9)
     private String emergencyContactPhone;
 
-    @Excel(name = "鍚堝悓骞撮檺", sort = 15)
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "鍏ヨ亴鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd", sort = 10)
+    private Date entryDate;
+
+    @Excel(name = "宀椾綅", sort = 11, prompt = "Fill enabled post name")
+    private String postName;
+
+    @Excel(name = "閮ㄩ棬", sort = 12, prompt = "Fill enabled department name")
+    private String deptName;
+
+    @Excel(name = "鍚堝悓骞撮檺", sort = 13)
     private String contractTerm;
 
     @JsonFormat(pattern = "yyyy-MM-dd")
     @DateTimeFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "鍚堝悓寮�濮嬫棩鏈�", width = 30, dateFormat = "yyyy-MM-dd", sort = 16)
+    @Excel(name = "鍚堝悓寮�濮嬫棩鏈�", width = 30, dateFormat = "yyyy-MM-dd", sort = 14)
     private Date contractStartTime;
 
     @JsonFormat(pattern = "yyyy-MM-dd")
     @DateTimeFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "鍚堝悓缁撴潫鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd", sort = 17)
+    @Excel(name = "鍚堝悓缁撴潫鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd", sort = 15)
     private Date contractEndTime;
-
 }
diff --git a/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java b/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
index 31d74b9..4b043d1 100644
--- a/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
+++ b/src/main/java/com/ruoyi/staff/pojo/StaffOnJob.java
@@ -53,6 +53,22 @@
     private String sex;
 
     /**
+     * 姘戞棌
+     */
+    @TableField("nation")
+    @Excel(name = "姘戞棌", sort = 23)
+    private String nation;
+
+    /**
+     * 鍑虹敓鏃ユ湡
+     */
+    @TableField("birth_date")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "鍑虹敓鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd", sort = 24)
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date birthDate;
+
+    /**
      * 绫嶈疮
      */
     @Excel(name = "绫嶈疮", sort = 5)
@@ -105,6 +121,15 @@
     private String phone;
 
     /**
+     * 鍏ヨ亴鏃ユ湡
+     */
+    @TableField("entry_date")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "鍏ヨ亴鏃ユ湡", width = 30, dateFormat = "yyyy-MM-dd", sort = 25)
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date entryDate;
+
+    /**
      * 绱ф�ヨ仈绯讳汉
      */
     @Excel(name = "绱ф�ヨ仈绯讳汉", sort = 14)
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 841247a..8cecf7b 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
@@ -1,6 +1,5 @@
 package com.ruoyi.staff.service.impl;
 
-
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -13,8 +12,8 @@
 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.dto.StaffOnJobImportDto;
 import com.ruoyi.staff.mapper.StaffContractMapper;
 import com.ruoyi.staff.mapper.StaffLeaveMapper;
 import com.ruoyi.staff.mapper.StaffOnJobMapper;
@@ -25,7 +24,6 @@
 import freemarker.template.Configuration;
 import freemarker.template.Template;
 import lombok.AllArgsConstructor;
-
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -34,18 +32,26 @@
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
-import java.io.*;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
 import java.nio.charset.StandardCharsets;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.ZoneId;
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @AllArgsConstructor
 @Service
-public class StaffOnJobServiceImpl extends ServiceImpl<StaffOnJobMapper, StaffOnJob>  implements IStaffOnJobService {
+public class StaffOnJobServiceImpl extends ServiceImpl<StaffOnJobMapper, StaffOnJob> implements IStaffOnJobService {
 
     @Autowired
     private StaffOnJobMapper staffOnJobMapper;
@@ -53,93 +59,91 @@
     private SysPostMapper sysPostMapper;
     @Autowired
     private SysDeptMapper sysDeptMapper;
-
     @Autowired
     private StaffContractMapper staffContractMapper;
     @Autowired
     private StaffLeaveMapper staffLeaveMapper;
 
-
-    //鍦ㄨ亴鍛樺伐鍙拌处鍒嗛〉鏌ヨ
     @Override
     public IPage<StaffOnJobDto> staffOnJobListPage(Page page, StaffOnJob staffOnJob) {
-        return staffOnJobMapper.staffOnJobListPage(page,staffOnJob);
+        IPage<StaffOnJobDto> result = staffOnJobMapper.staffOnJobListPage(page, staffOnJob);
+        fillNationFallback(result.getRecords());
+        return result;
     }
 
-    //鏂板鍏ヨ亴
     @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);
+    public int add(StaffOnJobDto staffOnJobParams) {
+        syncStaffBasicFields(staffOnJobParams);
 
-        // 鍒涘缓鍚堝悓璁板綍
+        List<StaffOnJob> existedStaffNo = staffOnJobMapper.selectList(Wrappers.<StaffOnJob>lambdaQuery()
+                .eq(StaffOnJob::getStaffNo, staffOnJobParams.getStaffNo()));
+        if (!CollectionUtils.isEmpty(existedStaffNo)) {
+            throw new BaseException("Duplicate staffNo: " + staffOnJobParams.getStaffNo());
+        }
+
+        staffOnJobParams.setContractExpireTime(staffOnJobParams.getContractEndTime());
+        staffOnJobParams.setStaffState(1);
+        staffOnJobMapper.insert(staffOnJobParams);
+
         StaffContract staffContract = new StaffContract();
-        staffContract.setStaffOnJobId(staffOnJobPrams.getId());
-        staffContract.setContractTerm(staffOnJobPrams.getContractTerm());
-        staffContract.setContractStartTime(staffOnJobPrams.getContractStartTime());
-        staffContract.setContractEndTime(staffOnJobPrams.getContractEndTime());
+        staffContract.setStaffOnJobId(staffOnJobParams.getId());
+        staffContract.setContractTerm(staffOnJobParams.getContractTerm());
+        staffContract.setContractStartTime(staffOnJobParams.getContractStartTime());
+        staffContract.setContractEndTime(staffOnJobParams.getContractEndTime());
         return staffContractMapper.insert(staffContract);
     }
 
-    //鏇存柊鍏ヨ亴淇℃伅
     @Override
     @Transactional(rollbackFor = Exception.class)
     public int update(Long id, StaffOnJobDto staffOnJobParams) {
-        // 鍒ゆ柇瀵硅薄鏄惁瀛樺湪
+        syncStaffBasicFields(staffOnJobParams);
+        staffOnJobParams.setId(id);
+
         StaffOnJob job = staffOnJobMapper.selectById(id);
-        if (job == null){
-            throw new BaseException("缂栧彿涓�"+staffOnJobParams.getStaffNo()+"鐨勫憳宸ヤ笉瀛樺湪,鏃犳硶鏇存柊!!!");
+        if (job == null) {
+            throw new BaseException("Staff not found, id=" + id);
         }
 
-        String[] ignoreProperties = {"id"};//鎺掗櫎鏇存柊灞炴��
+        if (StringUtils.isNotBlank(staffOnJobParams.getStaffNo())) {
+            List<StaffOnJob> existedStaffNo = staffOnJobMapper.selectList(Wrappers.<StaffOnJob>lambdaQuery()
+                    .eq(StaffOnJob::getStaffNo, staffOnJobParams.getStaffNo())
+                    .ne(StaffOnJob::getId, id));
+            if (!CollectionUtils.isEmpty(existedStaffNo)) {
+                throw new BaseException("Duplicate staffNo: " + 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);
+                .orderByDesc(StaffContract::getId)
+                .last("limit 1"));
+        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("璇ュ憳宸ヤ笉瀛樺湪,鏃犳硶鏇存柊!!!");
+        if (job == null) {
+            throw new BaseException("Staff not found, id=" + id);
         }
 
-        // 澧炲姞鍚堝悓
         StaffContract newStaffContract = new StaffContract();
         newStaffContract.setStaffOnJobId(id);
         newStaffContract.setContractTerm(staffContract.getContractTerm());
@@ -147,23 +151,21 @@
         newStaffContract.setContractEndTime(staffContract.getContractEndTime());
         staffContractMapper.insert(newStaffContract);
 
-        // 鏇存柊鍛樺伐鍚堝悓杩囨湡鏃堕棿
         job.setContractExpireTime(staffContract.getContractEndTime());
         staffOnJobMapper.updateById(job);
         return 0;
     }
 
-    //鍦ㄨ亴鍛樺伐璇︽儏
     @Override
     public StaffOnJobDto staffOnJobDetail(Long id) {
-        StaffOnJob staffOnJob  = staffOnJobMapper.selectById(id);
+        StaffOnJob staffOnJob = staffOnJobMapper.selectById(id);
         if (staffOnJob == null) {
-            throw new IllegalArgumentException("璇ュ憳宸ヤ笉瀛樺湪");
+            throw new BaseException("Staff not found, id=" + id);
         }
 
         StaffOnJobDto staffOnJobDto = new StaffOnJobDto();
         BeanUtils.copyProperties(staffOnJob, staffOnJobDto);
-        // 鏌ヨ宀椾綅鍚嶇О
+
         if (staffOnJob.getSysPostId() != null) {
             SysPost post = sysPostMapper.selectPostById(staffOnJob.getSysPostId().longValue());
             if (post != null) {
@@ -171,30 +173,33 @@
             }
         }
 
-        // 鏌ヨ鍚堝悓淇℃伅
         StaffContract contract = staffContractMapper.selectOne(Wrappers.<StaffContract>lambdaQuery()
                 .eq(StaffContract::getStaffOnJobId, staffOnJob.getId())
-                .last("limit 1")
-                .orderByDesc(StaffContract::getId));
-        if (contract != null){
+                .orderByDesc(StaffContract::getId)
+                .last("limit 1"));
+        if (contract != null) {
             staffOnJobDto.setContractTerm(contract.getContractTerm());
             staffOnJobDto.setContractStartTime(contract.getContractStartTime());
             staffOnJobDto.setContractEndTime(contract.getContractEndTime());
         }
+
+        fillNationFallback(staffOnJobDto);
         return staffOnJobDto;
     }
 
-    //鍦ㄨ亴鍛樺伐瀵煎嚭
     @Override
     public void staffOnJobExport(HttpServletResponse response, StaffOnJob staffOnJob) {
         List<StaffOnJobDto> staffOnJobs = staffOnJobMapper.staffOnJobList(staffOnJob);
-        ExcelUtil<StaffOnJobDto> util = new ExcelUtil<StaffOnJobDto>(StaffOnJobDto.class);
+        fillNationFallback(staffOnJobs);
+        ExcelUtil<StaffOnJobDto> util = new ExcelUtil<>(StaffOnJobDto.class);
         util.exportExcel(response, staffOnJobs, "鍦ㄨ亴鍛樺伐鍙拌处瀵煎嚭");
     }
 
     @Override
     public List<StaffOnJobDto> staffOnJobList(StaffOnJob staffOnJob) {
-        return staffOnJobMapper.staffOnJobList(staffOnJob);
+        List<StaffOnJobDto> staffOnJobs = staffOnJobMapper.staffOnJobList(staffOnJob);
+        fillNationFallback(staffOnJobs);
+        return staffOnJobs;
     }
 
     @Override
@@ -204,7 +209,7 @@
             ExcelUtil<StaffOnJobImportDto> util = new ExcelUtil<>(StaffOnJobImportDto.class);
             List<StaffOnJobImportDto> staffOnJobs = util.importExcel(file.getInputStream());
             if (CollectionUtils.isEmpty(staffOnJobs)) {
-                throw new BaseException("妯℃澘閿欒鎴栧鍏ユ暟鎹负绌�");
+                throw new BaseException("Import data is empty");
             }
 
             Map<String, SysPost> postMap = buildPostMap();
@@ -219,7 +224,7 @@
             if (e instanceof BaseException) {
                 throw (BaseException) e;
             }
-            throw new BaseException("瀵煎叆澶辫触锛岃妫�鏌ユā鏉挎牸寮忔槸鍚︽纭�");
+            throw new BaseException("Import failed, please check template and data format");
         }
     }
 
@@ -230,34 +235,37 @@
         String deptName = normalizeValue(row.getDeptName());
 
         if (StringUtils.isBlank(staffNo)) {
-            throw new BaseException("绗�" + rowNum + "琛屽憳宸ョ紪鍙蜂笉鑳戒负绌�");
+            throw new BaseException("Row " + rowNum + " staffNo cannot be blank");
         }
         if (!importedStaffNos.add(staffNo)) {
-            throw new BaseException("绗�" + rowNum + "琛屽憳宸ョ紪鍙烽噸澶嶏細" + staffNo);
+            throw new BaseException("Row " + rowNum + " duplicated staffNo: " + staffNo);
         }
         if (StringUtils.isBlank(normalizeValue(row.getStaffName()))) {
-            throw new BaseException("绗�" + rowNum + "琛屽憳宸ュ鍚嶄笉鑳戒负绌�");
+            throw new BaseException("Row " + rowNum + " staffName cannot be blank");
         }
         if (StringUtils.isBlank(postName)) {
-            throw new BaseException("绗�" + rowNum + "琛屽矖浣嶄笉鑳戒负绌�");
+            throw new BaseException("Row " + rowNum + " postName cannot be blank");
         }
         if (StringUtils.isBlank(deptName)) {
-            throw new BaseException("绗�" + rowNum + "琛岄儴闂ㄤ笉鑳戒负绌�");
+            throw new BaseException("Row " + rowNum + " deptName cannot be blank");
         }
         if (row.getContractStartTime() == null) {
-            throw new BaseException("绗�" + rowNum + "琛屽悎鍚屽紑濮嬫棩鏈熶笉鑳戒负绌�");
+            throw new BaseException("Row " + rowNum + " contractStartTime cannot be blank");
         }
         if (row.getContractEndTime() == null) {
-            throw new BaseException("绗�" + rowNum + "琛屽悎鍚岀粨鏉熸棩鏈熶笉鑳戒负绌�");
+            throw new BaseException("Row " + rowNum + " contractEndTime cannot be blank");
+        }
+        if (row.getEntryDate() == null) {
+            throw new BaseException("Row " + rowNum + " entryDate cannot be blank");
         }
 
         SysPost post = postMap.get(postName);
         if (post == null) {
-            throw new BaseException("绗�" + rowNum + "琛屽矖浣嶄笉瀛樺湪鎴栧凡鍋滅敤锛�" + postName);
+            throw new BaseException("Row " + rowNum + " post not found or disabled: " + postName);
         }
         SysDept dept = deptMap.get(deptName);
         if (dept == null) {
-            throw new BaseException("绗�" + rowNum + "琛岄儴闂ㄤ笉瀛樺湪鎴栧凡鍋滅敤锛�" + deptName);
+            throw new BaseException("Row " + rowNum + " dept not found or disabled: " + deptName);
         }
 
         StaffOnJobDto staffOnJobDto = new StaffOnJobDto();
@@ -265,30 +273,69 @@
         staffOnJobDto.setStaffNo(staffNo);
         staffOnJobDto.setStaffName(normalizeValue(row.getStaffName()));
         staffOnJobDto.setSex(normalizeValue(row.getSex()));
-        staffOnJobDto.setNativePlace(normalizeValue(row.getNativePlace()));
+        staffOnJobDto.setNation(normalizeValue(row.getNation()));
+        staffOnJobDto.setNativePlace(normalizeValue(row.getNation()));
+        staffOnJobDto.setBirthDate(row.getBirthDate());
+        staffOnJobDto.setIdentityCard(normalizeValue(row.getIdentityCard()));
         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.setEntryDate(row.getEntryDate());
         staffOnJobDto.setContractTerm(normalizeValue(row.getContractTerm()));
         staffOnJobDto.setSysPostId(post.getPostId().intValue());
         staffOnJobDto.setSysDeptId(dept.getDeptId().intValue());
+        syncStaffBasicFields(staffOnJobDto);
         return staffOnJobDto;
+    }
+
+    private void syncStaffBasicFields(StaffOnJobDto staffOnJobDto) {
+        if (staffOnJobDto == null) {
+            return;
+        }
+        staffOnJobDto.setStaffNo(normalizeValue(staffOnJobDto.getStaffNo()));
+        staffOnJobDto.setStaffName(normalizeValue(staffOnJobDto.getStaffName()));
+        staffOnJobDto.setNation(normalizeValue(staffOnJobDto.getNation()));
+        staffOnJobDto.setNativePlace(normalizeValue(staffOnJobDto.getNativePlace()));
+        if (StringUtils.isBlank(staffOnJobDto.getNation())) {
+            staffOnJobDto.setNation(staffOnJobDto.getNativePlace());
+        }
+        if (StringUtils.isBlank(staffOnJobDto.getNativePlace())) {
+            staffOnJobDto.setNativePlace(staffOnJobDto.getNation());
+        }
+        if (staffOnJobDto.getEntryDate() == null) {
+            staffOnJobDto.setEntryDate(staffOnJobDto.getContractStartTime());
+        }
+    }
+
+    private void fillNationFallback(StaffOnJob staffOnJob) {
+        if (staffOnJob == null) {
+            return;
+        }
+        if (StringUtils.isBlank(staffOnJob.getNation())) {
+            staffOnJob.setNation(staffOnJob.getNativePlace());
+        }
+        if (StringUtils.isBlank(staffOnJob.getNativePlace())) {
+            staffOnJob.setNativePlace(staffOnJob.getNation());
+        }
+    }
+
+    private void fillNationFallback(List<? extends StaffOnJob> staffOnJobs) {
+        if (CollectionUtils.isEmpty(staffOnJobs)) {
+            return;
+        }
+        staffOnJobs.forEach(this::fillNationFallback);
     }
 
     private Map<String, SysPost> buildPostMap() {
         SysPost query = new SysPost();
         query.setStatus("0");
-        return buildUniqueMap(sysPostMapper.selectPostList(query), SysPost::getPostName, "宀椾綅");
+        return buildUniqueMap(sysPostMapper.selectPostList(query), SysPost::getPostName, "post");
     }
 
     private Map<String, SysDept> buildDeptMap() {
         SysDept query = new SysDept();
         query.setStatus("0");
-        return buildUniqueMap(sysDeptMapper.selectDeptList(query), SysDept::getDeptName, "閮ㄩ棬");
+        return buildUniqueMap(sysDeptMapper.selectDeptList(query), SysDept::getDeptName, "dept");
     }
 
     private <T> Map<String, T> buildUniqueMap(List<T> dataList, Function<T, String> nameGetter, String fieldName) {
@@ -303,7 +350,7 @@
                 .sorted()
                 .collect(Collectors.toList());
         if (!duplicateNames.isEmpty()) {
-            throw new BaseException("绯荤粺涓瓨鍦ㄩ噸鍚�" + fieldName + "锛屾棤娉曞鍏ワ細" + String.join("銆�", duplicateNames));
+            throw new BaseException("Duplicate " + fieldName + " names: " + String.join(", ", duplicateNames));
         }
 
         return groupedMap.entrySet().stream()
@@ -314,38 +361,27 @@
         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 localDate = instant.atZone(ZoneId.of("Asia/Shanghai")).toLocalDate();
+        LocalDate localDate1 = localDate.minusYears(Integer.parseInt(staff.getContractTerm()));
         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")){
+        if (staff.getDateSelect().equals("A")) {
             staff.setSyear(localDate1.getYear() + "");
             staff.setSmoth(localDate1.getMonthValue() + "");
             staff.setSday(localDate1.getDayOfMonth() + "");
@@ -359,8 +395,7 @@
             staff.setSeyear(localDate4.getYear() + "");
             staff.setSemoth(localDate4.getMonthValue() + "");
             staff.setSeday(localDate4.getDayOfMonth() + "");
-        }else if (staff.getDateSelect().equals("B")){
-
+        } else if (staff.getDateSelect().equals("B")) {
             staff.setBsyear(localDate1.getYear() + "");
             staff.setBsmoth(localDate1.getMonthValue() + "");
             staff.setBsday(localDate1.getDayOfMonth() + "");
@@ -371,29 +406,24 @@
             staff.setBseyear(localDate4.getYear() + "");
             staff.setBsemoth(localDate4.getMonthValue() + "");
             staff.setBseday(localDate4.getDayOfMonth() + "");
-        }else if (staff.getDateSelect().equals("C")){
+        } 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 妯℃澘
+        Map<String, Object> data = new HashMap<>();
+        data.put("item", staff);
         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)) {
+        try (FileOutputStream fos = new FileOutputStream(outputFile);
+             OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8)) {
             osw.write(filledXml);
         }
         return url;
     }
-
-
-
 }
diff --git a/src/main/resources/mapper/staff/StaffOnJobMapper.xml b/src/main/resources/mapper/staff/StaffOnJobMapper.xml
index 75ae5ef..35e7d1c 100644
--- a/src/main/resources/mapper/staff/StaffOnJobMapper.xml
+++ b/src/main/resources/mapper/staff/StaffOnJobMapper.xml
@@ -19,10 +19,10 @@
             AND staff_name LIKE CONCAT('%',#{staffOnJob.staffName},'%')
         </if>
         <if test="staffOnJob.entryDateStart != null and staffOnJob.entryDateStart != '' ">
-            AND contract_expire_time &gt;= DATE_FORMAT(#{staffOnJob.entryDateStart},'%Y-%m-%d')
+            AND IFNULL(entry_date, DATE(create_time)) &gt;= DATE_FORMAT(#{staffOnJob.entryDateStart},'%Y-%m-%d')
         </if>
         <if test="staffOnJob.entryDateEnd != null and staffOnJob.entryDateEnd != '' ">
-            AND  contract_expire_time &lt;= DATE_FORMAT(#{staffOnJob.entryDateEnd},'%Y-%m-%d')
+            AND  IFNULL(entry_date, DATE(create_time)) &lt;= DATE_FORMAT(#{staffOnJob.entryDateEnd},'%Y-%m-%d')
         </if>
     </select>
     <select id="staffOnJobList" resultType="com.ruoyi.staff.dto.StaffOnJobDto">
@@ -48,7 +48,7 @@
         SELECT COUNT(*)
         FROM staff_on_job
         WHERE staff_state = 1
-        AND DATE_FORMAT(create_time, '%Y-%m-%d') &lt;= #{date}
+        AND IFNULL(entry_date, DATE(create_time)) &lt;= #{date}
     </select>
 
     <!-- 缁熻鎸囧畾鏈堜唤鐨勬柊鍏ヨ亴鍛樺伐鏁� -->
@@ -56,6 +56,6 @@
         SELECT COUNT(*)
         FROM staff_on_job
         WHERE staff_state = 1
-        AND DATE_FORMAT(create_time, '%Y-%m-%d') BETWEEN #{monthStart} AND #{monthEnd}
+        AND IFNULL(entry_date, DATE(create_time)) BETWEEN #{monthStart} AND #{monthEnd}
     </select>
 </mapper>
diff --git a/src/main/resources/mapper/stock/StockInRecordMapper.xml b/src/main/resources/mapper/stock/StockInRecordMapper.xml
index cd239c8..37cd615 100644
--- a/src/main/resources/mapper/stock/StockInRecordMapper.xml
+++ b/src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -33,6 +33,9 @@
             <if test="params.stockLocation != null and params.stockLocation != ''">
                 and sir.stock_location = #{params.stockLocation}
             </if>
+            <if test="params.model != null and params.model != ''">
+                and pm.model like concat('%',#{params.model},'%')
+            </if>
         </where>
         order by sir.id desc
     </select>
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
index 25fa872..86661d6 100644
--- a/src/main/resources/mapper/stock/StockInventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -84,6 +84,9 @@
         <if test="ew.stockLocation != null and ew.stockLocation != ''">
             and si.stock_location = #{ew.stockLocation}
         </if>
+        <if test="ew.model != null and ew.model !=''">
+            and pm.model like concat('%',#{ew.model},'%')
+        </if>
     </select>
     <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData">
         select si.qualitity,
diff --git a/src/main/resources/mapper/stock/StockOutRecordMapper.xml b/src/main/resources/mapper/stock/StockOutRecordMapper.xml
index 5fc1b3f..096bf14 100644
--- a/src/main/resources/mapper/stock/StockOutRecordMapper.xml
+++ b/src/main/resources/mapper/stock/StockOutRecordMapper.xml
@@ -45,6 +45,9 @@
             <if test="params.stockLocation != null and params.stockLocation != ''">
                 and sor.stock_location = #{params.stockLocation}
             </if>
+        <if test="params.model != null and params.model != ''">
+            and pm.model like concat('%',#{params.model},'%')
+        </if>
         </where>
         order by sor.id desc
     </select>

--
Gitblit v1.9.3