Explorar el Código

个人资质添加个人签名和日期的调整

徐滕 hace 1 semana
padre
commit
24666ba304

+ 10 - 0
src/main/java/com/jeeplus/modules/workprojectnotify/web/WorkProjectNotifyController.java

@@ -11401,6 +11401,16 @@ public class WorkProjectNotifyController extends BaseController {
 				Act act = new Act();
 				act.setComment(workProjectNotify.getAuditContent());
 				workStaffBasicInfo.setAct(act);
+
+				List<MainDictDetail> mainDictDetails=DictUtils.getMainDictListOnProjectAdvent("certificate_type");
+				for (MainDictDetail mainDictDetail:mainDictDetails){
+					for (WorkStaffCertificate workStaffCertificate : workStaffBasicInfo.getCertificateList()) {
+						if (mainDictDetail.getValue().equals(workStaffCertificate.getName())){
+							workStaffCertificate.setName(mainDictDetail.getLabel());
+							break;
+						}
+					}
+				}
 				return "modules/workstaff/workStaffBasicInfoView";
 			}
 		}

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

@@ -2318,9 +2318,9 @@ public class WorkStaffBasicInfoService extends CrudService<WorkStaffBasicInfoDao
 
         if(null != day){
             if(day>=0){
-                titleStr = titleStr + ",距离到期时间还剩" + day + "天。请及时更新。";
+                titleStr = titleStr + ",距离到期时间还剩" + day + "天。请通过我的信息及时更新。";
             }else{
-                titleStr = titleStr + -day + "天。请及时更新。";
+                titleStr = titleStr + -day + "天。请通过我的信息及时更新。";
             }
         }
 

+ 114 - 8
src/main/java/com/jeeplus/modules/workstaff/service/WorkStaffCertificateService.java

