搜索结果列表页面开发

This commit is contained in:
付民康
2025-03-12 18:41:20 +08:00
commit 7cebe8fc00
739 changed files with 88149 additions and 0 deletions

60
src/api/analysis/index.ts Normal file
View File

@@ -0,0 +1,60 @@
import request from '@/utils/request';
import type { AxiosResponse } from 'axios';
import type { CommitCountData, RepoCountData, TrendData } from '@/api/analysis/types';
// 获取项目统计
export function getRepoCount(params: { project_id: string; statistics?: boolean }): Promise<AxiosResponse<RepoCountData>> {
return request({
url: `/api/v2/projects/${params.project_id}`,
method: 'get',
params
});
}
// 获取仓库趋势统计数据
export function getTrendCount(params: { project_id: string; branch_name: string; }): Promise<AxiosResponse<TrendData>> {
return request({
url: `/api/v2/projects/${params.project_id}/repository/commit_statistics`,
method: 'get',
params
});
}
// 获取仓库语言统计数据
export function getLangCount(params: { project_id: string; }): Promise<AxiosResponse<{label: string; value: number;}[]>> {
return request({
url: `/api/v2/projects/${params.project_id}/languages`,
method: 'get',
params
}, {
customError: true
});
}
// 获取仓库提交活跃度数据
export function getCommitCount(params: { project_id: string; branch_name: string; }): Promise<AxiosResponse<CommitCountData>> {
return request({
url: `/api/v2/projects/${params.project_id}/repository/graph`,
method: 'get',
params
});
}
// 获取仓库分支提交线路图
export function getCommitNetwork(params: { project_id: string; ref_name: string; filter_ref: string; }): Promise<AxiosResponse<any>> {
return request({
url: `/api/v2/projects/${params.project_id}/repository/network`,
method: 'get',
params
});
}
// 数据刷新,记录执行人
export function postRepoStatistics(project_id: string, data: object): Promise<any> {
return request({
url: `/api/v2/projects/${project_id}/repository/statistics`,
method: 'post',
data
}, {
customError: true
})
}

54
src/api/analysis/types.ts Normal file
View File

@@ -0,0 +1,54 @@
export type RepoCountData = {
tag_count: number;
branch_count: number;
release_count: number;
statistics: {
commit_count?: string;
storage_size?: string;
repository_size?: string;
lfs_objects_size?: string;
job_artifacts_size?: string;
};
}
export type TrendData = {
commits: Commit[];
statistics: Statistic[];
total: number;
}
type Commit = {
author_name: string;
date: Date;
}
type Statistic = {
id: number;
project_id: number;
branch: string;
user_name: string;
add_lines: number;
delete_lines: number;
commit_count: number;
created_at: Date;
updated_at: Date;
}
export type CommitCountData = {
authors: number;
commit_per_day: number;
commits: CommitData[];
duration: number;
end_date: string;
start_date: string;
total: number;
}
export type CommitData = {
parents: Array<Array<number | string>>;
author: any;
time: number;
space: number;
refs: any;
id: string;
date: string;
message: string;
}

57
src/api/branch/index.ts Normal file
View File

@@ -0,0 +1,57 @@
import request from '@/utils/request';
import * as types from '@/api/branch/types';
import { reqCatch } from '@/utils/catch';
// 获取分支概览
export function getBranchesOverview(params: types.commonBranchReqType): Promise<types.commonBranchResType> {
return reqCatch(() => request({
url: `/api/v2/internal/projects/${params.repoId}/repository/branch_overview`,
method: 'get',
params: params
}), params);
}
// 获取分支列表
export function getBranches(params: types.commonBranchReqType): Promise<types.commonBranchResType> {
if (!params.view) {
params.view = 'simple';
}
return reqCatch(() => request({
url: `/api/v2/projects/${params.repoId}/repository/branches`,
method: 'get',
params: {
...params,
search: params?.search?.substring(0, 100) || ''
}
}), params);
}
// 创建分支
export function createBranches(data: types.commonBranchReqType): Promise<types.commonBranchResType> {
return reqCatch(() => request({
url: `/api/v2/projects/${data.repoId}/repository/branches`,
method: 'post',
data
}), data);
}
// 删除分支
export function deleteBranches(data: types.commonBranchReqType): Promise<types.commonBranchResType> {
return reqCatch(() => request({
url: `/api/v2/projects/${data.repoId}/repository/branches`,
method: 'delete',
params: data
}), data);
}
// 检测是否为分支
export function checkBranches(params: types.commonBranchReqType): Promise<types.commonBranchResType> {
const { project_id } = params;
delete params.project_id;
return reqCatch(() => request({
url: `/api/v2/projects/${project_id}/repository/branches/check`,
method: 'get',
params
}), params);
}

18
src/api/branch/types.ts Normal file
View File

@@ -0,0 +1,18 @@
import { type errorType, type resCatch } from '@/api/types/common';
import type { repoType } from '@/api/types/common';
export interface createBranchReqType extends repoType{
branch: string,
ref: string,
description?: string;
relatedIds?: string[];
[propName: string]: any;
}
export interface commonBranchReqType {
[propName: string]: any;
}
export interface commonBranchResType extends resCatch {
[propName: string]: any;
}

80
src/api/cla/index.ts Normal file
View File

@@ -0,0 +1,80 @@
import request from '@/utils/request';
import * as types from '@/api/cla/types';
// 签署CLA
export function signCla(data: types.signClaReqType): Promise<any> {
return request({
url: `/api/v2/cla/sign/add`,
method: 'post',
data
});
}
// 签署CLA详情
export function getClaInfo(params: types.paramsObj): Promise<any> {
return request({
url: `/api/v2/cla/sign/info`,
method: 'get',
params
}, {
customError: true
});
}
// 本人已签署CLA详情
export function getClaInfoDetail(params: types.paramsObj): Promise<any> {
return request({
url: `/api/v2/cla/sign/detail`,
method: 'get',
params
}, {
customError: true
});
}
// 获取组织里面用户已签署CLA详情
export function getGroupClaInfoDetail(params: types.paramsObj): Promise<any> {
return request({
url: `/api/v2/cla/${params.group_id}/detail`,
method: 'get',
params
}, {
customError: true
});
}
// 组织下的cla列表
export function getGroupClaList(params: types.paramsObj): Promise<any> {
return request({
url: `/api/v2/cla/${params.group_id}/list`,
method: 'get',
params
});
}
// 组织下的cla列表
export function setGroupClaStatus(params: types.paramsObj): Promise<any> {
return request({
url: `/api/v2/cla/${params.group_id}/status`,
method: 'put',
params
});
}
// 组织下的cla列表
export function deleteGroupCla(params: types.paramsObj): Promise<any> {
return request({
url: `/api/v2/cla/${params.group_id}/del`,
method: 'delete',
params
});
}
// 已签署CLA协议的用户列表
export function getClaUsers(params: types.paramsObj): Promise<any> {
return request({
url: `/api/v2/cla/${params.group_id}/signUsers`,
method: 'get',
params: params.params
});
}
// CLA协议历史版本列表
export function getClaVersion(params: types.paramsObj): Promise<any> {
return request({
url: `/api/v2/cla/getClaHistory`,
method: 'get',
params
});
}

19
src/api/cla/types.ts Normal file
View File

@@ -0,0 +1,19 @@
export interface signClaReqType {
claId: string,
version: string,
sourceUrl: string,
userId: string,
userName: string,
realName: string,
email: string,
phone: string,
status: number,
payload: string,
sign: string,
[x:string]: any
}
export interface paramsObj {
[x:string]: any
}

142
src/api/commit/index.ts Normal file
View File

@@ -0,0 +1,142 @@
import request from '@/utils/request';
import * as types from '@/api/commit/types';
import { reqCatch } from '@/utils/catch';
// 修改检视意见
export function editDiscussions(data: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/discussions/${data.discussionId}`,
method: 'post',
data
});
}
export function editDiscussionsByNoteId(data: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/discussions/${data.discussionId}/notes/${data.note_id}`,
method: 'put',
data
});
}
export function deleteDiscussionsByNoteId(data: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/discussions/${data.discussionId}/notes/${data.note_id}`,
method: 'delete',
data
});
}
export function getRepoCommits(params: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${params.repoId}/repository/commits`,
method: 'get',
params
});
}
export function addRepoCommits(data: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${data.repoId}/repository/commits`,
method: 'post',
data
}, {
customError: true
});
}
export function getRepoCommitsDetail(params: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${params.repoId}/repository/commits/${params.commitId}`,
method: 'get',
params: {
auth_current_project: params.auth_current_project
}
});
}
export function addRepoCommitsComments(data: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/comments`,
method: 'post',
data
});
}
export function getRepoCommitsComments(data: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/comments`,
method: 'get',
params: data
});
}
export function getRepoCommitsDiff(data: types.commonCommitReqType): Promise<any> {
return reqCatch(() => request({
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/diff`,
method: 'get',
params: data
}), data);
}
export function getRepoCommitsFileDiff(repoId, commitId, data: types.commonCommitReqType): Promise<any> {
return reqCatch(() => request({
url: `/api/v1/projects/${repoId}/repository/commits/${commitId}/file_diff`,
method: 'get',
params: data
}), data);
}
export function getRepoMergeRequests(data: types.commonCommitReqType): Promise<any> {
return reqCatch(() => request({
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/merge_requests`,
method: 'get',
data
}), data);
}
export function getCommitCommentDetail(data: types.commonCommitReqType): Promise<any> {
return reqCatch(() => request({
url: `/api/v1/projects/${data.repoId}/repository/commits/${data.commitId}/discussions/${data.discussion_id}/notes/${data.note_id}`,
method: 'get',
data
}), data);
}
// commit revert
export function commitRevert(repoId: string, commitId: string, data: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${repoId}/repository/commits/${commitId}/revert`,
method: 'post',
data
});
}
// commit cherry-pick
export function commitCherryPick(repoId: string, commitId: string, data: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v1/projects/${repoId}/repository/commits/${commitId}/cherry_pick`,
method: 'post',
data
});
}
export function getCommitMsgRegexTemplate(params: types.commonCommitReqType): Promise<any> {
return request({
url: `/api/v2/projects/${params.repoId}/common/commitMsgRegexTemplate`,
method: 'get',
params
});
}
// 保存commit设置
export function updateCommitSetting(data: types.commonCommitReqType, repoId: string): Promise<any> {
return request({
url: `/api/v2/projects/${repoId}/project_git_hook`,
method: 'put',
data
});
}
export function getCommitSetting(repoId: string): Promise<any> {
return request({
url: `/api/v2/projects/${repoId}/project_git_hook`,
method: 'get'
});
}

9
src/api/commit/types.ts Normal file
View File

@@ -0,0 +1,9 @@
import { type errorType } from '@/api/types/common';
export interface commonCommitReqType {
[propName: string]: any;
}
export interface commonCommitResType extends errorType {
[propName: string]: any;
}

32
src/api/common/index.ts Normal file
View File

@@ -0,0 +1,32 @@
import request from '@/utils/request';
import * as types from '@/api/common/types';
import { reqCatch } from '@/utils/catch';
export function upload(data: types.commonReqType): Promise<types.commonResType> {
return request({
url: `/api/v1/upload`,
method: 'post',
data
});
}
// 当前用户-项目权限
export function getRepoPermission(params: { repo_id: string }) {
const { repo_id } = params;
return reqCatch(() => request({
url: `/api/v1/projects/${repo_id}/role`,
method: 'get'
}), params);
}
// 当前用户-组织权限
export function getOrgPermission(params:{group_id:string}): Promise<any> {
const { group_id } = params;
return reqCatch(() => request({
url: `/api/v2/groups/${group_id}`,
method: 'get',
params
}, {
customError: true
}));
}

9
src/api/common/types.ts Normal file
View File

@@ -0,0 +1,9 @@
import { type errorType } from '@/api/types/common';
export interface commonReqType {
[propName: string]: any;
}
export interface commonResType extends errorType {
[propName: string]: any;
}

View File

@@ -0,0 +1,93 @@
import { ref } from 'vue';
import { useAccountStore } from '@/stores/user';
import { orgInfoStore } from '@/stores/Org/index';
import { repoInfoStore } from '@/stores/Repo/index';
import { getSettingsValues } from '@/api/repo';
import { getOrgDiscussionSettings } from '@/api/org';
import { useRepoId } from '@/utils/hooks/useRepoId';
import type {
repoAndOrgSettingDictType
} from '@/api/discussion/types';
/**
* 获取用户信息+是否登录
*/
export function useDiscussGetUserInfo() {
const { isLogin = false, accountInfo: userInfo = {}} = useAccountStore();
return { isLogin, userInfo };
}
/**
* 查询讨论模块是否开启,返回组织/项目id用于讨论接口请求
* @param source_type 1 组织2项目
* @param orgNamespace 组织 namespace
* 项目使用 useRepoId 获取 namespace
*/
export function useDiscussionOpen(source_type = 1, orgNamespace = '') {
const discussOpen = ref('0'); // 讨论模块是否打开0关闭1打开
const id = ref(''); // 项目/组织id
const project_id = ref(''); // 项目fullpath不带%2F
async function getDiscussionStatus() {
if (source_type === 1) {
// 组织讨论模块状态查询
const { orgInfo } = orgInfoStore();
const { module_setting } = orgInfo;
// 有 store 数据,从 store 取
if (orgNamespace === orgInfo.name && module_setting?.group_id) {
id.value = module_setting.group_id;
discussOpen.value = module_setting.modules.find(
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
)?.value || '0';
} else {
// 无 store 数据,接口获取
const res = await getOrgDiscussionSettings({ orgId: orgNamespace });
if (!res.error) {
const resData = res?.data;
id.value = resData.group_id;
const discussStatus = resData.modules.find(
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
).value; // 组织讨论是否开启, '0'关闭,'1'开启
if (discussStatus === '1') {
discussOpen.value = '1';
return;
}
}
}
} else {
const { repoInfo } = repoInfoStore();
const { module_setting } = repoInfo;
// 完整路径,供上传使用
const { repoId: fullRepoPath } = useRepoId('/');
fullRepoPath && (project_id.value = fullRepoPath.value);
// 有 store 数据,从 store 取
if (module_setting?.repo_id) {
id.value = module_setting.repo_id;
discussOpen.value = module_setting.modules.find(
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
)?.value || '0';
} else {
// 无 store 数据,接口获取
const { repoId } = useRepoId();
const res = await getSettingsValues({
repoId: repoId.value
});
if (!res.error) {
const resData = res?.data?.data;
id.value = resData.repo_id;
const discussStatus = resData.modules.find(
(e: repoAndOrgSettingDictType) => e.key === 'DISCUSSION'
).value; // 项目讨论是否开启, '0'关闭,'1'开启
if (discussStatus === '1') {
discussOpen.value = '1';
return;
}
}
}
}
}
return { id, discussOpen, project_id, getDiscussionStatus };
}

