Kaynağa Gözat

用户模板导入

cr 19 saat önce
ebeveyn
işleme
32f4b6fe5c

+ 0 - 2
blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/dto/UserImporterNew.java

@@ -80,6 +80,4 @@ public class UserImporterNew {
 
     private Long deptId;
 
-    private Map<String, List<String>> porjectAndContractMap=new HashMap<>();
-
 }

+ 240 - 107
blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

@@ -78,6 +78,7 @@ import org.springblade.system.user.wrapper.UserWrapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DataAccessException;
 import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.jdbc.core.BatchPreparedStatementSetter;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.SingleColumnRowMapper;
@@ -88,6 +89,9 @@ import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
@@ -2384,6 +2388,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
     }
 
     @Override
+    @Transactional
     public R importUserNew(MultipartFile file) {
         List<UserImporterNew> finalUserList = new ArrayList<>();
         List<ImportUserLog>logs=new ArrayList<>();
@@ -2403,8 +2408,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                     .build()
                     .excelExecutor()
                     .sheetList();
-
-            // 2. 遍历每个sheet处理
             for (ReadSheet sheet : allSheets) {
                 System.out.println("正在读取sheet:" + sheet.getSheetName() + "(索引:" + sheet.getSheetNo() + ")");
 
@@ -2415,8 +2418,9 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                         .headRowNumber(2)
                         .doReadSync();
 
-                // 3. 核心逻辑:收集同一用户的多个合同段,用逗号拼接
+                // 3. 核心逻辑:收集同一用户的多个项目名称+合同段,用逗号拼接
                 ExcelUserTemp currentUser = null; // 记录当前用户核心信息
+                List<String> projectNameList = new ArrayList<>(); // 收集当前用户的所有项目名称
                 List<String> contractList = new ArrayList<>(); // 收集当前用户的所有合同段
 
                 for (ExcelUserTemp row : sheetData) {
@@ -2424,24 +2428,42 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                     if (!isAllCoreFieldsNull(row)) {
                         // 先处理上一个用户(若存在)
                         if (currentUser != null) {
-                            generateSingleUserRecord(currentUser, contractList, finalUserList);
+                            generateSingleUserRecord(currentUser, projectNameList, contractList, finalUserList);
                         }
-                        // 初始化新用户信息
+                        // 初始化新用户信息+项目/合同段列表
                         currentUser = row;
+                        projectNameList = new ArrayList<>();
                         contractList = new ArrayList<>();
-                        // 收集当前行的合同段(首行可能带合同段)
-                        addValidContract(row.getContractInfo(), contractList);
+                        // 收集当前行的项目名称和合同段
+                        addValidValue(row.getProjectName(), projectNameList);
+                        addValidValue(row.getContractInfo(), contractList);
                     } else {
-                        // 当前行是“合同段补充行”(核心字段空,仅合同段有值)
+                        // 当前行是“补充行”(核心字段空,仅项目名称/合同段有值)
                         if (currentUser != null) {
-                            addValidContract(row.getContractInfo(), contractList);
+                            addValidValue(row.getProjectName(), projectNameList);
+                            addValidValue(row.getContractInfo(), contractList);
                         }
                     }
                 }
+
                 // 处理最后一个用户
                 if (currentUser != null) {
-                    generateSingleUserRecord(currentUser, contractList, finalUserList);
+                    generateSingleUserRecord(currentUser, projectNameList, contractList, finalUserList);
+                }
+            }
+            String file_path = FileUtils.getSysLocalFileUrl();
+            String filePath = file_path + "/importExcel/" + importId + ".xlsx";
+            try {
+                // 创建目录(如果不存在)
+                File directory = new File(file_path + "/importExcel/");
+                if (!directory.exists()) {
+                    directory.mkdirs();
                 }
+                // 保存文件
+                file.transferTo(new File(filePath));
+            } catch (IOException e) {
+                // 处理异常
+                throw new ServiceException("文件保存失败: " + e.getMessage());
             }
             // 5. 后续业务逻辑(批量保存等)
             if (!finalUserList.isEmpty()) {
@@ -2481,7 +2503,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                             ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),userImporterNew.getRealName()+"的账号为空",importTime,importId,importUser,file.getOriginalFilename());
                             logs.add(log);
                         }else {
-                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"账号姓名都为空",importTime,importId,importUser,file.getOriginalFilename());
+                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"账号姓名都为空",importTime,importId,importUser,filePath);
                             logs.add(log);
                         }
                         continue;
