Explorar o código

人员信息调整

徐滕 hai 3 semanas
pai
achega
b399853655
Modificáronse 29 ficheiros con 1200 adicións e 84 borrados
  1. 3 3
      src/main/java/com/jeeplus/common/oss/OSSClientUtil.java
  2. 9 2
      src/main/java/com/jeeplus/modules/knowledgeSharing/dify/DifyApiClient.java
  3. 9 0
      src/main/java/com/jeeplus/modules/workreimbursement/entity/WorkReimbursement.java
  4. 73 0
      src/main/java/com/jeeplus/modules/workstaff/entity/WorkStaffBasicInfo.java
  5. 85 4
      src/main/java/com/jeeplus/modules/workstaff/service/WorkStaffBasicInfoService.java
  6. 21 0
      src/main/java/com/jeeplus/modules/workstaff/service/WorkStaffCertificateService.java
  7. 4 0
      src/main/java/com/jeeplus/modules/workstaff/web/WorkStaffBasicInfoController.java
  8. 79 0
      src/main/java/com/jeeplus/modules/workstaff/web/WorkStaffBasicInfoDimissionController.java
  9. 79 0
      src/main/java/com/jeeplus/modules/workstaff/web/WorkStaffBasicInfoEmploymentInController.java
  10. 79 0
      src/main/java/com/jeeplus/modules/workstaff/web/WorkStaffBasicInfoTraineeController.java
  11. 15 0
      src/main/resources/mappings/modules/workreimbursement/WorkReimbursementDao.xml
  12. 20 4
      src/main/resources/mappings/modules/workstaff/WorkStaffAchivesDao.xml
  13. 51 9
      src/main/resources/mappings/modules/workstaff/WorkStaffBasicInfoDao.xml
  14. 3 1
      src/main/resources/mappings/modules/workstaff/WorkStaffCertificateDao.xml
  15. 55 1
      src/main/webapp/webpage/modules/sys/userInfo.jsp
  16. 6 6
      src/main/webapp/webpage/modules/workreimbursement/new/workReimbursementNewAudit.jsp
  17. 7 0
      src/main/webapp/webpage/modules/workreimbursement/workReimbursementAllList.jsp
  18. 7 0
      src/main/webapp/webpage/modules/workreimbursement/workReimbursementList.jsp
  19. 7 7
      src/main/webapp/webpage/modules/workstaff/qualificationForm.jsp
  20. 21 16
      src/main/webapp/webpage/modules/workstaff/workAddressBookList.jsp
  21. 1 1
      src/main/webapp/webpage/modules/workstaff/workAddressBookView.jsp
  22. 1 1
      src/main/webapp/webpage/modules/workstaff/workStaffAchiveInfoForm.jsp
  23. 1 1
      src/main/webapp/webpage/modules/workstaff/workStaffAchiveInfoForms.jsp
  24. 62 1
      src/main/webapp/webpage/modules/workstaff/workStaffBasicDetailAudit.jsp
  25. 145 2
      src/main/webapp/webpage/modules/workstaff/workStaffBasicDetailForm.jsp
  26. 139 1
      src/main/webapp/webpage/modules/workstaff/workStaffBasicDetailModify.jsp
  27. 1 1
      src/main/webapp/webpage/modules/workstaff/workStaffBasicDetailModifyDirectly.jsp
  28. 156 22
      src/main/webapp/webpage/modules/workstaff/workStaffBasicInfoForm.jsp
  29. 61 1
      src/main/webapp/webpage/modules/workstaff/workStaffBasicInfoView.jsp

+ 3 - 3
src/main/java/com/jeeplus/common/oss/OSSClientUtil.java