477
src/api/discussion/index.ts Normal file
View File

@@ -0,0 +1,477 @@
import request from '@/utils/request';
import * as types from '@/api/discussion/types';
import { reqCatch } from '@/utils/catch';
import type { categoryType } from '@/api/discussion/types';
// ---------------------------- discussion CRUD ----------------------------- //
// 新增讨论
export function discussSave(data: types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss',
method: 'post',
data
}), data);
}
// discussion 列表
export function discussList(data: types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/page',
method: 'post',
data
}), data);
}
// 删除讨论
export function discussDelete(data: {id:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss',
method: 'delete',
data
}), data);
}
// 更新讨论
export function discussUpdate(data: types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss',
method: 'put',
data
}), data);
}
// ---------------------------- discussion 详情操作 ----------------------------- //
// discuss 详情
export function discussDetail(data: {source_id: string, source_type:number, serial_number:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/detail',
method: 'post',
data
}), data);
}
// 讨论新建-组织可 @ 成员列表
// TODO: 暂未提供
export function discussOrgMembers(data: types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/org/v1/member/list',
method: 'post',
data
}), data);
}
// 讨论新建 - 项目可 @ 成员列表
export function discussRepoMembers(params: { repoId: string, page?: number, per_page?: number }): Promise<any> {
const { repoId, ...param } = params;
return reqCatch(() => request({
url: `/api/v1/projects/${repoId}/members/all`,
method: 'get',
params: Object.assign({ page: 1, per_page: 10 }, param)
}), params);
}
// 讨论详情,更改 discuss 关联标签
export function discussChangeRelatedLabels(data:{discuss_id:string;label:string[]}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/label',
method: 'post',
data
}), data);
}
// 查询讨论关联用户列表,需要登录
export function discussDetailRelatedUsers(params:{source_id:string}) {
const { source_id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/relateUser/${source_id}`,
method: 'get'
}), params);
}
// 查询讨论最近活动用户,不需要登录
export function discussDetailRecentActiveUsers(params:{source_id:string}) {
const { source_id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/recentActivity/${source_id}`,
method: 'get'
}), params);
}
// discussion 讨论-总列表置顶/取消置顶
export function discussPin(data:{id: string;is_pin: 0|1}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/changePin',
method: 'post',
data
}), data);
}
// discussion 分类置顶/取消置顶
export function disussTypePin(data:{id: string;is_pin: 0|1}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/changeCatePin',
method: 'post',
data
}), data);
}
// 关闭/重新打开 讨论
export function discussClose(data:{id: string;state: number}): Promise<any> {
// 讨论的状态0打开1正常关闭2过期关闭3:重复关闭
return reqCatch(() => request({
url: '/api/v1/discuss/changeState',
method: 'post',
data
}), data);
}
// 讨论锁定/解锁
export function disussionLock(data:{id: string;is_lock: 0|1}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/changeLock',
method: 'post',
data
}), data);
}
// 更换已创建讨论的分类 - 侧边栏操作
export function discussChangeType(data:{id: string;category_id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/changeCate',
method: 'post',
data
}), data);
}
// 讨论-投票
export function discussVote(data:{discuss_id:string;option_id:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/vote',
method: 'post',
data
}), data);
}
// 讨论 - 点赞
// targetType - 点赞的主体类型1讨论2评论3:评论回复
export function discussLike(data:{target_id:string; target_type:number}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/like',
method: 'post',
data
}), data);
}
// 讨论 - 取消点赞
// targetType - 点赞的主体类型1讨论2评论3:评论回复
export function discussUnLike(data:{target_id:string; target_type:number}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/unlike',
method: 'post',
data
}), data);
}
// ---------------------------- discussion 评论操作 ----------------------------- //
// 评论列表
export function commentList(data:{discuss_id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/page',
method: 'post',
data
}), data);
}
// 新增评论
export function commentSave(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment',
method: 'post',
data
}), data);
}
// 编辑评论
export function commentUpdate(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment',
method: 'put',
data
}), data);
}
// 删除评论
export function commentDelete(data:{id:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment',
method: 'delete',
data
}), data);
}
// 标记评论或者回复为答案
export function commentRemark(data:{id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/remark',
method: 'post',
data
}), data);
}
// 取消标记评论或者回复为答案
export function commentUnremark(data:{id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/unremark',
method: 'post',
data
}), data);
}
// ---------------------------- discussion 评论-回复 操作 ----------------------------- //
// 查询评论的回复列表
export function replyList(data:{parent_id: string, page:number; size:number }): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/reply/page',
method: 'post',
data
}), data);
}
// 新增回复
export function replySave(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/reply',
method: 'post',
data
}), data);
}
// 编辑回复
export function replyUpdate(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/reply',
method: 'put',
data
}), data);
}
// 删除回复
export function replyDelete(data:{id:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/comment/reply',
method: 'delete',
data
}), data);
}
// ---------------------------- 分类type CRUD ----------------------------- //
// 获取讨论分类的基础类型(字典)
export function categoryBasicType(params:types.commonDiscussionReqType) {
return reqCatch(() => request({
url: `/api/v1/discuss/category/type`,
method: 'get'
}), params);
}
// 获取某个项目或仓库下的所有讨论分类
export function getAllTypes(params: {id: string;source_type:number}) {
const { id, source_type } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/category/list/${id}/${source_type}`,
method: 'get'
}), params);
}
// 获取某个项目或者仓库下的所有讨论分类和分组
// 用于「管理内容分类」页
export function getAllSectionAndTypes(params: {source_id: string, source_type:number}) {
const { source_id, source_type } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/category/all/${source_id}/${source_type}`,
method: 'get'
}), params);
}
// 新增讨论分类 type
export function typeSave(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/category',
method: 'post',
data
}), data);
}
// 讨论分类 type 详情
export function typeDetail(params: {id: string|undefined}):Promise<any> {
const { id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/category/detail/${id}`,
method: 'get'
}), params);
}
// 更新 type
export function typeUpdate(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/category',
method: 'put',
data
}), data);
}
// 删除讨论分类 type
export function typeDelete(data:{id: string, transfer_id?:string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/category',
method: 'delete',
data
}), data);
}
// ---------------------------- section CRUD ----------------------------- //
// 新增 section
export function sectionSave(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/section',
method: 'post',
data
}), data);
}
// section 详情
export function sectionDetail(params: {id: string|undefined}) {
const { id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/section/detail/${id}`,
method: 'get'
}), params);
}
// 更新 section
export function sectionUpdate(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/section',
method: 'put',
data
}), data);
}
// 删除 section
export function sectionDelete(data:{id: string}): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/section',
method: 'delete',
data
}), data);
}
// 根据分组 id 获取下面所有内容分类
export function sectionOwnCategory(params: {section_id: string}) {
const { section_id } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/category/section/${section_id}`,
method: 'get'
}), params);
}
// 查询仓库/组织下的讨论分组
export function getAllSections(params: {source_id: string; source_type:number}) {
const { source_id, source_type } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/section/list/${source_id}/${source_type}`,
method: 'get'
}), params);
}
// ----------------------------------- else --------------------------//
// 组织标签列表
// TODO: 组织还没有标签
export function orgLabelList(params: {group_id:string}): Promise<any> {
const { group_id } = params;
return reqCatch(() => request({
url: `/api/v4/groups/${group_id}/labels`,
method: 'get',
params: { page: 1, per_page: 20 }
}), params);
}
// 仓库标签列表
export function repoLabelList(params: {project_id:string}): Promise<any> {
const { project_id } = params;
return reqCatch(() => request({
url: `/api/v1/projects/${project_id}/labels`,
method: 'get',
params: { page: 1, per_page: 20 }
}), params);
}
// 当前用户-项目权限
export function getRepoPermission(params: { repo_id: string }) {
const { repo_id } = params;
return reqCatch(() => request({
url: `/api/v1/projects/${repo_id}/role`,
method: 'get'
}), params);
}
// 当前用户-组织权限
export function getOrgPermission(params:{group_id:string}): Promise<any> {
const { group_id } = params;
return reqCatch(() => request({
url: `/api/v2/groups/${group_id}`,
method: 'get',
params
}, {
customError: true
}));
}
// 获取社区热心榜单
export function getAnswerRank(params: {source_id: string, source_type:number}): Promise<any> {
const { source_id, source_type } = params;
return reqCatch(() => request({
url: `/api/v1/discuss/answerSort/${source_id}/${source_type}`,
method: 'get'
}), params);
}
// ------------------------------ Dashboard 我的讨论,我参与的讨论 ---------------------------------------------------//
// 我创建的讨论列表
export function myCreatedDiscuss(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/my/page',
method: 'post',
data
}), data);
}
// 我参与的讨论列表
export function myJoineddDiscuss(data:types.commonDiscussionReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/discuss/join/page',
method: 'post',
data
}), data);
}
// 获取评论原始数据
export function getDiscussionOriginalData(id: string) {
return reqCatch(() => request({
url: `/api/v1/discuss/comment/origin_detail/${id}`,
method: 'get',
params: {}
}));
}
// 获取评论详情, 子评论的话, 同时获取父级评论信息
export function getDiscussionDetail(id: string) {
return reqCatch(() => request({
url: `/api/v1/discuss/comment/detail/${id}`,
method: 'get',
params: {}
}));
}

208
src/api/discussion/types.ts Normal file
View File

@@ -0,0 +1,208 @@
import { type errorType } from '@/api/types/common';
export interface commonDiscussionReqType {
[propName: string]: any;
}
export interface commonDiscussionResType extends errorType {
[propName: string]: any;
}
export interface commonDictType {
label: string;
value: string;
desc?: string; // 描述
color?: string;
hover_color?: string;
children?: any[];
}
export interface commonPaginationType {
page: number;
size: number;
}
export interface discussionListItemType {
id: string; // 讨论id
title: string;
section_id?: string;
category_id?: string;
category_type?: number; // 讨论类型4种,1-开放讨论2-问答3-公告4-投票
category_icon?:string;
category_name?: string;
comment_total?: number; // 评论总数
reply_total?: number; // 回复总数
like_total?: number | null;
is_like?: boolean; // 是否已点赞: true 已点赞false 未点赞
is_lock?: number; // 是否锁定01
is_pin?: number; // 是否置顶01
pin_date?: string;
is_category_pin?: number; // 是否分类置顶
pin_category_date?: string;
is_closed?: number; // 是否关闭
closed_date?: string;
is_answered?: number; // 回答是否采纳,01
label?: string[]; // labels
serial_number?: number; // 顺序号
created_by?: string; // 创建者id
created_by_user_name?: string;
created_by_user_photo?: string;
created_date?: string;
last_modified_date?: string;
category:categoryType; // 分类信息
source_type?:number; // 组织1项目2
source_id?:string;
}
export interface RadioOption<T> {
value: T;
label: string;
}
export interface repoAndOrgSettingDictType {
key:string;
type:string;
value:string;
};
// 讨论分类 || 讨论分组 itemType
export interface discussionTypeOrSection {
id: string;
icon: string;
title: string;
desc?: string;
answerAcceptEnable?: boolean;
isGroup: boolean;
categoryType?:number;
}
export interface categoryType {
id: string; // categoryId
category_name: string;
category_desc?: string;
category_type: number; // 讨论类型4种,1-开放讨论2-问答3-公告4-投票,不过现在有个专门的接口来查
section_id?: string; // 所属分组
category_icon: string; // icon
}
export interface sectionType {
id:string;
section_name:string;
section_icon:string;
}
export interface sectionOwnCategoryType extends sectionType {
category_list: categoryType[];
}
export interface sectionItemType {
unSection?: categoryType[];
section: sectionOwnCategoryType[];
}
export interface discussDetailType {
id:string;
category_id:string;
category?:categoryType;
created_by?:string;
created_date?:string;
created_by_user_name?:string;
created_by_user_photo?:string;
serial_number:number;
title:string;
content:string;
md_content:string;
is_lock:number; // 是否锁定10
is_pin:number;
pin_date?:string;
is_category_pin:number;
pin_category_date?:string;
is_closed:number; // 是否关闭10
closed_date?:string;
is_answered:number;
comment_total:number;
reply_total?:number;
like_total?:number;
is_like?:boolean;
question?:questionInfoType;
options?:quesitonOptionType[];
is_vote?:boolean; // 是否投过票
option_id?:string; // 投过票的id
label?:string[]; // 关联的 labels
is_edit?:boolean; // 投票类型的讨论 - 更新时是否变更了投票内容(标题 + 选项)
}
export interface commentType {
id:string;
content?:string;
md_content:string;
discuss_id?:string;
parent_id?:string;
serial_number?:number;
source_id?:string;
source_type?:number;
last_modified_date?:string;
last_modified_by?:string;
created_by?:string;
created_date?:string;
created_by_user_name?:string;
created_by_user_photo?:string;
ip?:string;
is_hide?:number; // 是否隐藏评论
reply_total?:number;
like_total?:number;
is_like?:boolean; // true:已点赞false:未点赞
is_deleted?:number;
is_remark?: number; // 是否采纳为答案10:否
replyCover?: any;
}
export interface questionInfoType {
created_by:string;
created_date:string;
id:string;
last_modified_by?:string;
last_modified_date?:string;
question:string; // 投票的标题
vote_total:number; // 投票参与总人数
}
// 投票选项信息
export interface quesitonOptionType {
created_by:string;
created_date:string;
id:string; // 投票选项id
last_modified_by?:string;
last_modified_date?:string;
option_order:number; // 投票选项顺序
vote_id:string;
vote_option:string;
vote_total:number;
vote_total_percent:number; // 选项投票百分比
}
export interface ISidebar {
id?:string; // discuss id,详情页才显示参与者和操作按钮组
labelDicts?:commonDictType[]; // 标签字典
checkedLabelIds?:string[]; // 已关联 label ids
checkedLabels?:commonDictType[]; // 要渲染的已选label list
setLabels?:Function; // emit 关联标签
categoryDicts?:commonDictType[];
checkedCategoryId?:string;
checkedCategory?:commonDictType;
changeCategory?:Function;
participators?:any[];
}
export interface userInfoType {
domain_id?: string
email?: string
id?: string
mobile?: string
nickname?: string
username?: string
access_token?: string
refresh_token?: string
xauth_token?: string
[x: string]: any
}