@@ -2494,7 +2516,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                          * 验证姓名
                          */
                         if(StringUtil.isEmpty(userImporterNew.getRealName())){
-                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"姓名为空",importTime,importId,importUser,file.getOriginalFilename());
+                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"姓名为空",importTime,importId,importUser,filePath);
                             logs.add(log);
                             continue;
                         }
@@ -2502,13 +2524,13 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                          * 验证手机号
                          */
                         if(StringUtil.isEmpty(userImporterNew.getPhone())){
-                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"手机号为空",importTime,importId,importUser,file.getOriginalFilename());
+                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"手机号为空",importTime,importId,importUser,filePath);
                             logs.add(log);
                             continue;
                         }else {
                             boolean b = isValidChinesePhoneNumber(userImporterNew.getPhone());
                             if(!b){
-                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"手机号格式错误",importTime,importId,importUser,file.getOriginalFilename());
+                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"手机号格式错误",importTime,importId,importUser,filePath);
                                 logs.add(log);
                                 continue;
                             }
@@ -2517,13 +2539,13 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                          * 验证身份证号
                          */
                         if(StringUtil.isEmpty(userImporterNew.getIdNumber())){
-                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"身份证号为空",importTime,importId,importUser,file.getOriginalFilename());
+                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"身份证号为空",importTime,importId,importUser,filePath);
                             logs.add(log);
                             continue;
                         }else {
                             boolean b = isValidIdCard(userImporterNew.getIdNumber());
                             if(!b){
-                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"身份证号格式错误",importTime,importId,importUser,file.getOriginalFilename());
+                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"身份证号格式错误",importTime,importId,importUser,filePath);
                                 logs.add(log);
                                 continue;
                             }