@@ -194,9 +194,9 @@ public class OSSClientUtil {
 //    }
 
     public String uploadImg2OSS(MultipartFile file,String fileDir) {
-        if (file.getSize() > 10 * 1024 * 1024) {
-            System.out.println("上传文件大小不能超过10M!");
-            return "上传文件大小不能超过10M!";
+        if (file.getSize() > 100 * 1024 * 1024) {
+            System.out.println("上传文件大小不能超过100M!");
+            return "上传文件大小不能超过100M!";
         }
         String originalFilename = file.getOriginalFilename();
         String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();

+ 9 - 2
src/main/java/com/jeeplus/modules/knowledgeSharing/dify/DifyApiClient.java

@@ -336,8 +336,9 @@ public class DifyApiClient {
                     API_URL+"/{0}/documents?page={1}&limit={2}",
                     id, pageNo, pageSize
             );
-            if(StringUtils.isNotBlank(fileName)){
-                url = url + "&keyword=" + fileName;
+            if (StringUtils.isNotBlank(fileName)) {
+                String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
+                url = url + "&keyword=" + encodedFileName;
             }
 
             HttpGet httpGet = new HttpGet(url);
@@ -355,7 +356,13 @@ public class DifyApiClient {
                     throw new RuntimeException("API request failed with status code: "
                             + response.getStatusLine().getStatusCode() + "\nResponse: " + responseString);
                 }
+            } catch (Exception e) {
+                System.out.println(e.getMessage());
+                throw new RuntimeException(e);
             }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            throw new RuntimeException(e);
         }
     }
 

+ 9 - 0
src/main/java/com/jeeplus/modules/workreimbursement/entity/WorkReimbursement.java

@@ -85,6 +85,7 @@ public class WorkReimbursement extends ActEntity<WorkReimbursement> {
 	private String replenishStatus; // 附件补充状态
 	private Date replenishDate; // 附件补充时间
 	private Integer oldDataType; // 老数据状态
+	private String invoiceNumber; // 报销数电票号
 
 	public String getComment() {
 		return comment;
@@ -747,4 +748,12 @@ public class WorkReimbursement extends ActEntity<WorkReimbursement> {
 	public void setOldDataType(Integer oldDataType) {
 		this.oldDataType = oldDataType;
 	}
+
+	public String getInvoiceNumber() {
+		return invoiceNumber;
+	}
+
+	public void setInvoiceNumber(String invoiceNumber) {
+		this.invoiceNumber = invoiceNumber;
+	}
 }

+ 73 - 0
src/main/java/com/jeeplus/modules/workstaff/entity/WorkStaffBasicInfo.java

@@ -132,6 +132,15 @@ public class WorkStaffBasicInfo extends DataEntity<WorkStaffBasicInfo> {
     private String relationshipStatus;
     private Act act;
 
+    private MultipartFile idCardPortrait;        // 身份证人身箱照片
+    private String idCardPortraitName;        // 身份证人身箱照片名称
+    private String idCardPortraitPath;        // 身份证人身箱照片路径
+    private String idCardPortraitPathStr;        // 身份证人身箱照片路径
+    private MultipartFile idCardNationalEmblem;        // 身份证国徽照片
+    private String idCardNationalEmblemName;        // 身份证国徽照片名称
+    private String idCardNationalEmblemPath;        // 身份证国徽照片路径
+    private String idCardNationalEmblemPathStr;        // 身份证国徽照片路径
+
     public String getDdId() {
         return ddId;
     }
@@ -983,4 +992,68 @@ public class WorkStaffBasicInfo extends DataEntity<WorkStaffBasicInfo> {
     public void setAct(Act act) {
         this.act = act;
     }
+
+    public MultipartFile getIdCardPortrait() {
+        return idCardPortrait;
+    }
+
+    public void setIdCardPortrait(MultipartFile idCardPortrait) {
+        this.idCardPortrait = idCardPortrait;
+    }
+
+    public MultipartFile getIdCardNationalEmblem() {
+        return idCardNationalEmblem;
+    }
+
+    public void setIdCardNationalEmblem(MultipartFile idCardNationalEmblem) {
+        this.idCardNationalEmblem = idCardNationalEmblem;
+    }
+
+    public String getIdCardPortraitName() {
+        return idCardPortraitName;
+    }
+
+    public void setIdCardPortraitName(String idCardPortraitName) {
+        this.idCardPortraitName = idCardPortraitName;
+    }
+
+    public String getIdCardPortraitPath() {
+        return idCardPortraitPath;
+    }
+
+    public void setIdCardPortraitPath(String idCardPortraitPath) {
+        this.idCardPortraitPath = idCardPortraitPath;
+    }
+
+    public String getIdCardNationalEmblemName() {
+        return idCardNationalEmblemName;
+    }
+
+    public void setIdCardNationalEmblemName(String idCardNationalEmblemName) {
+        this.idCardNationalEmblemName = idCardNationalEmblemName;
+    }
+
+    public String getIdCardNationalEmblemPath() {
+        return idCardNationalEmblemPath;
+    }
+
+    public void setIdCardNationalEmblemPath(String idCardNationalEmblemPath) {
+        this.idCardNationalEmblemPath = idCardNationalEmblemPath;
+    }
+
+    public String getIdCardPortraitPathStr() {
+        return idCardPortraitPathStr;
+    }
+
+    public void setIdCardPortraitPathStr(String idCardPortraitPathStr) {
+        this.idCardPortraitPathStr = idCardPortraitPathStr;
+    }
+
+    public String getIdCardNationalEmblemPathStr() {
+        return idCardNationalEmblemPathStr;
+    }
+
+    public void setIdCardNationalEmblemPathStr(String idCardNationalEmblemPathStr) {
+        this.idCardNationalEmblemPathStr = idCardNationalEmblemPathStr;
+    }
 }

+ 85 - 4
src/main/java/com/jeeplus/modules/workstaff/service/WorkStaffBasicInfoService.java

@@ -160,6 +160,13 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
             if (StringUtils.isNotBlank(workStaffBasicInfo.getHandSignature())) {
                 workStaffBasicInfo.setHandSignatureUrl(new OSSClientUtil().getFileTemporaryLookUrl(aliyunUrl + workStaffBasicInfo.getHandSignature()));
             }
+            if(StringUtils.isNotEmpty(workStaffBasicInfo.getIdCardPortraitPath())) {
+                workStaffBasicInfo.setIdCardPortraitPathStr(WorkattachmentService.fileUrlManage(workStaffBasicInfo.getIdCardPortraitPath()));
+            }
+            if(StringUtils.isNotEmpty(workStaffBasicInfo.getIdCardNationalEmblemPath())) {
+                workStaffBasicInfo.setIdCardNationalEmblemPathStr(WorkattachmentService.fileUrlManage(workStaffBasicInfo.getIdCardNationalEmblemPath()));
+            }
+
         }
         return workStaffBasicInfo;
     }
@@ -283,6 +290,38 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
 //                workStaffBasicInfo.getCurrentUser().setBranchOffice(workStaffBasicInfo.getCurrentUser().getCompany());
 //            }
 //        }
+        List<String> notOfficeParentIdList = officeService.getChildrenOffice("897d1bf0975a4598b3bb248049e2d1cf");
+        notOfficeParentIdList.add("897d1bf0975a4598b3bb248049e2d1cf");
+        workStaffBasicInfo.setNotOfficeParentIdList(notOfficeParentIdList);
+
+        if (null != workStaffBasicInfo.getOffice() && StringUtils.isNotBlank(workStaffBasicInfo.getOffice().getId())) {
+            if ("一部本部".equals(workStaffBasicInfo.getOffice().getId())) {
+                List<String> officeIdList = Lists.newArrayList();
+                Office office = officeService.getByName("工程一部");
+                officeIdList.add(office.getId());
+                workStaffBasicInfo.setOfficeIdList(officeIdList);
+            } else {
+                //查询该选择节点下所有的部门Id
+                List<String> officeIdList = officeService.getChildrenOffice(workStaffBasicInfo.getOffice().getId());
+                officeIdList.add(workStaffBasicInfo.getOffice().getId());
+                if (officeIdList.size() > 0) {
+                    workStaffBasicInfo.setOfficeIdList(officeIdList);
+                }
+            }
+        } else if (null != workStaffBasicInfo.getOffice() && StringUtils.isNotBlank(workStaffBasicInfo.getOffice().getName())) {
+            if ("一部本部".equals(workStaffBasicInfo.getOffice().getName())) {
+                List<String> officeIdList = Lists.newArrayList();
+                Office office = officeService.getByName("工程一部");
+                officeIdList.add(office.getId());
+                workStaffBasicInfo.setOfficeIdList(officeIdList);
+            } else {
+                //查询该选择节点下所有的部门Id
+                List<String> officeIdList = officeService.getChildrenOffice(workStaffBasicInfo.getOffice().getName());
+                if (officeIdList.size() > 0) {
+                    workStaffBasicInfo.setOfficeIdList(officeIdList);
+                }
+            }
+        }
         String companyId = UserUtils.getUser().getComId();
         Office office = new Office();
         office.setId(companyId);
@@ -472,15 +511,35 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
 
     public void uploadFile(WorkStaffBasicInfo workStaffBasicInfo) {
         MultipartFile pictureFile = workStaffBasicInfo.getPictureFile();
+        MultipartFile idCardPortrait = workStaffBasicInfo.getIdCardPortrait();
+        MultipartFile idCardNationalEmblem = workStaffBasicInfo.getIdCardNationalEmblem();
+        OSSClientUtil ossClientUtil = new OSSClientUtil();
         if (pictureFile != null && !pictureFile.isEmpty() && pictureFile.getSize() > 0) {
             try {
-                OSSClientUtil ossClientUtil = new OSSClientUtil();
                 String url = ossClientUtil.uploadFile2OSS(pictureFile, "certificate");
                 workStaffBasicInfo.setPicture(url);
             } catch (Exception e) {
                 logger.error("oss上传文件失败!");
             }
         }
+        if (idCardPortrait != null && !idCardPortrait.isEmpty() && idCardPortrait.getSize() > 0) {
+            try {
+                String url = ossClientUtil.uploadFile2OSS(idCardPortrait, "certificate");
+                workStaffBasicInfo.setIdCardPortraitPath(url);
+                workStaffBasicInfo.setIdCardPortraitName(idCardPortrait.getOriginalFilename());
+            } catch (Exception e) {
+                logger.error("oss上传文件失败!");
+            }
+        }
+        if (idCardNationalEmblem != null && !idCardNationalEmblem.isEmpty() && idCardNationalEmblem.getSize() > 0) {
+            try {
+                String url = ossClientUtil.uploadFile2OSS(idCardNationalEmblem, "certificate");
+                workStaffBasicInfo.setIdCardNationalEmblemPath(url);
+                workStaffBasicInfo.setIdCardNationalEmblemName(idCardNationalEmblem.getOriginalFilename());
+            } catch (Exception e) {
+                logger.error("oss上传文件失败!");
+            }
+        }
     }
 
     public Page<WorkStaffBasicInfo> getByRoleId(Page<WorkStaffBasicInfo> page, WorkStaffBasicInfo workStaffBasicInfo, String roleId) {
@@ -857,7 +916,7 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
         }
         //新增用户信息
         this.preSave(workStaffBasicInfo, request);
-//        this.uploadFile(workStaffBasicInfo);
+        this.uploadFile(workStaffBasicInfo);
         //新增员工档案
         this.saveAchive(workStaffBasicInfo);
         workStaffBasicInfo.setAchiveId(workStaffBasicInfo.getId());
@@ -883,7 +942,17 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
 
     public WorkStaffBasicInfo getAchive(WorkStaffBasicInfo workStaffBasicInfo) {
         workStaffBasicInfo.setId(workStaffBasicInfo.getAchiveId());
-        return workStaffAchivesDao.get(workStaffBasicInfo.getId());
+        workStaffBasicInfo = workStaffAchivesDao.get(workStaffBasicInfo.getId());
+        if (null != workStaffBasicInfo) {
+            if (StringUtils.isNotEmpty(workStaffBasicInfo.getIdCardPortraitPath())) {
+                workStaffBasicInfo.setIdCardPortraitPathStr(WorkattachmentService.fileUrlManage(workStaffBasicInfo.getIdCardPortraitPath()));
+            }
+            if (StringUtils.isNotEmpty(workStaffBasicInfo.getIdCardNationalEmblemPath())) {
+                workStaffBasicInfo.setIdCardNationalEmblemPathStr(WorkattachmentService.fileUrlManage(workStaffBasicInfo.getIdCardNationalEmblemPath()));
+            }
+        }
+        WorkStaffBasicInfo staffBasicInfo = workStaffAchivesDao.get(workStaffBasicInfo.getId());
+        return staffBasicInfo;
     }
 
     public boolean validateStaff(WorkStaffBasicInfo workStaffBasicInfo, StringBuilder errInfo) {
@@ -958,6 +1027,7 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
                     String name = field.getName();
                     if ("picture".equals(name) || "marriage".equals(name) || "politics".equals(name) || "exSoldier".equals(name) || "address".equals(name)
                             || "nativePlace".equals(name) || "household".equals(name) || "industryDate".equals(name) || "idCard".equals(name) || "age".equals(name)
+                            || "idCardPortraitName".equals(name) || "idCardPortraitPath".equals(name) || "idCardNationalEmblemName".equals(name) || "idCardNationalEmblemPath".equals(name)
                             || "birthday".equals(name) || "email".equals(name) || "nation".equals(name)) {
                         String setMethod = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
                         String getMethod = "get"+name.substring(0,1).toUpperCase()+name.substring(1);
@@ -1022,6 +1092,13 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
                         }
                     }
                 }
+
+        if(StringUtils.isNotEmpty(workStaffBasicInfo.getIdCardPortraitPath())) {
+            workStaffBasicInfo.setIdCardPortraitPathStr(WorkattachmentService.fileUrlManage(workStaffBasicInfo.getIdCardPortraitPath()));
+        }
+        if(StringUtils.isNotEmpty(workStaffBasicInfo.getIdCardNationalEmblemPath())) {
+            workStaffBasicInfo.setIdCardNationalEmblemPathStr(WorkattachmentService.fileUrlManage(workStaffBasicInfo.getIdCardNationalEmblemPath()));
+        }
     }
 
     private int saveDetailsApply(WorkStaffBasicInfo workStaffBasicInfo, boolean first) {
@@ -1176,7 +1253,10 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
         Class<? extends WorkStaffBasicInfo> basicInfoClass = workStaffBasicInfo.getClass();
         Class<? extends WorkStaffBasicInfo> wClass = w.getClass();
         Field[] declaredFields = basicInfoClass.getDeclaredFields();
-        if (workStaffBasicInfo.getPictureFile() != null && !workStaffBasicInfo.getPictureFile().isEmpty() && workStaffBasicInfo.getPictureFile().getSize() > 0) {
+        if ((workStaffBasicInfo.getPictureFile() != null && !workStaffBasicInfo.getPictureFile().isEmpty() && workStaffBasicInfo.getPictureFile().getSize() > 0) ||
+                (workStaffBasicInfo.getIdCardPortrait() != null && !workStaffBasicInfo.getIdCardPortrait().isEmpty() && workStaffBasicInfo.getIdCardPortrait().getSize() > 0) ||
+                (workStaffBasicInfo.getIdCardNationalEmblem() != null && !workStaffBasicInfo.getIdCardNationalEmblem().isEmpty() && workStaffBasicInfo.getIdCardNationalEmblem().getSize() > 0)
+        ) {
             MultipartFile file = workStaffBasicInfo.getPictureFile();
             this.uploadFile(workStaffBasicInfo);
         }
@@ -1184,6 +1264,7 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
             String name = field.getName();
             if ("picture".equals(name) || "marriage".equals(name) || "politics".equals(name) || "exSoldier".equals(name) || "address".equals(name)
                     || "nativePlace".equals(name) || "household".equals(name) || "industryDate".equals(name) || "idCard".equals(name) || "age".equals(name)
+                    || "idCardPortraitName".equals(name) || "idCardPortraitPath".equals(name) || "idCardNationalEmblemName".equals(name) || "idCardNationalEmblemPath".equals(name)
                     || "birthday".equals(name) || "email".equals(name) || "nation".equals(name)) {
                 String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
                 WorkStaffAchivesLog workStaffAchivesLog = new WorkStaffAchivesLog();

+ 21 - 0
src/main/java/com/jeeplus/modules/workstaff/service/WorkStaffCertificateService.java

@@ -86,10 +86,29 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
     public void saveAll(List<WorkStaffCertificate> workStaffCertificates) {
 	    for (WorkStaffCertificate certificate:workStaffCertificates){
 	        if("1".equals(certificate.getDelFlag())){
+                certificate.preUpdate();
                 dao.deleteByLogic(certificate);
                 continue;
             }else{
                 super.save(certificate);
+
+                if(certificate!=null&&"1".equals(certificate.getDelFlag())&&StringUtils.isBlank(certificate.getId())){
+                    continue;
+                }
+                if(certificate!=null&&"1".equals(certificate.getDelFlag())){
+                    certificate.preUpdate();
+                    dao.deleteByLogic(certificate);
+                    continue;
+                }
+                if(certificate!=null){
+                    if(certificate.getFile()!=null&&!certificate.getFile().isEmpty()&&certificate.getFile().getSize()>0){
+                        MultipartFile file = certificate.getFile();
+                        certificate.setFileName(file.getOriginalFilename());
+                        certificate.setFilePath(this.uploadFile(file,certificate.getFilePath()));
+                    }
+                    super.save(certificate);
+                }
+
             }
         }
     }
@@ -113,6 +132,7 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
                 continue;
             }
             if(entity!=null&&"1".equals(entity.getDelFlag())){
+                entity.preUpdate();
                 dao.deleteByLogic(entity);
                 continue;
             }
@@ -309,6 +329,7 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
                 this.save(entity);
             }
             if(entity!=null&&"1".equals(entity.getDelFlag())){
+                entity.preUpdate();
                 dao.deleteByLogic(entity);
                 continue;
             }

+ 4 - 0
src/main/java/com/jeeplus/modules/workstaff/web/WorkStaffBasicInfoController.java

@@ -1153,6 +1153,10 @@ public class WorkStaffBasicInfoController extends BaseController {
 	@RequiresPermissions("workstaff:workStaffBasicInfo:addressbook")
 	@RequestMapping(value = "addressbook")
 	public String addressBook(WorkStaffBasicInfo workStaffBasicInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+
+		if(StringUtils.isBlank(workStaffBasicInfo.getUserLoginFlag())){
+			workStaffBasicInfo.setUserLoginFlag("1");
+		}
 		Page<WorkStaffBasicInfo> page = workStaffBasicInfoService.findAddressBook(new Page<WorkStaffBasicInfo>(request, response), workStaffBasicInfo);
 		model.addAttribute("page", page);
 		return "modules/workstaff/workAddressBookList";

+ 79 - 0
src/main/java/com/jeeplus/modules/workstaff/web/WorkStaffBasicInfoDimissionController.java

@@ -0,0 +1,79 @@
+package com.jeeplus.modules.workstaff.web;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.sys.service.RoleService;
+import com.jeeplus.modules.workstaff.entity.WorkStaffBasicInfo;
+import com.jeeplus.modules.workstaff.service.WorkStaffBasicInfoService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 离职员工基本信息Controller
+ * @author 徐滕
+ * @version 2025-07-8
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/workstaff/workStaffBasicInfoDimission")
+public class WorkStaffBasicInfoDimissionController {
+
+    @Autowired
+    private WorkStaffBasicInfoService workStaffBasicInfoService;
+    @Autowired
+    private RoleService roleService;
+
+    @ModelAttribute
+    public WorkStaffBasicInfo get(@RequestParam(required=false) String id) {
+        WorkStaffBasicInfo entity = null;
+        if (StringUtils.isNotBlank(id)){
+            entity = workStaffBasicInfoService.get(id);
+        }
+        if (entity == null){
+            entity = new WorkStaffBasicInfo();
+            entity.setId(id);
+        }
+        return entity;
+    }
+
+
+    /**
+     * 离员工信息列表页面
+     */
+    @RequiresPermissions("workstaff:workStaffBasicInfoDimission:list")
+    @RequestMapping(value = {"list", ""})
+    public String list(WorkStaffBasicInfo workStaffBasicInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+        //进行查询之后进行任何操作,返回还是查询之后的数据页面
+        if (StringUtils.isNotBlank(workStaffBasicInfo.getToflag())){
+            if (workStaffBasicInfo.getToflag().equals("1")){
+                request.getSession().removeAttribute("searchStaffBasicInfo");
+                WorkStaffBasicInfo search=workStaffBasicInfo;
+                request.getSession().setAttribute("searchStaffBasicInfo",search);
+            }
+        }else{
+            if (request.getSession().getAttribute("searchStaffBasicInfo")!=null){
+                workStaffBasicInfo= (WorkStaffBasicInfo) request.getSession().getAttribute("searchStaffBasicInfo");
+                model.addAttribute("workStaffBasicInfo", workStaffBasicInfo);
+            }
+        }
+        if(StringUtils.isBlank(workStaffBasicInfo.getStatus())){
+            workStaffBasicInfo.setStatus("离职");
+        }
+        Page<WorkStaffBasicInfo> page = workStaffBasicInfoService.findPage(new Page<WorkStaffBasicInfo>(request, response), workStaffBasicInfo);
+        List<WorkStaffBasicInfo> list = page.getList();
+        for (WorkStaffBasicInfo info:list){
+            info.setRoleId(roleService.getRoleIdByUserId(info.getUserId()));
+            info.setRoleName(roleService.getRoleNameByUserId(info.getUserId()));
+        }
+        model.addAttribute("page", page);
+        return "modules/workstaff/workStaffBasicInfoList";
+    }
+}

+ 79 - 0
src/main/java/com/jeeplus/modules/workstaff/web/WorkStaffBasicInfoEmploymentInController.java

@@ -0,0 +1,79 @@
+package com.jeeplus.modules.workstaff.web;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.sys.service.RoleService;
+import com.jeeplus.modules.workstaff.entity.WorkStaffBasicInfo;
+import com.jeeplus.modules.workstaff.service.WorkStaffBasicInfoService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 返聘员工基本信息Controller
+ * @author 徐滕
+ * @version 2025-07-8
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/workstaff/workStaffBasicInfoEmploymentIn")
+public class WorkStaffBasicInfoEmploymentInController {
+
+    @Autowired
+    private WorkStaffBasicInfoService workStaffBasicInfoService;
+    @Autowired
+    private RoleService roleService;
+
+    @ModelAttribute
+    public WorkStaffBasicInfo get(@RequestParam(required=false) String id) {
+        WorkStaffBasicInfo entity = null;
+        if (StringUtils.isNotBlank(id)){
+            entity = workStaffBasicInfoService.get(id);
+        }
+        if (entity == null){
+            entity = new WorkStaffBasicInfo();
+            entity.setId(id);
+        }
+        return entity;
+    }
+
+
+    /**
+     * 离员工信息列表页面
+     */
+    @RequiresPermissions("workstaff:workStaffBasicInfoEmploymentIn:list")
+    @RequestMapping(value = {"list", ""})
+    public String list(WorkStaffBasicInfo workStaffBasicInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+        //进行查询之后进行任何操作,返回还是查询之后的数据页面
+        if (StringUtils.isNotBlank(workStaffBasicInfo.getToflag())){
+            if (workStaffBasicInfo.getToflag().equals("1")){
+                request.getSession().removeAttribute("searchStaffBasicInfo");
+                WorkStaffBasicInfo search=workStaffBasicInfo;
+                request.getSession().setAttribute("searchStaffBasicInfo",search);
+            }
+        }else{
+            if (request.getSession().getAttribute("searchStaffBasicInfo")!=null){
+                workStaffBasicInfo= (WorkStaffBasicInfo) request.getSession().getAttribute("searchStaffBasicInfo");
+                model.addAttribute("workStaffBasicInfo", workStaffBasicInfo);
+            }
+        }
+        if(StringUtils.isBlank(workStaffBasicInfo.getStatus())){
+            workStaffBasicInfo.setStatus("返聘");
+        }
+        Page<WorkStaffBasicInfo> page = workStaffBasicInfoService.findPage(new Page<WorkStaffBasicInfo>(request, response), workStaffBasicInfo);
+        List<WorkStaffBasicInfo> list = page.getList();
+        for (WorkStaffBasicInfo info:list){
+            info.setRoleId(roleService.getRoleIdByUserId(info.getUserId()));
+            info.setRoleName(roleService.getRoleNameByUserId(info.getUserId()));
+        }
+        model.addAttribute("page", page);
+        return "modules/workstaff/workStaffBasicInfoList";
+    }
+}

+ 79 - 0
src/main/java/com/jeeplus/modules/workstaff/web/WorkStaffBasicInfoTraineeController.java

@@ -0,0 +1,79 @@
+package com.jeeplus.modules.workstaff.web;
+
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.sys.service.RoleService;
+import com.jeeplus.modules.workstaff.entity.WorkStaffBasicInfo;
+import com.jeeplus.modules.workstaff.service.WorkStaffBasicInfoService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 实习生基本信息Controller
+ * @author 徐滕
+ * @version 2025-07-8
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/workstaff/workStaffBasicInfoTrainee")
+public class WorkStaffBasicInfoTraineeController {
+
+    @Autowired
+    private WorkStaffBasicInfoService workStaffBasicInfoService;
+    @Autowired
+    private RoleService roleService;
+
+    @ModelAttribute
+    public WorkStaffBasicInfo get(@RequestParam(required=false) String id) {
+        WorkStaffBasicInfo entity = null;
+        if (StringUtils.isNotBlank(id)){
+            entity = workStaffBasicInfoService.get(id);
+        }
+        if (entity == null){
+            entity = new WorkStaffBasicInfo();
+            entity.setId(id);
+        }
+        return entity;
+    }
+
+
+    /**
+     * 离员工信息列表页面
+     */
+    @RequiresPermissions("workstaff:workStaffBasicInfoTrainee:list")
+    @RequestMapping(value = {"list", ""})
+    public String list(WorkStaffBasicInfo workStaffBasicInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+        //进行查询之后进行任何操作,返回还是查询之后的数据页面
+        if (StringUtils.isNotBlank(workStaffBasicInfo.getToflag())){
+            if (workStaffBasicInfo.getToflag().equals("1")){
+                request.getSession().removeAttribute("searchStaffBasicInfo");
+                WorkStaffBasicInfo search=workStaffBasicInfo;
+                request.getSession().setAttribute("searchStaffBasicInfo",search);
+            }
+        }else{
+            if (request.getSession().getAttribute("searchStaffBasicInfo")!=null){
+                workStaffBasicInfo= (WorkStaffBasicInfo) request.getSession().getAttribute("searchStaffBasicInfo");
+                model.addAttribute("workStaffBasicInfo", workStaffBasicInfo);
+            }
+        }
+        if(StringUtils.isBlank(workStaffBasicInfo.getStatus())){
+            workStaffBasicInfo.setStatus("实习");
+        }
+        Page<WorkStaffBasicInfo> page = workStaffBasicInfoService.findPage(new Page<WorkStaffBasicInfo>(request, response), workStaffBasicInfo);
+        List<WorkStaffBasicInfo> list = page.getList();
+        for (WorkStaffBasicInfo info:list){
+            info.setRoleId(roleService.getRoleIdByUserId(info.getUserId()));
+            info.setRoleName(roleService.getRoleNameByUserId(info.getUserId()));
+        }
+        model.addAttribute("page", page);
+        return "modules/workstaff/workStaffBasicInfoList";
+    }
+}

+ 15 - 0
src/main/resources/mappings/modules/workreimbursement/WorkReimbursementDao.xml

@@ -168,6 +168,14 @@
 			<if test="endReimbursementPrice != '' and endReimbursementPrice != null">
 				AND a.money &lt;= #{endReimbursementPrice}
 			</if>
+
+			<if test="invoiceNumber != null and invoiceNumber != ''">
+				AND EXISTS (
+				SELECT 1 FROM reimbursement_vat_tax rvt
+				WHERE rvt.work_reimbursement_id = a.id
+				AND rvt.invoice_number like concat('%',#{invoiceNumber},'%')
+				)
+			</if>
 			<if test="sqlMap.dsf !=null and sqlMap.dsf!=''">
 				and (${sqlMap.dsf}
 				or wa.reimbursement_name = #{createBy.id})
@@ -264,6 +272,13 @@
 			<if test="endReimbursementPrice != '' and endReimbursementPrice != null">
 				AND a.money &lt;= #{endReimbursementPrice}
 			</if>
+			<if test="invoiceNumber != null and invoiceNumber != ''">
+				AND EXISTS (
+				SELECT 1 FROM reimbursement_vat_tax rvt
+				WHERE rvt.work_reimbursement_id = a.id
+				AND rvt.invoice_number like concat('%',#{invoiceNumber},'%')
+				)
+			</if>
 			<if test="sqlMap.dsf !=null and sqlMap.dsf!=''">
 				and (${sqlMap.dsf}
 				or wa.reimbursement_name = #{createBy.id})

+ 20 - 4
src/main/resources/mappings/modules/workstaff/WorkStaffAchivesDao.xml

@@ -60,7 +60,11 @@
 		a.try_out_job AS "tryOutJob",
 		a.trial_period AS "trialPeriod",
 		a.individual_resume AS "individualResume",
-		a.act_comment AS "act.comment"
+		a.act_comment AS "act.comment",
+		a.id_card_portrait_name As "idCardPortraitName",
+		a.id_card_portrait_path As "idCardPortraitPath",
+		a.id_card_national_emblem_name As "idCardNationalEmblemName",
+		a.id_card_national_emblem_path As "idCardNationalEmblemPath"
 	</sql>
 	
 	<sql id="workStaffBasicInfoJoins">
@@ -393,7 +397,11 @@
 			qq_id,
 			try_out_job,
 			trial_period,
-			individual_resume
+			individual_resume,
+			id_card_portrait_name,
+			id_card_portrait_path,
+			id_card_national_emblem_name,
+			id_card_national_emblem_path
 		) VALUES (
 			#{id},
 			#{createBy.id},
@@ -444,7 +452,11 @@
 			#{qqId},
 			#{tryOutJob},
 			#{trialPeriod},
-			#{individualResume}
+			#{individualResume},
+			#{idCardPortraitName},
+			#{idCardPortraitPath},
+			#{idCardNationalEmblemName},
+			#{idCardNationalEmblemPath}
 		)
 	</insert>
 	
@@ -495,7 +507,11 @@
 			qq_id = #{qqId},
 			try_out_job = #{tryOutJob},
 			trial_period = #{trialPeriod},
-			individual_resume = #{individualResume}
+			individual_resume = #{individualResume},
+			id_card_portrait_name = #{idCardPortraitName},
+			id_card_portrait_path = #{idCardPortraitPath},
+			id_card_national_emblem_name = #{idCardNationalEmblemName},
+			id_card_national_emblem_path = #{idCardNationalEmblemPath}
 		WHERE id = #{id}
 	</update>
 	

+ 51 - 9
src/main/resources/mappings/modules/workstaff/WorkStaffBasicInfoDao.xml

@@ -63,7 +63,11 @@
 		a.hand_signature As "handSignature",
 		a.other_service_flag As "otherServiceFlag",
 		a.dd_id As "ddId",
-		a.dd_type As "ddType"
+		a.dd_type As "ddType",
+		a.id_card_portrait_name As "idCardPortraitName",
+		a.id_card_portrait_path As "idCardPortraitPath",
+		a.id_card_national_emblem_name As "idCardNationalEmblemName",
+		a.id_card_national_emblem_path As "idCardNationalEmblemPath"
 <!--		ur.role_id AS "roleId",-->
 <!--		r.name AS "roleName"-->
 	</sql>
@@ -281,14 +285,19 @@
 		<include refid="workStaffBasicInfoColumns"/>
 		FROM work_staff_basic_info a
 		<include refid="workStaffBasicInfoJoins"/>
+		LEFT JOIN sys_user suc ON suc.id = a.user_id
 		<where>
 			a.del_flag = #{DEL_FLAG_NORMAL}
+
+			<if test="userLoginFlag != null and userLoginFlag != ''">
+				AND suc.login_flag = #{userLoginFlag}
+			</if>
 			<if test="company != null and company.id != null and company.id != ''">
 				AND a.company_id = #{company.id}
 			</if>
-			<if test="office != null and office.id != null and office.id != ''">
+			<!--<if test="office != null and office.id != null and office.id != ''">
 				AND a.office_id = #{office.id}
-			</if>
+			</if>-->
 			<if test="no != null and no != ''">
 				AND a.no = #{no}
 			</if>
@@ -302,14 +311,35 @@
 				AND a.id_card = #{idCard}
 			</if>
 			<if test="mobile != null and mobile != ''">
-				AND a.mobile = #{mobile}
+				AND a.mobile like concat('%', #{mobile}, '%')
 			</if>
 			<if test="jobGrade != null and jobGrade.id !=null and jobGrade.id != ''">
 				AND a.job_grade = #{jobGrade.id}
 			</if>
-			<if test="status != null and status != ''">
-				AND a.status = #{status}
+
+			<choose>
+				<when test="status != null and status != ''">
+					AND a.status = #{status}
+				</when>
+				<otherwise>
+					AND a.status in ('正式', '返聘')
+				</otherwise>
+			</choose>
+
+			<if test="notOfficeParentIdList!=null and notOfficeParentIdList.size!=0">
+				and a.office_id not in
+				<foreach collection="notOfficeParentIdList" item="officeId" separator="," open="(" close=")">
+					#{officeId}
+				</foreach>
 			</if>
+			<if test="officeIdList!=null and officeIdList.size!=0">
+				and a.office_id in
+				<foreach collection="officeIdList" item="officeId" separator="," open="(" close=")">
+					#{officeId}
+				</foreach>
+			</if>
+
+
 			<if test="beginEntryDate != null">
 				AND a.entry_date >= #{beginEntryDate}
 			</if>
@@ -405,7 +435,11 @@
 			hand_signature,
 			other_service_flag,
 		    dd_id,
-		    dd_type
+		    dd_type,
+			id_card_portrait_name,
+			id_card_portrait_path,
+			id_card_national_emblem_name,
+			id_card_national_emblem_path
 		) VALUES (
 			#{id},
 			#{createBy.id},
@@ -459,7 +493,11 @@
 			#{handSignature},
 			#{otherServiceFlag},
 			#{ddId},
-			#{ddType}
+			#{ddType},
+			#{idCardPortraitName},
+			#{idCardPortraitPath},
+			#{idCardNationalEmblemName},
+			#{idCardNationalEmblemPath}
 		)
 	</insert>
 
@@ -511,7 +549,11 @@
 			individual_resume = #{individualResume},
 			highest_education = #{highestEducation},
 			hand_signature = #{handSignature},
-			other_service_flag = #{otherServiceFlag}
+			other_service_flag = #{otherServiceFlag},
+			id_card_portrait_name = #{idCardPortraitName},
+			id_card_portrait_path = #{idCardPortraitPath},
+			id_card_national_emblem_name = #{idCardNationalEmblemName},
+			id_card_national_emblem_path = #{idCardNationalEmblemPath}
 		WHERE id = #{id}
 	</update>
 

+ 3 - 1
src/main/resources/mappings/modules/workstaff/WorkStaffCertificateDao.xml

@@ -158,7 +158,9 @@
 	
 	<!--逻辑删除-->
 	<update id="deleteByLogic">
-		UPDATE work_staff_certificate SET 
+		UPDATE work_staff_certificate SET
+			update_by = #{updateBy.id},
+			update_date = #{updateDate},
 			del_flag = #{DEL_FLAG_DELETE}
 		WHERE id = #{id}
 	</update>

+ 55 - 1
src/main/webapp/webpage/modules/sys/userInfo.jsp

@@ -4,6 +4,11 @@
 <head>
     <title>个人信息</title>
     <meta name="decorator" content="default"/>
+    <script type="text/javascript" src="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+    <script src="${ctxStatic}/layer-v2.3/layui/xmSelect.js" charset="utf-8"></script>
     <script type="text/javascript">
         $(document).ready(function () {
             if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {//如果是移动端,就使用自适应大小弹窗
@@ -297,6 +302,21 @@
                 }
             });
         }
+
+
+        function openLayerPreview(imgUrl) {
+            layui.use('layer', function(){
+                var layer = layui.layer;
+                layer.open({
+                    type: 1,
+                    title: '图片预览',
+                    shadeClose: true,
+                    shade: 0.2,
+                    area: ['600px', '400px'],
+                    content: '<img src="'+imgUrl+'" style="width:100%;height:100%;">'
+                });
+            });
+        }
     </script>
     <style>
         ul.dropdown-menu.dropdown-user li a {
@@ -725,6 +745,40 @@
                                                    value="<fmt:formatDate value="${workStaffBasicInfo.dimissionDate}" pattern="yyyy-MM-dd"/>"/>
                                         </div>
                                     </div>
+                                    <div class="layui-item layui-col-sm6 lw7">
+                                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证人像面:</label>
+                                        <div class="layui-input-block">
+                                            <!-- 图片展示区域 -->
+                                            <span id="idCardPortraitName1">
+                                              <c:if test="${not empty workStaffBasicInfo.idCardPortraitPathStr}">
+                                                <div style="position:relative; display:inline-block;">
+                                                  <img src="${workStaffBasicInfo.idCardPortraitPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardPortraitPathStr}')" alt="身份证照片">
+                                                </div>
+                                                  <!-- 下载按钮(重点)-->
+                                                  <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardPortraitName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardPortraitPath}', '${workStaffBasicInfo.idCardPortraitName}')"><i class="fa fa-download"></i></a>
+                                              </c:if>
+                                            </span>
+                                        </div>
+                                    </div>
+
+
+                                    <div class="layui-item layui-col-sm6 lw7">
+                                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证国徽面:</label>
+                                        <div class="layui-input-block">
+                                            <!-- 图片展示区域 -->
+                                            <span id="idCardNationalEmblemName1">
+                                              <c:if test="${not empty workStaffBasicInfo.idCardNationalEmblemPathStr}">
+                                                <div style="position:relative; display:inline-block;">
+                                                  <img src="${workStaffBasicInfo.idCardNationalEmblemPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardNationalEmblemPathStr}')" alt="身份证照片">
+                                                </div>
+                                                  <!-- 下载按钮 -->
+                                                  <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardNationalEmblemName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardNationalEmblemPath}', '${workStaffBasicInfo.idCardNationalEmblemName}')"><i class="fa fa-download"></i></a>
+
+                                              </c:if>
+                                            </span>
+                                        </div>
+                                    </div>
+
                                     <%--<div class="layui-item layui-col-sm6 lw7">
                                         <label class="layui-form-label double-line">考勤截止日期:</label>
                                         <div class="layui-input-block">
@@ -1047,7 +1101,7 @@
                                     </div>
                                 </div>
                                 <div class="form-group layui-row">
-                                    <div class="form-group-label"><h2>职称</h2></div>
+                                    <div class="form-group-label"><h2>职称证书</h2></div>
                                     <div class="layui-item layui-col-xs12 form-table-container">
                                         <table id="titleTable" class="table table-bordered table-condensed details">
                                             <thead>

+ 6 - 6
src/main/webapp/webpage/modules/workreimbursement/new/workReimbursementNewAudit.jsp

@@ -16,15 +16,15 @@
                 $("#opinion").val(ss);
                 if (obj == 1) {
                     $('#flag').val('yes');
+                    if(${ isChangeStatus == '1' }){
+                        if (!arraysEqual()) {
+                            parent.layer.msg("数电发票未全部确认,请检查确认后再次提交!", {icon: 5});
+                            return false
+                        }
+                    }
                 } else {
                     $('#flag').val('no');
                 }
-                if(${ isChangeStatus == '1' }){
-                    if (!arraysEqual()) {
-                        parent.layer.msg("数电发票未全部确认,请检查确认后再次提交!", {icon: 5});
-                        return false
-                    }
-                }
                 $("#inputForm").submit();
                 return true;
             } else {

+ 7 - 0
src/main/webapp/webpage/modules/workreimbursement/workReimbursementAllList.jsp

@@ -177,6 +177,13 @@
                                 </form:select>
                             </div>
                         </div>
+                        <div class="layui-item query athird">
+                            <label class="layui-form-label">数电发票号:</label>
+                            <div class="layui-input-block with-icon">
+                                <input id="invoiceNumber" placeholder="请输入数电发票号" name="invoiceNumber" type="text" maxlength="20" class="form-control layui-input" value="${workReimbursement.invoiceNumber}"/>
+                                </input>
+                            </div>
+                        </div>
                         <div style="clear:both;"></div>
                     </div>
                 </form:form>

+ 7 - 0
src/main/webapp/webpage/modules/workreimbursement/workReimbursementList.jsp

@@ -221,6 +221,13 @@
                                 </input>
                             </div>
                         </div>
+                        <div class="layui-item query athird">
+                            <label class="layui-form-label">数电发票号:</label>
+                            <div class="layui-input-block with-icon">
+                                <input id="invoiceNumber" placeholder="请输入数电发票号" name="invoiceNumber" type="text" maxlength="20" class="form-control layui-input" value="${workReimbursement.invoiceNumber}"/>
+                                </input>
+                            </div>
+                        </div>
                         <div style="clear:both;"></div>
                     </div>
                 </form:form>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 7 - 7
src/main/webapp/webpage/modules/workstaff/qualificationForm.jsp


+ 21 - 16
src/main/webapp/webpage/modules/workstaff/workAddressBookList.jsp

@@ -107,25 +107,27 @@
                         <label class="layui-form-label">部门:</label>
                         <div class="layui-input-block with-icon">
                             <sys:treeselect id="office" name="office.id" value="${workStaffBasicInfo.office.id}" labelName="office.name" labelValue="${workStaffBasicInfo.office.name}"
-                                            title="部门" url="/sys/office/treeData?type=2" cssClass="form-control layui-input required" notAllowSelectParent="true" isAll="true"/>
+                                            title="部门" url="/sys/office/treeDataAll?type=7" cssClass="form-control layui-input required" notAllowSelectParent="false" allowInput="true"/>
                         </div>
                     </div>
                     <div class="layui-item athird fr">
                         <div class="input-group">
                             <a href="#" id="moresee"><i class="glyphicon glyphicon-menu-down"></i></a>
-                            <button id="searchReset" class="fixed-btn searchReset fr" onclick="resetSearch()">重置</button>
-                            <button id="searchQuery" class="fixed-btn searchQuery fr" onclick="search()">查询</button>
+                            <div class="layui-btn-group search-spacing">
+                                <button id="searchQuery" class="layui-btn layui-btn-sm layui-bg-blue" onclick="search()">查询</button>
+                                <button id="searchReset" class="layui-btn layui-btn-sm " onclick="resetSearch()">重置</button>
+                            </div>
                         </div>
                     </div>
                     <div style="    clear:both;"></div>
                 </div>
                 <div id="moresees" style="clear:both;display:none;">
-                    <div class="layui-item query athird">
+                    <%--<div class="layui-item query athird">
                         <label class="layui-form-label">工    号:</label>
                         <div class="layui-input-block">
                             <form:input path="no" htmlEscape="false" maxlength="10"  class=" form-control layui-input"/>
                         </div>
-                    </div>
+                    </div>--%>
                     <div class="layui-item query athird">
                         <label class="layui-form-label">移动电话:</label>
                         <div class="layui-input-block">
@@ -139,14 +141,14 @@
                                             <%--title="部门" url="/sys/office/treeData?type=2" cssClass="form-control layui-input required" notAllowSelectParent="true"/>--%>
                         <%--</div>--%>
                     <%--</div>--%>
-                    <div class="layui-item query athird">
+                    <%--<div class="layui-item query athird">
                         <label class="layui-form-label">职级:</label>
                         <div class="layui-input-block with-icon">
                             <sys:treeselectJobGrade id="jobGrade" name="jobGrade.id" value="${workStaffBasicInfo.jobGrade.id}" labelName="jobGrade.name" labelValue="${workStaffBasicInfo.jobGrade.name}"
                                                     title="职级类型" url="/workjobgrade/workJobGrade/treeData"  cssClass="form-control layui-input" allowClear="true" notAllowSelectParent="true"/>
                         </div>
-                    </div>
-                    <div class="layui-item query athird">
+                    </div>--%>
+                    <%--<div class="layui-item query athird">
                         <label class="layui-form-label">员工状态:</label>
                         <div class="layui-input-block">
                             <form:select path="status" class="form-control simple-select required">
@@ -154,7 +156,7 @@
                                 <form:options items="${fns:getDictList('staff_status')}" itemLabel="label" itemValue="label" htmlEscape="false"/>
                             </form:select>
                         </div>
-                    </div>
+                    </div>--%>
                     <%--<div class="layui-item query athird">--%>
                         <%--<label class="layui-form-label">入职日期:</label>--%>
                         <%--<div class="layui-input-block">--%>
@@ -182,7 +184,7 @@
                     <%--<shiro:hasPermission name="workstaff:workStaffBasicInfo:add">--%>
                         <%--<table:addRow url="${ctx}/workstaff/workStaffBasicInfo/form" title="员工信息"></table:addRow><!-- 增加按钮 -->--%>
                     <%--</shiro:hasPermission>--%>
-                    <button class="nav-btn nav-btn-refresh" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"><i class="glyphicon glyphicon-repeat"></i>&nbsp;刷新</button>
+                    <button class="layui-btn layui-btn-sm" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"> 刷新</button>
                     <div style="clear: both;"></div>
                 </div>
                 <table class="oa-table layui-table" id="contentTable"></table>
@@ -204,21 +206,23 @@
             ,page: false
             ,cols: [[
                 {field:'index',align:'center', title: '序号',width:40}
-                ,{field:'no',align:'center', title: '工号',minWidth:100,templet:function(d){
+                /*,{field:'no',align:'center', title: '工号',minWidth:100,templet:function(d){
                         var xml = "<a class=\"attention-info\" href=\"javascript:void(0);\" onclick=\"openDialogView('查看员工信息', '${ctx}/workstaff/workStaffBasicInfo/addressbookview?id="+d.id+"','95%','95%')\">" +
                             "<span title=" + d.no + ">" + d.no + "</span></a>";
                         return xml;
-                    }}
-                ,{field:'name',align:'center', title: '姓名',minWidth:100,templet:function(d){
+                    }}*/
+                /*,{field:'name',align:'center', title: '姓名',minWidth:100,templet:function(d){
                     var xml = "<a class=\"attention-info\" href=\"javascript:void(0);\" onclick=\"openDialogView('查看员工信息', '${ctx}/workstaff/workStaffBasicInfo/addressbookview?id="+d.id+"','95%','95%')\">" +
                         "<span title=" + d.name + ">" + d.name + "</span></a>";
                     return xml;
-                }}
+                }}*/
+                ,{field:'name',align:'center', title: '姓名',minWidth:150}
                 // ,{field:'idCard',align:'center', title: '身份证号码',minWidth:150}
-                ,{field:'mobile',align:'center', title: '移动电话', minWidth:100}
                 ,{field:'office',align:'center', title: '部门', minWidth:100}
+                ,{field:'mobile',align:'center', title: '移动电话', minWidth:100}
+                ,{field:'phone',align:'center', title: '座机',minWidth:150}
                 // ,{field:'role',align:'center', title: '岗位', minWidth:100}
-                ,{field:'jobGrade',align:'center', title: '职级', minWidth:100}
+                //,{field:'jobGrade',align:'center', title: '职级', minWidth:100}
                 ,{field:'status',align:'center', title: '员工状态', minWidth:80}
                 // ,{field:'entryDate', align:'center',sort:true,title: '入职日期',width:100}
                 <%--,{field:'op',align:'center',title:"操作",width:130,templet:function(d){--%>
@@ -245,6 +249,7 @@
                     ,"name":"<c:out value="${workStaffBasicInfo.name}" escapeXml="false"/>"
                     <%--,"idCard":"<c:out value="${workStaffBasicInfo.idCard}" escapeXml="true"/>"--%>
                     ,'mobile':"<c:out value="${workStaffBasicInfo.mobile}" escapeXml="true"/>"
+                    ,'phone':"<c:out value="${workStaffBasicInfo.phone}" escapeXml="true"/>"
                     ,'office':"<c:out value="${workStaffBasicInfo.office.name}" escapeXml="true"/>"
                     ,'jobGrade':"<c:out value="${workStaffBasicInfo.jobGrade.name}" escapeXml="true"/>"
                     ,'status':"<c:out value="${workStaffBasicInfo.status}" escapeXml="true"/>"

+ 1 - 1
src/main/webapp/webpage/modules/workstaff/workAddressBookView.jsp

@@ -514,7 +514,7 @@
                     <%--</div>--%>
                 <%--</div>--%>
                 <%--<div class="form-group layui-row">--%>
-                    <%--<div class="form-group-label"><h2>职称</h2></div>--%>
+                    <%--<div class="form-group-label"><h2>职称证书</h2></div>--%>
                     <%--<div class="layui-item layui-col-xs12 form-table-container">--%>
                         <%--<table id="titleTable" class="table table-bordered table-condensed details">--%>
                             <%--<thead>--%>

+ 1 - 1
src/main/webapp/webpage/modules/workstaff/workStaffAchiveInfoForm.jsp

@@ -1035,7 +1035,7 @@
                 </div>
             </div>
             <div class="form-group layui-row">
-                <div class="form-group-label"><h2>职称</h2></div>
+                <div class="form-group-label"><h2>职称证书</h2></div>
                 <div class="layui-item nav-btns">
                     <a href=javascript:void(0); onclick="addRowTitle('#titleList',titleIdx,titleTpl)" class="nav-btn nav-btn-add" ><i class="fa fa-plus"></i> 新增</a>
                 </div>

+ 1 - 1
src/main/webapp/webpage/modules/workstaff/workStaffAchiveInfoForms.jsp

@@ -1035,7 +1035,7 @@
                 </div>
             </div>
             <div class="form-group layui-row">
-                <div class="form-group-label"><h2>职称</h2></div>
+                <div class="form-group-label"><h2>职称证书</h2></div>
                 <div class="layui-item nav-btns">
                     <a href=javascript:void(0); onclick="addRowTitle('#titleList',titleIdx,titleTpl)" class="nav-btn nav-btn-add" ><i class="fa fa-plus"></i> 新增</a>
                 </div>

+ 62 - 1
src/main/webapp/webpage/modules/workstaff/workStaffBasicDetailAudit.jsp

@@ -5,6 +5,11 @@
 <head>
 	<title>员工信息管理</title>
 	<meta name="decorator" content="default"/>
+    <script type="text/javascript" src="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+    <script src="${ctxStatic}/layer-v2.3/layui/xmSelect.js" charset="utf-8"></script>
 	<script type="text/javascript">
         var validateForm;
         function doSubmit(obj){//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
@@ -357,6 +362,20 @@
             // window.parent.document.getElementById('opinion').value = row;
             $("#opinion").val(row)
         }
+
+        function openLayerPreview(imgUrl) {
+            layui.use('layer', function(){
+                var layer = layui.layer;
+                layer.open({
+                    type: 1,
+                    title: '图片预览',
+                    shadeClose: true,
+                    shade: 0.2,
+                    area: ['600px', '400px'],
+                    content: '<img src="'+imgUrl+'" style="width:100%;height:100%;">'
+                });
+            });
+        }
     </script>
 </head>
 <body>
@@ -527,6 +546,48 @@
                                 <input name="roleName" value="${workStaffBasicInfo.roleName}" type="text" readonly="true" class="form-control  layui-input" />
                             </div>
                         </div>
+
+                    <div class="layui-item layui-col-sm6 lw7">
+                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证人像面:</label>
+                        <div class="layui-input-block">
+                            <!-- 图片展示区域 -->
+                            <span id="idCardPortraitName1">
+                              <c:if test="${not empty workStaffBasicInfo.idCardPortraitPathStr}">
+                                <div style="position:relative; display:inline-block;">
+                                  <img src="${workStaffBasicInfo.idCardPortraitPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardPortraitPathStr}')" alt="身份证照片">
+                                </div>
+                                  <!-- 下载按钮(重点)-->
+                                  <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardPortraitName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardPortraitPath}', '${workStaffBasicInfo.idCardPortraitName}')"><i class="fa fa-download"></i></a>
+                              </c:if>
+                            </span>
+
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardPortraitName" name="idCardPortraitName" value="${workStaffBasicInfo.idCardPortraitName}">
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardPortraitPath" name="idCardPortraitPath" value="${workStaffBasicInfo.idCardPortraitPath}">
+                        </div>
+                    </div>
+
+
+                    <div class="layui-item layui-col-sm6 lw7">
+                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证国徽面:</label>
+                        <div class="layui-input-block">
+                            <!-- 图片展示区域 -->
+                            <span id="idCardNationalEmblemName1">
+                              <c:if test="${not empty workStaffBasicInfo.idCardNationalEmblemPathStr}">
+                                <div style="position:relative; display:inline-block;">
+                                  <img src="${workStaffBasicInfo.idCardNationalEmblemPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardNationalEmblemPathStr}')" alt="身份证照片">
+                                </div>
+                                  <!-- 下载按钮 -->
+                                  <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardNationalEmblemName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardNationalEmblemPath}', '${workStaffBasicInfo.idCardNationalEmblemName}')"><i class="fa fa-download"></i></a>
+
+                              </c:if>
+                            </span>
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardNationalEmblemName" name="idCardNationalEmblemName" value="${workStaffBasicInfo.idCardNationalEmblemName}">
+                            <input type="hidden" id="idCardNationalEmblemPath" name="idCardNationalEmblemPath" value="${workStaffBasicInfo.idCardNationalEmblemPath}">
+                        </div>
+                    </div>
                     <%--<div class="layui-item layui-col-sm6 lw7">
                         <label class="layui-form-label">职    位:</label>
                         <div class="layui-input-block">
@@ -843,7 +904,7 @@
                     </div>
                 </div>
                 <div class="form-group layui-row">
-                    <div class="form-group-label"><h2>职称</h2></div>
+                    <div class="form-group-label"><h2>职称证书</h2></div>
                     <div class="layui-item layui-col-xs12 form-table-container">
                         <table id="titleTable" class="table table-bordered table-condensed can-edit">
                             <thead>

+ 145 - 2
src/main/webapp/webpage/modules/workstaff/workStaffBasicDetailForm.jsp

@@ -5,6 +5,23 @@
 <head>
 	<title>员工信息管理</title>
 	<meta name="decorator" content="default"/>
+    <script type="text/javascript" src="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+    <script src="${ctxStatic}/layer-v2.3/layui/xmSelect.js" charset="utf-8"></script>
+    <style>
+        label.error{
+            left:0;
+            top:40px;
+        }
+        .delete-icon {
+            font-size: 16px;
+            background: white;
+            border-radius: 50%;
+            line-height: 1;
+        }
+    </style>
 	<script type="text/javascript">
 		var validateForm;
 		var existStaff = false;
@@ -208,6 +225,84 @@
             var imgStr = '<img src="'+url+'" width="24" height="24" onclick="openDialogView(\'预览\',\'${ctx}/sys/picturepreview/picturePreview?url='+url+'\',\'90%\',\'90%\')" alt="'+file.name+'">';
             $('#'+spanId).html(imgStr);
         }
+        function changeIdCardFileName(obj, index) {
+            var file = obj.files[0];
+            if (!file) return;
+
+            var url = URL.createObjectURL(file);
+
+            var fileType = file.type;
+            if(file.size > 1000*1024 || !(fileType.indexOf("png")>=0 || fileType.indexOf("bmp")>=0 || fileType.indexOf("jpg")>=0 || fileType.indexOf("jpeg")>=0)){
+                layer.msg("请上传1000KB内图片!", {icon: 2});
+                return;
+            }
+
+            var spanId = $(obj).attr("id") + 'Name' + index;
+
+            // 读取 base64 用于下载
+            var reader = new FileReader();
+            reader.onload = function(e) {
+                var base64Data = e.target.result;
+
+                var imgStr = '<div style="position:relative; display:inline-block;">' +
+                    '<img src="'+url+'" width="50" height="50" style="cursor:pointer;" ' +
+                    'onclick="openLayerPreview(\'' + url + '\')" alt="'+file.name+'">' +
+
+                    // 删除按钮
+                    '<i class="fa fa-times-circle" style="position:absolute; top:-8px; right:-8px; color:red; cursor:pointer;" ' +
+                    'onclick="deleteImage(\'' + spanId + '\', \'' + obj.id + '\')"></i>' +
+                    '</div>' +
+
+                    // 下载按钮,使用 base64 下载
+                    '<a href="'+base64Data+'" download="'+file.name+'" title="下载 '+file.name+'" ' +
+                    'style="color: #28a745; margin-left: 5px; text-decoration: none;">' +
+                    '<i class="fa fa-download"></i></a>';
+
+                $('#' + spanId).html(imgStr);
+            };
+
+            reader.readAsDataURL(file); // 开始读取文件(转为 base64)
+        }
+
+        function openLayerPreview(imgUrl) {
+            layui.use('layer', function(){
+                var layer = layui.layer;
+                layer.open({
+                    type: 1,
+                    title: '图片预览',
+                    shadeClose: true,
+                    shade: 0.2,
+                    area: ['600px', '400px'],
+                    content: '<img src="'+imgUrl+'" style="width:100%;height:100%;">'
+                });
+            });
+        }
+
+        function deleteImage(spanId, inputId) {
+            // 1. 清空图片展示区域
+            $('#' + spanId).html('');
+
+            // 2. 清除上传的文件 input 值
+            $('#' + inputId).val('');
+            document.getElementById(inputId).value = ''; // 双保险
+            console.log($('#' + inputId + 'Path').val())
+            // 3. 清除隐藏的路径字段(用于提交给后台)
+            $('#' + inputId + 'Path').val('');
+            console.log($('#' + inputId + 'Path').val())
+        }
+
+
+        // 下载函数,利用a标签模拟点击下载blob图片
+        function downloadFile(blobUrl, fileName) {
+            var a = document.createElement('a');
+            a.href = blobUrl;
+            a.download = fileName || 'download.png';
+            document.body.appendChild(a);
+            a.click();
+            document.body.removeChild(a);
+        }
+
+
     </script>
 </head>
 <body>
@@ -385,7 +480,55 @@
                             <form:input path="roleName" htmlEscape="false" readonly="true" class="form-control layui-input"/>
                         </div>
                     </div>
-                   <%-- <div class="layui-item layui-col-sm6 lw7">
+                    <div class="layui-item layui-col-sm6 lw7">
+                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证人像面:</label>
+                        <div class="layui-input-block">
+                            <a class="op-btn op-btn-add" title="上传" onclick="this_upload_file_button('idCardPortrait')"><i class="fa fa-plus"></i>&nbsp;上传</a>
+                            <!-- 图片展示区域 -->
+                            <span id="idCardPortraitName1">
+                          <c:if test="${not empty workStaffBasicInfo.idCardPortraitPathStr}">
+                            <div style="position:relative; display:inline-block;">
+                              <img src="${workStaffBasicInfo.idCardPortraitPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardPortraitPathStr}')" alt="身份证照片">
+                                <!-- 删除按钮 -->
+                              <i class="fa fa-times-circle" style="position:absolute; top:-8px; right:-8px; color:red; cursor:pointer;" onclick="deleteImage('idCardPortraitName1', 'idCardPortrait')"></i>
+                            </div>
+                              <!-- 下载按钮(重点)-->
+                              <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardPortraitName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardPortraitPath}', '${workStaffBasicInfo.idCardPortraitName}')"><i class="fa fa-download"></i></a>
+                          </c:if>
+                        </span>
+                            <!-- 文件上传控件 -->
+                            <input id="idCardPortrait" name="idCardPortrait" style="display:none" type="file" onchange="changeIdCardFileName(this,1)" />
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardPortraitPath" name="idCardPortraitPath" value="${workStaffBasicInfo.idCardPortraitPath}">
+                        </div>
+                    </div>
+
+                    <div class="layui-item layui-col-sm6 lw7">
+                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证国徽面:</label>
+                        <div class="layui-input-block">
+                            <a class="op-btn op-btn-add" title="上传" onclick="this_upload_file_button('idCardNationalEmblem')"><i class="fa fa-plus"></i>&nbsp;上传</a>
+                            <!-- 图片展示区域 -->
+                            <span id="idCardNationalEmblemName1">
+                          <c:if test="${not empty workStaffBasicInfo.idCardNationalEmblemPathStr}">
+                            <div style="position:relative; display:inline-block;">
+                              <img src="${workStaffBasicInfo.idCardNationalEmblemPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardNationalEmblemPathStr}')" alt="身份证照片">
+                                <!-- 删除按钮 -->
+                              <i class="fa fa-times-circle" style="position:absolute; top:-8px; right:-8px; color:red; cursor:pointer;" onclick="deleteImage('idCardNationalEmblemName1', 'idCardNationalEmblem')"></i>
+                            </div>
+                              <!-- 下载按钮 -->
+                              <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardNationalEmblemName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardNationalEmblemPath}', '${workStaffBasicInfo.idCardNationalEmblemName}')"><i class="fa fa-download"></i></a>
+
+                          </c:if>
+                        </span>
+                            <!-- 文件上传控件 -->
+                            <input id="idCardNationalEmblem" name="idCardNationalEmblem" style="display:none" type="file" onchange="changeIdCardFileName(this,1)" />
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardNationalEmblemPath" name="idCardNationalEmblemPath" value="${workStaffBasicInfo.idCardNationalEmblemPath}">
+                        </div>
+                    </div>
+
+
+                <%-- <div class="layui-item layui-col-sm6 lw7">
                         <label class="layui-form-label"><span class="require-item">*</span>入职日期:</label>
                         <div class="layui-input-block">
                             <input name="entryDate" value="<fmt:formatDate value="${workStaffBasicInfo.entryDate}" pattern="yyyy-MM-dd"/>" type="text" readonly="true" class="form-control  layui-input" />
@@ -1080,7 +1223,7 @@
                     </div>
                 </div>
                 <div class="form-group layui-row">
-                    <div class="form-group-label"><h2>职称</h2></div>
+                    <div class="form-group-label"><h2>职称证书</h2></div>
                     <div class="layui-item nav-btns">
                         <a href=javascript:void(0); onclick="addRowTitle('#titleList',titleIdx,titleTpl)" class="nav-btn nav-btn-add" ><i class="fa fa-plus"></i> 新增</a>
                     </div>

+ 139 - 1
src/main/webapp/webpage/modules/workstaff/workStaffBasicDetailModify.jsp

@@ -7,6 +7,18 @@
 	<meta name="decorator" content="default"/>
     <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
     <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+    <style>
+        label.error{
+            left:0;
+            top:40px;
+        }
+        .delete-icon {
+            font-size: 16px;
+            background: white;
+            border-radius: 50%;
+            line-height: 1;
+        }
+    </style>
 	<script type="text/javascript">
 		var validateForm;
 		var existStaff = false;
@@ -213,6 +225,85 @@
             var imgStr = '<img src="'+url+'" width="24" height="24" onclick="openDialogView(\'预览\',\'${ctx}/sys/picturepreview/picturePreview?url='+url+'\',\'90%\',\'90%\')" alt="'+file.name+'">';
             $('#'+spanId).html(imgStr);
         }
+
+        function changeIdCardFileName(obj, index) {
+            var file = obj.files[0];
+            if (!file) return;
+
+            var url = URL.createObjectURL(file);
+
+            var fileType = file.type;
+            if(file.size > 1000*1024 || !(fileType.indexOf("png")>=0 || fileType.indexOf("bmp")>=0 || fileType.indexOf("jpg")>=0 || fileType.indexOf("jpeg")>=0)){
+                layer.msg("请上传1000KB内图片!", {icon: 2});
+                return;
+            }
+
+            var spanId = $(obj).attr("id") + 'Name' + index;
+
+            // 读取 base64 用于下载
+            var reader = new FileReader();
+            reader.onload = function(e) {
+                var base64Data = e.target.result;
+
+                var imgStr = '<div style="position:relative; display:inline-block;">' +
+                    '<img src="'+url+'" width="50" height="50" style="cursor:pointer;" ' +
+                    'onclick="openLayerPreview(\'' + url + '\')" alt="'+file.name+'">' +
+
+                    // 删除按钮
+                    '<i class="fa fa-times-circle" style="position:absolute; top:-8px; right:-8px; color:red; cursor:pointer;" ' +
+                    'onclick="deleteImage(\'' + spanId + '\', \'' + obj.id + '\')"></i>' +
+                    '</div>' +
+
+                    // 下载按钮,使用 base64 下载
+                    '<a href="'+base64Data+'" download="'+file.name+'" title="下载 '+file.name+'" ' +
+                    'style="color: #28a745; margin-left: 5px; text-decoration: none;">' +
+                    '<i class="fa fa-download"></i></a>';
+
+                $('#' + spanId).html(imgStr);
+            };
+
+            reader.readAsDataURL(file); // 开始读取文件(转为 base64)
+        }
+
+        function openLayerPreview(imgUrl) {
+            layui.use('layer', function(){
+                var layer = layui.layer;
+                layer.open({
+                    type: 1,
+                    title: '图片预览',
+                    shadeClose: true,
+                    shade: 0.2,
+                    area: ['600px', '400px'],
+                    content: '<img src="'+imgUrl+'" style="width:100%;height:100%;">'
+                });
+            });
+        }
+
+        function deleteImage(spanId, inputId) {
+            // 1. 清空图片展示区域
+            $('#' + spanId).html('');
+
+            // 2. 清除上传的文件 input 值
+            $('#' + inputId).val('');
+            document.getElementById(inputId).value = ''; // 双保险
+            console.log($('#' + inputId + 'Path').val())
+            // 3. 清除隐藏的路径字段(用于提交给后台)
+            $('#' + inputId + 'Path').val('');
+            console.log($('#' + inputId + 'Path').val())
+        }
+
+
+        // 下载函数,利用a标签模拟点击下载blob图片
+        function downloadFile(blobUrl, fileName) {
+            var a = document.createElement('a');
+            a.href = blobUrl;
+            a.download = fileName || 'download.png';
+            document.body.appendChild(a);
+            a.click();
+            document.body.removeChild(a);
+        }
+
+
     </script>
 </head>
 <body>
@@ -391,6 +482,53 @@
                             <input name="roleName" value="${workStaffBasicInfo.roleName}" type="text" readonly="true" class="form-control  layui-input" />
                         </div>
                     </div>
+                    <div class="layui-item layui-col-sm6 lw7">
+                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证人像面:</label>
+                        <div class="layui-input-block">
+                            <a class="op-btn op-btn-add" title="上传" onclick="this_upload_file_button('idCardPortrait')"><i class="fa fa-plus"></i>&nbsp;上传</a>
+                            <!-- 图片展示区域 -->
+                            <span id="idCardPortraitName1">
+                          <c:if test="${not empty workStaffBasicInfo.idCardPortraitPathStr}">
+                            <div style="position:relative; display:inline-block;">
+                              <img src="${workStaffBasicInfo.idCardPortraitPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardPortraitPathStr}')" alt="身份证照片">
+                                <!-- 删除按钮 -->
+                              <i class="fa fa-times-circle" style="position:absolute; top:-8px; right:-8px; color:red; cursor:pointer;" onclick="deleteImage('idCardPortraitName1', 'idCardPortrait')"></i>
+                            </div>
+                              <!-- 下载按钮(重点)-->
+                              <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardPortraitName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardPortraitPath}', '${workStaffBasicInfo.idCardPortraitName}')"><i class="fa fa-download"></i></a>
+                          </c:if>
+                        </span>
+                            <!-- 文件上传控件 -->
+                            <input id="idCardPortrait" name="idCardPortrait" style="display:none" type="file" onchange="changeIdCardFileName(this,1)" />
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardPortraitPath" name="idCardPortraitPath" value="${workStaffBasicInfo.idCardPortraitPath}">
+                        </div>
+                    </div>
+
+                    <div class="layui-item layui-col-sm6 lw7">
+                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证国徽面:</label>
+                        <div class="layui-input-block">
+                            <a class="op-btn op-btn-add" title="上传" onclick="this_upload_file_button('idCardNationalEmblem')"><i class="fa fa-plus"></i>&nbsp;上传</a>
+                            <!-- 图片展示区域 -->
+                            <span id="idCardNationalEmblemName1">
+                          <c:if test="${not empty workStaffBasicInfo.idCardNationalEmblemPathStr}">
+                            <div style="position:relative; display:inline-block;">
+                              <img src="${workStaffBasicInfo.idCardNationalEmblemPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardNationalEmblemPathStr}')" alt="身份证照片">
+                                <!-- 删除按钮 -->
+                              <i class="fa fa-times-circle" style="position:absolute; top:-8px; right:-8px; color:red; cursor:pointer;" onclick="deleteImage('idCardNationalEmblemName1', 'idCardNationalEmblem')"></i>
+                            </div>
+                              <!-- 下载按钮 -->
+                              <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardNationalEmblemName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardNationalEmblemPath}', '${workStaffBasicInfo.idCardNationalEmblemName}')"><i class="fa fa-download"></i></a>
+
+                          </c:if>
+                        </span>
+                            <!-- 文件上传控件 -->
+                            <input id="idCardNationalEmblem" name="idCardNationalEmblem" style="display:none" type="file" onchange="changeIdCardFileName(this,1)" />
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardNationalEmblemPath" name="idCardNationalEmblemPath" value="${workStaffBasicInfo.idCardNationalEmblemPath}">
+                        </div>
+                    </div>
+
                     <%--<div class="layui-item layui-col-sm6 lw7">
                         <label class="layui-form-label">职    位:</label>
                         <div class="layui-input-block">
@@ -1018,7 +1156,7 @@
                     </div>
                 </div>
                 <div class="form-group layui-row">
-                    <div class="form-group-label"><h2>职称</h2></div>
+                    <div class="form-group-label"><h2>职称证书</h2></div>
                     <div class="layui-item nav-btns">
                         <a href=javascript:void(0); onclick="addRowTitle('#titleList',titleIdx,titleTpl)" class="nav-btn nav-btn-add" ><i class="fa fa-plus"></i> 新增</a>
                     </div>

+ 1 - 1
src/main/webapp/webpage/modules/workstaff/workStaffBasicDetailModifyDirectly.jsp

@@ -937,7 +937,7 @@
                 </div>
             </div>
             <div class="form-group layui-row">
-                <div class="form-group-label"><h2>职称</h2></div>
+                <div class="form-group-label"><h2>职称证书</h2></div>
                 <div class="layui-item nav-btns">
                     <a href=javascript:void(0); onclick="addRowTitle('#titleList',titleIdx,titleTpl)" class="nav-btn nav-btn-add" ><i class="fa fa-plus"></i> 新增</a>
                 </div>

+ 156 - 22
src/main/webapp/webpage/modules/workstaff/workStaffBasicInfoForm.jsp

@@ -14,6 +14,12 @@
             left:0;
             top:40px;
         }
+        .delete-icon {
+            font-size: 16px;
+            background: white;
+            border-radius: 50%;
+            line-height: 1;
+        }
     </style>
     <script type="text/javascript">
         // var officeId;
@@ -469,6 +475,85 @@
             var imgStr = '<img src="'+url+'" width="24" height="24" onclick="openDialogView(\'预览\',\'${ctx}/sys/picturepreview/picturePreview?url='+url+'\',\'90%\',\'90%\')" alt="'+file.name+'">';
             $('#'+spanId).html(imgStr);
         }