105
src/api/home/index.ts Normal file
View File

@@ -0,0 +1,105 @@
import request from '@/utils/request';
import * as types from '@/api/home/types';
import { reqCatchV2, type catchRt } from '@/utils/catch';
// 获取banner
export function getBanner(): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/banner`,
method: 'get'
});
}
// 获取活跃社区
export function getCommunity(): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/active_community`,
method: 'get'
});
}
// 获取精选项目
export function getSelectedRepo(): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/selected_projects`,
method: 'get'
});
}
// 获取运营广告
export function getAdvertisement(): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/advertisement`,
method: 'get'
});
}
// 获取推荐项目列表
export function getRecommendedRepos(): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/recommended_projects`,
method: 'get'
});
}
// 获取活跃组织列表
export function getActiveOrganization(): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/active_organization`,
method: 'get'
});
}
// 活跃社区项目列表
export function getCommunityActiveRepos(): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/community_active_repos`,
method: 'get'
});
}
// 活跃社区项目列表
export function getDynamicRemarks(): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/dynamic_remarks`,
method: 'get'
});
}
// 首页搜索
export function homeSearchProject(params: {search:string}): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/projects/search`,
method: 'get',
params
});
}
// 首页全球精选开源组织
export function globalFeaturedGroups(): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/groups/global/featured`,
method: 'get'
});
}
// 全球精选开源项目
export function globalFeaturedProjects(params:{
group_id:string
page:number
per_page:number
}): Promise<types.commonHomeResType> {
return request({
url: `/api/v1/home_page/projects/global/featured`,
method: 'get',
params
});
}
// 获取搜索历史记录
export function getSearchHistory(params: object): catchRt<types.commonHomeResType> {
return reqCatchV2(() => request({
url: `/api/v1/search/searchHistory`,
method: 'get',
params
}));
}
// 删除搜索历史记录
export function delSearchHistory({ thread_id }:{thread_id:string}): catchRt<types.commonHomeResType> {
return reqCatchV2(() => request({
url: `/api/v1/search/searchHistory/${thread_id}`,
method: 'delete'
}));
}

30
src/api/home/types.ts Normal file
View File

@@ -0,0 +1,30 @@
import { type errorType } from '@/api/types/common';
export interface commonHomeReqType extends errorType {
[propName: string]: any;
}
export interface commonHomeResType extends errorType {
[propName: string]: any;
}
// 搜索项目信息
export interface projectSearchInfo {
id: number;
description: string;
name: string;
namespace: string;
name_with_namespace: string;
path: string;
path_with_namespace: string;
web_url: string;
star_count: number;
forks_count: number;
starred: true;
created_at: string;
last_activity_at: string;
main_repository_language: string[];
star_count_seven: number;
license?: string;
topic?: {topic_id:string, name:string}[]
}

218
src/api/issue/index.ts Normal file
View File

@@ -0,0 +1,218 @@
import request from '@/utils/request';
import * as types from '@/api/issue/types';
import { reqCatch, reqCatchV2, type catchRt } from '@/utils/catch';
export function createIssue(data: types.createIssueReqType): Promise<types.createIssueResType> {
return request({
url: `/api/v1/issue/${data.project_id}/issues`,
method: 'post',
data
});
}
export function deleteIssue(params: types.createIssueReqType): Promise<types.createIssueResType> {
return request({
url: `/api/v1/issue/${params.project_id}/issues/${params.issue_iid}`,
method: 'delete'
});
}
export function updateIssue(data: types.updateIssueReqType): Promise<types.updateIssueResType> {
const { project_id, issue_iid } = data;
delete data.project_id;
delete data.issue_iid;
return request({
url: `/api/v1/issue/${project_id}/issues/${issue_iid}`,
method: 'put',
data
});
}
// 关闭或打开issue
export function updateIssueStat(data: types.updateIssueStatReqType): Promise<types.updateIssueStatResType> {
const { project_id, issue_iid } = data;
delete data.project_id;
delete data.issue_iid;
return request({
url: `/api/v1/issue/${project_id}/issues/${issue_iid}/close`,
method: 'put',
data
});
}
export function fetchIssue(params: types.fetchIssueReqType): Promise<types.fetchIssueResType> {
return request({
url: `/api/v1/issue/${params.project_id}/issues/${params.issue_iid}`,
method: 'get'
});
}
// 项目issue列表
export function fetchIssueList(params: types.fetchIssueListReqType): Promise<types.fetchIssueListResType> {
return request({
url: `/api/v1/issue/${params.project_id}/issues`,
method: 'get',
params
});
}
export function createIssueDiscussions(data: types.createIssueDiscussionsReqType): Promise<types.createIssueDiscussionsResType> {
return request({
url: `/api/v1/issue/${data.project_id}/issues/${data.issue_iid}/discussions`,
method: 'post',
data
});
}
export function updateIssueDiscussions(data: types.updateIssueDiscussionsReqType): Promise<types.updateIssueDiscussionsResType> {
return request({
url: `/api/v1/projects/${data.project_id}/issues/${data.issue_iid}/notes/${data.note_id}`,
method: 'put',
data
});
}
export function deleteIssueDiscussions(params: types.deleteIssueDiscussionsReqType): Promise<types.deleteIssueDiscussionsResType> {
return request({
url: `/api/v1/projects/${params.project_id}/issues/${params.issue_iid}/notes/${params.note_id}`,
method: 'delete',
params
});
}
export function fetchIssueDiscussions(params: types.fetchIssueDiscussionsResType): Promise<types.fetchIssueDiscussionsResType> {
return request({
url: `/api/v1/issue/${params.project_id}/issues/${params.issue_iid}/discussions`,
method: 'get',
params
});
}
// 获取issue单条评论
export function fetchIssueNote(params: types.fetchIssueDiscussionsResType): Promise<types.fetchIssueDiscussionsResType> {
return request({
url: `/api/v1/projects/${params.project_id}/issues/${params.issue_iid}/notes/${params.note_id}`,
method: 'get'
});
}
// 回复issue评论
export function freplyIssueDiscussions(data: types.createIssueReqType): Promise<types.createIssueResType> {
return request({
url: `/api/v1/issue/api/v4/projects/${data.project_id}/issues/${data.issue_iid}/discussions/${data.discussion_id}/notes`,
method: 'post',
data
});
}
// issue参与者
export function issueParticipants(data: types.issueParticipantsResType): Promise<types.issueParticipantsReqType> {
return request({
url: `/api/v1/issue/${data.project_id}/issues/${data.issue_iid}/participants`,
method: 'get'
});
}
// issue 精选
export function pinIssue(params: types.pinIssueReqType): Promise<types.pinIssueResType> {
return request({
url: `/api/v1/featured/${params.type}`,
method: 'post',
params
});
}
export function deletePinIssue(params: types.deletePinIssueReqType): Promise<types.deletePinIssueResType> {
return request({
url: `/api/v1/featured/${params.type}`,
method: 'delete',
params
});
}
// 精选排序
export function sortPinIssue(data): Promise<types.pinIssueListResType> {
const { type, group_id, body } = data;
return request({
url: `/api/v1/featured/${type}/resort?group_id=${group_id}`,
method: 'put',
data: body
});
}
export function pinIssueList(params: types.pinIssueListReqType): Promise<types.pinIssueListResType> {
return request({
url: `/api/v1/featured/projects/${params.project_id}/issues`,
method: 'get'
});
}
// 我的issue列表
export function myIssueList(params: types.fetchIssueListReqType): Promise<types.fetchIssueListResType> {
return request({
url: `/api/v1/issues`,
method: 'get',
params
});
}
// 我的issue列表数量
export function myIssueListState(params: types.myIssueListStateReptype): Promise<types.myIssueListStateRestype> {
return request({
url: `/api/v1/issues/statistics`,
method: 'get',
params
});
}
// 组织的issue列表
export function groupIssueList(params: types.fetchIssueListResType): Promise<types.fetchIssueListResType> {
const { group_id } = params;
delete params.group_id;
return request({
url: `/api/v1/groups/${group_id}/issues`,
method: 'get',
params
});
}
// 获取issue关联的PR列表
export function getIssuePRList(params: types.fetchIssueListResType): Promise<types.fetchIssueListResType> {
const { project_id, issue_iid } = params;
delete params.project_id;
delete params.issue_iid;
return request({
url: `/api/v1/issue/${project_id}/issues/${issue_iid}/linked_merge_requests`,
method: 'get',
params
});
}
// issue关联PR
export function issueRelatePR(data: types.updateIssueReqType): Promise<types.fetchIssueListResType> {
return reqCatch(
() => request({
url: `/api/v1/issue/${data.project_id}/issues/${data.issue_id}/merge_request/${data.merge_request_id}/linked_merge_requests`,
method: 'post'
})
,
data
);
}
// issue取消关联PR
export function issueDeletePR(params: types.updateIssueReqType): Promise<types.fetchIssueListResType> {
return reqCatch(
() => request({
url: `/api/v1/issue/${params.project_id}/issues/${params.issue_id}/linked_merge_requests/${params.merge_request_id}`,
method: 'delete'
})
,
params
);
}
// 获取issue模版列表
export function fetchIssueTemplateList(project_id: string): Promise<Record<string, any>> {
return request({
url: `/api/v2/projects/${project_id}/repository/template/issue`,
method: 'get',
params: {}
}).catch((e) => {
return { data: [], error_code: e };
});
}

322
src/api/issue/types.ts Normal file
View File

@@ -0,0 +1,322 @@
export interface createIssueReqType {
project_id?: string;
issue_iid?: number;
title?: string;
description?: string;
updated_at?: string;
state_event?: 'reopen' | 'close';
assignee_id?: number;
assignee_ids?: string[];
milestone_id?: number;
labels?: ILabel[] | string[];
due_date?: string;
confidential?: boolean;
discussion_locked?: true;
created_at?: string;
issue_category?: string;
issue_stage?: string;
issue_severity?: string;
pbi_id?: number;
proposer_id?: string[];
[propName: string]: any;
}
export interface createIssueResType extends IIssue {
[propName: string]: any;
}
export interface deleteIssueReqType {
project_id: string;
issue_iid: number;
[propName: string]: any;
}
export interface deleteIssueResType {
[propName: string]: any;
}
export interface createIssueDiscussionsResType extends IIssue {
[propName: string]: any;
}
export interface createIssueDiscussionsReqType {
project_id: string;
issue_iid: number;
[propName: string]: any;
}
export interface fetchIssueResType {
project_id: string;
issue_iid: number;
[propName: string]: any;
}
export interface fetchIssueReqType extends IIssue {
[propName: string]: any;
}
export interface fetchIssueListReqType {
project_id: string;
state?: string;
sort?: string;
scope?: string;
search?: string;
page?: number;
per_page?: number;
[propName: string]: any;
}
export interface fetchIssueListResType extends IIssue {
[propName: string]: any;
}
export interface myIssueListStateReptype {
state: string;
[propName: string]: any;
}
export interface myIssueListStateRestype extends IIssue {
[propName: string]: any;
}
export interface issueParticipantsResType {
project_id: string;
issue_iid: number;
[propName: string]: any;
}
export interface issueParticipantsReqType extends IAuthor {
[propName: string]: any;
}
export interface fetchIssueDiscussionsResType {
project_id: string;
issue_iid: number;
type: 'user';
[propName: string]: any;
}
export interface fetchIssueDiscussionsReqType extends Idiscussions {
[propName: string]: any;
}
export interface updateIssueReqType extends createIssueReqType {
[propName: string]: any;
}
export interface updateIssueResType extends IIssue {
[propName: string]: any;
}
export interface updateIssueStatReqType extends createIssueReqType {
discussions?: string;
[propName: string]: any;
}
export interface updateIssueStatResType extends IIssue {
[propName: string]: any;
}
export interface updateIssueDiscussionsReqType {
project_id: string;
issue_iid: number;
note_id: string;
[propName: string]: any;
}
export interface updateIssueDiscussionsResType {
[propName: string]: any;
}
export interface deleteIssueDiscussionsReqType {
project_id: string;
issue_iid: number;
note_id: string;
[propName: string]: any;
}
export interface deleteIssueDiscussionsResType {
[propName: string]: any;
}
export interface pinIssueReqType {
type: 'project_issue';
resource_id: number | string;
[propName: string]: any;
}
export interface pinIssueResType {
[propName: string]: any;
}
export interface deletePinIssueReqType {
type: 'project_issue';
group_id: string;
resource_id: string;
[propName: string]: any;
}
export interface deletePinIssueResType {
[propName: string]: any;
}
export interface sortPinIssueReqType {
type: 'project_issue';
group_id: string;
body: string;
[propName: string]: any;
}
export interface sortPinIssueResType {
[propName: string]: any;
}
export interface pinIssueListReqType {
project_id: string;
[propName: string]: any;
}
export interface pinIssueListResType {
object_id: string,
type: string,
resource_id: string,
nextResource_id: string
[propName: string]: any;
}
// 用户
export interface IAuthor {
id: number;
name: string;
username: string;
state: 'active' | string;
avatar_url: string;
avatar_path?: string;
email?: string;
name_cn: string;
web_url: string;
nick_name?: string;
tenant_name?: string;
avatar?: string;
nickname?: string;
is_member?: string;
}
// 项目
export interface IProject {
id: number;
description?: string;
name: string;
name_with_namespace: string;
path: string;
path_with_namespace: string;
develop_mode?: 'normal' | string;
created_at: string;
updated_at?: string;
archived: false;
is_kia: false;
ssh_url_to_repo: string;
http_url_to_repo: string;
web_url: string;
readme_url?: string;
product_id?: string;
product_name?: string;
}
// issue
export interface IIssue {
id?: number;
iid?: number;
project_id?: number;
title?: string;
description?: string;
editIng?: boolean;
saveIng?: boolean;
editText?: string;
state?: 'opened' | 'closed' | 'all';
created_at?: string;
updated_at?: string;
closed_at?: string;
closed_by?: string;
labels?: ILabel[];
milestone?: string;
assignees?: [];
author?: IAuthor;
assignee?: string;
user_notes_count?: number;
merge_requests_count?: number;
confidential?: boolean;
discussion_locked?: boolean;
web_url?: string;
time_stats?: {
time_estimate?: string
total_time_spent?: string
human_time_estimate?: string
human_total_time_spent?: string
};
project_path_with_namespace?: string;
project?: IProject;
root_project_id?: string;
subscribed?: boolean;
related_merge_request?: string;
linked_merge_requests?: [];
related_note_params?: null;
[propName: string]: any;
}
// 评论
export interface INote {
id: number | string;
type: 'DiscussionNote' | string;
body: string;
attachment?: null;
author: IAuthor;
created_at: string;
updated_at: string;
system?: boolean;
noteable_id: number;
noteable_type: 'Issue' | string;
commit_id?: string;
resolvable?: boolean;
is_reply?: boolean;
resolved_by?: null;
noteable_iid: number;
discussion_id: string;
project: string;
diff_file?: null;
diff: string;
archived: boolean;
review_categories?: null;
review_categories_cn: string;
review_categories_en: string;
review_modules?: null;
severity: 'suggestion';
severity_cn: '建议' | string;
severity_en: 'Suggestion' | string;
file_path?: string;
line?: string;
assignee?: string;
proposer: IAuthor;
}
// 评论
export interface Idiscussions extends INote {
id: string | number,
individual_note?: boolean,
notes: INote[],
project_id: number,
project_full_path: string,
deleted_file?: null,
new_file?: null,
added_lines?: null,
removed_lines?: null,
issue?: null,
merge_request_version_params?: null,
amode?: null,
bmode?: null
}
// 标签
export interface ILabel {
color: string;
description: string;
expires_at?: string
id: number
is_expired: boolean;
name: string;
text_color: string;
}