@@ -2532,7 +2554,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                          * 验证用户平台
                          */
                         if(StringUtil.isEmpty(userImporterNew.getUserType())){
-                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"用户平台为空",importTime,importId,importUser,file.getOriginalFilename());
+                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"用户平台为空",importTime,importId,importUser,filePath);
                             logs.add(log);
                             continue;
                         }else {
@@ -2549,7 +2571,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                             Set<String> allowedTypes = new HashSet<>(Arrays.asList("1", "2", "3", "7"));
                             boolean isValid = types.stream().allMatch(allowedTypes::contains);
                             if(!isValid){
-                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"用户平台格式错误",importTime,importId,importUser,file.getOriginalFilename());
+                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"用户平台格式错误",importTime,importId,importUser,filePath);
                                 logs.add(log);
                                 continue;
                             }else {
@@ -2560,13 +2582,13 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                          * 验证部门
                          */
                         if(StringUtil.isEmpty(userImporterNew.getDeptName())){
-                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属部门为空",importTime,importId,importUser,file.getOriginalFilename());
+                            ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属部门为空",importTime,importId,importUser,filePath);
                             logs.add(log);
                             continue;
                         }else {
-                            Optional<Dept> dept = deptNames.stream().filter(deptName -> !StringUtil.isEmpty(deptName) && deptName.equals(userImporterNew.getDeptName())).findFirst();
+                            Optional<Dept> dept = deptNames.stream().filter(deptName -> !StringUtil.isEmpty(deptName.getDeptName()) && deptName.getDeptName().equals(userImporterNew.getDeptName())).findFirst();
                             if(!dept.isPresent()){
-                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属部门不存在",importTime,importId,importUser,file.getOriginalFilename());
+                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属部门不存在",importTime,importId,importUser,filePath);
                                 logs.add(log);
                                 continue;
                             }else {
@@ -2579,21 +2601,30 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                              * 验证项目信息
                              */
                             if(StringUtil.isEmpty(userImporterNew.getProjectId())){
-                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属项目为空",importTime,importId,importUser,file.getOriginalFilename());
+                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属项目为空",importTime,importId,importUser,filePath);
                                 logs.add(log);
                                 continue;
                             }else {
-                                if(!projectIds.contains(userImporterNew.getProjectId())){
-                                    ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属项目Id没找到对应的项目",importTime,importId,importUser,file.getOriginalFilename());
-                                    logs.add(log);
-                                    continue;
+                                StringBuilder pid=new StringBuilder();
+                                String projectIdJoin = userImporterNew.getProjectId();
+                                String[] projectIdJoins = projectIdJoin.split(",");
+                                for (String idJoin : projectIdJoins) {
+                                    if(!projectIds.contains(idJoin)){
+                                        ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属项目Id:"+idJoin+",没找到对应的项目",importTime,importId,importUser,filePath);
+                                        logs.add(log);
+                                    }else {
+                                        pid.append(",").append(idJoin);
+                                    }
+                                }
+                                if(pid!=null&&!StringUtil.isEmpty(pid.toString())){
+                                    userImporterNew.setProjectId(pid.substring(1));
                                 }
                             }
                             /**
                              * 验证合同段
                              */
                             if(StringUtil.isEmpty(userImporterNew.getContractInfo())){
-                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"合同段名称/编号为空",importTime,importId,importUser,file.getOriginalFilename());
+                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"合同段名称/编号为空",importTime,importId,importUser,filePath);
                                 logs.add(log);
                                 continue;
                             }else {
@@ -2601,12 +2632,20 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                 String contractInfo = userImporterNew.getContractInfo();
                                 String[] contractInfoData = contractInfo.split(",");
                                 //根据名称或编号来查找
-                                List<ContractInfo> contractInfos = contractNamesMap.get(userImporterNew.getProjectId());
+                                List<ContractInfo> contractInfos=new ArrayList<>();
+                                String projectId = userImporterNew.getProjectId();
+                                String[] projectIdList = projectId.split(",");
+                                for (String id : projectIdList) {
+                                    List<ContractInfo> infos = contractNamesMap.get(id);
+                                    if(!infos.isEmpty()){
+                                        contractInfos.addAll(infos);
+                                    }
+                                }
                                 for (String info : contractInfoData) {
                                     Optional<ContractInfo> nameOptional = contractInfos.stream().filter(c -> !StringUtil.isEmpty(c.getContractName()) && c.getContractName().equals(info)).findFirst();
                                     Optional<ContractInfo> numberOptional  = contractInfos.stream().filter(c -> !StringUtil.isEmpty(c.getContractNumber()) && c.getContractNumber().equals(info)).findFirst();
                                     if(!(nameOptional.isPresent()||numberOptional.isPresent())){
-                                        ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"合同段名称/编号不存在",importTime,importId,importUser,file.getOriginalFilename());
+                                        ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"合同段名称/编号不存在:"+info,importTime,importId,importUser,filePath);
                                         logs.add(log);
                                     }else {
                                         if(nameOptional.isPresent()){
@@ -2616,19 +2655,21 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                         }
                                     }
                                 }
-                                userImporterNew.setContractId(contractId.substring(1));
+                                if(contractId.toString()!=null&&!StringUtil.isEmpty(contractId.toString())){
+                                    userImporterNew.setContractId(contractId.substring(1));
+                                }
                             }
                             /**
                              * 验证所属方
                              */
                             if(StringUtil.isEmpty(userImporterNew.getOwner())){
-                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属方为空",importTime,importId,importUser,file.getOriginalFilename());
+                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属方为空",importTime,importId,importUser,filePath);
                                 logs.add(log);
                                 continue;
                             }else {
                                 String owner = userImporterNew.getOwner();
                                 if(!(owner.equals("1")||owner.equals("2")||owner.equals("3"))){
-                                    ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属方格式错误",importTime,importId,importUser,file.getOriginalFilename());
+                                    ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属方格式错误",importTime,importId,importUser,filePath);
                                     logs.add(log);
                                     continue;
                                 }
@@ -2637,7 +2678,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                              * 验证岗位
                              */
                             if(StringUtil.isEmpty(userImporterNew.getRoleName())){
-                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"角色为空",importTime,importId,importUser,file.getOriginalFilename());
+                                ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"角色为空",importTime,importId,importUser,filePath);
                                 logs.add(log);
                             }else {
                                 List<Role> roles = roleMap.get(userImporterNew.getOwner());
@@ -2645,7 +2686,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                 if (role.isPresent()) {
                                     userImporterNew.setRoleId(role.get().getId());
                                 } else {
-                                    ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"角色不存在",importTime,importId,importUser,file.getOriginalFilename());
+                                    ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"角色不存在",importTime,importId,importUser,filePath);
                                     logs.add(log);
                                 }
                             }
