Explorar el Código

优化fork流程

hushuyu hace 4 meses
padre
commit
677ec73326

+ 28 - 35
web/src/main/java/cn/seecoder/web/service/fork/impl/ForkServiceImpl.java

@@ -12,23 +12,16 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 
-import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
-import java.util.Random;
-import java.util.Set;
 
 @RequiredArgsConstructor
 @Service
 @Slf4j
 public class ForkServiceImpl implements ForkService {
-    private static final String ALPHABETS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-    private static final int FORK_NAME_SUFFIX_LEN = 6;
-    private static final int MAX_RETRY = 10;
     private final SeecoderGitlabApi gitlabApi;
     private final ProjectMapper projectMapper;
     private final ApplicationProperties properties;
-    private final Random random = new Random();
 
     @Override
     public ForkVO forkProject(ForkVO forkVO) {
@@ -55,18 +48,31 @@ public class ForkServiceImpl implements ForkService {
                 log.error("获取用户项目列表失败, userId={}", userId);
                 return null;
             }
+            // Fallback流程
+            for (com.nju.edu.gitlab.vo.ProjectVO projectVO : allProjects) {
+                if (projectVO == null || projectVO.getProjectName() == null) {
+                    continue;
+                }
+                if (Objects.equals(projectVO.getProjectName(), oldProject.getName())) {
+                    log.warn("该项目已被 fork, sourceProjectId={}, userId={}, existedProjectId={}",
+                            forkVO.getProjectId(), userId, projectVO.getProjectId());
+                    Integer existedProjectId = projectVO.getProjectId();
 
-            Set<String> existingNames = new HashSet<>();
-            for (com.nju.edu.gitlab.vo.ProjectVO project : allProjects) {
-                if (project != null && project.getProjectName() != null) {
-                    existingNames.add(project.getProjectName());
+                    // 检查 Devcloud 数据库中是否有该 fork 项目;缺失时补写。
+                    ProjectPO existedProject = projectMapper.getProjectByIdIncludeDeleted(existedProjectId);
+                    if (existedProject == null) {
+                        ProjectPO projectPO = new ProjectPO(existedProjectId,
+                                projectVO.getProjectName(),
+                                projectVO.getWebUrl(),
+                                oldProject.getDescription(),
+                                false);
+                        projectMapper.insertProject(projectPO);
+                    } else if (Boolean.TRUE.equals(existedProject.getIsDeleted())) {
+                        projectMapper.recoverProjectById(existedProjectId);
+                    }
+                    return new ForkVO(existedProjectId, projectVO.getProjectName());
                 }
             }
-            String newName = generateAvailableForkName(oldProject.getName(), existingNames);
-            if (newName == null) {
-                log.error("生成 Fork 项目名失败, baseName={}", oldProject.getName());
-                return null;
-            }
 
             // TODO 软工二没有userName与examId,这里先传null
             Integer newProjectId = gitlabApi.forkProject(forkVO.getProjectId(), userId, null, null);
@@ -75,6 +81,10 @@ public class ForkServiceImpl implements ForkService {
                 return null;
             }
             allProjects = gitlabApi.getAllProjectsByUserId(userId);
+            if (allProjects == null) {
+                log.error("Fork 后获取用户项目列表失败, sourceProjectId={}, userId={}", forkVO.getProjectId(), userId);
+                return null;
+            }
             // 拿 Fork 出来的项目的对象,主要是要拿到它的 Web URL
             com.nju.edu.gitlab.vo.ProjectVO newProject = allProjects.stream()
                     .filter(Objects::nonNull)
@@ -89,7 +99,7 @@ public class ForkServiceImpl implements ForkService {
             // 向 Devcloud 数据库中插入新项目的 PO
             // 添加 Gitlab Web Hook 回调
             ProjectPO projectPO = new ProjectPO(newProjectId,
-                    newProject.getProjectName() == null ? newName : newProject.getProjectName(),
+                    newProject.getProjectName(),
                     newProject.getWebUrl(),
                     oldProject.getDescription(),
                     false);
@@ -99,27 +109,10 @@ public class ForkServiceImpl implements ForkService {
                     true,
                     false,
                     false);
-            return new ForkVO(newProjectId, newName);
+            return new ForkVO(newProjectId, newProject.getProjectName());
         } catch (Exception e) {
             log.error("Fork API failed, projectId={}, userId={}, exceptionType={}",
                     forkVO.getProjectId(), userId, e.getClass().getName(), e);
-            return null;
-        }
-    }
-
-    private String generateAvailableForkName(String baseName, Set<String> existingNames) {
-        if (baseName == null || baseName.isEmpty()) {
-            return null;
-        }
-        for (int i = 0; i < MAX_RETRY; i++) {
-            StringBuilder sb = new StringBuilder(baseName).append('-');
-            for (int j = 0; j < FORK_NAME_SUFFIX_LEN; ++j) {
-                sb.append(ALPHABETS.charAt(random.nextInt(ALPHABETS.length())));
-            }
-            String candidate = sb.toString();
-            if (!existingNames.contains(candidate)) {
-                return candidate;
-            }
         }
         return null;
     }

+ 1 - 0
web/src/main/java/cn/seecoder/web/service/impl/project/ProjectServiceImpl.java

@@ -185,6 +185,7 @@ public class ProjectServiceImpl implements ProjectService {
             throw new ServiceException(HttpStatus.SC_NOT_FOUND, "项目不存在");
         }
         try {
+            seecoderGitlabApi.deleteProject(projectId);
             projectMapper.deleteProjectById(projectId);
         } catch (Exception e) {
             throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "删除项目失败", e);