+
+        function changeIdCardFileName(obj, index) {
+            var file = obj.files[0];
+            if (!file) return;
+
+            var url = URL.createObjectURL(file);
+
+            var fileType = file.type;
+            if(file.size > 1000*1024 || !(fileType.indexOf("png")>=0 || fileType.indexOf("bmp")>=0 || fileType.indexOf("jpg")>=0 || fileType.indexOf("jpeg")>=0)){
+                layer.msg("请上传1000KB内图片!", {icon: 2});
+                return;
+            }
+
+            var spanId = $(obj).attr("id") + 'Name' + index;
+
+            // 读取 base64 用于下载
+            var reader = new FileReader();
+            reader.onload = function(e) {
+                var base64Data = e.target.result;
+
+                var imgStr = '<div style="position:relative; display:inline-block;">' +
+                    '<img src="'+url+'" width="50" height="50" style="cursor:pointer;" ' +
+                    'onclick="openLayerPreview(\'' + url + '\')" alt="'+file.name+'">' +
+
+                    // 删除按钮
+                    '<i class="fa fa-times-circle" style="position:absolute; top:-8px; right:-8px; color:red; cursor:pointer;" ' +
+                    'onclick="deleteImage(\'' + spanId + '\', \'' + obj.id + '\')"></i>' +
+                    '</div>' +
+
+                    // 下载按钮,使用 base64 下载
+                    '<a href="'+base64Data+'" download="'+file.name+'" title="下载 '+file.name+'" ' +
+                    'style="color: #28a745; margin-left: 5px; text-decoration: none;">' +
+                    '<i class="fa fa-download"></i></a>';
+
+                $('#' + spanId).html(imgStr);
+            };
+
+            reader.readAsDataURL(file); // 开始读取文件(转为 base64)
+        }
+
+        function openLayerPreview(imgUrl) {
+            layui.use('layer', function(){
+                var layer = layui.layer;
+                layer.open({
+                    type: 1,
+                    title: '图片预览',
+                    shadeClose: true,
+                    shade: 0.2,
+                    area: ['600px', '400px'],
+                    content: '<img src="'+imgUrl+'" style="width:100%;height:100%;">'
+                });
+            });
+        }
+
+        function deleteImage(spanId, inputId) {
+            // 1. 清空图片展示区域
+            $('#' + spanId).html('');
+
+            // 2. 清除上传的文件 input 值
+            $('#' + inputId).val('');
+            document.getElementById(inputId).value = ''; // 双保险
+            console.log($('#' + inputId + 'Path').val())
+            // 3. 清除隐藏的路径字段(用于提交给后台)
+            $('#' + inputId + 'Path').val('');
+            console.log($('#' + inputId + 'Path').val())
+        }
+
+
+        // 下载函数,利用a标签模拟点击下载blob图片
+        function downloadFile(blobUrl, fileName) {
+            var a = document.createElement('a');
+            a.href = blobUrl;
+            a.download = fileName || 'download.png';
+            document.body.appendChild(a);
+            a.click();
+            document.body.removeChild(a);
+        }
+
+
         function shortenFileName(name, maxLength) {
             if (name.length <= maxLength) {
                 return name;
@@ -487,8 +572,8 @@
                 url = window.webkitURL.createObjectURL(file);
             }
 
-            if (file.size > 10 * 1024 * 1024) {
-                layer.msg("请上传10M以内文件!", { icon: 2 });
+            if (file.size > 100 * 1024 * 1024) {
+                layer.msg("请上传100M以内文件!", { icon: 2 });
                 return;
             }
 
@@ -505,7 +590,7 @@
                     + ' alt="图片预览" title="点击预览图片"/>';
             } else {
                 // 显示带文件名的链接(文件名过长会截断)
-                var shortName = shortenFileName(file.name, 7);
+                var shortName = shortenFileName(file.name, 20);
                 fileStr = '<span style="display:inline-block;width:24px;height:24px;margin-right:5px;"></span>'
                     + '<a href="javascript:void(0);" onclick="openDialogView(\'预览\',\'' + url + '\',\'90%\',\'90%\')" '
                     + 'title="' + file.name + '" style="text-decoration:none;color:#007bff;">'
@@ -813,6 +898,53 @@
                     </div>
                 </div>
 
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line"><span class="require-item">*</span>身份证人像面:</label>
+                    <div class="layui-input-block">
+                        <a class="op-btn op-btn-add" title="上传" onclick="this_upload_file_button('idCardPortrait')"><i class="fa fa-plus"></i>&nbsp;上传</a>
+                        <!-- 图片展示区域 -->
+                        <span id="idCardPortraitName1">
+                          <c:if test="${not empty workStaffBasicInfo.idCardPortraitPathStr}">
+                            <div style="position:relative; display:inline-block;">
+                              <img src="${workStaffBasicInfo.idCardPortraitPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardPortraitPathStr}')" alt="身份证照片">
+                                <!-- 删除按钮 -->
+                              <i class="fa fa-times-circle" style="position:absolute; top:-8px; right:-8px; color:red; cursor:pointer;" onclick="deleteImage('idCardPortraitName1', 'idCardPortrait')"></i>
+                            </div>
+                              <!-- 下载按钮(重点)-->
+                              <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardPortraitName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardPortraitPath}', '${workStaffBasicInfo.idCardPortraitName}')"><i class="fa fa-download"></i></a>
+                          </c:if>
+                        </span>
+                        <!-- 文件上传控件 -->
+                        <input id="idCardPortrait" name="idCardPortrait" style="display:none" type="file" onchange="changeIdCardFileName(this,1)" />
+                        <!-- ✅ 后端路径字段(用于提交) -->
+                        <input type="hidden" id="idCardPortraitPath" name="idCardPortraitPath" value="${workStaffBasicInfo.idCardPortraitPath}">
+                    </div>
+                </div>
+
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line"><span class="require-item">*</span>身份证国徽面:</label>
+                    <div class="layui-input-block">
+                        <a class="op-btn op-btn-add" title="上传" onclick="this_upload_file_button('idCardNationalEmblem')"><i class="fa fa-plus"></i>&nbsp;上传</a>
+                        <!-- 图片展示区域 -->
+                        <span id="idCardNationalEmblemName1">
+                          <c:if test="${not empty workStaffBasicInfo.idCardNationalEmblemPathStr}">
+                            <div style="position:relative; display:inline-block;">
+                              <img src="${workStaffBasicInfo.idCardNationalEmblemPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardNationalEmblemPathStr}')" alt="身份证照片">
+                                <!-- 删除按钮 -->
+                              <i class="fa fa-times-circle" style="position:absolute; top:-8px; right:-8px; color:red; cursor:pointer;" onclick="deleteImage('idCardNationalEmblemName1', 'idCardNationalEmblem')"></i>
+                            </div>
+                              <!-- 下载按钮 -->
+                              <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardNationalEmblemName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardNationalEmblemPath}', '${workStaffBasicInfo.idCardNationalEmblemName}')"><i class="fa fa-download"></i></a>
+
+                          </c:if>
+                        </span>
+                        <!-- 文件上传控件 -->
+                        <input id="idCardNationalEmblem" name="idCardNationalEmblem" style="display:none" type="file" onchange="changeIdCardFileName(this,1)" />
+                        <!-- ✅ 后端路径字段(用于提交) -->
+                        <input type="hidden" id="idCardNationalEmblemPath" name="idCardNationalEmblemPath" value="${workStaffBasicInfo.idCardNationalEmblemPath}">
+                    </div>
+                </div>
+
 
                 <%--<div class="layui-item layui-col-sm6 lw7">
                     <label class="layui-form-label"><span class="require-item">*</span>最高学历:</label>