47
src/api/labels/index.ts Normal file
View File

@@ -0,0 +1,47 @@
import request from '@/utils/request';
import { reqCatch } from '@/utils/catch';
import type { ProjectLabelsReqType, LabelsReqType } from './types';
const defaultPages = {
page: 1,
per_page: 10
};
/** 获取项目labels */
export function getProLabels(params: ProjectLabelsReqType): Promise<any> {
const { project_id, ...conf } = params;
return reqCatch(() => request({
url: `/api/v1/projects/${project_id}/labels`,
params: Object.assign({ ...defaultPages }, conf)
}), params);
}
/** 新增项目label */
export function createProjectLabels(data: LabelsReqType) {
const { project_id, ...conf } = data;
return reqCatch(() => request({
url: `/api/v1/projects/${project_id}/labels`,
data: Object.assign({ ...conf }),
method: 'post'
}), data);
}
/** 编辑项目标签 */
export function editProjectLabels(data: LabelsReqType & { new_name: string }) {
const { project_id, ...conf } = data;
return reqCatch(() => request({
url: `/api/v1/projects/${project_id}/labels`,
data: conf,
method: 'put'
}), data);
}
/** 删除标签 */
export function deleteProjectLabels(data: { project_id: string, name: string }) {
const { project_id, name } = data;
return reqCatch(() => request({
url: `/api/v1/projects/${project_id}/labels?name=${name}`,
method: 'delete'
}));
}

19
src/api/labels/types.ts Normal file
View File

@@ -0,0 +1,19 @@
export interface ProjectLabelsReqType {
project_id: string;
search?: string
sort?: 'asc' | 'desc'
include_expired?: boolean
most_active_ones?: boolean
view?: 'simple' | 'basic' | 'detail'
page?: number
per_page?: number
}
export interface LabelsReqType {
project_id: string;
name: string
color: string
description: string
priority?: number // 优先级
expires_at?: string // 过期时间
}

185
src/api/merge/index.ts Normal file
View File

@@ -0,0 +1,185 @@
import request from '@/utils/request';
import * as types from '@/api/merge/types';
const removeParamsPathId = (data: types.commonMergeReqType): types.commonMergeReqType => {
delete data.project_id;
delete data.merge_request_iid;
delete data.discussion_id;
delete data.note_id;
delete data.group_id;
delete data.note_id;
return data;
};
const urlPre = '/api/v1/projects/';
const httpGet = (url: string, params: types.commonMergeReqType): Promise<types.commonMergeResType> => request({
url: urlPre + url,
method: 'get',
params
});
const httpPost = (url: string, data: types.commonMergeReqType): Promise<types.commonMergeResType> => request({
url: urlPre + url,
method: 'post',
data
}, { customError: true });
const httpPut = (url: string, data: types.commonMergeReqType): Promise<types.commonMergeResType> => request({
url: urlPre + url,
method: 'put',
data
}, { customError: true });
const httpDel = (url: string, data: types.commonMergeReqType): Promise<types.commonMergeResType> => request({
url: urlPre + url,
method: 'delete',
data
}, { customError: true });
// 创建合并请求
export const createMerge = data => httpPost(`${data.repoId}/merge_requests`, data);
// 修改合并请求
export const putMerge = data => httpPut(`${data.repoId}/isource/merge_requests/${data.iid}`, data);
// 修改审核人
export const putApprovers = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/approval_approvers`, data);
// 修改检视人
export const putReviewers = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/approval_reviewers`, data);
// 详情已分配合并人列表
export const assignees = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/assignees`, data);
// 详情分配合并人(筛选项)
export const assigneeCandidates = data => httpGet(`${data.repoId}/merge_requests/assignee_candidates`, data);
// 详情获取已分配检视人
export const approvalReviewers = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/approval_reviewers`, data);
export const updateApprovalReviewers = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/approval_reviewers`, data);
// 详情获取已分配检视人(筛选项)
export const approvalReviewersOption = params => httpGet(`${params.repoId}/merge_requests/approval_reviewers`, params);
// 详情获取已关联issue
export const fetchPRIssueList = params => httpGet(`${params.project_id}/merge_requests/${params.merge_request_iid}/e2e_issues`, params);
export const updateIssueList = params => httpPut(`${params.project_id}/isource/merge_requests/${params.merge_request_iid}`, params);
// 列表页 获取审视人(不关联mr)
export const fetchApprovalReviewers = params => httpGet(`${params.repoId}/merge_requests/reviewers`, params);
// 列表页 获取审视人(不关联mr)
// 获取pr模版
export const fetchPrTemplate = (params:{ project_id: string }) => request({
url: `/api/v2/projects/${params.project_id}/repository/template/pr`,
method: 'get'
});
// 获取pr 门禁默认设置人员
export const fetchPrSetDefaultPerson = (params: types.commonMergeReqType) => httpGet(`${params.repoId}/create_merge_requests/person_liable`, params);
// 创建时搜索门禁人员列表
export const searchPrSetPerson = (params: types.commonMergeReqType) => httpGet(`${params.repoId}/merge_requests_create/search_person_liable`, params);
// 获取已经设置门禁人员列表 汇总 评审人,审查人,测试人
export const fetchPrExaminePerson = (params: types.commonMergeReqType) => httpGet(`${params.repoId}/merge_requests/${params.iid}/person_liable`, params);
// 搜索 门禁设置人员
export const searchPrExaminePerson = (params: types.commonMergeReqType | { merge_request_iid:string; source_branch: string; target_branch: string;
search_type: string; target_project_id: string; project_id:string, approval_type: string; search: string; page: number; per_page: number;
}) => httpGet(`${params.repoId}/merge_requests/${params.iid}/search_person_liable`, params);
// 获取门禁配置 汇总版 评审人,审查人,测试人
export const fetchPrExaminerules = (params: types.commonMergeReqType) => httpGet(`${params.repoId}/merge_requests/${params.iid}/person_liable_rules`, params);
// 指定配置各个门禁人员配置
export const editPrExaminePerson = (data: types.commonMergeReqType) => request({
url: `/api/v1/projects/${data.repoId}/merge_requests/${data.iid}/person_liable`,
method: 'put',
data
});
// 审查门禁
export const examineApproval = (data:types.commonMergeReqType & {action_type:'approve'|'reset'}) => request({
url: `/api/v1/projects/${data.repoId}/merge_requests/${data.iid}/approval`,
method: 'put',
data
});
// 测试门禁
export const examineTester = (data:types.commonMergeReqType & {action_type:'pass'|'reset'}) => request({
url: `/api/v1/projects/${data.repoId}/merge_requests/${data.iid}/approval_test`,
method: 'put',
data
});
// 合并
export const merge = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/merge`, data);
// 关闭
export const closeMerge = data => httpPut(`${data.repoId}/isource/merge_requests/${data.iid}`, data);
// 仓库MR创建者列表
export const users = data => httpGet(`${data.repoId}/merge_requests/users`, data);
// 项目MR列表
export const getMergeRequests = data => httpGet(`${data.repoId}/isource/merge_requests`, data);
export const getMergeListCount = data => httpGet(`${data.repoId}/isource/merge_requests/count`, data);
// 我的MR 列表
export const getMyMergeRequests = (params: object) => request({ url: '/api/v1/merge_requests', method: 'get', params });
// 组织 mr 列表
export const getMyOrgMergeRequests = (params: object) => request({ url: `/api/v1/groups/${params.group_id}/merge_requests`, method: 'get', params });
// 合并请求详情 @param view:[simple,basic]
export const mergeDetail = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/internal`, data);
// 讨论列表
export const mrDiscussions = data => httpGet(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions`, removeParamsPathId(data));
// 获取评论详情
export const getMrNote = data => httpGet(`${data.project_id}/merge_requests/${data.merge_request_iid}/notes/${data.note_id}`, removeParamsPathId(data));
// 创建评论 - 代码评论 - 有解决状态
export const addMRDiscussion = data => httpPost(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions`, removeParamsPathId(data));
// 更新 评论
export const updateMRDiscussion = data => httpPut(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions/${data.discussion_id}`, removeParamsPathId(data));
// 创建评论 没有 解决状态
export const addMRDiscussionNote = data => httpPost(`${data.project_id}/merge_requests/${data.merge_request_iid}/notes`, removeParamsPathId(data));
// 修改评论
export const putDiscussionsNotes = data => httpPut(`${data.project_id}/merge_requests/${data.merge_request_iid}/notes/${data.note_id}`, data);
// 创建回复评论
export const replayDiscussionsNote = data => httpPost(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions/${data.discussion_id}/notes`, data);
// export const updateReplayDiscussionsNote = data => httpPut(`${data.project_id}/merge_requests/${data.merge_request_iid}/discussions/${data.discussion_id}/notes/${data.note_id}`, data);
// 删除 mr 评论
export const delMRDiscussionsNote = (data) => request({
url: `/api/v1/projects/${data.project_id}/merge_requests/${data.merge_request_iid}/notes/${data.note_id}`,
method: 'delete'
});
// 代码评论 - 没有解决状态
export const postNotes = data => httpPost(`${data.repoId}/merge_requests/${data.iid}/notes`, data);
// 文件提交记录 commit 记录 - 查库
export const commits = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/commits`, data);
// 检查列表 (合并门禁)
export const mergeableState = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/mergeable_state`, data);
// 文件差异 查库
export const changes = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/changes`, data);
// 文件差异目录
export const changesTrees = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/changes_trees`, data);
// revert
export const revert = data => httpPost(`${data.repoId}/merge_request/${data.iid}/revert`, data);
// cherry-pick
export const cherryPick = data => httpPost(`${data.repoId}/merge_request/${data.iid}/cherry_pick`, data);
// // issue关联MR
// export const revert = data => httpPut(`${data.repoId}/isource/merge_requests/${data.iid}`, data);
// // MR详情获取关联issue
// export const e2eIssues = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/e2e_issues`, data);
export const versions = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/versions`, data);
// 获取评审人数
export const getReviewers = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/reviewer_rules`, data);
// discussions
export const getDis = data => httpGet(`${data.repoId}/merge_requests/${data.iid}/comments_by_line`, data);
export const postDis = data => httpPost(`${data.repoId}/merge_requests/${data.iid}/discussions`, data);
export const putDis = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/discussions/${data.disId}`, data);
export const postNote = data => httpPost(`${data.repoId}/merge_requests/${data.iid}/discussions/${data.disId}/notes`, data);
export const putNote = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/notes/${data.noteId}`, data);
export const delNote = data => httpDel(`${data.repoId}/merge_requests/${data.iid}/notes/${data.noteId}`, data);
export const diffLines = data => httpGet(`${data.repoId}/repository/diff_lines`, data);
// 检视意见统计信息与门禁信息
export const statistic = data => httpGet(`${data.repoId}/merge_requests/statistic`, data);
export const conflict_files = data => httpGet(`${data.repoId}/merge_requests/conflict_files`, data);
export const convertMrComment = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/approval_reviewers`, data);
// 变基rebase
export const changeMrRebase = data => httpPut(`${data.repoId}/merge_requests/${data.iid}/rebase`, data);
// 重新打开
export const reOpen = data => httpPut(`${data.repoId}/isource/merge_requests/${data.iid}`, data);
// MR详情审核人审核通过/拒绝/撤销按钮
export const putApproval_review = data => request({
url: `/api/v1/projects/${data.repoId}/merge_requests/${data.iid}/approval_review`,
method: 'put',
data
});
// 最新一次流水线 show_job =true
export const actual_head_pipeline = (repoId, iid, data) => httpGet(`${repoId}/merge_requests/${iid}/actual_head_pipeline`, data);
export const quality = (repoId, pipeId) => httpGet(`${repoId}/pipelines/${pipeId}/quality`);
export const diverged_commits_count = (repoId, iid) => httpGet(`${repoId}/merge_requests/${iid}/diverged_commits_count`);

46
src/api/merge/types.ts Normal file
View File

@@ -0,0 +1,46 @@
import { type errorType } from '@/api/types/common';
export interface commonMergeReqType {
repoId: string
iid: string
[propName: string]: any;
}
export interface commonMergeResType extends errorType {
[propName: string]: any;
}
export interface IMergeableState {
'merge_request_id': number, // 合并请求ID
'state': boolean,
'status_without_user_auth': boolean, // 无用户授权的状态
'conflict_passed': boolean, // 冲突通过
'branch_missing_passed': boolean, // 分支缺失通过
'non_ff_passed': boolean, // 非快进通过
'mr_state_passed': boolean, // 合并请求状态通过
'merged_by_user_passed': boolean, // 用户合并通过
'work_in_progress_passed': boolean, // 工作进展通过
'resolve_discussion_passed': boolean, // 解决讨论通过
'ci_state_passed': boolean, // CI状态通过
'merge_by_self_passed': boolean, // 自我合并通过
'can_force_merge': boolean, // 可以强制合并
'approval_reviewers_required_passed': boolean, // 需要审批的审查者通过
'merge_request_switch': {
'review_mode': 'string', // 审查模式
'merge_method': 'string', // 合并方法
'only_allow_merge_if_all_discussions_are_resolved': boolean, // 只有在解决所有讨论后才允许合并
'disable_merge_by_self': boolean, // 禁止自我合并
'only_allow_merge_if_pipeline_succeeds': boolean, // 只有在管道成功后才允许合并
'disable_squash_merge': boolean, // 禁止压缩合并
'squash_merge_with_no_merge_commit': boolean, // 无合并提交的压缩合并
'approval_required_reviewers_count': number, // 需要审批的审查者数量
'approval_required_reviewers_branch': 'string', // 需要审批的审查者分支
'add_notes_after_merged': boolean, // 合并后添加注释
'mark_auto_merged_mr_as_closed': boolean, // 将自动合并的MR标记为已关闭
'can_force_merge': boolean, // 可以强制合并
'can_reopen': boolean // 可以重新开放
},
'reason': {}, // description
'can_not_reopen': boolean, // 不能重新开放
'check_tasks_num': number // 检查事项总数
}

View File

@@ -0,0 +1,11 @@
import request from '@/utils/request';
import * as types from '@/api/milestone/types';
// 里程碑详情
export function getMilestones(params: types.commonMilestoneReqType): Promise<types.commonMilestoneResType> {
return request({
url: `/api/v1/projects/${params.project_id}/milestones/${params.milestone_id}`,
method: 'get'
});
}

View File

@@ -0,0 +1,28 @@
import { type errorType } from '@/api/types/common';
export interface commonMilestoneReqType {
project_id:string;
milestone_id:string;
[propName: string]: any;
}
export interface commonMilestoneResType extends errorType{
[propName: string]: any;
}
export interface IMilestone {
id: number,
iid: number,
project_id: number,
title: string,
description: string,
due_date?: string,
progress?: number
state: 'active' | string,
created_at: string,
updated_at?: string,
start_date?: string,
web_url: string,
issues_count: number,
merge_requests_count: number,
}

59
src/api/notice/index.ts Normal file
View File

@@ -0,0 +1,59 @@
import request from '@/utils/request';
import type { AxiosResponse } from 'axios';
import type { MessageListData } from '@/views/Notice/components/types';
// 获取用户未读消息数
export function getUnreadCount(params: { [propName: string]: any }): Promise<AxiosResponse<{ all: number; issue: number; mr: number; }>> {
return request({
url: '/api/v1/internal/messages/count_unread',
method: 'get',
params
});
}
// 设置消息为已读
export function setRead(data: { message_ids: number[] }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/internal/messages/set_read',
method: 'put',
data
});
}
// 获取用户消息列表
type MessageListQuery = {
page?: number;
pageSize?: number;
status?: string;
message_type?: string;
reason?: string;
creator_id?: number;
search?: string;
project_id?: number;
[propName: string]: any;
}
export function getMessageList(params: MessageListQuery): Promise<AxiosResponse<MessageListData[]>> {
return request({
url: '/api/v1/internal/messages',
method: 'get',
params
});
}
// 获取项目列表
export function getMessageRepoList(params: { page_num?: number; page_size?: number; search?: string; }): Promise<AxiosResponse<{ project_full_path: string; project_id: number; unread_count?: number; }[]>> {
return request({
url: '/api/v1/internal/messages/projects',
method: 'get',
params
});
}
/** 获取邀请相关未读信息 */
export function getMessageCount() {
return request({
url: '/api/v1/user/notify/targetInfo',
method: 'get',
params: {}
});
}

124
src/api/org/devIndex.ts Normal file
View File

@@ -0,0 +1,124 @@
import request from '@/utils/request';
import * as types from '@/api/org/types';
import { reqCatch, type ReqReturn } from '@/utils/catch';
// 获取自定义menu菜单
export function getCustomMenuList({ namespace, onlyCustomNav = true }): Promise<any> {
return request({
url: `/v1/namespace_page/custom/nav?domain=${namespace}&onlyCustomNav=${onlyCustomNav}`,
method: 'get',
apiType: 'devApi'
});
}
// 组织主页-关注社区
export function joinCommunity(data: types.createGroupReqType): Promise<any> {
return request({
url: `/api/v1/follow`,
method: 'post',
data
});
}
// 组织主页-取消关注社区
export function unJoinCommunity(data: types.createGroupReqType): Promise<any> {
return request({
url: `/api/v1/follow`,
method: 'delete',
params: data
});
}
// 组织主页-获取文章
export function getArticle(data: types.createGroupReqType): Promise<any> {
return request({
url: `/v1/plus/group/home/article`,
method: 'get',
params: data,
apiType: 'devApi'
});
}
// 组织主页-获取组织社区是否被关注
export function getCommunityAttentionStatus(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/follow/hasFollowed`,
method: 'get',
params: data
});
}
// 组织主页-社区最新活动
export function getActivity(data: types.createGroupReqType): Promise<any> {
return request({
url: `/v1/plus/group/home/activityLive`,
method: 'get',
params: data,
apiType: 'devApi'
});
}
// 组织主页-获取技术文章数
export function getArticleTotle(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/v1/namespace_article/tech-article-count`,
method: 'get',
params: data,
apiType: 'devApi'
});
}
// 组织主页-获取社区粉丝数
export function getfansTotle(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/v1/member/user/count`,
method: 'get',
params: data,
apiType: 'devApi'
});
}
// 组织主页-获取技术文章数和粉丝数
export function getArticleAndFansTotle(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/${data.orgId}/stats`,
method: 'get',
params: data
});
}
// 组织主页-获取运营广告
export function getAdvertisement(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/v1/namespace_page/banner`,
method: 'get',
params: data,
apiType: 'devApi'
});
}
// 刷新devpress登录转态
export function getLoginState(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/v1/check/login`,
method: 'get',
apiType: 'devApi'
});
}
// 退出devpress社区
export function devLogout(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/v1/logout`,
method: 'get',
apiType: 'devApi'
});
}
/* 组织的关注用户 */
export function getGroupFollows(params: types.commonGroupReqType): Promise<types.commonGroupResType> {
return reqCatch(() => request({
url: '/api/v1/follow/getGroupFollows',
method: 'get',
params
}));
}