@@ -2654,43 +2695,52 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                         /**
                          * 用户账号表
                          */
-                        user.setId(SnowFlakeUtil.getId());
-                        user.setTenantId(AuthUtil.getTenantId());
-                        user.setAccount(userImporterNew.getAccount());
-                        user.setUserType(userImporterNew.getUserType());
-                        user.setPassword(DigestUtil.encrypt(userImporterNew.getPassword()));
-                        user.setPlaintextPassword(userImporterNew.getPassword());
-                        user.setName(userImporterNew.getRealName());
-                        user.setRealName(userImporterNew.getRealName());
-                        user.setIdNumber(userImporterNew.getIdNumber());
-                        user.setPhone(userImporterNew.getPhone());
-                        user.setRoleId(userImporterNew.getRoleId()+"");
-                        user.setDeptId(userImporterNew.getDeptId()+"");
-                        user.setStatus("是".equals(userImporterNew.getStatus()) ? 1 : 0);
-                        user.setAccCode(userImporterNew.getAccCode());
-                        insertUserList.add(user);
+                        User insertUser=new User();
+                        insertUser.setId(SnowFlakeUtil.getId());
+                        insertUser.setTenantId(AuthUtil.getTenantId());
+                        insertUser.setAccount(userImporterNew.getAccount());
+                        insertUser.setUserType(userImporterNew.getUserType());
+                        insertUser.setPassword(DigestUtil.encrypt(userImporterNew.getPassword()));
+                        insertUser.setPlaintextPassword(userImporterNew.getPassword());
+                        insertUser.setName(userImporterNew.getRealName());
+                        insertUser.setRealName(userImporterNew.getRealName());
+                        insertUser.setIdNumber(userImporterNew.getIdNumber());
+                        insertUser.setPhone(userImporterNew.getPhone());
+                        insertUser.setRoleId(userImporterNew.getRoleId()+"");
+                        insertUser.setDeptId(userImporterNew.getDeptId()+"");
+                        insertUser.setStatus("是".equals(userImporterNew.getStatus()) ? 1 : 0);
+                        insertUser.setAccCode(userImporterNew.getAccCode());
+                        insertUserList.add(insertUser);
                         /**
                          * 用户部门表
                          */
                         UserDept userDept = new UserDept();