@@ -1485,7 +1617,7 @@
                 </div>
             </div>
             <div class="form-group layui-row">
-                <div class="form-group-label"><h2>职称</h2></div>
+                <div class="form-group-label"><h2>职称证书</h2></div>
                 <div class="layui-item nav-btns">
                     <a href=javascript:void(0); onclick="addRowTitle('#titleList',titleIdx,titleTpl)" class="nav-btn nav-btn-add" ><i class="fa fa-plus"></i> 新增</a>
                 </div>
@@ -2142,12 +2274,12 @@
                         <thead>
                         <tr>
                             <th width="10%"><span class="require-item">*</span>合同类型</th>
-                            <th width="10%">合同编号</th>
+                            <%--<th width="10%">合同编号</th>--%>
                             <th width="10%"><span class="require-item">*</span>合同期限</th>
                             <th width="11%">合同起始日期</th>
                             <th width="11%">合同终止日期</th>
                             <th width="11%">试用期结束日期</th>
-                            <th width="11%">办理日期</th>
+                            <%--<th width="11%">办理日期</th>--%>
                             <th >文件</th>
                             <th width="10%">操作</th>
                         </tr>
@@ -2168,9 +2300,9 @@
                                         </c:forEach>
                                     </select>
                                 </td>
-                                <td>
+                                <%--<td>
                                     <input id="laborContractList${varStatus.index}_contractNum" name="laborContractList[${varStatus.index}].contractNum" type="text" value="${buyDetails.contractNum}"/>
