mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 03:48:05 +08:00
feat(project): 重构 通过私人令牌导入仓库
This commit is contained in:
parent
3618d8e188
commit
bf4ecb3499
@ -24,7 +24,6 @@ package io.jpom.controller.build;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.lang.Tuple;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@ -32,15 +31,13 @@ import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.hutool.db.Page;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import io.jpom.build.BuildUtil;
|
||||
import io.jpom.common.BaseServerController;
|
||||
import io.jpom.common.JsonMessage;
|
||||
import io.jpom.common.ServerConst;
|
||||
import io.jpom.common.validator.ValidatorItem;
|
||||
import io.jpom.controller.build.repository.*;
|
||||
import io.jpom.controller.build.repository.ImportRepoUtil;
|
||||
import io.jpom.model.data.RepositoryModel;
|
||||
import io.jpom.model.enums.GitProtocolEnum;
|
||||
import io.jpom.permission.ClassFeature;
|
||||
@ -50,7 +47,6 @@ import io.jpom.plugin.IPlugin;
|
||||
import io.jpom.plugin.PluginFactory;
|
||||
import io.jpom.service.dblog.BuildInfoService;
|
||||
import io.jpom.service.dblog.RepositoryService;
|
||||
import io.jpom.system.JpomRuntimeException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
@ -197,6 +193,13 @@ public class RepositoryController extends BaseServerController {
|
||||
return new JsonMessage<>(200, "操作成功");
|
||||
}
|
||||
|
||||
@GetMapping(value = "/build/repository/provider_info")
|
||||
@Feature(method = MethodFeature.LIST)
|
||||
public JsonMessage<Map<String, Map<String, Object>>> providerInfo() {
|
||||
Map<String, Map<String, Object>> providerList = ImportRepoUtil.getProviderList();
|
||||
return JsonMessage.success(HttpStatus.OK.name(), providerList);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/build/repository/authorize_repos")
|
||||
@Feature(method = MethodFeature.LIST)
|
||||
public JsonMessage<PageResultDto<JSONObject>> authorizeRepos(HttpServletRequest request,
|
||||
@ -208,258 +211,25 @@ public class RepositoryController extends BaseServerController {
|
||||
Map<String, String> paramMap = ServletUtil.getParamMap(request);
|
||||
Page page = repositoryService.parsePage(paramMap);
|
||||
Assert.hasText(token, "请填写个人令牌");
|
||||
//String gitlabAddress = StrUtil.blankToDefault(paramMap.get("gitlabAddress"), "https://gitlab.com");
|
||||
//String giteaAddress = paramMap.get("giteaAddress");
|
||||
// 搜索条件
|
||||
// 远程仓库
|
||||
PageResultDto<JSONObject> pageResultDto;
|
||||
switch (type) {
|
||||
case "gitee":
|
||||
pageResultDto = this.giteeRepos(token, page, condition, request);
|
||||
break;
|
||||
case "github":
|
||||
// GitHub 不支持条件搜索
|
||||
pageResultDto = this.githubRepos(token, page, request);
|
||||
break;
|
||||
case "gitlab":
|
||||
pageResultDto = this.gitlabRepos(token, page, condition, address, request);
|
||||
break;
|
||||
case "gitea":
|
||||
pageResultDto = this.giteaRepos(token, page, condition, address, request);
|
||||
break;
|
||||
case "gogs":
|
||||
pageResultDto = this.gogsRepos(token, page, condition, address, request);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("不支持的类型");
|
||||
}
|
||||
ImportRepoUtil.getProviderConfig(type);
|
||||
|
||||
String userName = ImportRepoUtil.getCurrentUserName(type, token, address);
|
||||
cn.hutool.json.JSONObject repoList = ImportRepoUtil.getRepoList(type, condition, page, token, userName, address);
|
||||
pageResultDto = new PageResultDto<>(page.getPageNumber(), page.getPageSize(), repoList.getLong("total").intValue());
|
||||
List<JSONObject> objects = repoList.getJSONArray("data").stream().map(o -> {
|
||||
cn.hutool.json.JSONObject obj = (cn.hutool.json.JSONObject) o;
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.putAll(obj);
|
||||
jsonObject.put("exists", RepositoryController.this.checkRepositoryUrl(obj.getStr("url"), request));
|
||||
return jsonObject;
|
||||
}).collect(Collectors.toList());
|
||||
pageResultDto.setResult(objects);
|
||||
return JsonMessage.success(HttpStatus.OK.name(), pageResultDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* gitlab 仓库
|
||||
* <p>
|
||||
* <a href="https://docs.gitlab.com/ee/api/projects.html#list-all-projects">https://docs.gitlab.com/ee/api/projects.html#list-all-projects</a>
|
||||
*
|
||||
* @param token 个人令牌
|
||||
* @param page 分页
|
||||
* @param gitlabAddress gitLab 地址
|
||||
* @return page
|
||||
*/
|
||||
private PageResultDto<JSONObject> gitlabRepos(String token, Page page, String condition, String gitlabAddress, HttpServletRequest request) {
|
||||
gitlabAddress = StrUtil.blankToDefault(gitlabAddress, "https://gitlab.com");
|
||||
// 删除最后的 /
|
||||
if (gitlabAddress.endsWith("/")) {
|
||||
gitlabAddress = gitlabAddress.substring(0, gitlabAddress.length() - 1);
|
||||
}
|
||||
|
||||
// 内部自建 GitLab,一般都没有配置 https 协议,如果用户没有指定协议,默认走 http,gitlab 走 https
|
||||
// https 访问不了的情况下自动替换为 http
|
||||
if (!StrUtil.startWithAnyIgnoreCase(gitlabAddress, "http://", "https://")) {
|
||||
gitlabAddress = "http://" + gitlabAddress;
|
||||
}
|
||||
|
||||
HttpResponse userResponse = null;
|
||||
try {
|
||||
userResponse = GitLabUtil.getGitLabUserInfo(gitlabAddress, token);
|
||||
} catch (IORuntimeException ioRuntimeException) {
|
||||
// 连接超时,切换至 http 协议进行重试
|
||||
if (StrUtil.startWithIgnoreCase(gitlabAddress, "https")) {
|
||||
gitlabAddress = "http" + gitlabAddress.substring(5);
|
||||
userResponse = GitLabUtil.getGitLabUserInfo(gitlabAddress, token);
|
||||
}
|
||||
Assert.state(userResponse != null, "无法连接至 GitLab:" + ioRuntimeException.getMessage());
|
||||
}
|
||||
|
||||
Assert.state(userResponse.isOk(), "令牌不正确:" + userResponse.body());
|
||||
JSONObject userBody = JSONObject.parseObject(userResponse.body());
|
||||
String username = userBody.getString("username");
|
||||
|
||||
Map<String, Object> gitLabRepos = GitLabUtil.getGitLabRepos(gitlabAddress, token, page, condition);
|
||||
|
||||
JSONArray jsonArray = JSONArray.parseArray((String) gitLabRepos.get("body"));
|
||||
List<JSONObject> objects = jsonArray.stream().map(o -> {
|
||||
JSONObject repo = (JSONObject) o;
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", repo.getString("name"));
|
||||
String htmlUrl = repo.getString("http_url_to_repo");
|
||||
jsonObject.put("url", htmlUrl);
|
||||
jsonObject.put("full_name", repo.getString("path_with_namespace"));
|
||||
// visibility 有三种:public, internal, or private.(非 public,都是 private)
|
||||
jsonObject.put("private", !StrUtil.equalsIgnoreCase("public", repo.getString("visibility")));
|
||||
jsonObject.put("description", repo.getString("description"));
|
||||
jsonObject.put("username", username);
|
||||
jsonObject.put("exists", RepositoryController.this.checkRepositoryUrl(htmlUrl, request));
|
||||
return jsonObject;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
PageResultDto<JSONObject> pageResultDto = new PageResultDto<>(page.getPageNumber(), page.getPageSize(), (int) gitLabRepos.get("total"));
|
||||
pageResultDto.setResult(objects);
|
||||
return pageResultDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* github 仓库
|
||||
*
|
||||
* @param token 个人令牌
|
||||
* @param page 分页
|
||||
* @return page
|
||||
*/
|
||||
private PageResultDto<JSONObject> githubRepos(String token, Page page, HttpServletRequest request) {
|
||||
GitHubUtil.GitHubUserInfo gitHubUserInfo = GitHubUtil.getGitHubUserInfo(token);
|
||||
JSONArray gitHubUserReposArray = GitHubUtil.getGitHubUserRepos(token, page);
|
||||
|
||||
List<JSONObject> objects = gitHubUserReposArray.stream().map(o -> {
|
||||
JSONObject repo = (JSONObject) o;
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", repo.getString("name"));
|
||||
String cloneUrl = repo.getString("clone_url");
|
||||
jsonObject.put("url", cloneUrl);
|
||||
jsonObject.put("full_name", repo.getString("full_name"));
|
||||
jsonObject.put("description", repo.getString("description"));
|
||||
jsonObject.put("private", repo.getBooleanValue("private"));
|
||||
//
|
||||
jsonObject.put("username", gitHubUserInfo.getLogin());
|
||||
jsonObject.put("exists", RepositoryController.this.checkRepositoryUrl(cloneUrl, request));
|
||||
return jsonObject;
|
||||
}).collect(Collectors.toList());
|
||||
//
|
||||
PageResultDto<JSONObject> pageResultDto = new PageResultDto<>(page.getPageNumber(), page.getPageSize(), gitHubUserInfo.public_repos);
|
||||
pageResultDto.setResult(objects);
|
||||
return pageResultDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* gitee 仓库
|
||||
*
|
||||
* @param token 个人令牌
|
||||
* @param page 分页
|
||||
* @return page
|
||||
*/
|
||||
private PageResultDto<JSONObject> giteeRepos(String token, Page page, String condition, HttpServletRequest request) {
|
||||
String giteeUsername = GiteeUtil.getGiteeUsername(token);
|
||||
|
||||
Map<String, Object> giteeReposMap = GiteeUtil.getGiteeRepos(token, page, condition);
|
||||
JSONArray jsonArray = (JSONArray) giteeReposMap.get("jsonArray");
|
||||
int totalCount = (int) giteeReposMap.get("totalCount");
|
||||
|
||||
List<JSONObject> objects = jsonArray.stream().map(o -> {
|
||||
JSONObject repo = (JSONObject) o;
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
// 项目名称,如:Jpom
|
||||
jsonObject.put("name", repo.getString("name"));
|
||||
|
||||
// 项目地址,如:https://gitee.com/dromara/Jpom.git
|
||||
String htmlUrl = repo.getString("html_url");
|
||||
jsonObject.put("url", htmlUrl);
|
||||
|
||||
// 所属者/项目名,如:dromara/Jpom
|
||||
jsonObject.put("full_name", repo.getString("full_name"));
|
||||
|
||||
// 是否为私有仓库,是私有仓库为 true,非私有仓库为 false
|
||||
jsonObject.put("private", repo.getBooleanValue("private"));
|
||||
|
||||
// 项目描述,如:简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件
|
||||
jsonObject.put("description", repo.getString("description"));
|
||||
|
||||
jsonObject.put("username", giteeUsername);
|
||||
jsonObject.put("exists", this.checkRepositoryUrl(htmlUrl, request));
|
||||
return jsonObject;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
PageResultDto<JSONObject> pageResultDto = new PageResultDto<>(page.getPageNumber(), page.getPageSize(), totalCount);
|
||||
pageResultDto.setResult(objects);
|
||||
return pageResultDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* gogo仓库
|
||||
*
|
||||
* @param token 个人令牌
|
||||
* @param page 分页
|
||||
* @return page
|
||||
*/
|
||||
private PageResultDto<JSONObject> gogsRepos(String token, Page page, String condition, String giteaAddress, HttpServletRequest request) {
|
||||
Assert.hasText(giteaAddress, "请填写 gogs 地址");
|
||||
String gogsUsername = GogsUtil.getUsername(giteaAddress, token);
|
||||
|
||||
Map<String, Object> giteaReposMap = GiteaUtil.getRepos(giteaAddress, token, page, condition);
|
||||
JSONArray jsonArray = (JSONArray) giteaReposMap.get("jsonArray");
|
||||
int totalCount = (int) giteaReposMap.get("totalCount");
|
||||
|
||||
List<JSONObject> objects = jsonArray.stream().map(o -> {
|
||||
JSONObject repo = (JSONObject) o;
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
// 项目名称,如:Jpom
|
||||
jsonObject.put("name", repo.getString("name"));
|
||||
|
||||
// 项目地址,如:https://10.0.0.1:3000/dromara/Jpom.git
|
||||
String htmlUrl = repo.getString("html_url");
|
||||
jsonObject.put("url", htmlUrl);
|
||||
|
||||
// 所属者/项目名,如:dromara/Jpom
|
||||
jsonObject.put("full_name", repo.getString("full_name"));
|
||||
|
||||
// 是否为私有仓库,是私有仓库为 true,非私有仓库为 false
|
||||
jsonObject.put("private", repo.getBooleanValue("private"));
|
||||
|
||||
// 项目描述,如:简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件
|
||||
jsonObject.put("description", repo.getString("description"));
|
||||
|
||||
jsonObject.put("username", gogsUsername);
|
||||
jsonObject.put("exists", this.checkRepositoryUrl(htmlUrl, request));
|
||||
return jsonObject;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
PageResultDto<JSONObject> pageResultDto = new PageResultDto<>(page.getPageNumber(), page.getPageSize(), totalCount);
|
||||
pageResultDto.setResult(objects);
|
||||
return pageResultDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* gitea仓库
|
||||
*
|
||||
* @param token 个人令牌
|
||||
* @param page 分页
|
||||
* @return page
|
||||
*/
|
||||
private PageResultDto<JSONObject> giteaRepos(String token, Page page, String condition, String giteaAddress, HttpServletRequest request) {
|
||||
Assert.hasText(giteaAddress, "请填写 gitea 地址");
|
||||
String giteaUsername = GiteaUtil.getUsername(giteaAddress, token);
|
||||
|
||||
Map<String, Object> giteaReposMap = GiteaUtil.getRepos(giteaAddress, token, page, condition);
|
||||
JSONArray jsonArray = (JSONArray) giteaReposMap.get("jsonArray");
|
||||
int totalCount = (int) giteaReposMap.get("totalCount");
|
||||
|
||||
List<JSONObject> objects = jsonArray.stream().map(o -> {
|
||||
JSONObject repo = (JSONObject) o;
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
// 项目名称,如:Jpom
|
||||
jsonObject.put("name", repo.getString("name"));
|
||||
|
||||
// 项目地址,如:https://10.0.0.1:3000/dromara/Jpom.git
|
||||
String htmlUrl = repo.getString("html_url");
|
||||
jsonObject.put("url", htmlUrl);
|
||||
|
||||
// 所属者/项目名,如:dromara/Jpom
|
||||
jsonObject.put("full_name", repo.getString("full_name"));
|
||||
|
||||
// 是否为私有仓库,是私有仓库为 true,非私有仓库为 false
|
||||
jsonObject.put("private", repo.getBooleanValue("private"));
|
||||
|
||||
// 项目描述,如:简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件
|
||||
jsonObject.put("description", repo.getString("description"));
|
||||
|
||||
jsonObject.put("username", giteaUsername);
|
||||
jsonObject.put("exists", this.checkRepositoryUrl(htmlUrl, request));
|
||||
return jsonObject;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
PageResultDto<JSONObject> pageResultDto = new PageResultDto<>(page.getPageNumber(), page.getPageSize(), totalCount);
|
||||
pageResultDto.setResult(objects);
|
||||
return pageResultDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查信息
|
||||
*
|
||||
|
@ -1,125 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Code Technology Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.controller.build.repository;
|
||||
|
||||
import cn.hutool.db.Page;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.Data;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* GitHub 工具
|
||||
*
|
||||
* @author sam
|
||||
* @since 2023/3/9
|
||||
*/
|
||||
public class GitHubUtil {
|
||||
/**
|
||||
* GitHub 用户信息实体类
|
||||
* <p>
|
||||
* 参考:https://docs.github.com/en/rest/users/users#about-the-users-api
|
||||
*/
|
||||
@Data
|
||||
public static class GitHubUserInfo {
|
||||
// 只列出目前需要用到的字段
|
||||
|
||||
/**
|
||||
* 用户名,如:octocat
|
||||
*/
|
||||
private String login;
|
||||
|
||||
/**
|
||||
* 公开仓库数量,如:2
|
||||
*/
|
||||
public int public_repos;
|
||||
|
||||
/**
|
||||
* 私有的仓库总数,如:100
|
||||
*/
|
||||
public int total_private_repos;
|
||||
|
||||
/**
|
||||
* 拥有的私有仓库,如:100
|
||||
*/
|
||||
public int owned_private_repos;
|
||||
}
|
||||
|
||||
/**
|
||||
* GitHub 头部
|
||||
*/
|
||||
private static final String GITHUB_HEADER_ACCEPT = "application/vnd.github.v3+json";
|
||||
|
||||
/**
|
||||
* GitHub 用户 token 前缀
|
||||
*/
|
||||
private static final String GITHUB_TOKEN = "token ";
|
||||
|
||||
/**
|
||||
* GitHub API 前缀
|
||||
*/
|
||||
private static final String GITHUB_API_PREFIX = "https://api.github.com";
|
||||
|
||||
/**
|
||||
* 获取 GitHub 用户信息
|
||||
*
|
||||
* @param token 用户 token
|
||||
* @return GitHub 用户信息
|
||||
*/
|
||||
public static GitHubUserInfo getGitHubUserInfo(String token) {
|
||||
// 参考:https://docs.github.com/en/rest/users/users#about-the-users-api
|
||||
HttpResponse response = HttpUtil
|
||||
.createGet(GITHUB_API_PREFIX + "/user")
|
||||
.header(Header.ACCEPT, GITHUB_HEADER_ACCEPT)
|
||||
.header(Header.AUTHORIZATION, GITHUB_TOKEN + token)
|
||||
.execute();
|
||||
String body = response.body();
|
||||
Assert.state(response.isOk(), "令牌信息错误:" + body);
|
||||
return JSONObject.parseObject(body, GitHubUserInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 GitHub 仓库信息
|
||||
*
|
||||
* @param token
|
||||
*/
|
||||
public static JSONArray getGitHubUserRepos(String token, Page page) {
|
||||
// 参考:https://docs.github.com/en/rest/repos/repos#list-repositories-for-the-authenticated-user
|
||||
HttpResponse response = HttpUtil
|
||||
.createGet(GITHUB_API_PREFIX + "/user/repos")
|
||||
.header(Header.ACCEPT, GITHUB_HEADER_ACCEPT)
|
||||
.header(Header.AUTHORIZATION, GITHUB_TOKEN + token)
|
||||
.form("access_token", token)
|
||||
.form("sort", "pushed")
|
||||
.form("page", page.getPageNumber())
|
||||
.form("per_page", page.getPageSize())
|
||||
.execute();
|
||||
String body = response.body();
|
||||
Assert.state(response.isOk(), "拉取仓库信息错误:" + body);
|
||||
return JSONArray.parseArray(body);
|
||||
}
|
||||
|
||||
}
|
@ -1,193 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Code Technology Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.controller.build.repository;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.db.Page;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import lombok.Data;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* GitLab 工具
|
||||
*
|
||||
* @author sam
|
||||
* @since 2023/3/9
|
||||
*/
|
||||
public class GitLabUtil {
|
||||
/**
|
||||
* GitLab 版本号信息,参考:https://docs.gitlab.com/ee/api/version.html
|
||||
*/
|
||||
@Data
|
||||
private static class GitLabVersionInfo {
|
||||
|
||||
/**
|
||||
* 版本号,如:8.13.0-pre
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* 修订号,如:4e963fe
|
||||
*/
|
||||
private String revision;
|
||||
|
||||
/**
|
||||
* API 版本号,如:v4
|
||||
*/
|
||||
private String apiVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* GitLab 版本信息容器,key:GitLab 地址,value:GitLabVersionInfo
|
||||
*/
|
||||
public static final Map<String, GitLabVersionInfo> gitlabVersionMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 获取 GitLab 版本
|
||||
*
|
||||
* @param gitlabAddress GitLab 地址
|
||||
* @param token 用户 token
|
||||
* @return 请求结果
|
||||
*/
|
||||
public static HttpResponse getGitLabVersion(String gitlabAddress, String token, String apiVersion) {
|
||||
// 参考:https://docs.gitlab.com/ee/api/version.html
|
||||
return HttpUtil.createGet(StrUtil.format("{}/api/{}/version", gitlabAddress, apiVersion), true)
|
||||
.header("PRIVATE-TOKEN", token)
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 GitLab 版本信息
|
||||
*
|
||||
* @param url GitLab 地址
|
||||
* @param token 用户 token
|
||||
*/
|
||||
public static GitLabVersionInfo getGitLabVersionInfo(String url, String token) {
|
||||
// 缓存中有的话,从缓存读取
|
||||
GitLabVersionInfo gitLabVersionInfo = gitlabVersionMap.get(url);
|
||||
if (gitLabVersionInfo != null) {
|
||||
return gitLabVersionInfo;
|
||||
}
|
||||
|
||||
// 获取 GitLab 版本号信息
|
||||
GitLabVersionInfo glvi = null;
|
||||
String apiVersion = "v4";
|
||||
HttpResponse v4 = getGitLabVersion(url, token, apiVersion);
|
||||
if (v4 != null) {
|
||||
glvi = JSON.parseObject(v4.body(), GitLabVersionInfo.class);
|
||||
} else {
|
||||
apiVersion = "v3";
|
||||
HttpResponse v3 = getGitLabVersion(url, token, apiVersion);
|
||||
if (v3 != null) {
|
||||
glvi = JSON.parseObject(v3.body(), GitLabVersionInfo.class);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.state(glvi != null, "获取 GitLab 版本号失败,请检查 GitLab 地址和 token 是否正确");
|
||||
|
||||
// 添加到缓存中
|
||||
glvi.setApiVersion(apiVersion);
|
||||
gitlabVersionMap.put(url, glvi);
|
||||
|
||||
return glvi;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 GitLab API 版本号
|
||||
*
|
||||
* @param url GitLab 地址
|
||||
* @param token 用户 token
|
||||
* @return GitLab API 版本号,如:v4
|
||||
*/
|
||||
public static String getGitLabApiVersion(String url, String token) {
|
||||
return getGitLabVersionInfo(url, token).getApiVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 GitLab 用户信息
|
||||
*
|
||||
* @param gitlabAddress GitLab 地址
|
||||
* @param token 用户 token
|
||||
* @return 请求结果
|
||||
*/
|
||||
public static HttpResponse getGitLabUserInfo(String gitlabAddress, String token) {
|
||||
// 参考:https://docs.gitlab.com/ee/api/users.html
|
||||
return HttpUtil.createGet(
|
||||
StrUtil.format(
|
||||
"{}/api/{}/user",
|
||||
gitlabAddress,
|
||||
getGitLabApiVersion(gitlabAddress, token)
|
||||
), true
|
||||
)
|
||||
.form("access_token", token)
|
||||
.timeout(5000)
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 GitLab 仓库信息
|
||||
*
|
||||
* @param gitlabAddress GitLab 地址
|
||||
* @param token 用户 token
|
||||
* @return 响应结果
|
||||
*/
|
||||
public static Map<String, Object> getGitLabRepos(String gitlabAddress, String token, Page page, String condition) {
|
||||
// 参考:https://docs.gitlab.com/ee/api/projects.html
|
||||
HttpResponse reposResponse = HttpUtil.createGet(
|
||||
StrUtil.format(
|
||||
"{}/api/{}/projects",
|
||||
gitlabAddress,
|
||||
getGitLabApiVersion(gitlabAddress, token)
|
||||
), true
|
||||
)
|
||||
.form("private_token", token)
|
||||
.form("membership", true)
|
||||
// 当 simple=true 时,不返回项目的 visibility,无法判断是私有仓库、公开仓库还是内部仓库
|
||||
// .form("simple", true)
|
||||
.form("order_by", "updated_at")
|
||||
.form("page", page.getPageNumber())
|
||||
.form("per_page", page.getPageSize())
|
||||
.form("search", condition)
|
||||
.execute();
|
||||
|
||||
String body = reposResponse.body();
|
||||
Assert.state(reposResponse.isOk(), "拉取仓库信息错误:" + body);
|
||||
|
||||
String totalCountStr = reposResponse.header("X-Total");
|
||||
int totalCount = Convert.toInt(totalCountStr, 0);
|
||||
//String totalPage = reposResponse.header("total_page");
|
||||
|
||||
Map<String, Object> map = new HashMap<>(2);
|
||||
map.put("body", body);
|
||||
map.put("total", totalCount);
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Code Technology Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.controller.build.repository;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.db.Page;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Gitea 工具
|
||||
*
|
||||
* @author songxinqiang
|
||||
* @since 2023/3/9
|
||||
*/
|
||||
public class GiteaUtil {
|
||||
|
||||
/**
|
||||
* Gitea API 版本号
|
||||
*/
|
||||
private static final String API_VERSION = "v1";
|
||||
|
||||
/**
|
||||
* 用户授权码
|
||||
*/
|
||||
private static final String ACCESS_TOKEN = "access_token";
|
||||
|
||||
/**
|
||||
* 排序方式: 创建时间(created),更新时间(updated),最后推送时间(pushed),仓库所属与名称(full_name)。默认: full_name
|
||||
*/
|
||||
private static final String SORT = "sort";
|
||||
|
||||
/**
|
||||
* 当前的页码
|
||||
*/
|
||||
private static final String PAGE = "page";
|
||||
|
||||
/**
|
||||
* 每页的数量,最大为 100
|
||||
*/
|
||||
private static final String LIMIT = "limit";
|
||||
|
||||
/**
|
||||
* 获取 Gitea 用户名
|
||||
*
|
||||
* @param token 用户授权码
|
||||
* @return Gitea 用户名
|
||||
*/
|
||||
public static String getUsername(String giteaAddress, String token) {
|
||||
HttpResponse userResponse = HttpUtil.createGet(giteaAddress + "/api/v1/user", true)
|
||||
.form(ACCESS_TOKEN, token)
|
||||
.execute();
|
||||
Assert.state(userResponse.isOk(), "令牌不正确:" + userResponse.body());
|
||||
JSONObject userBody = JSONObject.parseObject(userResponse.body());
|
||||
return userBody.getString("login");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Gitea 用户仓库信息
|
||||
*
|
||||
* @param giteaAddress Gitea 地址
|
||||
* @param token 用户授权码
|
||||
* @param page 分页参数
|
||||
* @return map
|
||||
*/
|
||||
public static Map<String, Object> getRepos(String giteaAddress, String token, Page page, String condition) {
|
||||
if (condition == null) {
|
||||
HttpResponse reposResponse = HttpUtil.createGet(giteaAddress + "/api/v1/user/repos", true)
|
||||
.form(ACCESS_TOKEN, token)
|
||||
//.form(SORT, "newest")
|
||||
.form(PAGE, page.getPageNumber())
|
||||
.form(LIMIT, page.getPageSize())
|
||||
// 搜索关键字
|
||||
//.form("q", condition)
|
||||
.execute();
|
||||
String body = reposResponse.body();
|
||||
Assert.state(reposResponse.isOk(), "获取仓库信息错误:" + body);
|
||||
// 所有仓库总数,包括公开的和私有的
|
||||
String totalCountStr = reposResponse.header("x-total-count");
|
||||
int totalCount = Convert.toInt(totalCountStr, 0);
|
||||
//String totalPage = reposResponse.header("total_page");
|
||||
|
||||
Map<String, Object> map = new HashMap<>(2);
|
||||
map.put("jsonArray", JSONArray.parseArray(body));
|
||||
// 仓库总数
|
||||
map.put("totalCount", totalCount);
|
||||
return map;
|
||||
} else {
|
||||
return getGiteaReposSearch(giteaAddress, token, page, condition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Gitea 用户仓库信息搜索
|
||||
*
|
||||
* @param giteaAddress Gitea 地址
|
||||
* @param token 用户授权码
|
||||
* @param page 分页参数
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, Object> getGiteaReposSearch(String giteaAddress, String token, Page page, String condition) {
|
||||
HttpResponse reposResponse = HttpUtil.createGet(giteaAddress + "/api/v1/repos/search", true)
|
||||
.form(ACCESS_TOKEN, token)
|
||||
.form(SORT, "created")
|
||||
.form(PAGE, page.getPageNumber())
|
||||
.form(LIMIT, page.getPageSize())
|
||||
// 搜索关键字
|
||||
.form("q", condition)
|
||||
.execute();
|
||||
String body = reposResponse.body();
|
||||
JSONObject jsonObject = JSON.parseObject(body);
|
||||
JSONArray data = jsonObject.getJSONArray("data");
|
||||
Assert.state(reposResponse.isOk(), "获取仓库信息错误:" + data.toString());
|
||||
// 所有仓库总数,包括公开的和私有的
|
||||
String totalCountStr = reposResponse.header("x-total-count");
|
||||
int totalCount = Convert.toInt(totalCountStr, 0);
|
||||
|
||||
Map<String, Object> map = new HashMap<>(2);
|
||||
map.put("jsonArray", JSONArray.parseArray(data.toString()));
|
||||
// 仓库总数
|
||||
map.put("totalCount", totalCount);
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Code Technology Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.controller.build.repository;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.db.Page;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Gitee 工具
|
||||
*
|
||||
* @author sam
|
||||
* @since 2023/3/9
|
||||
*/
|
||||
public class GiteeUtil {
|
||||
|
||||
/**
|
||||
* Gitee API 前缀
|
||||
*/
|
||||
private static final String GITEE_API_PREFIX = "https://gitee.com/api";
|
||||
|
||||
/**
|
||||
* Gitee API 版本号
|
||||
*/
|
||||
private static final String API_VERSION = "v5";
|
||||
|
||||
/**
|
||||
* Gitee API 地址前缀
|
||||
*/
|
||||
private static final String GITEE_API_URL_PREFIX = GITEE_API_PREFIX + "/" + API_VERSION;
|
||||
|
||||
/**
|
||||
* 用户授权码
|
||||
*/
|
||||
private static final String ACCESS_TOKEN = "access_token";
|
||||
|
||||
/**
|
||||
* 排序方式: 创建时间(created),更新时间(updated),最后推送时间(pushed),仓库所属与名称(full_name)。默认: full_name
|
||||
*/
|
||||
private static final String SORT = "sort";
|
||||
|
||||
/**
|
||||
* 当前的页码
|
||||
*/
|
||||
private static final String PAGE = "page";
|
||||
|
||||
/**
|
||||
* 每页的数量,最大为 100
|
||||
*/
|
||||
private static final String PER_PAGE = "per_page";
|
||||
|
||||
/**
|
||||
* 获取 Gitee 用户名
|
||||
*
|
||||
* @param token 用户授权码
|
||||
* @return Gitee 用户名
|
||||
*/
|
||||
public static String getGiteeUsername(String token) {
|
||||
// 参考:https://gitee.com/api/v5/swagger#/getV5User
|
||||
HttpResponse userResponse = HttpUtil.createGet(GITEE_API_URL_PREFIX + "/user", true)
|
||||
.form(ACCESS_TOKEN, token)
|
||||
.execute();
|
||||
Assert.state(userResponse.isOk(), "令牌不正确:" + userResponse.body());
|
||||
JSONObject userBody = JSONObject.parseObject(userResponse.body());
|
||||
return userBody.getString("login");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Gitee 用户仓库信息
|
||||
*
|
||||
* @param token 用户授权码
|
||||
* @param page 分页参数
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, Object> getGiteeRepos(String token, Page page, String condition) {
|
||||
// 参考:https://gitee.com/api/v5/swagger#/getV5UserRepos
|
||||
HttpResponse reposResponse = HttpUtil.createGet(GITEE_API_URL_PREFIX + "/user/repos", true)
|
||||
.form(ACCESS_TOKEN, token)
|
||||
.form(SORT, "pushed")
|
||||
.form(PAGE, page.getPageNumber())
|
||||
.form(PER_PAGE, page.getPageSize())
|
||||
// 搜索关键字
|
||||
.form("q", condition)
|
||||
.execute();
|
||||
String body = reposResponse.body();
|
||||
Assert.state(reposResponse.isOk(), "获取仓库信息错误:" + body);
|
||||
|
||||
// 所有仓库总数,包括公开的和私有的
|
||||
String totalCountStr = reposResponse.header("total_count");
|
||||
int totalCount = Convert.toInt(totalCountStr, 0);
|
||||
//String totalPage = reposResponse.header("total_page");
|
||||
|
||||
Map<String, Object> map = new HashMap<>(2);
|
||||
map.put("jsonArray", JSONArray.parseArray(body));
|
||||
// 仓库总数
|
||||
map.put("totalCount", totalCount);
|
||||
return map;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Code Technology Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.controller.build.repository;
|
||||
|
||||
/**
|
||||
* @author bwcx_jzy
|
||||
* @since 2023/3/19
|
||||
*/
|
||||
public class GogsUtil extends GiteaUtil {
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Code Technology Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.controller.build.repository;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 仓库提供商配置
|
||||
*
|
||||
* @author WeiHongBin
|
||||
*/
|
||||
@Data
|
||||
public class ImportRepoProviderConfig {
|
||||
private String baseUrl;
|
||||
/**
|
||||
* 鉴权方式 1:header 2:from 3:body
|
||||
*/
|
||||
private Integer authType;
|
||||
/**
|
||||
* 鉴权key 例如:Authorization
|
||||
*/
|
||||
private String authKey;
|
||||
/**
|
||||
* 鉴权值 例如:Bearer ${token}
|
||||
*/
|
||||
private String authValue;
|
||||
/**
|
||||
* 扩展参数
|
||||
*/
|
||||
private Map<String, String> extraParams;
|
||||
/**
|
||||
* 扩展参数类型 1:header 2:from 3:body
|
||||
*/
|
||||
private Integer extraParamsType;
|
||||
/**
|
||||
* 获取用户信息的请求方式
|
||||
*/
|
||||
private String currentUserMethod;
|
||||
/**
|
||||
* 获取用户信息的请求地址
|
||||
*/
|
||||
private String currentUserUrl;
|
||||
/**
|
||||
* 获取用户名 path
|
||||
*/
|
||||
private String userNamePath;
|
||||
/**
|
||||
* 获取仓库列表的请求方式
|
||||
*/
|
||||
private String repoListMethod;
|
||||
/**
|
||||
* 获取仓库列表的请求地址
|
||||
*/
|
||||
private String repoListUrl;
|
||||
/**
|
||||
* 获取仓库列表的请求参数
|
||||
*/
|
||||
private Map<String, String> repoListParam;
|
||||
/**
|
||||
* 获取仓库列表数组 path
|
||||
*/
|
||||
private String repoListPath;
|
||||
/**
|
||||
* 仓库信息 转换 path
|
||||
*/
|
||||
private Map<String, String> repoConvertPath;
|
||||
/**
|
||||
* 获取仓库总数 X-Total
|
||||
*/
|
||||
private String repoTotalHeader;
|
||||
|
||||
}
|
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Code Technology Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.jpom.controller.build.repository;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.db.Page;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.http.Method;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.setting.yaml.YamlUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@UtilityClass
|
||||
public class ImportRepoUtil {
|
||||
|
||||
private static final String IMPORT_REPO_PROVIDER_DIR = "/import-repo-provider";
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public Map<String, Map<String, Object>> getProviderList() {
|
||||
String normalize = FileUtil.normalize(IMPORT_REPO_PROVIDER_DIR);
|
||||
ClassPathResource classPathResource = new ClassPathResource(normalize);
|
||||
if (!classPathResource.exists()) {
|
||||
return null;
|
||||
}
|
||||
return Arrays.stream(Objects.requireNonNull(classPathResource.getFile()
|
||||
.listFiles(pathname -> StrUtil.endWith(pathname.getName(), ".yml"))))
|
||||
.map(file -> {
|
||||
String name = file.getName().replace(".yml", "");
|
||||
ImportRepoProviderConfig providerConfig = getProviderConfig(name);
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("name", name);
|
||||
map.put("baseUrl", providerConfig.getBaseUrl());
|
||||
// 是否支持查询
|
||||
map.put("query", providerConfig.getRepoListParam().values().stream().anyMatch(s -> s.contains("${query}")));
|
||||
return map;
|
||||
}).collect(Collectors.toMap(map -> (String) map.get("name"), map -> map));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public ImportRepoProviderConfig getProviderConfig(String platform) {
|
||||
String normalize = FileUtil.normalize(String.format("%s/%s.yml", IMPORT_REPO_PROVIDER_DIR, platform));
|
||||
ClassPathResource classPathResource = new ClassPathResource(normalize);
|
||||
Assert.state(classPathResource.exists(), "配置文件不存在");
|
||||
try (InputStream inputStream = classPathResource.getInputStream()) {
|
||||
return YamlUtil.load(inputStream, ImportRepoProviderConfig.class);
|
||||
}
|
||||
}
|
||||
|
||||
private void setCommonParams(String platform, HttpRequest request, String token) {
|
||||
ImportRepoProviderConfig provider = getProviderConfig(platform);
|
||||
String callToken = provider.getAuthValue().replace("${token}", token);
|
||||
if (provider.getAuthType() == 1) {
|
||||
request.header(provider.getAuthKey(), callToken);
|
||||
} else if (provider.getAuthType() == 2) {
|
||||
request.form(provider.getAuthKey(), callToken);
|
||||
} else if (provider.getAuthType() == 3) {
|
||||
request.body(JSONUtil.createObj().set(provider.getAuthKey(), callToken).toString());
|
||||
}
|
||||
|
||||
Map<String, String> extraParams = provider.getExtraParams();
|
||||
if (CollUtil.isNotEmpty(extraParams)) {
|
||||
if (provider.getExtraParamsType() == 1) {
|
||||
extraParams.forEach(request::header);
|
||||
} else if (provider.getExtraParamsType() == 2) {
|
||||
extraParams.forEach(request::form);
|
||||
} else if (provider.getExtraParamsType() == 3) {
|
||||
request.body(JSONUtil.toJsonStr(extraParams));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JSONObject getRepoList(String platform, String query, Page page, String token, String username, String baseUrl) {
|
||||
baseUrl = StrUtil.blankToDefault(baseUrl, getProviderConfig(platform).getBaseUrl());
|
||||
ImportRepoProviderConfig provider = getProviderConfig(platform);
|
||||
HttpRequest request = HttpUtil.createRequest(Method.valueOf(provider.getRepoListMethod()), baseUrl + provider.getRepoListUrl());
|
||||
setCommonParams(platform, request, token);
|
||||
query = StrUtil.blankToDefault(query, "");
|
||||
String finalQuery = query;
|
||||
provider.getRepoListParam().forEach((k, v) -> {
|
||||
if ("${query}".equals(v)) {
|
||||
v = v.replace("${query}", finalQuery);
|
||||
}
|
||||
if ("${page}".equals(v)) {
|
||||
v = v.replace("${page}", String.valueOf(page.getPageNumber()));
|
||||
}
|
||||
if ("${pageSize}".equals(v)) {
|
||||
v = v.replace("${pageSize}", String.valueOf(page.getPageSize()));
|
||||
}
|
||||
request.form(k, v);
|
||||
});
|
||||
String body;
|
||||
int total;
|
||||
request.getUrl();
|
||||
log.debug(String.format("url: %s headers: %s form: %s", request.getUrl(), request.headers(), request.form()));
|
||||
try (HttpResponse execute = request.execute()) {
|
||||
body = execute.body();
|
||||
int status = execute.getStatus();
|
||||
Map<String, List<String>> headers = execute.headers();
|
||||
String totalHeader = execute.header(provider.getRepoTotalHeader());
|
||||
int totalCount = page.getPageSize() * page.getPageNumber();
|
||||
if ("Link".equals(provider.getRepoTotalHeader()) && StrUtil.isNotBlank(totalHeader)) {
|
||||
// github 特殊处理
|
||||
Pattern pattern = Pattern.compile("page=(\\d+)&per_page=(\\d+)>; rel=\"last\"");
|
||||
Matcher matcher = pattern.matcher(totalHeader);
|
||||
if (matcher.find()) {
|
||||
int linkPage = Integer.parseInt(matcher.group(2));
|
||||
int linkPerPage = Integer.parseInt(matcher.group(1));
|
||||
total = linkPage * linkPerPage;
|
||||
} else {
|
||||
total = totalCount;
|
||||
}
|
||||
} else {
|
||||
total = StrUtil.isNotBlank(totalHeader) ? Integer.parseInt(totalHeader) : totalCount;
|
||||
}
|
||||
log.debug(String.format("status: %s body: %s headers: %s", status, body, headers));
|
||||
Assert.state(execute.isOk(), String.format("请求失败: status: %s body: %s headers: %s", status, body, headers));
|
||||
}
|
||||
JSONArray jsonArray = JSONUtil.parse(body).getByPath(provider.getRepoListPath(), JSONArray.class);
|
||||
List<JSONObject> data = jsonArray.stream().map(o -> {
|
||||
JSONObject obj = (JSONObject) o;
|
||||
JSONObject entries = new JSONObject();
|
||||
provider.getRepoConvertPath().forEach((k, v) -> {
|
||||
if (StrUtil.startWith(v, "$ ")) {
|
||||
String[] expression = v.split(" ");
|
||||
String value = obj.getStr(expression[1]);
|
||||
// 对比方式
|
||||
String compare = expression[2];
|
||||
// 对比值
|
||||
String compareValue = expression[3];
|
||||
switch (compare) {
|
||||
case "==":
|
||||
entries.set(k, value.equals(compareValue));
|
||||
break;
|
||||
case "!=":
|
||||
entries.set(k, !value.equals(compareValue));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("表达式目前仅支持 == 和 != 比较");
|
||||
}
|
||||
} else {
|
||||
entries.set(k, obj.get(v));
|
||||
}
|
||||
});
|
||||
entries.set("username", username);
|
||||
return entries;
|
||||
}).collect(Collectors.toList());
|
||||
return JSONUtil.createObj().set("data", data).set("total", total);
|
||||
}
|
||||
|
||||
public String getCurrentUserName(String platform, String token, String baseUrl) {
|
||||
baseUrl = StrUtil.blankToDefault(baseUrl, getProviderConfig(platform).getBaseUrl());
|
||||
Assert.state(StrUtil.isNotBlank(baseUrl), String.format("请填写 %s 的 地址", platform));
|
||||
ImportRepoProviderConfig provider = getProviderConfig(platform);
|
||||
HttpRequest request = HttpUtil.createRequest(Method.valueOf(provider.getCurrentUserMethod()), baseUrl + provider.getCurrentUserUrl());
|
||||
setCommonParams(platform, request, token);
|
||||
String body;
|
||||
log.debug(String.format("url: %s headers: %s form: %s", request.getUrl(), request.headers(), request.form()));
|
||||
try (HttpResponse execute = request.execute()) {
|
||||
body = execute.body();
|
||||
int status = execute.getStatus();
|
||||
Map<String, List<String>> headers = execute.headers();
|
||||
log.debug(String.format("status: %s body: %s headers: %s", status, body, headers));
|
||||
Assert.state(execute.isOk(), String.format("请求失败: status: %s body: %s headers: %s", status, body, headers));
|
||||
}
|
||||
return JSONUtil.parse(body).getByPath(provider.getUserNamePath(), String.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
baseUrl: https://try.gitea.io
|
||||
authType: 1
|
||||
authKey: Authorization
|
||||
authValue: 'Bearer ${token}'
|
||||
currentUserMethod: GET
|
||||
currentUserUrl: /api/v1/user
|
||||
userNamePath: login
|
||||
repoListMethod: GET
|
||||
repoListUrl: /api/v1/user/repos
|
||||
repoListParam:
|
||||
page: '${page}'
|
||||
limit: '${pageSize}'
|
||||
repoListPath: ''
|
||||
repoConvertPath:
|
||||
name: name
|
||||
full_name: full_name
|
||||
description: description
|
||||
url: clone_url
|
||||
private: private
|
||||
repoTotalHeader: X-Total-Count
|
@ -0,0 +1,24 @@
|
||||
baseUrl: https://gitee.com
|
||||
authType: 2
|
||||
authKey: access_token
|
||||
authValue: '${token}'
|
||||
currentUserMethod: GET
|
||||
currentUserUrl: /api/v5/user
|
||||
userNamePath: login
|
||||
repoListMethod: GET
|
||||
repoListUrl: /api/v5/user/repos
|
||||
repoListParam:
|
||||
type: all
|
||||
sort: pushed
|
||||
direction: desc
|
||||
q: '${query}'
|
||||
page: '${page}'
|
||||
per_page: '${pageSize}'
|
||||
repoListPath: ''
|
||||
repoConvertPath:
|
||||
name: name
|
||||
full_name: full_name
|
||||
description: description
|
||||
url: html_url
|
||||
private: private
|
||||
repoTotalHeader: total_count
|
@ -0,0 +1,27 @@
|
||||
baseUrl: https://api.github.com
|
||||
authType: 1
|
||||
authKey: Authorization
|
||||
authValue: 'Bearer ${token}'
|
||||
extraParams:
|
||||
Accept: application/vnd.github.v3+json
|
||||
X-GitHub-Api-Version: 2022-11-28
|
||||
extraParamsType: 1
|
||||
currentUserMethod: GET
|
||||
currentUserUrl: /user
|
||||
userNamePath: login
|
||||
repoListMethod: GET
|
||||
repoListUrl: /user/repos
|
||||
repoListParam:
|
||||
type: all
|
||||
sort: pushed
|
||||
direction: desc
|
||||
page: '${page}'
|
||||
per_page: '${pageSize}'
|
||||
repoListPath: ''
|
||||
repoConvertPath:
|
||||
name: name
|
||||
full_name: full_name
|
||||
description: description
|
||||
url: clone_url
|
||||
private: private
|
||||
repoTotalHeader: Link
|
@ -0,0 +1,23 @@
|
||||
baseUrl: https://gitlab.com
|
||||
authType: 1
|
||||
authKey: Authorization
|
||||
authValue: 'Bearer ${token}'
|
||||
currentUserMethod: GET
|
||||
currentUserUrl: /api/v4/user
|
||||
userNamePath: username
|
||||
repoListMethod: GET
|
||||
repoListUrl: /api/v4/projects
|
||||
repoListParam:
|
||||
membership: true
|
||||
order_by: updated_at
|
||||
search: '${query}'
|
||||
page: '${page}'
|
||||
per_page: '${pageSize}'
|
||||
repoListPath: ''
|
||||
repoConvertPath:
|
||||
name: name
|
||||
full_name: path_with_namespace
|
||||
description: description
|
||||
url: http_url_to_repo
|
||||
private: $ visibility != public
|
||||
repoTotalHeader: X-Total
|
@ -0,0 +1,23 @@
|
||||
baseUrl: https://gitlab.com
|
||||
authType: 1
|
||||
authKey: Authorization
|
||||
authValue: 'Bearer ${token}'
|
||||
currentUserMethod: GET
|
||||
currentUserUrl: /api/v3/user
|
||||
userNamePath: username
|
||||
repoListMethod: GET
|
||||
repoListUrl: /api/v3/projects
|
||||
repoListParam:
|
||||
membership: true
|
||||
order_by: updated_at
|
||||
search: '${query}'
|
||||
page: '${page}'
|
||||
per_page: '${pageSize}'
|
||||
repoListPath: ''
|
||||
repoConvertPath:
|
||||
name: name
|
||||
full_name: path_with_namespace
|
||||
description: description
|
||||
url: http_url_to_repo
|
||||
private: $ visibility != public
|
||||
repoTotalHeader: X-Total
|
@ -0,0 +1,20 @@
|
||||
baseUrl: https://try.gogs.io
|
||||
authType: 1
|
||||
authKey: Authorization
|
||||
authValue: 'Bearer ${token}'
|
||||
currentUserMethod: GET
|
||||
currentUserUrl: /api/v1/user
|
||||
userNamePath: login
|
||||
repoListMethod: GET
|
||||
repoListUrl: /api/v1/user/repos
|
||||
repoListParam:
|
||||
page: '${page}'
|
||||
limit: '${pageSize}'
|
||||
repoListPath: ''
|
||||
repoConvertPath:
|
||||
name: name
|
||||
full_name: full_name
|
||||
description: description
|
||||
url: clone_url
|
||||
private: private
|
||||
repoTotalHeader: X-Total-Count
|
@ -92,6 +92,13 @@ export function authorizeRepos(param) {
|
||||
});
|
||||
}
|
||||
|
||||
export function providerInfo() {
|
||||
return axios({
|
||||
url: "/build/repository/provider_info",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
export function sortItem(params) {
|
||||
return axios({
|
||||
url: "/build/repository/sort-item",
|
||||
|
@ -168,8 +168,8 @@
|
||||
</template>
|
||||
<a-form-model-item label="文件共享" prop="global">
|
||||
<a-radio-group v-model="temp.global">
|
||||
<a-radio :value="true"> 全局 </a-radio>
|
||||
<a-radio :value="false"> 当前工作空间 </a-radio>
|
||||
<a-radio :value="true"> 全局</a-radio>
|
||||
<a-radio :value="false"> 当前工作空间</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
<!-- <a-form-model-item v-if="temp.id" prop="restHideField">
|
||||
@ -192,22 +192,18 @@
|
||||
<a-form-model-item prop="token" label="私人令牌" help="使用私人令牌,可以在你不输入账号密码的情况下对你账号内的仓库进行管理,你可以在创建令牌时指定令牌所拥有的权限。">
|
||||
<a-tooltip :title="`${giteeImportForm.type} 的令牌${importTypePlaceholder[giteeImportForm.type]}`">
|
||||
<a-input v-model="giteeImportForm.token" :placeholder="importTypePlaceholder[giteeImportForm.type]">
|
||||
<a-select slot="addonBefore" v-model="giteeImportForm.type">
|
||||
<a-select-option value="gitee"> gitee </a-select-option>
|
||||
<a-select-option value="github"> github </a-select-option>
|
||||
<a-select-option value="gitlab"> gitlab </a-select-option>
|
||||
<a-select-option value="gitea"> gitea </a-select-option>
|
||||
<a-select-option value="gogs"> gogs </a-select-option>
|
||||
<a-select slot="addonBefore" style="width: 100px" @change="importChange" v-model="giteeImportForm.type">
|
||||
<a-select-option :value="item" v-for="item in Object.keys(providerData)" :key="item"> {{ item }}</a-select-option>
|
||||
</a-select>
|
||||
|
||||
<a-button slot="addonAfter" size="small" type="primary" icon="search" @click="handleGiteeImportFormOk"> </a-button>
|
||||
<a-button slot="addonAfter" size="small" type="primary" icon="search" @click="handleGiteeImportFormOk"></a-button>
|
||||
</a-input>
|
||||
</a-tooltip>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item prop="address" label="地址" :help="importTypeAddressHelp[giteeImportForm.type]" v-if="importTypeAddressHelp[giteeImportForm.type]">
|
||||
<a-form-model-item prop="address" label="地址">
|
||||
<a-input v-model="giteeImportForm.address" placeholder="请填写平台地址" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item prop="condition" label="搜索" help="输入仓库名称或者仓库路径进行搜索">
|
||||
<a-form-model-item prop="condition" label="搜索" help="输入仓库名称或者仓库路径进行搜索" v-if="providerData[giteeImportForm.type].query">
|
||||
<a-input v-model="giteeImportForm.condition" placeholder="输入仓库名称或者仓库路径进行搜索" />
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
@ -236,7 +232,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { authorizeRepos, deleteRepository, editRepository, getRepositoryList, restHideField, sortItem } from "@/api/repository";
|
||||
import { providerInfo, authorizeRepos, deleteRepository, editRepository, getRepositoryList, restHideField, sortItem } from "@/api/repository";
|
||||
import { CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY, parseTime } from "@/utils/const";
|
||||
|
||||
export default {
|
||||
@ -247,6 +243,13 @@ export default {
|
||||
PAGE_DEFAULT_SIZW_OPTIONS: ["15", "20", "25", "30", "35", "40", "50"],
|
||||
listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY, { limit: 15 }),
|
||||
list: [],
|
||||
providerData: {
|
||||
gitee: {
|
||||
baseUrl: "https://gitee.com",
|
||||
name: "gitee",
|
||||
query: true
|
||||
}
|
||||
},
|
||||
total: 0,
|
||||
temp: {},
|
||||
isSystem: false,
|
||||
@ -263,7 +266,7 @@ export default {
|
||||
width: 300,
|
||||
sorter: true,
|
||||
ellipsis: true,
|
||||
scopedSlots: { customRender: "tooltip" },
|
||||
scopedSlots: { customRender: "tooltip" }
|
||||
},
|
||||
{
|
||||
title: "仓库类型",
|
||||
@ -271,7 +274,7 @@ export default {
|
||||
width: 100,
|
||||
sorter: true,
|
||||
ellipsis: true,
|
||||
scopedSlots: { customRender: "repoType" },
|
||||
scopedSlots: { customRender: "repoType" }
|
||||
},
|
||||
{
|
||||
title: "协议",
|
||||
@ -279,7 +282,7 @@ export default {
|
||||
width: 100,
|
||||
sorter: true,
|
||||
ellipsis: true,
|
||||
scopedSlots: { customRender: "protocol" },
|
||||
scopedSlots: { customRender: "protocol" }
|
||||
},
|
||||
{ title: "共享", dataIndex: "workspaceId", ellipsis: true, scopedSlots: { customRender: "global" }, width: "80px" },
|
||||
{ title: "创建人", dataIndex: "createUser", ellipsis: true, scopedSlots: { customRender: "tooltip" }, width: "120px" },
|
||||
@ -289,14 +292,14 @@ export default {
|
||||
dataIndex: "createTimeMillis",
|
||||
sorter: true,
|
||||
customRender: (text) => parseTime(text),
|
||||
width: "170px",
|
||||
width: "170px"
|
||||
},
|
||||
{
|
||||
title: "修改时间",
|
||||
dataIndex: "modifyTimeMillis",
|
||||
sorter: true,
|
||||
customRender: (text) => parseTime(text),
|
||||
width: "170px",
|
||||
width: "170px"
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
@ -304,8 +307,8 @@ export default {
|
||||
fixed: "right",
|
||||
align: "center",
|
||||
width: "180px",
|
||||
scopedSlots: { customRender: "operation" },
|
||||
},
|
||||
scopedSlots: { customRender: "operation" }
|
||||
}
|
||||
],
|
||||
reposColumns: [
|
||||
{ title: "仓库名称", dataIndex: "name", ellipsis: true, scopedSlots: { customRender: "name" } },
|
||||
@ -317,7 +320,7 @@ export default {
|
||||
dataIndex: "description",
|
||||
|
||||
ellipsis: true,
|
||||
scopedSlots: { customRender: "description" },
|
||||
scopedSlots: { customRender: "description" }
|
||||
},
|
||||
{ title: "私有", dataIndex: "private", width: 80, ellipsis: true, scopedSlots: { customRender: "private" } },
|
||||
{
|
||||
@ -325,17 +328,17 @@ export default {
|
||||
dataIndex: "operation",
|
||||
width: 100,
|
||||
scopedSlots: { customRender: "operation" },
|
||||
align: "left",
|
||||
},
|
||||
align: "left"
|
||||
}
|
||||
],
|
||||
giteeImportForm: Object.assign({}, PAGE_DEFAULT_LIST_QUERY, { limit: 15, type: "gitee" }),
|
||||
giteeImportForm: Object.assign({}, PAGE_DEFAULT_LIST_QUERY, { limit: 15, type: "gitee", address: "https://gitee.com" }),
|
||||
giteeImportFormRules: {
|
||||
token: [{ required: true, message: "请输入私人令牌", trigger: "blur" }],
|
||||
token: [{ required: true, message: "请输入私人令牌", trigger: "blur" }]
|
||||
// address: [{ required: true, message: "请填写平台地址", trigger: "blur" }],
|
||||
},
|
||||
rules: {
|
||||
name: [{ required: true, message: "请填写仓库名称", trigger: "blur" }],
|
||||
gitUrl: [{ required: true, message: "请填写仓库地址", trigger: "blur" }],
|
||||
gitUrl: [{ required: true, message: "请填写仓库地址", trigger: "blur" }]
|
||||
},
|
||||
importTypePlaceholder: {
|
||||
gitee: "在 设置-->安全设置-->私人令牌 中获取",
|
||||
@ -343,13 +346,8 @@ export default {
|
||||
gitlab: "在 preferences-->Access Tokens 中获取",
|
||||
gitea: "在 设置 --> 应用 --> 生成令牌",
|
||||
gogs: "在 设置 --> 应用 --> 生成令牌",
|
||||
other: "请输入私人令牌",
|
||||
},
|
||||
importTypeAddressHelp: {
|
||||
gitlab: "请输入 GitLab 的地址,支持自建 GitLab,不需要输入协议,如:gitlab.com、gitlab.jpom.io、10.1.2.3、10.1.2.3:8888 等",
|
||||
gitea: "请输入 gitea 的地址,不需要输入协议,如:10.1.2.3、10.1.2.3:3000 等",
|
||||
gogs: "请输入 gogs 的地址,不需要输入协议,如:10.1.2.3、10.1.2.3:3000 等",
|
||||
},
|
||||
other: "请输入私人令牌"
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -359,7 +357,7 @@ export default {
|
||||
},
|
||||
reposPagination() {
|
||||
return COMPUTED_PAGINATION(this.giteeImportForm, this.PAGE_DEFAULT_SIZW_OPTIONS);
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
created() {
|
||||
@ -367,7 +365,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
// 加载数据
|
||||
loadData(pointerEvent) {
|
||||
async loadData(pointerEvent) {
|
||||
this.listQuery.page = pointerEvent?.altKey || pointerEvent?.ctrlKey ? 1 : this.listQuery.page;
|
||||
this.loading = true;
|
||||
getRepositoryList(this.listQuery).then((res) => {
|
||||
@ -377,6 +375,13 @@ export default {
|
||||
}
|
||||
this.loading = false;
|
||||
});
|
||||
const response = await providerInfo();
|
||||
if (response.code === 200) {
|
||||
this.providerData = response.data;
|
||||
}
|
||||
},
|
||||
importChange(value) {
|
||||
this.giteeImportForm.address = this.providerData[value].baseUrl;
|
||||
},
|
||||
// // 筛选
|
||||
// handleFilter() {
|
||||
@ -386,7 +391,7 @@ export default {
|
||||
handleAdd() {
|
||||
this.temp = {
|
||||
repoType: 0,
|
||||
protocol: 0,
|
||||
protocol: 0
|
||||
};
|
||||
this.editVisible = true;
|
||||
},
|
||||
@ -420,12 +425,12 @@ export default {
|
||||
userName: record.username,
|
||||
password: this.giteeImportForm.token,
|
||||
name: record.name,
|
||||
gitUrl: record.url,
|
||||
gitUrl: record.url
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
// 成功
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
message: res.msg
|
||||
});
|
||||
record.exists = true;
|
||||
this.loadData();
|
||||
@ -453,7 +458,7 @@ export default {
|
||||
if (res.code === 200) {
|
||||
// 成功
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
message: res.msg
|
||||
});
|
||||
this.editVisible = false;
|
||||
this.loadData();
|
||||
@ -471,19 +476,19 @@ export default {
|
||||
cancelText: "取消",
|
||||
onOk: () => {
|
||||
const params = {
|
||||
id: record.id,
|
||||
id: record.id
|
||||
//isRealDel: this.isSystem,
|
||||
};
|
||||
// 删除
|
||||
deleteRepository(params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
message: res.msg
|
||||
});
|
||||
this.loadData();
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@ -499,12 +504,12 @@ export default {
|
||||
restHideField(record.id).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
message: res.msg
|
||||
});
|
||||
this.loadData();
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
},
|
||||
// 分页、排序、筛选变化时触发
|
||||
@ -518,7 +523,7 @@ export default {
|
||||
const msgData = {
|
||||
top: "确定要将此数据置顶吗?",
|
||||
up: "确定要将此数上移吗?",
|
||||
down: "确定要将此数据下移吗?下移操作可能因为列表后续数据没有排序值操作无效!",
|
||||
down: "确定要将此数据下移吗?下移操作可能因为列表后续数据没有排序值操作无效!"
|
||||
};
|
||||
let msg = msgData[method] || "确定要操作吗?";
|
||||
if (!record.sortValue) {
|
||||
@ -536,21 +541,21 @@ export default {
|
||||
sortItem({
|
||||
id: record.id,
|
||||
method: method,
|
||||
compareId: compareId,
|
||||
compareId: compareId
|
||||
}).then((res) => {
|
||||
if (res.code == 200) {
|
||||
this.$notification.success({
|
||||
message: res.msg,
|
||||
message: res.msg
|
||||
});
|
||||
|
||||
this.loadData();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
|
Loading…
Reference in New Issue
Block a user