-                        userDept.setUserId(user.getId());
+                        userDept.setUserId(insertUser.getId());
                         userDept.setDeptId(userImporterNew.getDeptId());
                         insertUserDeptList.add(userDept);
                         /**
                          * 项目分配用户关系表
                          */
                         if(!StringUtil.isEmpty(userImporterNew.getProjectId())&&!StringUtil.isEmpty(userImporterNew.getContractId())){
+                            String projectIdList = userImporterNew.getProjectId();
+                            String[] pids = projectIdList.split(",");
                             String contractIds = userImporterNew.getContractId();
                             String[] contractList = contractIds.split(",");
-                            for (String contractId : contractList) {
-                                SaveUserInfoByProjectDTO dto = new SaveUserInfoByProjectDTO();
-                                dto.setId(SnowFlakeUtil.getId());
-                                dto.setProjectId(userImporterNew.getProjectId());
-                                dto.setContractId(contractId);
-                                dto.setRoleId(user.getRoleId());
-                                dto.setUserId(user.getId()+"");
-                                dto.setStatus(1);
-                                insertUserInfoByProjectList.add(dto);
+                            for (String pid : pids) {
+                                List<ContractInfo> contractInfos = contractNamesMap.get(pid);
+                                Set<Long> longContractIds = contractInfos.stream().map(c -> c.getId()).collect(Collectors.toSet());
+                                for (String contractId : contractList) {
+                                    if(longContractIds.contains(Long.valueOf(contractId))){
+                                        SaveUserInfoByProjectDTO dto = new SaveUserInfoByProjectDTO();
+                                        dto.setId(SnowFlakeUtil.getId());
+                                        dto.setProjectId(pid);
+                                        dto.setContractId(contractId);
+                                        dto.setRoleId(insertUser.getRoleId());
+                                        dto.setUserId(insertUser.getId()+"");
+                                        dto.setStatus(1);
+                                        insertUserInfoByProjectList.add(dto);
+                                    }
+                                }
                             }
                         }
                     }else {
@@ -2705,21 +2755,30 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                     * 验证项目信息
                                     */
                                    if(StringUtil.isEmpty(userImporterNew.getProjectId())){
-                                       ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属项目为空",importTime,importId,importUser,file.getOriginalFilename());
+                                       ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属项目为空",importTime,importId,importUser,filePath);
                                        logs.add(log);
                                        continue;
                                    }else {
-                                       if(!projectIds.contains(userImporterNew.getProjectId())){
-                                           ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属项目Id没找到对应的项目",importTime,importId,importUser,file.getOriginalFilename());
-                                           logs.add(log);
-                                           continue;
+                                       StringBuilder pid=new StringBuilder();
+                                       String projectIdJoin = userImporterNew.getProjectId();
+                                       String[] projectIdJoins = projectIdJoin.split(",");
+                                       for (String idJoin : projectIdJoins) {
+                                           if(!projectIds.contains(idJoin)){
+                                               ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属项目Id:"+idJoin+",没找到对应的项目",importTime,importId,importUser,filePath);
+                                               logs.add(log);
+                                           }else {
+                                               pid.append(",").append(idJoin);
+                                           }
+                                       }
+                                       if(pid!=null&&!StringUtil.isEmpty(pid.toString())){
+                                           userImporterNew.setProjectId(pid.substring(1));
                                        }
                                    }
                                    /**
                                     * 验证合同段
                                     */
                                    if(StringUtil.isEmpty(userImporterNew.getContractInfo())){
-                                       ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"合同段名称/编号为空",importTime,importId,importUser,file.getOriginalFilename());
+                                       ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"合同段名称/编号为空",importTime,importId,importUser,filePath);
                                        logs.add(log);
                                        continue;
                                    }else {
@@ -2727,12 +2786,20 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                        String contractInfo = userImporterNew.getContractInfo();
                                        String[] contractInfoData = contractInfo.split(",");
                                        //根据名称或编号来查找
-                                       List<ContractInfo> contractInfos = contractNamesMap.get(userImporterNew.getProjectId());
+                                       List<ContractInfo> contractInfos=new ArrayList<>();
+                                       String projectId = userImporterNew.getProjectId();
+                                       String[] projectIdList = projectId.split(",");
+                                       for (String id : projectIdList) {
+                                           List<ContractInfo> infos = contractNamesMap.get(id);
+                                           if(!infos.isEmpty()){
+                                               contractInfos.addAll(infos);
+                                           }
+                                       }
                                        for (String info : contractInfoData) {
                                            Optional<ContractInfo> nameOptional = contractInfos.stream().filter(c -> !StringUtil.isEmpty(c.getContractName()) && c.getContractName().equals(info)).findFirst();
                                            Optional<ContractInfo> numberOptional  = contractInfos.stream().filter(c -> !StringUtil.isEmpty(c.getContractNumber()) && c.getContractNumber().equals(info)).findFirst();
                                            if(!(nameOptional.isPresent()||numberOptional.isPresent())){
-                                               ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"合同段名称/编号不存在",importTime,importId,importUser,file.getOriginalFilename());
+                                               ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"合同段名称/编号不存在",importTime,importId,importUser,filePath);
                                                logs.add(log);
                                            }else {
                                                if(nameOptional.isPresent()){
@@ -2742,19 +2809,21 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                                }
                                            }
                                        }