-                                </td>
+                                </td>--%>
                                 <td>
                                     <select name="laborContractList[${varStatus.index}].contractLimit" id="laborContractList${varStatus.index}_contractLimit" class="form-control required">
                                         <c:forEach items="${fns:getMainDictList('contract_limit')}" var="var">
@@ -2190,10 +2322,10 @@
                                     <input id="laborContractList${varStatus.index}_tryEndTime" name="laborContractList[${varStatus.index}].tryEndTime" type="text" maxlength="20" class="laydate-icon form-control layer-date laydate-icondate"
                                            value="<fmt:formatDate value="${buyDetails.tryEndTime}" pattern="yyyy-MM-dd"/>" readOnly="true" />
                                 </td>
-                                <td>
+                                <%--<td>
                                     <input id="laborContractList${varStatus.index}_transactTime" name="laborContractList[${varStatus.index}].transactTime" type="text" maxlength="20" class="laydate-icon form-control layer-date laydate-icondate"
                                            value="<fmt:formatDate value="${buyDetails.transactTime}" pattern="yyyy-MM-dd"/>" readOnly="true" />
-                                </td>
+                                </td>--%>
 
                                 <td class="text-left op-td">
                                     <!-- 上传按钮 -->
@@ -2248,15 +2380,17 @@
                                     </span>
 
                                     <!-- 下载按钮 -->