@@ -149,7 +149,7 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
                     String originalFileName = file.getOriginalFilename();
                     String basePath = "";
                     try {
-                        if ("161".equals(name)
+                        if (("161".equals(name) || "151".equals(name)  || "181".equals(name) )
                                 && StringUtils.isNotBlank(originalFileName)
                                 && originalFileName.toLowerCase().endsWith(".pdf")) {
                             // -------------------------- 1. 按系统生成临时存储路径 --------------------------
@@ -178,7 +178,7 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
                             Map<String, Object> map = null;
                             if(null != tempFile && StringUtils.isNotBlank(workStaffBasicInfo.getHandSignature())){
                                 // 入参传临时文件路径,方便你在方法里直接读取处理
-                                map = disposeFile(tempFile, workStaffBasicInfo.getHandSignature(), basePath);
+                                map = disposeFile(tempFile, workStaffBasicInfo.getHandSignature(), basePath, name);
                             }
 
                             //获取处理好的一造文件
@@ -310,8 +310,10 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
      *
      * @param tempFile  一造文件
      * @param handSignature 个人签名章
+     * @param path
+     * @param type 处理的资质类型:161:一造,151:一建,181:监理
      */
-    private Map<String,Object> disposeFile(File tempFile, String handSignature, String path) {
+    private Map<String,Object> disposeFile(File tempFile, String handSignature, String path, String type) {
         Map<String,Object> map = null;
         File srcFile = null;
         try{
@@ -345,7 +347,7 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
             //将下载下来的文件转换为file文件
             srcFile = new File(path+fileName);
 
-            map = PdfSignUtil.disposePdfFile(tempFile, srcFile, path);
+            map = PdfSignUtil.disposePdfFile(tempFile, srcFile, path, type );
 
 
         } catch (Exception e) {
@@ -900,7 +902,7 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
                         String originalFileName = file.getOriginalFilename();
                         String basePath = "";
                         try {
-                            if ("161".equals(name)
+                            if (("161".equals(name) || "151".equals(name)  || "181".equals(name) )
                                     && StringUtils.isNotBlank(originalFileName)
                                     && originalFileName.toLowerCase().endsWith(".pdf") && StringUtils.isNotBlank(workStaffBasicInfo.getHandSignature())) {
                                 // -------------------------- 1. 按系统生成临时存储路径 --------------------------
@@ -929,7 +931,7 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
                                 Map<String, Object> map = null;
                                 if(null != tempFile && StringUtils.isNotBlank(workStaffBasicInfo.getHandSignature())){
                                     // 入参传临时文件路径,方便你在方法里直接读取处理
-                                    map = disposeFile(tempFile, workStaffBasicInfo.getHandSignature(), basePath);
+                                    map = disposeFile(tempFile, workStaffBasicInfo.getHandSignature(), basePath,name);
                                 }
 
                                 //获取处理好的一造文件
@@ -1106,10 +1108,114 @@ public class WorkStaffCertificateService extends CrudService<WorkStaffCertificat
                         }
                     }
                 }else if((newCertificate.getId()==null||"".equals(newCertificate.getId()))&&"0".equals(newCertificate.getDelFlag())){//新增
-                    if(newCertificate.getFile()!=null&&!newCertificate.getFile().isEmpty()&&newCertificate.getFile().getSize()>0){
+
+
+                    // 1. 先处理文件上传(按系统区分路径,临时存储)
+                    String staffId = workStaffBasicInfo.getId();
+                    MultipartFile file = newCertificate.getFile();
+
+                    // 临时文件路径(用于try中处理,处理完自动删除)
+                    String tempFilePath = null;
+
+                    if (file != null && !file.isEmpty() && file.getSize() > 0) {
+
+                        String name = newCertificate.getName();
+                        // 生成临时文件名(避免重名)
+                        String originalFileName = file.getOriginalFilename();
+                        String basePath = "";
+                        try {
+                            if (("161".equals(name) || "151".equals(name)  || "181".equals(name) )
+                                    && StringUtils.isNotBlank(originalFileName)
+                                    && originalFileName.toLowerCase().endsWith(".pdf") && StringUtils.isNotBlank(workStaffBasicInfo.getHandSignature())) {
+                                // -------------------------- 1. 按系统生成临时存储路径 --------------------------
+                                String os = System.getProperty("os.name").toLowerCase();
+                                if (os.contains("win")) {
+                                    // Windows系统:D盘根目录
+                                    basePath = "D:/attachment-file/staffCertificate/" + staffId + "/";
+                                } else {
+                                    // Linux系统:根目录
+                                    basePath = "/attachment-file/staffCertificate/" + staffId + "/";
+                                }
+
+                                // 确保目录存在,不存在则自动创建
+                                File dir = new File(basePath);
+                                if (!dir.exists()) {
+                                    dir.mkdirs();
+                                }
+
+                                String tempFileName = System.currentTimeMillis() + "_" + originalFileName;
+                                tempFilePath = basePath + tempFileName;
+
+                                // 2. 将上传的文件保存到临时路径
+                                File tempFile = new File(tempFilePath);
+                                file.transferTo(tempFile);
+
+                                Map<String, Object> map = null;
+                                if(null != tempFile && StringUtils.isNotBlank(workStaffBasicInfo.getHandSignature())){
+                                    // 入参传临时文件路径,方便你在方法里直接读取处理
+                                    map = disposeFile(tempFile, workStaffBasicInfo.getHandSignature(), basePath,name);
+                                }
+
+                                //获取处理好的一造文件
+                                String outPdfPath = (String) map.get("outPdfPath");
+                                MultipartFile multipartFile = transformFile(new File(outPdfPath));
+
+                                // 3. 调用原有的uploadFile方法,上传到CDN(保持你原有逻辑不变)
+                                String cdnFilePath = this.uploadFile(multipartFile, newCertificate.getFilePath());
+                                newCertificate.setFileName(originalFileName);
+                                newCertificate.setFilePath(cdnFilePath);
+
+                                //获取本次生成的一级造价师的文件的使用时效时间
+                                String startDateStr = (String) map.get("startDate");
+                                String endDateStr = (String) map.get("endDate");
+                                //获取一级造价师文件的有效时间
+                                String certValidStartDateStr = (String) map.get("certValidStart");
+                                String certValidEndDateStr = (String) map.get("certValidEnd");
+
+                                // 转换为 Date
+                                sdf = new SimpleDateFormat("yyyy年MM月dd日");
+
+                                newCertificate.setValidStartDate(sdf.parse(startDateStr));
+                                newCertificate.setValidEndDate(sdf.parse(endDateStr));
+                                newCertificate.setStartDate(sdf.parse(certValidStartDateStr));
+                                newCertificate.setEndDate(sdf.parse(certValidEndDateStr));
+
+                                // -------------------------- 4. 条件判断:name=161 且 是PDF,调用disposeFile --------------------------
+
+                            }else{
+                                //如果不是一造  也不是pdf文件的话,按照以前的处理方式进行处理
+                                newCertificate.setFileName(file.getOriginalFilename());
+                                newCertificate.setFilePath(this.uploadFile(file,newCertificate.getFilePath()));
+                            }
+
+                        } catch (Exception e) {
+                            // 异常处理:打印日志,抛出业务异常(可根据你的项目规范调整)
+                            //throw new RuntimeException("证书文件处理失败:" + e.getMessage());
+                            result = "一级造价师证书处理失败" + e.getMessage();
+                            return result;
+                        } finally {
+                            // -------------------------- 5. 无论成功失败,最终删除临时文件 --------------------------
+                            if (StringUtils.isNotBlank(tempFilePath)) {
+                                File tempFile = new File(tempFilePath);
+                                if (tempFile.exists()) {
+                                    tempFile.delete();
+                                }
+                            }
+                            if (StringUtils.isNotBlank(basePath)) {
+                                File basePathFile = new File(basePath);
+                                if (basePathFile.exists() && basePathFile.isDirectory()) {
+                                    // 清空目录下所有文件/子文件夹,保留目录本身
+                                    clearDirectory(basePathFile);
+                                }
+                            }
+                        }
+                    }
+
+
+                    /*if(newCertificate.getFile()!=null&&!newCertificate.getFile().isEmpty()&&newCertificate.getFile().getSize()>0){
                         MultipartFile file = newCertificate.getFile();
                         newCertificate.setFilePath(this.uploadFile(file,newCertificate.getFilePath()));
-                    }
+                    }*/
                     String newId=IdGen.uuid();
                     for (Field field : declaredFields) {
                         String name = field.getName();

+ 109 - 20
src/main/java/com/jeeplus/modules/workstaff/utils/PdfSignUtil.java

@@ -25,25 +25,88 @@ public class PdfSignUtil {
     private static final String SIGN_IMG = "d:/吴明华签字章.png";
     private static final String OUT_PDF  = "d:/new造价工程师证书.pdf";*/
 
-    private static final float SIGN_WIDTH = 70;
-    private static final float SIGN_HEIGHT = 25;
-    private static final float SIGN_X = 180;
-    private static final float SIGN_Y = 110;
+    //签字章位置
+    //private static final float SIGN_WIDTH = 70;
+    //private static final float SIGN_HEIGHT = 25;
+    //private static final float SIGN_X = 180;
+    //private static final float SIGN_Y = 110;
 
-    //private static final String DATE_TEMP_PNG = "d:/date_temp.png";
-    private static final float DATE_X = 180;
-    private static final float DATE_Y = 80;
-    private static final float DATE_WIDTH = 80;
-    private static final float DATE_HEIGHT = 30;
+    //日期位置
+    //private static final float DATE_X = 180;
+    //private static final float DATE_Y = 80;
+    //private static final float DATE_WIDTH = 80;
+    //private static final float DATE_HEIGHT = 30;
 
     // 字体文件放在当前类同级目录
     private static final String HAND_FONT = PdfSignUtil.class.getResource("font.ttf").getPath();
 
+    // ==============================================
+    // 坐标配置类:根据 type 切换多套坐标
+    // type 161:一造,151:一建,181:监理
+    // ==============================================
+    private static class SignPosition {
+        // 签章
+        float signWidth;
+        float signHeight;
+        float signX;
+        float signY;
+        // 日期
+        float dateX;
+        float dateY;
+        float dateWidth;
+        float dateHeight;
+
+        public SignPosition(float signWidth, float signHeight, float signX, float signY,
+                            float dateX, float dateY, float dateWidth, float dateHeight) {
+            this.signWidth = signWidth;
+            this.signHeight = signHeight;
+            this.signX = signX;
+            this.signY = signY;
+            this.dateX = dateX;
+            this.dateY = dateY;
+            this.dateWidth = dateWidth;
+            this.dateHeight = dateHeight;
+        }
+    }
+
+
+    // 161 一造坐标(你原来默认的那套)
+    private static final SignPosition POS_161 = new SignPosition(
+            70,    // SIGN_WIDTH
+            25,    // SIGN_HEIGHT
+            180,   // SIGN_X
+            110,   // SIGN_Y
+            180,   // DATE_X
+            80,    // DATE_Y
+            80,    // DATE_WIDTH
+            30     // DATE_HEIGHT
+    );
+
+    // 151 一建坐标(第二套,自行修改数值)
+    private static final SignPosition POS_151 = new SignPosition(
+            70, 25, 250, 80,
+            250, 50, 80, 30
+    );
+
+    // 181 监理坐标(第三套,自行修改数值)
+    private static final SignPosition POS_181 = new SignPosition(
+            70, 25, 240, 100,
+            240, 60, 80, 30
+    );
+
     public static void main(String[] args) {
         //disposePdfFile(new File(SRC_PDF), new File(SIGN_IMG), "d:/");
     }
 
-    public static Map<String,Object> disposePdfFile(File file, File signFile, String path) {
+    /**
+     *
+     * @param file
+     * @param signFile
+     * @param path
+     * @param type 处理的资质类型:161:一造,151:一建,181:监理
+     * @return
+     */
+    public static Map<String,Object> disposePdfFile(File file, File signFile, String path, String type) {
         Map<String,Object> map = new HashMap<String,Object>();
         PDDocument doc = null;
         try {
@@ -92,6 +155,9 @@ public class PdfSignUtil {
             map.put("certValidStart", certValidStart);
             map.put("certValidEnd", certValidEnd);
 
+            // 根据类型获取对应坐标
+            SignPosition pos = getPositionByType(type);
+
             // 下面原有逻辑全部不动
             String today = new SimpleDateFormat("yyyy.MM.dd").format(new Date());
             generateHandWritingDate(today, signFile, path + "/date_temp.png");
@@ -101,8 +167,8 @@ public class PdfSignUtil {
             PDImageXObject dateImage = PDImageXObject.createFromFile(path + "/date_temp.png", doc);
 
             PDPageContentStream cs = new PDPageContentStream(doc, page, true, true, true);
-            cs.drawImage(signImage, SIGN_X, SIGN_Y, SIGN_WIDTH, SIGN_HEIGHT);
-            cs.drawImage(dateImage, DATE_X, DATE_Y, DATE_WIDTH, DATE_HEIGHT);
+            cs.drawImage(signImage, pos.signX, pos.signY, pos.signWidth, pos.signHeight);
+            cs.drawImage(dateImage, pos.dateX, pos.dateY, pos.dateWidth, pos.dateHeight);
             cs.close();
 
             // 动态生成输出路径
@@ -125,6 +191,22 @@ public class PdfSignUtil {
         return map;
     }
 
+    /**
+     * 根据资质类型获取对应签章/日期坐标
+     */
+    private static SignPosition getPositionByType(String type) {
+        switch (type) {
+            case "161":
+                return POS_161;
+            case "151":
+                return POS_151;
+            case "181":
+                return POS_181;
+            default:
+                return POS_161; // 默认一造
+        }
+    }
+
     // 生成日期:直采签字原色、多层叠加加深、防割裂
     private static void generateHandWritingDate(String date, File signFile, String outPath) throws Exception {
         BufferedImage signImg = ImageIO.read(signFile);
@@ -133,27 +215,34 @@ public class PdfSignUtil {
 
         File fontFile = new File(HAND_FONT);
         FileInputStream fontIn = new FileInputStream(fontFile);
-        Font handFont = Font.createFont(Font.TRUETYPE_FONT, fontIn).deriveFont(Font.BOLD,22f);
+        // 字号你已经设为28,我就用28
+        Font handFont = Font.createFont(Font.TRUETYPE_FONT, fontIn).deriveFont(Font.BOLD, 22f);
         fontIn.close();
 
-        BufferedImage img = new BufferedImage(130, 30, BufferedImage.TYPE_INT_ARGB);
-        Graphics2D g2d = img.createGraphics();
+        // 注意:这里宽度160是为了容纳加粗后的字体,防止截断
+        BufferedImage img = new BufferedImage(160, 40, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g2d = img.createGraphics(); // 修正:变量名统一为 g2d
 
         g2d.setComposite(AlphaComposite.Clear);
-        g2d.fillRect(0,0,130,30);
+        g2d.fillRect(0, 0, 160, 40);
         g2d.setComposite(AlphaComposite.SrcOver);
 
         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
-        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
         g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
 
         g2d.setColor(realInkColor);
         g2d.setFont(handFont);
 
-        g2d.drawString(date, 2, 22);
-        g2d.drawString(date, 2, 22);
-        g2d.drawString(date, 2, 22);
+        // 核心修复:使用 g2d 变量,并添加偏移量实现超级加粗
+        // 左右上下偏移叠加,保证非常黑、非常粗
+        // 核心:只保留 3层叠加,粗细适中
+        g2d.drawString(date, 1, 25);
+        g2d.drawString(date, 2, 24);
+        g2d.drawString(date, 2, 25);
+
+        // 最后画一层主字,保证清晰
+        g2d.drawString(date, 2, 25);
 
         g2d.dispose();
         ImageIO.write(img, "png", new File(outPath));

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

@@ -823,6 +823,14 @@ public class WorkStaffBasicInfoController extends BaseController {
 		workStaffBasicInfo = workStaffBasicInfoService.getAchive(workStaffBasicInfo);
 		workStaffBasicInfo.setAchiveId(workStaffBasicInfo.getId());
 
+		WorkStaffBasicInfo byUserId = workStaffBasicInfoService.getWorkStaffBasicInfoByUserId(workStaffBasicInfo.getUserId());
+		WorkStaffBasicInfo workStaffBasicInfo1 = workStaffBasicInfoService.get(byUserId.getId());
+
+		if(StringUtils.isNotBlank(workStaffBasicInfo1.getHandSignature()) && StringUtils.isBlank(workStaffBasicInfo.getHandSignature())){
+			workStaffBasicInfo.setHandSignature(workStaffBasicInfo1.getHandSignature());
+			workStaffBasicInfo.setHandSignatureUrl(workStaffBasicInfo1.getHandSignatureUrl());
+		}
+
 		List<Role> roleList = Lists.newArrayList();
 		List<String> roleNameList = Lists.newArrayList();
 		List<String> roleIdList = Lists.newArrayList();

+ 125 - 2
src/main/webapp/webpage/modules/workstaff/workStaffBasicCertificateModify.jsp

@@ -16,6 +16,29 @@
 		          layer.msg("该员工在职,不能提交入职信息,请确认身份证信息",{icon:2})
                   return false;
               }
+
+              // 👇 核心修复:正确获取证书行集合
+              var $certificateRows = $("#certificateList tr");
+              console.log("证书行数:", $certificateRows.length); // 这里会正确打印1(你当前有1行数据)
+
+              // 遍历每一行证书
+              for (var i = 0; i < $certificateRows.length; i++) {
+                  var $row = $certificateRows.eq(i); // 当前行的jQuery对象
+                  var prefix = "certificateList" + i; // 拼接ID前缀(对应你input的id:certificateList0_file等)
+
+                  // 获取对应行的证书名称(_name后缀的input)
+                  var targetValue = $("#" + prefix + "_name").val();
+                  console.log("第" + i + "行证书名称:", targetValue);
+
+                  // 你的原有校验逻辑
+                  if(targetValue === '151' || targetValue === '161' || targetValue === '181'){
+                      var handSignature = $("#handSignature").val();
+                      if(!handSignature){
+                          layer.msg("因您的资格证书需要您的手签章(个人签字章)信息,请您上传后再进行提交。", {icon:2});
+                          return false;
+                      }
+                  }
+              }
 			  $("#inputForm").submit();
 			  return true;
 		  }
@@ -24,9 +47,52 @@
 		}
 
 		$(document).ready(function() {
-            layui.use(['form', 'layer'], function () {
+            layui.use(['form','upload', 'element', 'layer'], function() {
                 var form = layui.form;
-            });
+                var $ = layui.jquery
+                    , upload = layui.upload
+                    , element = layui.element
+                    , layer = layui.layer;
+
+                //常规使用 - 普通图片上传
+                var uploadInst = upload.render({
+                    elem: '#test1'
+                    ,url: '${ctx}/bos/upLoadHandSignatureImg' //此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。
+                    ,before: function(obj){
+                        //预读本地文件示例,不支持ie8
+                        obj.preview(function(index, file, result){
+                            $('#handSignatureImg').attr('src', result); //图片链接(base64)
+                        });
+                        layer.msg('上传中', {icon: 16, time: 0});
+                    }
+                    ,done: function(res){
+                        //如果上传失败
+                        if(res.code != 1){
+                            return layer.msg('上传失败');
+                        }
+                        //上传成功的一些操作
+                        //console.log(res.url)
+                        $("#handSignature").val(res.url);
+                        layer.msg('上传完毕', {icon: 1});
+                        //……
+                        $('#handSignatureText').html(''); //置空上传失败的状态
+                    }
+                    ,error: function(){
+                        //演示失败状态,并实现重传
+                        var handSignatureText = $('#handSignatureText');
+                        handSignatureText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
+                        handSignatureText.find('.demo-reload').on('click', function(){
+                            uploadInst.upload();
+                        });
+                    }
+                    //进度条
+                    /*,progress: function(n, elem, e){
+                        if(n == 100){
+                            layer.msg('上传完毕', {icon: 1});
+                        }
+                    }*/
+                });
+            })
 			validateForm = $("#inputForm").validate({
 				submitHandler: function(form){
 					loading('正在提交,请稍等...');
@@ -286,6 +352,24 @@
             $('#'+spanId).html(imgStr);
         }
         function changelaborContractFileName(obj, index) {
+            console.log("进入changelaborContractFileName方法")
+            // 1. 获取元素的id属性
+            const elementId = obj.id;
+
+            // 2. 截取_之前的内容(核心逻辑)
+            // 原理:找到第一个_的索引,截取从0到该索引的字符串
+            const underscoreIndex = elementId.indexOf('_');
+            const idPrefix = underscoreIndex !== -1 ? elementId.substring(0, underscoreIndex) : elementId;
+
+            //console.log("提取的id前缀:", idPrefix);
+
+            // 3. 用提取的前缀拼接name选择器,获取对应值
+            // 优化:使用模板字符串简化拼接,同时保留index参数的兼容性
+            const targetValue = $("#" + idPrefix + "_name").val();
+
+
+            //console.log("获取到的目标值:", targetValue);
+
             var file = obj.files[0];
             var url = null;
             if (window.createObjectURL != undefined) {
@@ -304,6 +388,25 @@
             var ext = file.name.split('.').pop().toLowerCase();
             var isImage = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext);
 
+            // 4. 新增:PDF格式判断(兼容.pdf/.PDF/.Pdf等所有大小写)
+            var isPdf = ext === 'pdf';
+
+            // 5. 【可选】PDF格式校验拦截(如果只允许PDF,可直接用这段)
+            if('151' === targetValue || '161' === targetValue || '181' === targetValue){
+                if (!isPdf) {
+                    if('151' === targetValue){
+                        layer.msg("请上传一级建造师pdf格式文件", { icon: 2 });
+                    }
+                    if('161' === targetValue){
+                        layer.msg("请上传一级造价师pdf格式文件", { icon: 2 });
+                    }
+                    if('181' === targetValue){
+                        layer.msg("请上传监理师pdf格式文件", { icon: 2 });
+                    }
+                    return;
+                }
+            }
+
             var spanId = $(obj).attr("id") + 'Name' + index;
             var fileStr = "";
 
@@ -370,6 +473,7 @@
                 <form:hidden path="id"/>
                 <form:hidden path="userId"/>
                 <form:hidden path="home"/>
+                <form:hidden path="handSignature"/>
                 <div class="form-group layui-row first">
                     <div class="form-group-label"><h2>基本信息</h2></div>
                         <div class="layui-item layui-col-sm6 lw7">
@@ -413,6 +517,25 @@
                 </div>
 
 
+                <div class="form-group layui-row">
+                    <div class="form-group-label"><h2>手签章<span style="color: red; font-size: 14px; font-weight: normal;">   请在白纸上签字并扫描,截取签字部分进行上传</span></h2></div>
+                    <div class="layui-item nav-btns">
+                        <button type="button" class="layui-btn" id="test1">上传手签章</button>
+                        <div class="layui-upload-list">
+                            <c:choose>
+                                <c:when test="${not empty workStaffBasicInfo.handSignatureUrl}">
+                                    <img class="layui-upload-img" width="200px" height="150px" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workStaffBasicInfo.handSignatureUrl}','90%','90%')" id="handSignatureImg" src="${workStaffBasicInfo.handSignatureUrl}">
+                                </c:when>
+                                <c:otherwise>
+                                    <img class="layui-upload-img" width="100px" height="75px" id="handSignatureImg">
+                                </c:otherwise>
+                            </c:choose>
+                            <p id="handSignatureText"></p>
+                        </div>
+                    </div>
+                </div>
+
+
 
                 <div class="form-group layui-row">
                     <div class="form-group-label"><h2>执业资格证书</h2></div>

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

@@ -66,6 +66,32 @@
                       return false;
                   }
 
+
+                  // 👇 核心修复:正确获取证书行集合
+                  var $certificateRows = $("#certificateList tr");
+                  console.log("证书行数:", $certificateRows.length); // 这里会正确打印1(你当前有1行数据)
+
+                  // 遍历每一行证书
+                  for (var i = 0; i < $certificateRows.length; i++) {
+                      var $row = $certificateRows.eq(i); // 当前行的jQuery对象
+                      var prefix = "certificateList" + i; // 拼接ID前缀(对应你input的id:certificateList0_file等)
+
+                      // 获取对应行的证书名称(_name后缀的input)
+                      var targetValue = $("#" + prefix + "_name").val();
+                      console.log("第" + i + "行证书名称:", targetValue);
+
+                      // 你的原有校验逻辑
+                      if(targetValue === '151' || targetValue === '161' || targetValue === '181'){
+                          var handSignature = $("#handSignature").val();
+                          if(!handSignature){
+                              layer.msg("因您的资格证书需要您的手签章(个人签字章)信息,请您上传后再进行提交。", {icon:2});
+                              return false;
+                          }
+                      }
+                  }
+
+
+
                   var subbmitFlag = $("#subbmitFlag").val();
                   subbmitFlag ++;
                   $("#subbmitFlag").val(subbmitFlag)
@@ -594,6 +620,21 @@
         }
 
         function changelaborContractFileName(obj, index) {
+            console.log("进入changelaborContractFileName方法")
+            // 1. 获取元素的id属性
+            const elementId = obj.id;
+
+            // 2. 截取_之前的内容(核心逻辑)
+            // 原理:找到第一个_的索引,截取从0到该索引的字符串
+            const underscoreIndex = elementId.indexOf('_');
+            const idPrefix = underscoreIndex !== -1 ? elementId.substring(0, underscoreIndex) : elementId;
+
+            console.log("提取的id前缀:", idPrefix);
+
+            // 3. 用提取的前缀拼接name选择器,获取对应值
+            // 优化:使用模板字符串简化拼接,同时保留index参数的兼容性
+            const targetValue = $("#" + idPrefix + "_name").val();
+
             var file = obj.files[0];
             var url = null;
             if (window.createObjectURL != undefined) {
@@ -612,6 +653,28 @@
             var ext = file.name.split('.').pop().toLowerCase();
             var isImage = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext);
 
+            // 4. 新增:PDF格式判断(兼容.pdf/.PDF/.Pdf等所有大小写)
+            var isPdf = ext === 'pdf';
+
+            // 5. 【可选】PDF格式校验拦截(如果只允许PDF,可直接用这段)
+            if (idPrefix.indexOf("certificate") !== -1) {
+                if('151' === targetValue || '161' === targetValue || '181' === targetValue){
+                    if (!isPdf) {
+                        if('151' === targetValue){
+                            layer.msg("请上传一级建造师pdf格式文件", { icon: 2 });
+                        }
+                        if('161' === targetValue){
+                            layer.msg("请上传一级造价师pdf格式文件", { icon: 2 });
+                        }
+                        if('181' === targetValue){
+                            layer.msg("请上传监理师pdf格式文件", { icon: 2 });
+                        }
+                        return;
+                    }
+                }
+            }
+
+
             var spanId = $(obj).attr("id") + 'Name' + index;
             var fileStr = "";
 
@@ -1014,7 +1077,7 @@
                 </div>
 
                 <div class="form-group layui-row">
-                    <div class="form-group-label"><h2>手签章</h2></div>
+                    <div class="form-group-label"><h2>手签章<span style="color: red; font-size: 14px; font-weight: normal;">   请在白纸上签字并扫描,截取签字部分进行上传</span></h2></div>
                     <div class="layui-item nav-btns">
                         <button type="button" class="layui-btn" id="test1">上传手签章</button>
                         <div class="layui-upload-list">