-                                       userImporterNew.setContractId(contractId.substring(1));
+                                       if(contractId!=null&&!StringUtil.isEmpty(contractId.toString())){
+                                           userImporterNew.setContractId(contractId.substring(1));
+                                       }
                                    }
                                    /**
                                     * 验证所属方
                                     */
                                    if(StringUtil.isEmpty(userImporterNew.getOwner())){
-                                       ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属方为空",importTime,importId,importUser,file.getOriginalFilename());
+                                       ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属方为空",importTime,importId,importUser,filePath);
                                        logs.add(log);
                                        continue;
                                    }else {
                                        String owner = userImporterNew.getOwner();
                                        if(!(owner.equals("1")||owner.equals("2")||owner.equals("3"))){
-                                           ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属方格式错误",importTime,importId,importUser,file.getOriginalFilename());
+                                           ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"所属方格式错误",importTime,importId,importUser,filePath);
                                            logs.add(log);
                                            continue;
                                        }
@@ -2763,7 +2832,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                     * 验证岗位
                                     */
                                    if(StringUtil.isEmpty(userImporterNew.getRoleName())){
-                                       ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"角色为空",importTime,importId,importUser,file.getOriginalFilename());
+                                       ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"角色为空",importTime,importId,importUser,filePath);
                                        logs.add(log);
                                    }else {
                                        List<Role> roles = roleMap.get(userImporterNew.getOwner());
@@ -2771,14 +2840,14 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                        if (role.isPresent()) {
                                            userImporterNew.setRoleId(role.get().getId());
                                        } else {
-                                           ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"角色不存在",importTime,importId,importUser,file.getOriginalFilename());
+                                           ImportUserLog log=new ImportUserLog(SnowFlakeUtil.getId(),userImporterNew.getAccount(),userImporterNew.getRealName(),"角色不存在",importTime,importId,importUser,filePath);
                                            logs.add(log);
                                        }
                                    }
                                }
                                //将当前的项目以及合同段做比较
                                //查出当前用户分配的项目和合同段