-                                    <a href="javascript:void(0);"
-                                       title="下载 ${buyDetails.fileName}"
-                                       style="color: #28a745; margin-left: 5px; text-decoration: none;"
-                                       onclick="downloadFile('${ctx}', '${buyDetails.filePath}', '${buyDetails.fileName}')">
-                                        <i class="fa fa-download"></i>
-                                    </a>
+                                    <c:if test="${not empty buyDetails.filePathStr}">
+                                        <a href="javascript:void(0);"
+                                           title="下载 ${buyDetails.fileName}"
+                                           style="color: #28a745; margin-left: 5px; text-decoration: none;"
+                                           onclick="downloadFile('${ctx}', '${buyDetails.filePath}', '${buyDetails.fileName}')">
+                                            <i class="fa fa-download"></i>
+                                        </a>
+                                    </c:if>
                                     <!-- 隐藏的上传输入框 -->
                                     <input id="laborContractList${varStatus.index}_file"
-                                           name="trainingList[${varStatus.index}].file"
+                                           name="laborContractList[${varStatus.index}].file"
                                            style="display:none"
                                            type="file"
                                            onchange="changelaborContractFileName(this,1)" />
@@ -2287,9 +2421,9 @@
                                 </select>
 
                             </td>
-                            <td>
+                            <%--<td>
                                 <input placeholder="请输入合同编号" id="laborContractList{{idx}}_contractNum" name="laborContractList[{{idx}}].contractNum" class="form-control" value="{{row.contractNum}}"/>