495
src/api/org/index.ts Normal file
View File

@@ -0,0 +1,495 @@
import request from '@/utils/request';
import * as types from '@/api/org/types';
import { reqCatch, type ReqReturn } from '@/utils/catch';
export function createOrg(data: types.createGroupReqType): Promise<any> {
return request({
url: `/api/v2/groups`,
method: 'post',
data
});
}
export function getOrg(params: types.commonGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/${params.orgId}`,
method: 'get',
params
});
}
// 获取/搜索组织
export function getOrgs(params: types.commonGroupReqType): Promise<ReqReturn<types.commonGroupResType>> {
return reqCatch(() => request({
url: `/api/v2/groups`,
method: 'get',
params
}));
}
export function setOrg(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/${data.orgId}`,
method: 'put',
data
});
}
export function deleteOrg(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/${data.orgId}`,
method: 'delete'
});
}
// 查询登录用户是否关注某组织
export function checkHasFollowed(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: '/api/v1/follow/hasFollowed',
method: 'get',
params: data
});
}
// 获取组织下所有项目
export function getOrgProjectList(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/${data.orgId}/projects`,
method: 'get',
params: data
});
}
// 查询组织项目精选
export function getOrgHandpickProjectList(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/featured/project/${data.type}`,
method: 'get',
params: data
});
}
// 项目精选重排序
export function reorderSelectedItems(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/featured/${data.type}/resort`,
method: 'put',
data
});
}
// 查询组织path是否重复
export function inquireOrgPathIsRepeat(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/path_suggestion`,
method: 'get',
params: data
}, { customError: true });
}
// 组织讨论设置回显
export function getOrgDiscussionSettings(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/${data.orgId}/module/setting`,
method: 'get',
params: data
}, {
customError: true
});
}
// 组织讨论设置保存
export function saveOrgDiscussionSettings(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/${data.orgId}/module/setting`,
method: 'put',
data
});
}
// 获取组织语言
export function getOrgLanguages(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/${data.orgId}/languages`,
method: 'get',
params: data
}, {
customError: true
});
}
// 查询组织首页运营内容
export function getOrgOperationContent(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/devpress/group/${data.orgId}/home_operation`,
method: 'get',
params: data
});
}
// 判断是否绑定csdn账号
export function isBindCsdnCount(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/user/csdn-identity`,
method: 'get',
params: data
});
}
// 申请社区
export function applicantCommunity(data: types.createGroupReqType): Promise<any> {
return request({
url: `/api/v1/devpress/${data.orgId}`,
method: 'post',
data
});
}
// 注销社区
export function deleteCommunity(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/devpress/${data.orgId}`,
method: 'delete'
});
}
// 社区基本信息
export function getCommunityInfo(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/devpress/${data.orgId}/info`,
method: 'get'
});
}
// 转移组织
export function transferOrg(data: types.createGroupReqType): Promise<any> {
return request({
url: `/api/v4/groups/${data.orgId}/transfer`,
method: 'post',
data
});
}
// 判断用户是否能创建组织
export function checkUserCreateOrg(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/groups/quota`,
method: 'get',
params: data
});
}
export function getOrgMemberList(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/groups/${data.orgId}/members/list`,
method: 'get'
});
}
/** 组织邀请成员 */
export function createInvite(data: { group_id: string, conf: Record<string, any> }) {
const { group_id, conf } = data;
return reqCatch(() => request({
url: `/api/v1/invitation/${group_id}/invite`,
method: 'post',
data: {
...conf,
source_type: '0'
}
}));
}
export function checkInvite(data: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/invitation/check`,
method: 'get',
params: data
});
}
export function acceptInvite(token: string) {
return request({
url: `/api/v1/invitation/members/${token}/accept`,
method: 'put'
});
}
export function revokeInvite(token: string): Promise<types.commonGroupResType> {
return request({
url: `/api/v1/invitation/members/${token}/revoke`,
method: 'delete'
});
}
/** 获取组织下的成员 */
export function getOrgMembers(data: { group_id: string, page?: number, per_page?: number, query?: string }) {
return request({
url: `/api/v1/groups/${data.group_id}/members/list`,
method: 'get',
params: data
});
}
/** 获取组织下的待邀请成员 */
export function getMembersInvite(data: { group_id: string, page: number, per_page: number }) {
return reqCatch(() => request({
url: `/api/v1/groups/${data.group_id}/members/invite`,
method: 'get',
params: data
}));
}
/** 移除组织内的用户 */
export function removeGroupUser(data: { group_id: string, username: string }) {
const { group_id, username } = data;
return reqCatch(() => request({
url: `/api/v1/groups/${group_id}/members/${username}`,
method: 'delete'
}));
}
/** 撤销组织中的成员邀请 */
export function retractGroupInvite(data: { group_id: string, username: string }) {
const { group_id, username } = data;
return reqCatch(() => request({
url: `/api/v1/invitation/${group_id}/0/members/${username}/revoke`,
method: 'delete'
}));
}
/** 退出当前组织 */
export function exitGroup(data: { group_id: string }) {
const { group_id } = data;
return reqCatch(() => request({
url: `/api/v1/groups/${group_id}/leave`,
method: 'delete'
}));
}
/** 设置组织中成员的权限 */
export function setGroupUserLevel(data: { group_id: string, username: string, access_level: '30' | '50' | '10' }) {
const { group_id, username, access_level } = data;
return reqCatch(() => request({
url: `/api/v1/groups/${group_id}/members/${username}`,
method: 'put',
data: { access_level }
}));
}
/** 精准搜索匹配组织中的成员 */
export function toSearchGroupMember(group_id: string, username: string) {
return reqCatch(() => request({
url: `/api/v1/groups/${group_id}/members/${username}`
}));
}
/* 查询path是个人还是组织 */
export function getPathType(params: types.createGroupReqType): Promise<types.commonGroupResType> {
return request({
url: '/api/v2/groups/path_suggestion',
method: 'get',
params
});
}
/** 获取用量以及存储相关 */
export function getOrgStock(group_id: string) {
return reqCatch(() => request({
url: `/api/v1/namespaces/${group_id}/statistic`
}));
}
/** 创建组织成员邀请链接 **/
export function createGroupMemberLink(data: { namespace: string } & types.MemberInviteLinkProps) {
const { namespace, ...config } = data;
return reqCatch(() => request({
url: `/api/v1/group/${namespace}/invite/link`,
method: 'post',
data: config
}));
}
/** 删除组织成员邀请链接 */
export function deleteMemberInviteLink(namespace: string, inviteId: string) {
return reqCatch(() => request({
url: `/api/v1/group/${namespace}/${inviteId}/invite/link`,
method: 'delete'
}));
}
/** 查询组织成员邀请链接列表 */
export function getMemberInviteLinks(params: { namespace: string, page?: number, per_page?: number }) {
const { namespace, ...pager } = params;
return reqCatch(() => request({
url: `/api/v1/${namespace}/invite/link`,
params: Object.assign({ page: 1, per_page: 10 }, pager)
}));
}
/** 修改组织成员邀请链接 **/
export function updateGroupMemberLink(data: { namespace: string, inviteId: string } & types.MemberInviteLinkProps) {
const { namespace, inviteId, ...config } = data;
return reqCatch(() => request({
url: `/api/v1/group/${namespace}/${inviteId}/invite/link`,
method: 'put',
data: config
}));
}
/** 接受组织邀请链接 */
export function acceptGroupInvite(invite_code: string) {
return reqCatch(() => request({
url: `/api/v1/${invite_code}/invite/accept`
}));
}
/** 查看组织邀请链接待接受成员列表 */
export function getAcceptGroupMember(params: { namespace: string, page?: number, per_page?: number }) {
const { namespace, ...pager } = params;
return reqCatch(() => request({
url: `/api/v1/${namespace}/invite/accept/member`,
params: Object.assign({ page: 1, per_page: 10 }, pager)
}));
}
/** 审核组织链接访问的成员 */
export function checkGroupLinkMember(data: { namespace: string, id:number, access_level: string, member_expires_at?: string, audit: '0' | '2' }) {
const { namespace, id, ...conf } = data;
return reqCatch(() => request({
url: `/api/v1/group/${namespace}/${id}/invite/audit`,
method: 'put',
data: conf
}));
}
/** 删除链接访问组织的成员 */
export function removeGroupLinkMember(namespace: string, id: number) {
return reqCatch(() => request({
url: `/api/v1/group/${namespace}/${id}/invite/audit`,
method: 'delete'
}));
}
/** 模糊搜索匹配相关组织 */
export function getFuzzyGroups(params: { name?: string, path?: string, description?: string, page?:number, per_page?:number, orderBy?: 'name' | 'path' | 'id' | 'created_at' | 'updated_at', sort: 'asc' | 'desc'}) {
const { page, per_page, ...param } = params;
return reqCatch(() => request({
url: '/api/v2/groups/search/list',
params: { ...param, ...Object.assign({ page: 1, per_page: 10 }, { page, per_page }) }
}));
}
// 新建CLA协议
export function claAdd(data: types.commonGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/cla/${data.orgId}/add`,
method: 'post',
data
});
}
// 编辑CLA协议
export function claUpdate(data: types.commonGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/cla/${data.orgId}/update`,
method: 'put',
data
});
}
// 获取CLA协议详情
export function claDetail(params: types.commonGroupReqType): Promise<types.commonGroupResType> {
return request({
url: `/api/v2/cla/detail`,
method: 'get',
params
});
}
/* 组织webhooks对应接口开始 */
/** 获取项目分支webhook */
export function getRepoWebhooks(params: { repoId: string | null; conf: Record<string, any> }) {
return reqCatch(
() =>
request({
url: `/api/v2/groups/${params.repoId}/hooks`,
params: params.conf
}),
params
);
}
/** 新增webhook配置 */
export function createWebhook(data: { repoId: string | number | null; conf: Record<string, any> }) {
return reqCatch(
() =>
request(
{
url: `/api/v2/groups/${data.repoId}/hooks`,
data: data.conf,
method: 'post'
},
{
customError: true
}
),
data
);
}
/** 编辑webhook */
export function editWebhook(data: { repoId: string | null; hook_id: string; conf: Record<string, any> }) {
const { repoId, hook_id, conf } = data;
return reqCatch(() =>
request({
url: `/api/v2/groups/${repoId}/hooks/${hook_id}`,
method: 'put',
data: conf
})
);
}
/** 获取webhook详情 */
export function getWebhookDetail(data: { repoId: string | null; hook_id: string }) {
const { repoId, hook_id } = data;
return reqCatch(() =>
request({
url: `/api/v2/groups/${repoId}/hooks/${hook_id}`
})
);
}
/** 获取webhook请求日志 */
export function getWebhookLogs(data: { repoId: string | null; hook_id: string; page?: number; per_page?: number }) {
const { repoId, hook_id, ...param } = data;
return reqCatch(() =>
request({
url: `/api/v2/groups/${repoId}/hooks/${hook_id}/logs`,
params: Object.assign({ page: 1, per_page: 10 }, param)
})
);
}
/** 获取项目webhook日志详情 */
export function getWebhookLogDetail(data: { repoId: string | null; hook_id: string; id: string }) {
const { repoId, hook_id, id } = data;
return reqCatch(() =>
request({
url: `/api/v2/groups/${repoId}/hooks/${hook_id}/logs/${id}`
})
);
}
/** 删除webhook */
export function deleteWebHook(data: { repoId: string | null; hook_id: string }) {
const { repoId, hook_id } = data;
return reqCatch(() =>
request({
url: `/api/v2/groups/${repoId}/hooks/${hook_id}`,
method: 'delete'
})
);
}
/* 组织webhooks对应接口结束 */
/** 获取组织默认设置 */
export function getOrgDefaultSetting(params: { group_id: string }) {
return reqCatch(() => request({
url: `/api/v2/groups/${params.group_id}`,
method: 'get'
}));
}
/** 更新组织默认设置 */
export function updateOrgDefaultSetting(data: types.commonGroupReqType) {
const { group_id } = data;
delete data.group_id;
return reqCatch(() => request({
url: `/api/v2/groups/${group_id}/ext/setting`,
method: 'put',
data
}));
}

24
src/api/org/types.ts Normal file
View File

@@ -0,0 +1,24 @@
import { type errorType } from '@/api/types/common';
import type { ComputedRef } from 'vue';
export interface createGroupReqType {
[propName: string]: any;
}
export interface commonGroupReqType {
[propName: string]: any;
repoId?: string | number | string[];
orgId?: string | number | string[] | ComputedRef<string | string[]>;
}
export interface commonGroupResType extends errorType {
[propName: string]: any;
}
export interface MemberInviteLinkProps {
access_level: number | string,
audit_status: 0 | 1 | string,
url_expires_at?:string,
member_expires_at?:string,
remark?:string
}

34
src/api/release/index.ts Normal file
View File

@@ -0,0 +1,34 @@
import request from '@/utils/request';
import * as types from '@/api/release/types';
import { reqCatchV2, type catchRt } from '@/utils/catch';
import type { CommonWithPageReqType } from '@/utils/types';
export function createRelease(data: types.createReleaseReqType): Promise<types.createReleaseReqType> {
return request({
url: `/api/v1/projects/${data.repoId}/releases`,
method: 'post',
data
});
}
export function getReleases(params: types.getReleasesType): catchRt<CommonWithPageReqType<types.getReleaseResType[]>> {
return reqCatchV2(() => request({
url: `/api/v1/projects/${params.repoId}/releases`,
method: 'get',
params
}));
}
export function getReleaseDetail(params: types.getReleaseDetailReqType): Promise<types.getReleaseDetailReqType> {
return request({
url: `/api/v1/projects/${params.repoId}/releases/${params.tag_name}`,
method: 'get',
params
});
}
export function deleteRelease(data: types.commonReleaseResType): Promise<types.commonReleaseResType> {
return request({
url: `/api/v1/projects/${data.repoId}/releases/${data.tag_name}`,
method: 'delete',
data
});
}

102
src/api/release/types.ts Normal file
View File

@@ -0,0 +1,102 @@
import { releaseType; type errorType } from '@/api/types/common';
export interface getReleasesType extends releaseType {
/**
* 当前页码
*/
page?: string;
/**
* 每页的项目数
*/
per_page?: string;
}
export interface commonReleaseResType extends errorType {
[propName: string]: any;
}
export interface createReleaseReqType {
tag_name: string;
name: string;
description: string;
ref: string;
assets?: {
links: [
{
name: string;
url: string
}
]
};
[propName: string]: any;
}
export interface getReleaseDetailReqType {
tag_name: string;
name: string;
description?: string;
[propName: string]: any;
}
interface Author {
id: number;
name: string;
username: string;
iam_id: string;
state: string;
avatar_url: string;
avatar_path: string;
email: string;
name_cn: string;
web_url: string;
nick_name: string;
tenant_name: string;
}
interface Commit {
id: string;
message: string;
parent_ids:string[];
authored_date: string;
author_name: string;
author_email: string;
committed_date: string;
committer_name: string;
committer_email: string;
open_gpg_verified: true;
verification_status: number;
gpg_primary_key_id: string;
short_id: string;
created_at: string;
title: string;
author_avatar_url: string;
committer_avatar_url: string;
relate_url: {
related_id: string;
related_url: string
}[]
}
export interface getReleaseResType {
tag_name: string;
description: string;
name: string;
description_html: string;
created_at: string;
can_delete: true;
can_edit: true;
can_download: true;
author:Author;
commit:Commit;
assets: {
count: number;
sources:
{
format: string;
url: string
}[];
links:
{
id: number;
name: string;
url: string;
external: true
}[];
}
}

1544
src/api/repo/index.ts Normal file

File diff suppressed because it is too large Load Diff

209
src/api/repo/types.ts Normal file
View File

@@ -0,0 +1,209 @@
import { VISIBILITY } from '@/constant/enum';
import { type forkType, type errorType, type repoType } from '@/api/types/common';
import { type TypeAll } from '@/utils/types';
export interface createRepoReqType {
name: string;
path: string;
import_url?:string;
description?: string;
visibility?: VISIBILITY;
}
export interface createRepoResType extends errorType {
[propName: string]: any;
}
export interface commonRepoReqType extends repoType {
[propName: string]: any;
}
export interface forkRepoReqType extends forkType {
[propName: string]: any;
name?: string;
namespace?: number;
need_sync_settings?: string[];
path?: string;
fork_from_project_id?: string;
}
export interface commonRepoResType extends errorType {
name: string // 项目名称
default_branch: string // 项目默认分支
path: string // 仓库路径
description: string // 项目描述
ci_config_path?: string // ci配置文件路径
issues_enabled?: boolean // 是否启用问题追踪器
merge_requests_enabled?: boolean // 是否启用合并请求
wiki_enabled?: boolean // 是否启用wiki
jobs_enabled?: boolean // 是否启用作业
snippets_enabled?: boolean // 是否启用代码片段
shared_runners_enabled?: boolean // 是否为该项目启用共享Runner
resolve_outdated_diff_discussions?: boolean // 是否在推送时自动解决合并请求差异讨论
container_registry_enabled?: boolean // 是否为该项目启用容器注册表
lfs_enabled?: boolean // 是否为该项目启用Git LFS
visibility: 'private' | 'internal' | 'public' // 项目可见性级别
security?: 'secret_top' | 'secret' | 'secret_outer' | 'confidential' | 'internal' | 'open_source' // 项目安全级别
visibility_level?: number // 项目在devclound中的可见性级别
public_builds?: boolean // 是否执行公共构建
request_access_enabled?: boolean // 是否允许用户请求成员访问权限
only_allow_merge_if_pipeline_succeed?: boolean // 仅在管道后成功允许
only_allow_merge_if_all_discussions_are_resolved?: boolean // 仅在所有讨论都已解决后允许合并
tag_list?: string[] // 标签列表
avatar?: string[] // 头像列表
printing_merge_request_link_enabled?: boolean // 从命令行推送时是否显示创建/查看合并请求的链接
merge_method?: 'ff' | 'rebase_merge' | 'merge' // 合并请求时使用的合并方法
iright_snapshot?: string // iright应用信息
initialize_with_readme?: boolean // 是否使用Readme.md初始化项目
initialize_with_gitignore?: string // 选择添加.gitignore模板
initialize_with_license?: string // 选择添加license模板
partition?: string // 分区
[x: string]: any
}
export interface commonRepoBranchResType {
description: string // 分支描述
name: string // 分支名称
protected: boolean // 是否受到分支保护
merged: boolean // 是否合并
default: boolean // 是否为默认分支
[x: string]: any
}
// 项目用户角色权限
export interface IRole {
'id': number,
'username': string,
// 管理员 50开发30 浏览者10
'access_level': 50 | 30 | 10,
'project': {
// 安全级别
'security_level': 40
},
'committer_system_from'?: boolean
}
// 获取贡献者的返回
export interface ContributorReqType {
additions:number;
commits:number;
deletions:number;
email:string;
name:string;
}
interface User {
id:number;
username:string;
nickname:string;
avatar:string;
skill:any[]
}
interface Ext {
liveId:string;
coverImg:string;
isRecommend:boolean;
isHot:true;
}
// 精选内容的返回
export interface SelectedArticleReqType {
nsId:number;
mediaAid:string;
type:number;
title:string;
desc:string;
customDomain:string;
startAt:string;
endAt:string;
status:number;
ext:Ext;
user:User;
}
// 相关搜索关键词返回
export type HotSearchKeyReqType = TypeAll<'name'|'link', string>;
// 通知类型返回
export interface RepoNoticeReqType {
count:number;
custom_watching:any;
watch_type:string;
}
export interface RepoWikiReqType {// wiki创建更新文件请求参数
repo_path: string,
name: string,
file_path?: string,
commit_message: string,
content: string,
currUserId?: string
}
export interface WikiFileResType {// wiki详情返回
name:string;
path:string;
size: number,
encoding:string;
blob_id:string;
file_type:string;
commit_history_count:string;
last_commit_id:string;
author_name:string;
committed_date:string;
content:string;
}
export interface WikiListReqType {// wikilist请求参数
repo_path:string;
page?:number;
per_page?:number;
}
export interface WikiListResType {// wikilist返回
author_name:string;
name:string;
avatar?:string;
committed_date:string;
}
export interface RepoWikiHistoryReqType {// wiki历史版本请求参数
file_path:string,
repo_path: string,
page?: number,
per_page?: number,
}
export interface WikiHistoryResType {// wiki历史版本返回
id:string;
message:string;
parent_ids:string[];
authored_date:string;
author_name:string;
author_email:string;
committed_date:string;
committer_name:string;
committer_email:string;
open_gpg_verified: boolean;
verification_status: number;
gpg_primary_key_id:string;
short_id:string;
created_at:string;
title:string;
author_avatar_url:string;
committer_avatar_url:string;
relate_url: {
related_id:string;
related_url:string;
}[]
}
export interface archiveType extends repoType {
sha: string;
archive_format: string;
}
export interface MemberInviteLinkProps {
access_level: number | string,
audit_status: 0 | 1 | string,
url_expires_at?:string,
member_expires_at?:string,
remark?:string
}
export interface DiscussionPreviewProps {
discussion: string,
}
export interface DiscussionCommentProps {
type: 1 | 2 | 3 | 4,
discussionId: string | number,
}

11
src/api/report/index.ts Normal file
View File

@@ -0,0 +1,11 @@
import request from '@/utils/request';
// 数据上报
export function report(eventId: string, data: object, headers: object = {}): Promise<any> {
return request({
url: `/api/v1/report?event_id=${eventId}`,
method: 'post',
data,
headers
});
}

53
src/api/settings/index.ts Normal file
View File

@@ -0,0 +1,53 @@
import { reqCatchV2, type catchRt } from '@/utils/catch';
import request from '@/utils/request';
import type { userCreateSSHKeyReqType, generalSearchReqType, getUserSSHKeyResType, sshKeyid } from './types';
import Mock from 'mockjs';
// 获取镜像信息
export function getMirrorData(params: any): Promise<any> {
return Promise.resolve([(Mock.mock({
'isOpen': false,
'dataList': [
{
type: 0,
add: 'http:6',
success: 1,
time: 2
},
{
type: 1,
add: 'http:fdsjoijfsdoijdfsiojfsdiojoidsfoijfdsijo',
success: 0,
time: 2
}]
}))
]);
}
// 创建用户SSHKey
export function createUserSSH(sshKey: userCreateSSHKeyReqType): catchRt<any> {
const reqForm = new FormData();
reqForm.append('key', sshKey.keyValue);
reqForm.append('title', sshKey.keyName);
return reqCatchV2(() => request({
url: `/api/v1/user/keys`,
method: 'post',
data: reqForm
}, { customError: true }));
}
// 查询用户SSHKey列表
export function getUserSSHList(searchParams: generalSearchReqType): catchRt<getUserSSHKeyResType[]> {
return reqCatchV2(() => request({
url: `/api/v1/user/keys`,
method: 'get',
params: searchParams
}));
}
// 删除用户SSHKey
export function deleteSSHKey(key_id:sshKeyid, title:string): catchRt<any> {
return reqCatchV2(() => request({
url: `/api/v1/user/keys/${key_id}`,
method: 'delete',
params: { title: title }
}));
}

51
src/api/settings/types.ts Normal file
View File

@@ -0,0 +1,51 @@
import type { SSHData } from '@/components/SecretKeyItem/types';
export interface ITransSSHKey {
keyName: string;
keyValue: string;
writable: boolean;
}
// 用户创建SSHKey请求参数
export interface userCreateSSHKeyReqType {
keyName: string;
keyValue: string;
permissions: string;
expireTime: string;
}
// 通用列表查询参数
export interface generalSearchReqType {
page: number;
per_page: number;
search: string;
}
// 用户SSHKey接口返回
export interface getUserSSHKeyResType {
id: string | number;
key: string;
title: string;
created_at: string;
}
export type sshKeyid = SSHData['id'];
export interface Log {
type: string;
operator: string;
logInfo: string;
createdTime: string;
}
export interface LogFilter {
type?: string;
operator?: string;
logInfo?: string;
range?: [Date | '', Date | ''];
}
export interface LogSource {
(pageSize: number, pageIndex: number, logFilter: LogFilter): Promise<Log[]>
}
export interface UserRepo {
organization: string;
repoName: string;
repoSize: string;
isMine: boolean;
}

35
src/api/storage-apis.ts Normal file
View File

@@ -0,0 +1,35 @@
import type { IRequestCache } from "@/utils/apiStorage";
const TIMEOUT = 5000;
const RETRY = 2;
export const storageApis: IRequestCache[] = [
{
url: '/api/v1/issues',
timeout: 5000,
retry: RETRY,
method: 'get',
excludeStatusCode: [401,403, 404]
},
{
url: '/api/v1/merge_requests',
timeout: TIMEOUT,
retry: RETRY,
method: 'get',
excludeStatusCode: [401,403, 404]
},
{
url: '/api/v1/projects/{projectId}/isource/merge_requests',
timeout: TIMEOUT,
retry: RETRY,
method: 'get',
excludeStatusCode: [401,403, 404]
},
{
url: '/api/v1/issue/{projectId}/issues',
timeout: TIMEOUT,
retry: RETRY,
method: 'get',
excludeStatusCode: [401,403, 404]
}
]

53
src/api/tags/index.ts Normal file
View File

@@ -0,0 +1,53 @@
import request from '@/utils/request';
import * as types from '@/api/tags/types';
export function createTag(data: types.createTagReqType): Promise<types.createTagReqType> {
return request({
url: `/api/v1/projects/${data.repoId}/repository/tags`,
method: 'post',
data
});
}
export function getTags(params: types.getTagsReqType): Promise<any> {
return request({
url: `/api/v1/projects/${params.repoId}/repository/tags`,
method: 'get',
params
});
}
export function getTagDetail(params: types.tagDetailType): Promise<types.tagDetailType> {
return request({
url: `/api/v1/projects/${params.repoId}/repository/tags/${params.tag_name}`,
method: 'get',
params
});
}
export function deleteTag(params: types.tagDetailType): Promise<types.tagDetailType> {
return request({
url: `/api/v1/projects/${params.repoId}/repository/tags/${params.tag_name}`,
method: 'delete',
params
});
}
// 获取未发布版本的tag列表
export function getUnreleasedTags(params: types.tagDetailType): Promise<types.tagDetailType> {
return request({
url: `/api/v1/projects/${params.repoId}/releases/linktags`,
method: 'get',
params
});
}
export function createTagAuth(project_path: string): Promise<any> {
return request({
url: `/api/v2/projects/get_create_tag_setting`,
method: 'get',
params: {
project_path
}
});
}

48
src/api/tags/types.ts Normal file
View File

@@ -0,0 +1,48 @@
import { tagType, type errorType } from '@/api/types/common';
export interface getTagsReqType extends tagType {
/**
* 用户ID或用户名
*/
creator?: string;
/**
* 返回按照名称name、更新时间updated或创建时间created字段排序
*/
order_by?: string;
/**
* 当前页码
*/
page?: string;
/**
* 每页的项目数
*/
per_page?: string;
/**
* 返回与搜索条件匹配的标签列表
*/
search?: string;
/**
* 返回排序为升序asc或降序desc
*/
sort?: string;
/**
* 仅返回标签名称
*/
view?: string;
}
export interface tagDetailType extends tagType {
[propName: string]: any;
}
export interface commonTagsResType extends errorType {
[propName: string]: any;
}
export interface createTagReqType {
tag_name: string;
ref: string;
message?: string;
release_description?: string;
[propName: string]: any;
}

35
src/api/types/common.ts Normal file
View File

@@ -0,0 +1,35 @@
export interface errorType {
error_code?: number;
error_code_name?: string;
error_message?: string;
trace_id?: string;
}
export interface repoType {
repoId?: string;
}
export interface orgType {
groupId: string;
}
export interface commitType extends repoType {
commitId: string;
}
export interface tagType extends repoType {
tag_name?: string;
}
export interface forkType extends repoType {
forked_from_id?: string;
}
export interface releaseType extends repoType {
tag_name?: string;
}
export interface resCatch {
error: any;
data: any;
}

0
src/api/types/login.ts Normal file
View File

697
src/api/user/index.ts Normal file
View File

@@ -0,0 +1,697 @@
import request from '@/utils/request';
import { reqCatch } from '@/utils/catch';
import { fileToBlob } from '@/utils/index';
import type { RegisterReqType, UserProfileReqType, UserPreferenceReqType, UserRepoReqType, LoginPassword, LoginMobile, UserProfileResType, UserProfile, OrgData, FollowerData } from './types';
import { reqCatchV2, type catchRt } from '@/utils/catch';
import { AES, enc, mode, pad } from 'crypto-js';
import type { AxiosResponse } from 'axios';
import type { ProfileRepoItemResData } from '@/views/User/hooks/useRepoList';
/** 帐号密码登录 */
export function toLogin(data: LoginPassword): Promise<any> {
const key = enc.Utf8.parse((import.meta as any).env.VITE_SECRET_KEY);
const iv = enc.Utf8.parse((import.meta as any).env.VITE_SECRET_IV);
const cryptoCode = AES.encrypt(data.password, key, {
iv,
mode: mode.CBC,
padding: pad.Pkcs7
});
const userInfo = {
username: data.username,
password: cryptoCode.toString()
};
return reqCatch(() => request({
url: '/api/v1/user/oauth/login',
method: 'post',
data: userInfo,
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
}), userInfo);
}
/** 验证码登录 */
export function loginByMobile(data: Exclude<LoginMobile, 'type'>): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/user/oauth/login/mobile',
method: 'post',
data,
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
}));
}
/** 获取gitcode手机号验证码 */
export function verifyRegisterCode(data: { mobile: string, type: 'REGISTER' | 'ATTACH_MOBILE', raw_data?: string }): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/user/sms/send/codeByBiz',
method: 'post',
data: {
biz_enum: data.type,
mobile: data.mobile,
raw_data: data.raw_data || ''
}
}));
}
/** 获取华为手机号验证码 */
export function verifyHwCode(data: { mobile: string }): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/user/sendVeriCode',
method: 'post',
data
}));
}
/** gitcode手机号验证注册 */
export function registerByMobile(data: RegisterReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/user/register',
method: 'post',
data
}));
}
/**
* 华为云手机号验证注册
* @deprecated at 2023.11.02 精简注册
*/
export function registerBind(data: { mobile: string, user_id: string, mask: string, verificationcode: string }): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/user/registerIAM',
method: 'post',
data
}));
}
/** 快捷注册短信验证 */
export function getQuickLoginMsg(data: { mobile: string, biz_enum?: string }): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/user/sms/send/codeByBiz',
method: 'post',
data: {
mobile: data.mobile,
biz_enum: data.biz_enum || 'LOGIN'
}
}));
}
/** 手机号快捷注册 */
export function quickRegister(data: RegisterReqType): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/user/quickRegister',
method: 'post',
data: data
}));
}
/** 获取手机或者邮箱验证码 */
export function getMobileEmailCode(mobile_email: string) {
return reqCatch(() => request({
url: `/api/v1/user/forgetCode?mobile_email=${mobile_email}`
}));
}
/** 登录重置密码 */
export function resetUserPassword(data: { mobile_email: string, password: string, code: string }) {
return reqCatch(() => request({
url: '/api/v1/user/forgetPassword',
method: 'post',
data
}));
}
/** 退出登录 */
export function toLogout() {
return reqCatch(() => request({
url: '/api/v1/user/oauth/logout',
method: 'post'
}));
}
/** 获取第三方绑定信息 */
export function getBindUserInfo(platform: 'csdn' | 'gitee' | 'github' | 'atomgit', code: string, state: string, signup_type: string) {
return reqCatch(() => request({
url: `/api/v1/oauth/callback/${platform}`,
params: { code, state, signup_type }
}));
}
/** 第三方登录绑定手机号 */
export function bindAuthMobile(data: { user_id: string, mask: string, identity_id: string, mobile: string, verificationcode: string, signup_type: string }) {
return reqCatch(() => request({
url: '/api/v1/oauth/attach/mobile',
method: 'post',
data
}));
}
/** 模糊查询用户信息 */
export function fuzzyFindUserInfo(usernameOrEmail: string) {
return reqCatch(() => request({
url: '/api/v1/findUser/fuzzy',
params: { usernameOrEmail }
}));
}
/** 查询用户名是否已存在 */
export function checkUsername(username: string) {
return reqCatch(() => request({
url: '/api/v1/user/checkSameUser',
params: { username }
}));
}
// 获取当前用户所有命名空间
export function getNamespaces(params: any): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/groups',
method: 'get',
params
}), params);
}
// 获取当前用户fork的所有命名空间
export function getForkGroups(params: any): Promise<any> {
return reqCatch(() => request({
url: `/api/v2/projects/${params.repoId}/fork_groups/page`,
method: 'get',
params
}), params);
}
// 获取当前用户所有命名空间
export function getManageableGroups(params: any): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/user_groups/manageable_groups',
method: 'get',
params
}), params);
}
export function postUploadAvatar(params: any): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/obs/user/avatar',
method: 'get'
}), params);
}
export function postUploadImage(params: any): Promise<any> {
return reqCatch(() => request({
url: '/api/v1/obs/image',
method: 'post',
data: params
}), params);
}
// 封装公共文件上传方法
export async function uploadFile(fileInfo: any, isAvatar: boolean, fileType: string = '') {
try {
if (fileInfo.length > 0) {
const file = fileInfo[0];
const params = {
object_key: `${location.pathname}/` + file.name,
file_type: file.name.split('.')[1],
is_avatar: isAvatar
};
let res;
if (isAvatar) {
res = await postUploadAvatar(params);
} else {
params.content_type = fileType;
res = await postUploadImage(params);
}
const blob: any = await fileToBlob(file);
let url = '';
let uploadParams: any = {};
for (const key in res.data.data) {
url = key;
uploadParams = res.data.data[key];
}
const imgRes = await fetch(url, {
method: 'put',
body: blob,
headers: {
'Content-Type': uploadParams['Content-Type'],
'x-obs-acl': uploadParams['x-obs-acl'],
'Host': uploadParams['Host']
}
});
if (imgRes.status === 200) {
return uploadParams['cdn-img-addr'];
} else {
return '';
}
}
} catch (err) {
return err;
}
};
export function findUser(data: object | null): Promise<object | null> {
return request({
url: '/api/v1/findUser/condition',
method: 'get',
params: data
});
};
// 更新用户基本信息
export function updateUserProfile(data: UserProfileReqType | UserPreferenceReqType | UserRepoReqType): catchRt<UserProfileResType> {
return reqCatchV2(() => request({
url: '/api/v1/user/setting/save',
method: 'post',
data
}));
}
// 查询用户信息
export function getUserProfile(params: { username: string, type?: string }): Promise<AxiosResponse<UserProfile>> {
return request({
url: '/api/v1/user/setting/profile',
method: 'get',
params
});
}
// 查询用户活动
export function queryUserActivities(params: any): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/events',
method: 'get',
params
}, { customError: true });
}
// 查询用户活动-新接口
export function queryUserActivitiesNew(params: any): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/events/user',
method: 'get',
params
}, { customError: true });
}
// 查询用户项目
export function queryUserRepos(params: { user_id: string;[propName: string]: any; }): Promise<AxiosResponse<ProfileRepoItemResData[]>> {
return request({
url: `/api/v1/featured/project/profile_project?group_id=${params.username}`,
method: 'get',
params
});
}
// 查询用户创建的项目
export function queryUserCreateRepos(params: { user_name: string; search?: string, [propName: string]: any; }): Promise<AxiosResponse<ProfileRepoItemResData[]>> {
return request({
url: `/api/v1/profile/${params.user_name}/created_projects`,
method: 'get',
params
});
}
// 查询用户关注的项目
export function queryUserStarredRepos(params: { user_name: string;[propName: string]: any; }): Promise<AxiosResponse<ProfileRepoItemResData[]>> {
return request({
url: `/api/v1/profile/${params.user_name}/starred_projects`,
method: 'get',
params
}, { customError: true });
}
// 更新项目状态
export function updateRepoStatus(params: { type: string; group_id: string; resource_id: string; }): Promise<AxiosResponse<any>> {
return request({
url: `/api/v1/featured/${params.type}`,
method: 'post',
params
});
}
// 移除对应类型项目
export function removeRepoStatus(params: { type: string; group_id: string; resource_id: string; }): Promise<AxiosResponse<any>> {
return request({
url: `/api/v1/featured/${params.type}`,
method: 'delete',
params
});
}
// 查询用户关注数
export function getUserFollows(params: { username: string }): Promise<AxiosResponse<number>> {
return request({
url: '/api/v1/follow/followingCount',
method: 'get',
params
});
}
// 查询用户粉丝数
export function getUserFollowers(params: { username: string; followType: string; }): Promise<AxiosResponse<number>> {
return request({
url: '/api/v1/follow/followersCount',
method: 'get',
params
});
}
// 查询用户粉丝数和关注数
export function getUserFollowerCounts(params: { username: string; }): Promise<AxiosResponse<{ follow_count: number; fans_count: number }>> {
return request({
url: '/api/v1/follow/userBaseInfo',
method: 'get',
params
}, { customError: true });
}
// 查询登录用户是否关注某用户
export function checkHasFollowed(params: { username: string; otherUsername: string; followType: number }): Promise<AxiosResponse<boolean>> {
return request({
url: '/api/v1/follow/hasFollowed',
method: 'get',
params
});
}
// 查询特定用户组织列表
export function getUserOrgans(params: { user_name: string; page: number; per_page: number }): Promise<AxiosResponse<{ content: OrgData[] }>> {
return request({
url: `/api/v1/groups/${params.user_name}/list`,
method: 'get',
params
});
}
// 查询特定用户的贡献图
export function queryUserContributes(params: {
username: string;
period?: string;
year?: string;
}): Promise<AxiosResponse<{ [propName: string]: number }>> {
return request({
url: `/api/v1/events/${params.username}/contributions`,
method: 'get',
params
}, { customError: true });
}
// 关注某用户
export function followUser(params: { username: string; followedUsername: string; followType: number }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/follow',
method: 'post',
data: params
});
}
// 取消关注某用户
export function unfollowUser(params: { username: string; unfollowUsername: string; followType: number; }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/follow',
method: 'delete',
params
});
}
// 获取用户邮箱列表
export function getEmailList(params: { username: string; }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/getEmailList',
method: 'get',
params
});
}
export function getEmailListForCombobox(params: { username: string; }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/getEmailListForCombobox',
method: 'get',
params
});
}
// 设置并更新邮箱
export function setVerifyEmail(params: { objectId: string }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/verifyEmail',
method: 'get',
data: params
});
}
// 删除用户设置邮箱
export function deleteEmail(params: { email: string; }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/deleteEmail',
method: 'delete',
params
});
}
// 更新主邮箱设置
export function updateEmail(params: { username: string; email: string }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/updateEmail',
method: 'put',
data: params
});
}
// 发送更新邮箱验证码接口
export function sendEmailVeriCode(params: { username: string; email: string; }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/sendEmailVeriCode',
method: 'post',
data: params
});
}
// 发送更新邮箱验证码接口
export function verifyCodeEmail(params: { code: string; email: string; }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/verifyCodeEmail',
method: 'put',
params: params
});
}
// 设置密码
export function setPassword(params: { password: string; username: string; }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/setPassword',
method: 'post',
data: params
});
}
// 修改密码
export function updatePassword(params: { origin_password: string; password: string; username: string; }): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/updatePassword',
method: 'post',
data: params
});
}
// 判断是否有设置密码
export function passwordAvailable(): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user/passwordAvailable',
method: 'get'
});
}
// 获取当前用户加入的组织
export function getMyGroupsList(params: any): Promise<AxiosResponse<any>> {
return request({
url: '/api/v1/user_groups/related_me',
method: 'get',
params
});
}
/** 退出组织 */
export function leaveGroups(params: any): Promise<AxiosResponse<any>> {
return request({
url: `/api/v1/groups/${params.orgId}/leave`,
method: 'delete'
});
}
// 获取用户访问令牌列表
export function getImpersonationTokens(params: any): Promise<AxiosResponse<any>> {
return request({
url: `/api/v1/user/getImpersonationTokens`,
method: 'get',
params
});
}
// 创建用户访问令牌
export function addImpersonationTokens(params: any): Promise<AxiosResponse<any>> {
return request({
url: `/api/v1/user/${params.username}/impersonation_tokens`,
method: 'post',
data: params
});
}
// 删除用户访问令牌
export function deleteImpersonationTokens(params: any): Promise<AxiosResponse<any>> {
return request({
url: `/api/v1/user/${params.username}/impersonation_tokens/${params.id}`,
method: 'delete',
params: { name: params.name }
});
}
// 活动会话列表
export function getLatest(params: any): Promise<AxiosResponse<any>> {
return request({
url: `/api/v1/user/activity-session/latest`,
method: 'get'
});
}
// 删除活动会话
export function deleteOffline(params: any): Promise<AxiosResponse<any>> {
return request({
url: `/api/v1/user/activity-session/offline`,
method: 'put',
params
});
}
// 获取用户参与的项目
export function getUserProject(params: any): Promise<AxiosResponse<any>> {
return request({
url: `/api/v1/user_projects/related_me`,
method: 'get',
params
});
}
// 获取用户粉丝列表
export function getFollowersList(params: { username: string; pageNum: number; pageSize: number; }): Promise<AxiosResponse<{ content: FollowerData[]; total: number; }>> {
return request({
url: '/api/v1/follow/followers',
method: 'get',
params
}, { customError: true });
}
// 搜索用户列表
export function searchUserList(params: { keyword?: string; pageNum: number; pageSize: number; }): Promise<AxiosResponse<{ content: any[]; total: number; }>> {
return request({
url: '/api/v1/user/search',
method: 'get',
params
}, { customError: true });
}
// 获取用户关注列表
export function getFollowingList(params: { username: string; pageNum: number; pageSize: number; }): Promise<AxiosResponse<{ content: FollowerData[]; total: number; }>> {
return request({
url: '/api/v1/follow/followingList',
method: 'get',
params
}, { customError: true });
}
// 获取用户语言集合
export function getUserLangData(params: { type: string; user_name: string; }): Promise<AxiosResponse<string[]>> {
return request({
url: `/api/v1/profile/${params.user_name}/project_languages`,
method: 'get',
params
}, { customError: true });
}
// 获取用户关注的项目动态推送
export function getUserConcernEvents(params?: any): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/events/follower_events',
method: 'get',
params
}));
}
// 获取用户被邀请的项目列表
export function getUserInviteRepo(params?: any): Promise<AxiosResponse<string[]>> {
return request({
url: `/api/v1/invite/sourcePage`,
method: 'get',
params
}, { customError: true });
}
// 获取用户绑定的三方信息
export function getUserIdentity(params?: any): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/user/identity/list',
method: 'get',
params
}));
}
// 用户绑定三方平台
export function bindUserIdentity(data?: any): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/user/identity',
method: 'post',
data
}));
}
// 第三方平台解绑
export function unBindUserIdentity(data?: any): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/user/identity',
method: 'delete',
data
}));
}
// 获取当前用户的手机号
export function getLoginMobile(params?: any): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/user/mobile',
method: 'get',
params
}));
}
// 用户账号注销
export function userAccountDel(params?: any): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/user/del',
method: 'delete',
params
}));
}
// 获取第三方atomgit账号使用流水线
export function getAtomgitIdentity(): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/user/identity/atomgit',
method: 'get'
}));
}
// 获取登录弹窗配置
export function getLoginConfig(): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/config/isLogin',
method: 'get'
}));
}
// 获取登陆token
export function getUserToken(): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/user/oauth/token',
method: 'get'
}, {
customError: true
}));
}
// 获取用户信息
export function getUserInfo(): catchRt<any> {
return reqCatchV2(() => request({
url: '/api/v1/user/oauth/userInfo',
method: 'get'
}, {
customError: true
}));
}

185
src/api/user/types.ts Normal file
View File

@@ -0,0 +1,185 @@
export interface LoginMobile {
type: 'verifyCode'
mobile: string
code: string
}
export interface LoginPassword {
type: 'password'
username: string
password: string
}
export interface RegisterMobile {
type: 'register'
username: string
mobile: string
password: string
verificationcode: string
nickname: string
}
export type LoginReqType = 'register' | 'verifyCode' | 'password'
export interface RegisterReqType {
username: string
mobile: string
email?: string
nickname: string
password?: string
verificationcode?: string
[x: string]: any
}
export interface LoginResType {
domain_id?: string
email?: string
id?: string
mobile?: string
nickname?: string
username?: string
access_token?: string
refresh_token?: string
xauth_token?: string
}
export interface Profile {
setting_private: boolean;
website: string;
description: string;
location: string;
company: string;
email_private: boolean;
email?: string;
show_email?: string;
github_account: string;
bg_image: string;
}
export interface preferenceProfile {
highlight: string;
tab_space_len: number;
}
export interface repoProfile {
default_branch: string;
}
// 获取用户基本信息
export interface UserProfileResType {
profile: Profile;
nickname: string;
avatar: string;
}
// 用户修改资料参数
export interface UserProfileReqType {
profile: Partial<Profile>;
nickname: string;
avatar: String;
}
// 用户修改偏好设置参数
export interface UserPreferenceReqType {
profile: Partial<preferenceProfile>;
type: string;
}
// 用户修改项目设置参数
export interface UserRepoReqType {
profile: Partial<repoProfile>;
type: string;
}
// 用户详细信息
export interface UserProfile {
profile: Profile;
nickname: string;
nick_name?: string;
username: string;
fans: null;
concerns: null;
avatar: string;
}
// 组织信息
export interface OrgData {
id: number;
path: string;
name: string;
avatar_url: null;
full_path: string;
full_name: string;
web_url: string;
}
// 关注用户列表信息
export interface FollowerData {
user_id?: string;
follow_id?: string;
follow_type?: number;
ip: string;
remark?: string;
is_friend?: number;
create_time?: string;
avatar?: string;
nick_name?: string;
username?: string;
description?: string;
location?: string;
groupname?: string;
website?: string;
}
// 参数的项目接口信息
export interface projectItems {
star_count: number;
forks_count: number;
watch_count: null | number;
import_star_count: number;
import_forks_count: number;
import_watch_count: number;
id: number;
description: string;
name: string;
name_with_namespace: string;
path: string;
path_with_namespace: null | string;
develop_mode: string;
created_at: null | string;
updated_at: null | string;
archived: boolean;
is_kia: null | string;
ssh_url_to_repo: string;
http_url_to_repo: string;
web_url: string;
readme_url: null | string;
product_id: null | string;
product_name: null | string;
license_url: null | string;
license: null | string;
namespace: string;
namespace_info: {
id: number;
name: string;
path: string;
develop_mode: string;
region: null | string;
cell: null | string;
kind: string;
full_path: string;
full_name: string;
parent_id: null | string;
visibility_level: number;
enable_file_control: boolean;
owner_id: number;
},
mirror_project_data: null | string;
visibility: string;
open_issues_count: number;
open_merge_requests_count: number;
open_change_requests_count: number;
starred: boolean;
last_activity_at: Date;
main_repository_language: Array<string>;
forked_from_project: null | string;
permissions: number;
member_count: number;
repository_size: number;
topic_names: null | string;
is_recommend: number;
}