-                               String sql="select * from m_project_assignment_user where user_id="+user.getId()+" and is_deleted=0 and project_id="+userImporterNew.getProjectId();
+                               String sql="select * from m_project_assignment_user where user_id="+user.getId()+" and is_deleted=0 and project_id in (" + userImporterNew.getProjectId() + ")";
                                List<SaveUserInfoByProjectDTO> projectAssignmentUsers = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(SaveUserInfoByProjectDTO.class));
                                //说明该项目是新增的
                                if(projectAssignmentUsers.isEmpty()){
@@ -2786,17 +2855,25 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                    user.setStatus("是".equals(userImporterNew.getStatus()) ? 1 : 0);
                                    updateUserList.add(user);
                                    if(!StringUtil.isEmpty(userImporterNew.getProjectId())&&!StringUtil.isEmpty(userImporterNew.getContractId())){
+                                       String projectIdList = userImporterNew.getProjectId();
+                                       String[] pids = projectIdList.split(",");
                                        String contractIds = userImporterNew.getContractId();
                                        String[] contractList = contractIds.split(",");
-                                       for (String contractId : contractList) {
-                                           SaveUserInfoByProjectDTO dto = new SaveUserInfoByProjectDTO();
-                                           dto.setId(SnowFlakeUtil.getId());
-                                           dto.setProjectId(userImporterNew.getProjectId());
-                                           dto.setContractId(contractId);
-                                           dto.setRoleId(user.getRoleId());
-                                           dto.setUserId(user.getId()+"");
-                                           dto.setStatus(1);
-                                           insertUserInfoByProjectList.add(dto);
+                                       for (String pid : pids) {
+                                           List<ContractInfo> contractInfos = contractNamesMap.get(pid);
+                                           Set<Long> longContractIds = contractInfos.stream().map(c -> c.getId()).collect(Collectors.toSet());
+                                           for (String cId : contractList) {
+                                               if(longContractIds.contains(Long.valueOf(cId))){
+                                                   SaveUserInfoByProjectDTO dto = new SaveUserInfoByProjectDTO();
+                                                   dto.setId(SnowFlakeUtil.getId());
+                                                   dto.setProjectId(userImporterNew.getProjectId());
+                                                   dto.setContractId(cId);
+                                                   dto.setRoleId(userImporterNew.getRoleId()+"");
+                                                   dto.setUserId(user.getId()+"");
+                                                   dto.setStatus(1);
+                                                   insertUserInfoByProjectList.add(dto);
+                                               }
+                                           }
                                        }
                                    }
                                }else {
@@ -2840,16 +2917,24 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                        List<String> newContractIds = processedContractIds.stream()
                                                .filter(id -> !existContractIdSet.contains(id))
                                                .collect(Collectors.toList());
-                                       if(!newContractIds.isEmpty()){
-                                           for (String cId : newContractIds) {
-                                               SaveUserInfoByProjectDTO dto = new SaveUserInfoByProjectDTO();
-                                               dto.setId(SnowFlakeUtil.getId());
-                                               dto.setProjectId(userImporterNew.getProjectId());
-                                               dto.setContractId(cId);
-                                               dto.setRoleId(user.getRoleId());
-                                               dto.setUserId(user.getId()+"");
-                                               dto.setStatus(1);
-                                               insertUserInfoByProjectList.add(dto);
+                                       if(!StringUtil.isEmpty(userImporterNew.getProjectId())&&!newContractIds.isEmpty()){
+                                           String projectIdList = userImporterNew.getProjectId();
+                                           String[] pids = projectIdList.split(",");
+                                           for (String pid : pids) {
+                                               List<ContractInfo> contractInfos = contractNamesMap.get(pid);
+                                               Set<Long> longContractIds = contractInfos.stream().map(c -> c.getId()).collect(Collectors.toSet());
+                                               for (String cId : newContractIds) {
+                                                   if(longContractIds.contains(Long.valueOf(cId))){
+                                                       SaveUserInfoByProjectDTO dto = new SaveUserInfoByProjectDTO();
+                                                       dto.setId(SnowFlakeUtil.getId());
+                                                       dto.setProjectId(pid);
+                                                       dto.setContractId(cId);
+                                                       dto.setRoleId(userImporterNew.getRoleId()+"");
+                                                       dto.setUserId(user.getId()+"");
+                                                       dto.setStatus(1);
+                                                       insertUserInfoByProjectList.add(dto);
+                                                   }
+                                               }
                                            }
                                        }
                                        // 3. 本次导入的contractIds和existContractIds相对比 相同的部分 (存在相同的情况下)
@@ -2867,9 +2952,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                                            }
                                        }
                                    }
-
                                }
-
                            }
                         }
                     }
@@ -2883,11 +2966,26 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                 if(!insertUserInfoByProjectList.isEmpty()){
                     saveUserInfoByProjectClient.insertUserInfoBatch(insertUserInfoByProjectList);
                 }
+                if(!updateUserInfoByProjectList.isEmpty()){
+                    saveUserInfoByProjectClient.updateUserInfoBatch(updateUserInfoByProjectList);
+                }
                 if(!updateUserList.isEmpty()){
+                    for (User user : updateUserList) {
+                        String sql="select role_id from m_project_assignment_user where user_id="+user.getId()+" and is_deleted=0";
+                        List<String> roleIds = jdbcTemplate.query(sql, new SingleColumnRowMapper<>(String.class));
+                        String roleId = user.getRoleId();
+                        if (!StringUtil.isEmpty(roleId)) {
+                            // 按逗号分割,去重后再重新拼接
+                            List<String> roleIdList = Arrays.asList(roleId.split(","));
+                            List<String> distinctRoleIds = roleIdList.stream().distinct().collect(Collectors.toList());
+                            roleId = String.join(",", distinctRoleIds);
+                        }
+                        user.setRoleId(roleIds.isEmpty() ? roleId : String.join(",", roleIds));
+                    }
                     this.updateBatchById(updateUserList);
                 }
-                if(!updateUserInfoByProjectList.isEmpty()){
-                    saveUserInfoByProjectClient.updateUserInfoBatch(updateUserInfoByProjectList);
+                if(!logs.isEmpty()){
+                    this.saveUserImportLogs(logs);
                 }
             }
         } catch (Exception e) {
@@ -2895,27 +2993,61 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
             return R.fail("导入失败:" + e.getMessage());
         }
 