-                            </td>
+                            </td>--%>
 
                             <td style="text-align:center;">
                                 <select name="laborContractList[{{idx}}].contractLimit" id="laborContractList{{idx}}_contractLimit" class="form-control required">
@@ -2312,12 +2446,12 @@
                                 <input id="laborContractList{{idx}}_tryEndTime" name="laborContractList[{{idx}}].tryEndTime" type="text" maxlength="20" class="laydate-icon form-control layer-date laydate-icondate"
                                        style="background-color:#fff " placeholder="试用期结束日期" value="<fmt:formatDate value="${row.tryEndTime}" pattern="yyyy-MM-dd"/>" readOnly="true" />
                             </td>
-                            <td>
+                            <%--<td>
                                 <input id="laborContractList{{idx}}_transactTime" name="laborContractList[{{idx}}].transactTime" type="text" maxlength="20" class="laydate-icon form-control layer-date laydate-icondate"
                                        style="background-color:#fff " placeholder="办理日期" value="<fmt:formatDate value="${row.transactTime}" pattern="yyyy-MM-dd"/>" readOnly="true" />
-                            </td>
+                            </td>--%>
 
-                            <td class="text-center op-td">
+                            <td class="op-td">
                                 <a class="op-btn op-btn-add" title="上传" onclick="this_upload_file_button('laborContractList{{idx}}_file')"><i class="fa fa-plus"></i>&nbsp;上传</a><span id="laborContractList{{idx}}_fileName1"></span>
                                 <input id="laborContractList{{idx}}_file" name="laborContractList[{{idx}}].file" style="display:none" type="file" onchange="changelaborContractFileName(this,1)"/>
                             </td>

