|
@@ -20,43 +20,28 @@ import com.nju.edu.gitlab.SeecoderGitlabApi;
|
|
|
import com.nju.edu.gitlab.SeecoderGitlabException;
|
|
import com.nju.edu.gitlab.SeecoderGitlabException;
|
|
|
import com.nju.edu.gitlab.dto.member.AccessLevelForm;
|
|
import com.nju.edu.gitlab.dto.member.AccessLevelForm;
|
|
|
import com.nju.edu.gitlab.dto.project.VisibilityForm;
|
|
import com.nju.edu.gitlab.dto.project.VisibilityForm;
|
|
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.http.HttpStatus;
|
|
import org.apache.http.HttpStatus;
|
|
|
-import org.slf4j.Logger;
|
|
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.beans.BeanUtils;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
+@Slf4j
|
|
|
@Service
|
|
@Service
|
|
|
|
|
+@RequiredArgsConstructor
|
|
|
public class ProjectServiceImpl implements ProjectService {
|
|
public class ProjectServiceImpl implements ProjectService {
|
|
|
|
|
|
|
|
private final UserService userService;
|
|
private final UserService userService;
|
|
|
-
|
|
|
|
|
private final ProjectMapper projectMapper;
|
|
private final ProjectMapper projectMapper;
|
|
|
-
|
|
|
|
|
private final ProjectRelatedMapper projectRelatedMapper;
|
|
private final ProjectRelatedMapper projectRelatedMapper;
|
|
|
-
|
|
|
|
|
private final UserMapper userMapper;
|
|
private final UserMapper userMapper;
|
|
|
-
|
|
|
|
|
private final SeecoderGitlabApi seecoderGitlabApi;
|
|
private final SeecoderGitlabApi seecoderGitlabApi;
|
|
|
-
|
|
|
|
|
private final ApplicationProperties properties;
|
|
private final ApplicationProperties properties;
|
|
|
|
|
|
|
|
- private final static Logger log = LoggerFactory.getLogger(ProjectServiceImpl.class);
|
|
|
|
|
-
|
|
|
|
|
- @Autowired
|
|
|
|
|
- public ProjectServiceImpl(UserService userService, ProjectMapper projectMapper, ProjectRelatedMapper projectRelatedMapper, UserMapper userMapper, SeecoderGitlabApi seecoderGitlabApi, ApplicationProperties properties) {
|
|
|
|
|
- this.userService = userService;
|
|
|
|
|
- this.projectMapper = projectMapper;
|
|
|
|
|
- this.projectRelatedMapper = projectRelatedMapper;
|
|
|
|
|
- this.userMapper = userMapper;
|
|
|
|
|
- this.seecoderGitlabApi = seecoderGitlabApi;
|
|
|
|
|
- this.properties = properties;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public List<ProjectVO> listProjectsByUserId() throws ServiceException {
|
|
public List<ProjectVO> listProjectsByUserId() throws ServiceException {
|
|
@@ -65,12 +50,16 @@ public class ProjectServiceImpl implements ProjectService {
|
|
|
try {
|
|
try {
|
|
|
projects = seecoderGitlabApi.getAllProjectsByUserId(userId);
|
|
projects = seecoderGitlabApi.getAllProjectsByUserId(userId);
|
|
|
|
|
|
|
|
- //同步数据,有可能gitlab那边有的项目我们这边没有
|
|
|
|
|
- List<ProjectPO> pos = projects.stream().filter(x -> projectMapper.getProjectById(x.getProjectId()) == null).map(ProjectPO::new).collect(Collectors.toList());
|
|
|
|
|
- if (pos.size() != 0) {
|
|
|
|
|
|
|
+ // 同步数据,有可能 gitlab 那边有的项目我们这边没有
|
|
|
|
|
+ List<ProjectPO> pos = projects.stream()
|
|
|
|
|
+ .filter(x -> projectMapper.getProjectById(x.getProjectId()) == null)
|
|
|
|
|
+ .map(ProjectPO::new)
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ if (!pos.isEmpty()) {
|
|
|
for (ProjectPO po : pos) {
|
|
for (ProjectPO po : pos) {
|
|
|
seecoderGitlabApi.addWebHook(po.getId(), properties.getGitlab().getWebhookProxy(), true, false, false);
|
|
seecoderGitlabApi.addWebHook(po.getId(), properties.getGitlab().getWebhookProxy(), true, false, false);
|
|
|
- log.info("项目Id是{},名称是{}",po.getId(),po.getName());
|
|
|
|
|
|
|
+ log.info("项目 ID: {}, 名称: {}", po.getId(), po.getName());
|
|
|
projectMapper.insertProject(po);
|
|
projectMapper.insertProject(po);
|
|
|
log.info("同步成功");
|
|
log.info("同步成功");
|
|
|
}
|
|
}
|
|
@@ -78,9 +67,15 @@ public class ProjectServiceImpl implements ProjectService {
|
|
|
} catch (SeecoderGitlabException e) {
|
|
} catch (SeecoderGitlabException e) {
|
|
|
throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "获取项目列表失败", e);
|
|
throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "获取项目列表失败", e);
|
|
|
}
|
|
}
|
|
|
- List<Integer> projectIds = projects.stream().map(com.nju.edu.gitlab.vo.ProjectVO::getProjectId).collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
- return projectIds.size() == 0 ? new ArrayList<>() : projectMapper.selectByIds(projectIds).stream().map(ProjectVO::new).collect(Collectors.toList());
|
|
|
|
|
|
|
+ List<Integer> projectIds = projects.stream()
|
|
|
|
|
+ .map(com.nju.edu.gitlab.vo.ProjectVO::getProjectId)
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ return projectIds.isEmpty() ? new ArrayList<>() :
|
|
|
|
|
+ projectMapper.selectByIds(projectIds).stream()
|
|
|
|
|
+ .map(ProjectVO::new)
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -93,82 +88,92 @@ public class ProjectServiceImpl implements ProjectService {
|
|
|
public ProjectVO createProject(ProjectCreateVO vo) throws ServiceException {
|
|
public ProjectVO createProject(ProjectCreateVO vo) throws ServiceException {
|
|
|
ProjectPO po = new ProjectPO();
|
|
ProjectPO po = new ProjectPO();
|
|
|
BeanUtils.copyProperties(vo, po);
|
|
BeanUtils.copyProperties(vo, po);
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
- if(vo.getVisibility()==null) vo.setVisibility("private");
|
|
|
|
|
- com.nju.edu.gitlab.vo.ProjectVO project = seecoderGitlabApi.createPrivateProject(po.getName(), vo.getVisibility().equals("public")?VisibilityForm.PUBLIC:VisibilityForm.PRIVATE, UserService.loginUser().getId());
|
|
|
|
|
- log.info("项目可见性为:{}", vo.getVisibility());
|
|
|
|
|
|
|
+ if (vo.getVisibility() == null) {
|
|
|
|
|
+ vo.setVisibility("private");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ VisibilityForm visibility = "public".equals(vo.getVisibility()) ?
|
|
|
|
|
+ VisibilityForm.PUBLIC : VisibilityForm.PRIVATE;
|
|
|
|
|
+
|
|
|
|
|
+ com.nju.edu.gitlab.vo.ProjectVO project = seecoderGitlabApi.createPrivateProject(
|
|
|
|
|
+ po.getName(), visibility, UserService.loginUser().getId());
|
|
|
|
|
+
|
|
|
|
|
+ log.info("项目可见性: {}", vo.getVisibility());
|
|
|
po.setId(project.getProjectId());
|
|
po.setId(project.getProjectId());
|
|
|
po.setGitRemoteUrl(project.getWebUrl());
|
|
po.setGitRemoteUrl(project.getWebUrl());
|
|
|
} catch (SeecoderGitlabException e) {
|
|
} catch (SeecoderGitlabException e) {
|
|
|
- e.printStackTrace();
|
|
|
|
|
|
|
+ log.error("创建项目时发生异常: project id={}, error={}", po.getId(), e.getMessage(), e);
|
|
|
throw new ServiceException("创建项目时发生异常[project id:" + po.getId() + ", " + e.getMessage() + "]", e);
|
|
throw new ServiceException("创建项目时发生异常[project id:" + po.getId() + ", " + e.getMessage() + "]", e);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
projectMapper.insertProject(po);
|
|
projectMapper.insertProject(po);
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
seecoderGitlabApi.addWebHook(po.getId(), properties.getGitlab().getWebhookProxy(), true, false, false);
|
|
seecoderGitlabApi.addWebHook(po.getId(), properties.getGitlab().getWebhookProxy(), true, false, false);
|
|
|
} catch (SeecoderGitlabException e) {
|
|
} catch (SeecoderGitlabException e) {
|
|
|
- throw new ServiceException("给项目添加webhook发生异常[project id:" + po.getId() + ", " + e.getMessage() + "]", e);
|
|
|
|
|
|
|
+ throw new ServiceException("给项目添加 webhook 发生异常[project id:" + po.getId() + ", " + e.getMessage() + "]", e);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- //ANA 日志需要打出创建项目的基础信息
|
|
|
|
|
- try{
|
|
|
|
|
- JSONObject object = new JSONObject();
|
|
|
|
|
- object.put("user_id",userService.getLoginUser().getId());
|
|
|
|
|
- object.put("project_id",po.getId());
|
|
|
|
|
- object.put("project_name",po.getName());
|
|
|
|
|
- object.put("description",po.getDescription());
|
|
|
|
|
-
|
|
|
|
|
- String data = JSONObject.toJSONString(object);
|
|
|
|
|
- LogTrackingUtil.log(data,OpType.CREATE_PROJECT);
|
|
|
|
|
- }catch (Exception e){}
|
|
|
|
|
|
|
+ // ANA 日志需要打出创建项目的基础信息
|
|
|
|
|
+ logCreateProject(po);
|
|
|
|
|
|
|
|
return new ProjectVO(po);
|
|
return new ProjectVO(po);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void logCreateProject(ProjectPO po) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ JSONObject object = new JSONObject();
|
|
|
|
|
+ object.put("user_id", userService.getLoginUser().getId());
|
|
|
|
|
+ object.put("project_id", po.getId());
|
|
|
|
|
+ object.put("project_name", po.getName());
|
|
|
|
|
+ object.put("description", po.getDescription());
|
|
|
|
|
|
|
|
|
|
+ LogTrackingUtil.log(object.toJSONString(), OpType.CREATE_PROJECT);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("记录创建项目日志失败", e);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void addMember(Integer projectId, String phone) throws ServiceException {
|
|
public void addMember(Integer projectId, String phone) throws ServiceException {
|
|
|
Integer userId = userMapper.selectIdByPhone(phone);
|
|
Integer userId = userMapper.selectIdByPhone(phone);
|
|
|
- if(userId == null){
|
|
|
|
|
|
|
+ if (userId == null) {
|
|
|
throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "该手机号不存在对应用户");
|
|
throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "该手机号不存在对应用户");
|
|
|
}
|
|
}
|
|
|
- try {
|
|
|
|
|
- seecoderGitlabApi.addAuthorization(projectId, userId, AccessLevelForm.MASTER);
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "添加项目权限失败", e);
|
|
|
|
|
- }
|
|
|
|
|
- //ANA 日志需要打出加入的成员信息
|
|
|
|
|
- try{
|
|
|
|
|
- JSONObject object = new JSONObject();
|
|
|
|
|
-
|
|
|
|
|
- object.put("project_id",projectId);
|
|
|
|
|
- object.put("user_id",userId);
|
|
|
|
|
-
|
|
|
|
|
- String data = JSONObject.toJSONString(object);
|
|
|
|
|
- LogTrackingUtil.log(data, OpType.ADD_MEMBER);
|
|
|
|
|
- }catch (Exception e){}
|
|
|
|
|
|
|
+ addMemberToProject(projectId, userId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public void addMember(Integer projectId, Integer userId) throws ServiceException {
|
|
public void addMember(Integer projectId, Integer userId) throws ServiceException {
|
|
|
-// Integer userId = userMapper.selectIdByPhone(phone);
|
|
|
|
|
- if(userId == null){
|
|
|
|
|
- throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "该手机号不存在对应用户");
|
|
|
|
|
|
|
+ if (userId == null) {
|
|
|
|
|
+ throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "用户 ID 不能为空");
|
|
|
}
|
|
}
|
|
|
|
|
+ addMemberToProject(projectId, userId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void addMemberToProject(Integer projectId, Integer userId) throws ServiceException {
|
|
|
try {
|
|
try {
|
|
|
seecoderGitlabApi.addAuthorization(projectId, userId, AccessLevelForm.MASTER);
|
|
seecoderGitlabApi.addAuthorization(projectId, userId, AccessLevelForm.MASTER);
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "添加项目权限失败", e);
|
|
throw new ServiceException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "添加项目权限失败", e);
|
|
|
}
|
|
}
|
|
|
- //ANA 日志需要打出加入的成员信息
|
|
|
|
|
- try{
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // ANA 日志需要打出加入的成员信息
|
|
|
|
|
+ logAddMember(projectId, userId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void logAddMember(Integer projectId, Integer userId) {
|
|
|
|
|
+ try {
|
|
|
JSONObject object = new JSONObject();
|
|
JSONObject object = new JSONObject();
|
|
|
- object.put("project_id",projectId);
|
|
|
|
|
- object.put("user_id",userId);
|
|
|
|
|
|
|
+ object.put("project_id", projectId);
|
|
|
|
|
+ object.put("user_id", userId);
|
|
|
|
|
|
|
|
- String data = JSONObject.toJSONString(object);
|
|
|
|
|
- LogTrackingUtil.log(data, OpType.ADD_MEMBER);
|
|
|
|
|
- }catch (Exception e){}
|
|
|
|
|
|
|
+ LogTrackingUtil.log(object.toJSONString(), OpType.ADD_MEMBER);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("记录添加成员日志失败", e);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -185,50 +190,66 @@ public class ProjectServiceImpl implements ProjectService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public String generaterelateCode(Integer projectId) {
|
|
|
|
|
|
|
+ public String generateRelateCode(Integer projectId) {
|
|
|
return ShareCodeUtil.idToCode(projectId.longValue());
|
|
return ShareCodeUtil.idToCode(projectId.longValue());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public String relateProjects(Integer projectId, String relateCode) {
|
|
public String relateProjects(Integer projectId, String relateCode) {
|
|
|
Long[] result = ShareCodeUtil.codeToId(relateCode);
|
|
Long[] result = ShareCodeUtil.codeToId(relateCode);
|
|
|
- if (System.currentTimeMillis() - result[1] > 1000 * 60 * 5) {
|
|
|
|
|
|
|
+ long timestamp = result[1];
|
|
|
|
|
+ int targetProjectId = result[0].intValue();
|
|
|
|
|
+
|
|
|
|
|
+ // 验证码有效期 5 分钟
|
|
|
|
|
+ long expireTime = 5 * 60 * 1000;
|
|
|
|
|
+ if (System.currentTimeMillis() - timestamp > expireTime) {
|
|
|
return "验证码有效时间为五分钟,已过期";
|
|
return "验证码有效时间为五分钟,已过期";
|
|
|
}
|
|
}
|
|
|
- if (projectId == result[0].intValue()) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (projectId.equals(targetProjectId)) {
|
|
|
return "不可将本项目与自身关联!";
|
|
return "不可将本项目与自身关联!";
|
|
|
}
|
|
}
|
|
|
- List<ProjectRelatedPO> projectRelatedPOS = projectRelatedMapper.isExistRelated(projectId, result[0].intValue());
|
|
|
|
|
- if (projectRelatedPOS.size() != 0) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ List<ProjectRelatedPO> projectRelatedPOS = projectRelatedMapper.isExistRelated(projectId, targetProjectId);
|
|
|
|
|
+ if (!projectRelatedPOS.isEmpty()) {
|
|
|
return "该项目已与目标项目关联过,无须重复关联";
|
|
return "该项目已与目标项目关联过,无须重复关联";
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
projectRelatedMapper.insert(ProjectRelatedPO.builder()
|
|
projectRelatedMapper.insert(ProjectRelatedPO.builder()
|
|
|
.projectIdA(projectId)
|
|
.projectIdA(projectId)
|
|
|
- .projectIdB(result[0].intValue()).build(), "id");
|
|
|
|
|
-
|
|
|
|
|
- //ANA 日志需要打出关联项目的id
|
|
|
|
|
- try{
|
|
|
|
|
- JSONObject object = new JSONObject();
|
|
|
|
|
- object.put("user_id",userService.getLoginUser().getId());
|
|
|
|
|
- object.put("projectA_id",projectId);
|
|
|
|
|
- object.put("projectB_id",result[0].intValue());
|
|
|
|
|
|
|
+ .projectIdB(targetProjectId)
|
|
|
|
|
+ .build(), "id");
|
|
|
|
|
|
|
|
- String data = JSONObject.toJSONString(object);
|
|
|
|
|
- LogTrackingUtil.log(data, OpType.RELATE_PROJECT);
|
|
|
|
|
- }catch (Exception e){}
|
|
|
|
|
|
|
+ // ANA 日志需要打出关联项目的 ID
|
|
|
|
|
+ logRelateProject(projectId, targetProjectId);
|
|
|
|
|
|
|
|
return "关联项目成功";
|
|
return "关联项目成功";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private void logRelateProject(Integer projectIdA, Integer projectIdB) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ JSONObject object = new JSONObject();
|
|
|
|
|
+ object.put("user_id", userService.getLoginUser().getId());
|
|
|
|
|
+ object.put("projectA_id", projectIdA);
|
|
|
|
|
+ object.put("projectB_id", projectIdB);
|
|
|
|
|
+
|
|
|
|
|
+ LogTrackingUtil.log(object.toJSONString(), OpType.RELATE_PROJECT);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("记录关联项目日志失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public List<ProjectVO> getRelatedProjects(Integer projectId) {
|
|
public List<ProjectVO> getRelatedProjects(Integer projectId) {
|
|
|
List<ProjectRelatedPO> projectRelatedPOS = projectRelatedMapper.selectByProjectId(projectId);
|
|
List<ProjectRelatedPO> projectRelatedPOS = projectRelatedMapper.selectByProjectId(projectId);
|
|
|
- List<Integer> projectIds = new ArrayList<>();
|
|
|
|
|
- for (ProjectRelatedPO projectRelatedPO : projectRelatedPOS) {
|
|
|
|
|
- int projectIdA = projectRelatedPO.getProjectIdA();
|
|
|
|
|
- int projectIdB = projectRelatedPO.getProjectIdB();
|
|
|
|
|
- projectIds.add(projectIdA == projectId ? projectIdB : projectIdA);
|
|
|
|
|
- }
|
|
|
|
|
- return projectIds.size() == 0 ? new ArrayList<>() : projectMapper.selectByIds(projectIds).stream().map(ProjectVO::new).collect(Collectors.toList());
|
|
|
|
|
|
|
+
|
|
|
|
|
+ List<Integer> projectIds = projectRelatedPOS.stream()
|
|
|
|
|
+ .map(po -> po.getProjectIdA().equals(projectId) ? po.getProjectIdB() : po.getProjectIdA())
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ return projectIds.isEmpty() ? new ArrayList<>() :
|
|
|
|
|
+ projectMapper.selectByIds(projectIds).stream()
|
|
|
|
|
+ .map(ProjectVO::new)
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|