-        return R.success("导入成功,共生成" + finalUserList.size() + "条有效记录");
+        return R.success("导入成功,共新增:" + insertUserList.size() + "条有效记录,更新:"+updateUserList.size()+"条记录,失败:"+logs.size()+"条记录");
+    }
+
+    /**
+     * 保存用户导入日志
+     * @param logs
+     */
+    private void saveUserImportLogs(List<ImportUserLog> logs) {
+        if (logs == null || logs.isEmpty()) {
+            return;
+        }
+        String sql = "INSERT INTO blade_import_user_log " +
+                "(id, account, name, message, import_time, import_id, import_user, file_path) " +
+                "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
+        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
+            @Override
+            public void setValues(PreparedStatement ps, int i) throws SQLException {
+                ImportUserLog log = logs.get(i);
+                ps.setObject(1, log.getId());            // id
+                ps.setString(2, log.getAccount());       // account
+                ps.setString(3, log.getName());          // name
+                ps.setString(4, log.getMessage());       // message
+                ps.setString(5, log.getImportTime());    // import_time
+                ps.setObject(6, log.getImportId());      // import_id
+                ps.setObject(7, log.getImportUser());    // import_user
+                ps.setString(8, log.getFilePath());      // file_path
+            }
+            @Override
+            public int getBatchSize() {
+                return logs.size();
+            }
+        });
     }
 
     /**
-     * 校验并添加有效合同段(过滤空值和纯空格)
+     * 校验并添加有效值(过滤null、空字符串、纯空格)
      */
-    private void addValidContract(String contract, List<String> contractList) {
-        if (Objects.nonNull(contract) && !contract.trim().isEmpty()) {
-            contractList.add(contract.trim());
+    private void addValidValue(String value, List<String> list) {
+        if (Objects.nonNull(value) && !value.trim().isEmpty()) {
+            list.add(value.trim());
         }
     }
 
     /**
-     * 生成单个用户记录(多个合同段用逗号拼接)
+     * 生成单个用户记录(项目名称+合同段均用逗号拼接)
      */
-    private void generateSingleUserRecord(ExcelUserTemp currentUser, List<String> contractList, List<UserImporterNew> finalList) {
+    private void generateSingleUserRecord(ExcelUserTemp currentUser, List<String> projectNameList,
+                                          List<String> contractList, List<UserImporterNew> finalList) {
         // 处理默认值
         String defaultPwd = Objects.isNull(currentUser.getPassword()) ? "user123456" : currentUser.getPassword();
         String defaultStatus = Objects.isNull(currentUser.getStatus()) ? "是" : currentUser.getStatus();
 
-        // 拼接合同段(空列表则存空字符串)
+        // 拼接项目名称(空列表存空字符串)
+        String joinedProjectName = projectNameList.isEmpty() ? "" : String.join(",", projectNameList);
+        // 拼接合同段(空列表存空字符串)
         String joinedContract = contractList.isEmpty() ? "" : String.join(",", contractList);
 
         // 构建用户记录(仅一条)
@@ -2928,16 +3060,17 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
         user.setIdNumber(currentUser.getIdNumber());
         user.setDeptName(currentUser.getDeptName());
         user.setAccCode(currentUser.getAccCode());
-        user.setProjectId(currentUser.getProjectName());
-        user.setContractInfo(joinedContract); // 逗号拼接后的合同段
+        user.setProjectId(joinedProjectName); // 拼接后的项目名称(后续需转项目id可在此处处理)
+        user.setContractInfo(joinedContract); // 拼接后的合同段
         user.setOwner(currentUser.getOwner());
         user.setRoleName(currentUser.getRoleName());
         user.setStatus(defaultStatus);
 
         finalList.add(user);
-        System.out.println("用户" + currentUser.getRealName() + "合同段:" + joinedContract);
+        System.out.println("用户" + currentUser.getRealName() + " - 项目名称:" + joinedProjectName + ",合同段:" + joinedContract);
     }
 
+
     /**
      * 判断核心字段是否全为空(识别新用户行)
      */