+ 61 - 1
src/main/webapp/webpage/modules/workstaff/workStaffBasicInfoView.jsp

@@ -4,6 +4,11 @@
 <head>
 	<title>员工信息管理</title>
 	<meta name="decorator" content="default"/>
+    <script type="text/javascript" src="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+    <script src="${ctxStatic}/layer-v2.3/layui/xmSelect.js" charset="utf-8"></script>
 	<script type="text/javascript">
 		$(document).ready(function() {
             cacuAge('${workStaffBasicInfo.idCard}','1');
@@ -42,6 +47,20 @@
             if(age<0)age=0;
             $("#age").val(age);
         }
+
+        function openLayerPreview(imgUrl) {
+            layui.use('layer', function(){
+                var layer = layui.layer;
+                layer.open({
+                    type: 1,
+                    title: '图片预览',
+                    shadeClose: true,
+                    shade: 0.2,
+                    area: ['600px', '400px'],
+                    content: '<img src="'+imgUrl+'" style="width:100%;height:100%;">'
+                });
+            });
+        }
     </script>
 
 </head>
@@ -263,6 +282,47 @@
                             <input style="background-color: #f1f1f1" id="roleName" value="${workStaffBasicInfo.roleName}" type="text" readonly class="form-control layui-input" />
                         </div>
                     </div>
+                    <div class="layui-item layui-col-sm6 lw7">
+                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证人像面:</label>
+                        <div class="layui-input-block">
+                            <!-- 图片展示区域 -->
+                            <span id="idCardPortraitName1">
+                              <c:if test="${not empty workStaffBasicInfo.idCardPortraitPathStr}">
+                                <div style="position:relative; display:inline-block;">
+                                  <img src="${workStaffBasicInfo.idCardPortraitPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardPortraitPathStr}')" alt="身份证照片">
+                                </div>
+                                  <!-- 下载按钮(重点)-->
+                                  <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardPortraitName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardPortraitPath}', '${workStaffBasicInfo.idCardPortraitName}')"><i class="fa fa-download"></i></a>
+                              </c:if>
+                            </span>
+
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardPortraitName" name="idCardPortraitName" value="${workStaffBasicInfo.idCardPortraitName}">
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardPortraitPath" name="idCardPortraitPath" value="${workStaffBasicInfo.idCardPortraitPath}">
+                        </div>
+                    </div>
+
+
+                    <div class="layui-item layui-col-sm6 lw7">
+                        <label class="layui-form-label double-line"><span class="require-item">*</span>身份证国徽面:</label>
+                        <div class="layui-input-block">
+                            <!-- 图片展示区域 -->
+                            <span id="idCardNationalEmblemName1">
+                              <c:if test="${not empty workStaffBasicInfo.idCardNationalEmblemPathStr}">
+                                <div style="position:relative; display:inline-block;">
+                                  <img src="${workStaffBasicInfo.idCardNationalEmblemPathStr}" width="50" height="50" style="cursor:pointer;" onclick="openLayerPreview('${workStaffBasicInfo.idCardNationalEmblemPathStr}')" alt="身份证照片">
+                                </div>
+                                  <!-- 下载按钮 -->
+                                  <a href="javascript:void(0);" title="下载 ${workStaffBasicInfo.idCardNationalEmblemName}" style="color: #28a745; margin-left: 5px; text-decoration: none;" onclick="downloadFile('${ctx}', '${workStaffBasicInfo.idCardNationalEmblemPath}', '${workStaffBasicInfo.idCardNationalEmblemName}')"><i class="fa fa-download"></i></a>
+
+                              </c:if>
+                            </span>
+                            <!-- ✅ 后端路径字段(用于提交) -->
+                            <input type="hidden" id="idCardNationalEmblemName" name="idCardNationalEmblemName" value="${workStaffBasicInfo.idCardNationalEmblemName}">
+                            <input type="hidden" id="idCardNationalEmblemPath" name="idCardNationalEmblemPath" value="${workStaffBasicInfo.idCardNationalEmblemPath}">
+                        </div>
+                    </div>
                     <%--<div class="layui-item layui-col-sm6 lw7">
                         <label class="layui-form-label"><span class="require-item">*</span>最高学历:</label>
                         <div class="layui-input-block ">
@@ -662,7 +722,7 @@
                     </div>
                 </div>
                 <div class="form-group layui-row">
-                    <div class="form-group-label"><h2>职称</h2></div>
+                    <div class="form-group-label"><h2>职称证书</h2></div>
                     <div class="layui-item layui-col-xs12 form-table-container">
                         <table id="titleTable" class="table table-bordered table-condensed details">
                             <thead>