搜索结果列表页面开发

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

228
src/App.vue Normal file
View File

@@ -0,0 +1,228 @@
// eslint-disable-next-line vue/name-property-casing
<script setup lang="ts">
import { RouterView } from 'vue-router';
import { ref, onMounted, onBeforeUnmount, watchEffect } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { addEventListener, clearEvent } from '@/utils/eventBus';
import { useLogin } from './utils/hooks/useLogin';
import { useNotification } from './utils/hooks/useNotice';
import { useAccount } from './utils/hooks/useAccount';
import { useAccModal } from './utils/hooks/useAccModal';
import { NotificationService } from 'vue-devui/notification';
import { Message } from 'vue-devui/message';
import { getOrgInfo } from '@/views/Org/hooks/orgInfo';
import cookie from 'js-cookie';
import { useGlobalInfoStore } from '@/stores/Global';
import dayjs from 'dayjs';
import { getLoginConfig } from './api/user';
const globalInfo = useGlobalInfoStore();
const { login, unMount, isMounted } = useLogin();
const { openModal, closeModal, isMountedModal } = useAccModal();
const { notice } = useNotification();
const { RemoveInfo } = useAccount();
const status = ref(false);
const isPending = ref(false);
const router = useRouter();
const route = useRoute();
const toNotice = () => {
if (localStorage.getItem('validator_email') === 'invalid') {
notice();
}
};
const checkoutFirstTime = () => {
const uuid = cookie.get('uuid_tt_dd');
const firstTime = cookie.get('gitcode_first_time');
if (uuid && !firstTime) {
const expireDate = new Date(`${dayjs().year() + 2}-01-01 00:00:00`);
const expirationUTC = new Date(
Date.UTC(
expireDate.getFullYear(),
expireDate.getMonth(),
expireDate.getDate(),
expireDate.getHours(),
expireDate.getMinutes(),
expireDate.getSeconds()
)
);
const domainMatch = (location.host.match(/(gitcode..+)/) || []) as string[];
cookie.set('gitcode_first_time', dayjs().format('YYYY-MM-DD HH:mm:ss'), { expires: expirationUTC, domain: domainMatch[1] });
}
};
onMounted(() => {
/** pc端刷新窗口 */
toNotice();
addEventListener('logout', (options) => {
const token = localStorage.getItem('access_token');
if (!status.value) {
status.value = true;
if (isMounted()) {
setTimeout(() => {
status.value = false;
}, 2000);
} else {
NotificationService.open({
type: 'success',
title: 'Gitcode 提示',
content: token ? '你的登录信息已过期,请重新登录!' : '登录之后才能开启全新体验哦',
onClose: () => {
status.value = false;
}
});
}
token && RemoveInfo();
const data = typeof options === 'boolean' ? { Authorization: options } : options;
login(data);
}
});
addEventListener('login', (options) => {
login(options);
});
/** 403刷新页面一次 */
addEventListener('forbiddenRefresh', () => {
// 暂时跳转组织创建
if (route.path === '/org/create') {
localStorage.removeItem('refresh_count');
return;
}
if (!isPending.value) {
isPending.value = true;
if (!localStorage.getItem('refresh_count') && route.name !== '403') {
localStorage.setItem('refresh_count', 'pending');
router.go(0);
} else {
Message.warning({
message: '权限不足',
onClose: () => {
localStorage.removeItem('refresh_count');
}
});
}
}
});
/** mobile暂定全部重定向为首页 */
addEventListener('notice', toNotice);
window.addEventListener('message', (event) => {
if (event.origin === (import.meta as any).env.VITE_HOST) {
if (event.data.type === 'success') {
if (isMountedModal()) {
closeModal();
}
if (isMounted()) {
unMount();
}
if (event.data?.path) {
router.replace(event.data?.path);
} else {
router.go(0);
}
} else if (event.data.type === 'fail') {
Message.warning(event.data.message || '授权失败');
}
}
});
/** 获取用户组织配额权限 */
if (!localStorage.getItem('group_quota')) {
const { getUserCreateOrg } = getOrgInfo();
getUserCreateOrg();
}
checkoutFirstTime();
});
watchEffect(async() => {
if (route?.query?.isLogin && !localStorage.getItem('access_token')) {
if (!isMountedModal()) {
const cache_timeStamp = localStorage.getItem('cache_timeStamp');
const currentTimestamp = Date.now();
const oneDayMilliseconds = 24 * 60 * 60 * 1000;
// 获取不加防打扰的配置
let loginList = [];
if (route?.query?.isLogin !== '1') {
const res = await getLoginConfig();
loginList = res?.data?.data || [];
}
// isLogin为配置字符串时一直弹窗
if (loginList.includes(route?.query?.isLogin) || !cache_timeStamp || (Number(cache_timeStamp) + oneDayMilliseconds) < currentTimestamp) {
setTimeout(() => {
localStorage.setItem('cache_timeStamp', currentTimestamp.toString());
openModal();
}, 1000);
}
}
}
// 注册来源utm_source保存
if (route?.query?.utm_source) {
const currentTime = Date.now();
localStorage.setItem('utm_source_sign_time', currentTime.toString());
localStorage.setItem('utm_source_sign', JSON.stringify(route?.query?.utm_source));
}
});
onBeforeUnmount(() => {
clearEvent();
window.removeEventListener('message', () => {});
});
</script>
<template>
<RouterView :class="`g-theme-${globalInfo.globalTheme}`" />
</template>
<style lang="scss">
.global-notification {
&-mobile {
.devui-notification {
right: 15px;
left: 15px;
width: #{calc(100vw - 30px )};
top: 60px;
&__title {
padding: 0;
}
}
.devui-notification-item-container {
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
padding: 15px;
opacity: 1;
.devui-notification__item {
padding: 0;
}
}
}
&-pc {
.devui-notification {
width: 296px;
right: 22px;
top: 60px;
&__title {
padding: 0;
}
}
.devui-notification-item-container {
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
padding: 22px;
opacity: 1;
.devui-notification__item {
padding: 0;
}
}
}
.devui-notification__message {
margin-left: 0;
}
.icon-close {
font-size: 0 !important;
&:before {
content: ''
}
}
}
</style>

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; // 是否锁定:0:否;1:是;
is_pin?: number; // 是否置顶:0:否;1:是;
pin_date?: string;
is_category_pin?: number; // 是否分类置顶
pin_category_date?: string;
is_closed?: number; // 是否关闭
closed_date?: string;
is_answered?: number; // 回答是否采纳,0:否;1:是;
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; // 是否锁定:1:是;0:否
is_pin:number;
pin_date?:string;
is_category_pin:number;
pin_category_date?:string;
is_closed:number; // 是否关闭:1:是;0:否
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; // 是否采纳为答案:1:是;0:否
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;
}

318
src/assets/css/devui.scss Normal file
View File

@@ -0,0 +1,318 @@
/* devui css override */
// d-layout
div.devui-layout__header {
flex: none;
}
div.devui-layout__content {
flex: 1;
min-height: auto;
min-width: 0;
}
ul.devui-menu-vertical {
.devui-menu-item {
background: transparent;
align-items: center;
}
.devui-menu-item-select {
background: var(--color-CG300) !important;
border-radius: var(--border-radius);
&:after {
display: none;
}
}
}
.devui-input-slot__suffix > span {
color: var(--devui-text);
}
div.devui-tooltip {
z-index: var(--devui-z-index-pop-up, 1060);
background-color: var(--devui-feedback-overlay-bg, #464d6e);
border-radius: var(--devui-border-radius-feedback, 4px);
}
/* 隐藏必选符号 */
// .devui-form__label--required:before {
// display: none;
// content: '';
// }
// d-skeleton-item
.devui-skeleton-item {
&.devui-skeleton-item--square {
border-radius: var(--border-radius);
}
}
// d-tree
.devui-tree {
&__node,
&__node-title {
color: var(--color-font) !important;
}
}
// d-editor
.devui-code-editor {
.monaco-editor {
.line-numbers {
color: var(--color-lighter);
}
}
}
.devui-splitter {
&__collapse {
background-color: var(--color-lighter) !important;
}
}
// tab
.devui-menu-horizontal {
.devui-menu-item {
span {
font-weight: 400;
color: var(--color-light);
}
}
.devui-menu-item-select,
.devui-menu-active-parent,
.devui-menu-overflow-container:hover,
.devui-menu-item:hover {
span {
color: var(--color-light);
}
&:after {
background-color: var(--color-font) !important;
}
}
}
.devui-icon--operable.devui-icon__container {
display: inline-flex;
align-items: center;
}
.devui-menu-vertical {
.devui-menu-item:hover {
background-color: $devui-list-item-hover-bg;
border-radius: var(--border-radius);
}
}
// input输入框icon
.devui-input {
&__container {
i.icon {
&:before {
color: var(--color-CG500);
}
}
}
}
// date-range组件
.devui-range-date-picker-pro {
.devui-range-date-picker-pro__range-picker-icon {
svg {
width: 14px;
height: 14px;
}
}
}
// modal
.devui-modal {
&__header {
height: 40px !important;
}
}
// textarea 文字计数颜色
.devui-textarea__show-count {
color: var(--color-lighter) !important;
}
.devui-progress__content .devui-progress__line {
background: var(--color-CG300, #e4e9f0);
}
// radio button
.devui-radio-button {
&.active {
background-color: var(--color-primary) !important;
border-color: var(--color-primary) !important;
color: white;
}
}
// button
button.devui-button--solid--primary {
background-color: #5e7ce0;
border: none;
}
button.devui-button--solid--danger {
background-color: var(--devui-contrast, #c7000b);
border: none;
}
button.devui-button--outline {
background-color: #fff;
}
// 次要按钮样式
button.devui-button--solid--secondary {
border: var(--devui-btn-common-border-color) solid 1px;
border-radius: 4px;
background: #D1D1D1;
&:hover,
&:active,
&:focus {
border: var(--devui-btn-common-border-color) solid 1px;
color: var(--devui-text);
background: linear-gradient(0deg, rgba(188, 188, 208, 0.1) 0%, rgba(188, 188, 208, 0.1) 100%), var(--White, #FFF);
}
}
// d-avatar
.devui-avatar {
vertical-align: middle;
display: inline-flex;
align-items: center;
margin-top: auto;
margin-bottom: auto;
img {
background-color: white;
}
&.devui-avatar-square {
img,
.devui-avatar--style {
border-radius: var(--border-radius) !important;
}
&.radius-big {
img,
.devui-avatar--style {
border-radius: 8px !important;
}
}
}
}
.devui-result {
&__title {
color: var(--color-light);
}
&__desc {
color: var(--color-light);
}
&__extra {
color: var(--color-lighter);
}
}
.devui-tree {
&__node {
&-content {
&--value-wrapper {
div {
white-space: nowrap;
word-break: keep-all;
text-overflow: ellipsis;
overflow: hidden;
}
}
}
}
}
.devui-tabs__nav--slider > li.active {
text-shadow: none;
}
.devui-table {
&__tbody {
tr {
td {
border-bottom: 1px solid var(--color-border-light);
}
&:first-of-type {
td {
border-top: none;
&:first-of-type {
border-top-left-radius: var(--border-radius);
}
&:last-of-type {
border-top-right-radius: var(--border-radius);
}
}
}
&:last-of-type {
td {
border-bottom: none;
&:first-of-type {
border-bottom-left-radius: var(--border-radius);
}
&:last-of-type {
border-bottom-right-radius: var(--border-radius);
}
}
}
}
}
}
.devui-breadcrumb {
&__separator {
margin: 0 2px;
}
}
// .devui-input--error,.devui-select__selection--error,.devui-textarea--error {
// background-color: #fff;
// }
.devui-editable-select .devui-editable-select__inner {
max-height: 300px;
}
.devui-link-hover {
&:hover {
color: var(--devui-link) !important;
}
}
.devui-textarea__show-count {
color: var(--devui-text) !important;
}
//.devui-form__label-span {
// color: var(--devui-text) !important;
// font-size: 16px !important;
// line-height: 22px;
// font-weight: 500;
//}
.devui-checkbox {
padding: 3px 0;
}
.devui-radio__wrapper {
padding: 3px 0;
}
.devui-checkbox__label-text {
font-size: 16px;
}
.devui-radio.devui-radio--md span .devui-radio__label {
font-size: 16px;
}
.devui-radio-group div.devui-radio__wrapper {
height: auto;
}
.devui-radio__wrapper label.devui-radio {
display: flex;
align-items: center;
}
.button-content {
// font-weight: 600;
}
.devui-checkbox span.devui-checkbox__material {
border-color: var(--checkbox-border-color);
}
circle.devui-radio__material-outer {
stroke: var(--checkbox-border-color);
}
.devui-table--lg tbody>tr.devui-table__row>td,
.cardlist-item-padding {
padding: 16px 20px;
}

View File

@@ -0,0 +1,458 @@
// markdown
.dp-md-view {
pre {
position: relative;
code {
padding-right: 32px!important;
}
}
.md-view-copy-icon {
cursor: pointer;
position: absolute;
right: 8px;
top: 9px;
&:hover {
opacity: 0.5;
}
}
}
.g-md-container {
:deep(.md-toolbar-container) {
padding-right: 88px;
}
:deep(.dp-editor-md-preview-container.dp-md-view summary) {
cursor: pointer;
}
position: relative;
.g-md-preview-btn {
position: absolute;
top: 12px;
right: 16px;
color: var(--color-lighter);
&:hover {
:deep(.button-content) {
color: var(--color-primary) !important;
}
}
}
.g-md-upload-btn {
position: absolute;
left: 710px;
top: 10px;
cursor: pointer;
:deep(.devui-icon__container) {
display: inline-flex;
justify-content: center;
align-items: center;
}
:deep(.icon) {
color: var(--devui-icon-text, #71757f);
}
}
:deep(.devui-fullscreen) {
z-index: 999 !important;
}
}
:deep(.dp-md-container) {
border: none;
.CodeMirror {
border-radius: 3px;
pre {
word-break: break-all;
}
}
}
.dp-editor-md-preview-container.dp-md-view {
word-break: break-all;
line-height: normal;
* {
box-sizing: border-box;
}
/* 文章正文 */
p {
font-size: 14px;
color: var(--color-G900);
font-weight: normal;
line-height: 26px;
margin: 0;
overflow-x: auto;
overflow: hidden;
}
p:has(+ pre) {
margin-bottom: 8px;
}
span,
p span {
line-height: 1.5;
}
/* 加粗 */
strong {
font-weight: bold;
}
/* 斜体 */
i,
cite,
em,
var,
address,
dfn {
font-style: italic;
}
/* 上标 */
sup {
left: 2px;
}
/* 下标 */
sub {
margin: 0 2px;
}
/* 标题通用格式 */
h1,
h2,
h3,
h4,
h5,
h6 {
color: var(--color-G900);
margin: 0.67em 0;
font-weight: 600;
}
h1 {
font-size: 22px;
line-height: 32px;
margin-top: 24px;
margin-bottom: 16px;
}
h2 {
font-size: 20px;
line-height: 30px;
}
h3 {
font-size: 18px;
line-height: 28px;
}
h4 {
font-size: 16px;
line-height: 26px;
}
h5 {
font-size: 16px;
line-height: 24px;
}
h6 {
font-size: 16px;
line-height: 24px;
}
h1 code {
font-size: 28px;
}
h2 code {
font-size: 24px;
}
h3 code {
font-size: 22px;
}
h4 code {
font-size: 20px;
}
h5 code {
font-size: 18px;
}
h6 code {
font-size: 16px;
}
/* 列表(有序,无序) */
ul,
ol {
margin: 0 0 8px 0;
padding: 0;
font-size: 14px;
overflow: hidden;
overflow-x: auto;
color: var(--color-CG600);
}
li {
margin: 4px 0 0 18px;
}
ol,
ol > li {
list-style-type: decimal !important;
// 表达式,修复有序列表序号展示不全的问题
:nth-child(n+10){
margin-left: 24px;
}
:nth-child(n+100){
margin-left: 30px;
}
}
ul,
ul > li {
list-style-type: disc;
font-size: 14px;
margin-right: 11px;
color: var(--color-G900);
}
ol ul,
ol ul > li,
ul ul,
ul ul li {
// list-style: circle;
font-size: 14px;
list-style: none;
margin-left: 16px;
}
ul ul ul,
ul ul ul li,
ol ol,
ol ol > li,
ol ul ul,
ol ul ul > li,
ul ol,
ul ol > li {
list-style: square;
}
/* 任务列表 */
.task-list-item {
list-style: none;
margin: 8px 0 0 0;
}
.task-list-item label {
margin-left: 4px;
}
input[type=checkbox]+label, label+a {
vertical-align: middle;
}
input[type=checkbox]+label {
margin-left: 5px;
}
/* 图片 */
img {
margin: 8px 0;
max-width: 100%;
display: inline-block;
}
/* 引用 */
blockquote {
display: block;
padding: 16px;
margin: 0 0 24px;
border-left: 8px solid #dddfe4;
background: #eef0f4;
overflow: auto;
word-break: break-word !important;
}
blockquote ul,
blockquote ol {
margin-bottom: 0;
padding: 0;
font-size: 14px;
line-height: 22px;
}
blockquote ul li {
margin-bottom: 0;
}
blockquote ol li {
margin-bottom: 0;
}
/* 引用 - 文字 */
blockquote p {
font-size: 14px;
line-height: 22px;
color: #555666;
font-weight: normal;
margin-bottom: 0;
}
/* 分割线 */
hr {
margin: 24px 0;
border: none;
border-bottom: solid #ddd 1px;
}
/* 表格 */
tbody {
border: 0;
}
table tr {
border: 0;
border-top: 1px solid #ddd;
background-color: white;
}
table {
border-collapse: collapse;
display: table;
width: 100%;
text-align: center;
margin-bottom: 24px;
}
tbody {
border: 0;
}
table tr:nth-child(2n) {
background-color: #f7f7f7;
}
table tr th,
table tr td {
font-size: 14px;
color: #4f4f4f;
line-height: 22px;
border: 1px solid #ddd;
padding: 8px;
word-break: normal !important;
vertical-align: middle;
}
table tr th code,
table tr td code {
white-space: normal;
word-break: normal !important;
}
table tr th {
font-weight: bold;
background-color: #eff3f5;
}
/* 目录列表 */
dl {
margin: 24px;
}
dl dt {
margin: 8px;
font-weight: bold;
}
dl dd {
margin: 0 0 8px 40px;
}
dl dt dd {
margin: 8px;
}
/* pre */
pre {
margin-bottom: 24px;
white-space: pre-wrap;
padding: 0;
}
pre code {
// color: unset;
color: var(--color-G900);
}
/* 代码块字体 */
code,
kbd,
pre,
samp {
font-size: 14px;
line-height: 22px;
color: var(--color-G900);
}
code {
color: #c7254e;
// background-color: #f9f2f4;
background-color: var(--color-G200);
border-radius: 4px;
padding: 6px;
// display: inline;
}
kbd {
padding: 2px 8px;
border: 1px solid rgba(63, 63, 63, 0.25);
box-shadow: 0 1px 0 rgba(63, 63, 63, 0.25);
background-color: #fff;
color: #333;
border-radius: 4px;
display: inline-block;
margin: 0 2px;
white-space: nowrap;
}
/* 超链接 */
a {
// color: #4ea1db;
color: var(--color-B600);
text-decoration: none;
}
a:hover,
a:focus {
// color: #ca0c16;
color: var(--color-B600);
text-decoration: underline;
}
a:visited {
// color: #6795b5;
color: var(--color-B600);
}
/* abbr */
abbr[title],
abbr[data-original-title] {
cursor: help;
border-bottom: 1px dotted #999;
}
/* toc TODO: devui 尚未支持 */
.toc {
font-size: 18px;
line-height: 24px;
margin: 0 0 24px;
padding: 0;
}
.toc ul {
margin: 0 0 8px;
padding: 0;
}
.toc ul ul {
padding-left: 24px;
}
.toc ul li {
list-style-type: none;
margin: 8px 0 0 24px;
}
/* 脚注 TODO: devui 尚未支持*/
.footnote {
vertical-align: top;
position: relative;
top: -4px;
font-size: 12px;
}
.footnotes ol li {
font-size: 14px;
line-height: 22px;
margin: 0 0 8px 24px;
}
}

49
src/assets/css/jyh.scss Normal file
View File

@@ -0,0 +1,49 @@
/* devui css override */
// d-layout
.jyh-form {
.devui-form__label-span {
color: #595959;
font-family: HarmonyOS Sans SC;
font-weight: regular;
font-size: 14px;
line-height: 32px;
letter-spacing: 0px;
text-align: left;
}
.devui-form__label--start {
text-align: right;
}
.devui-form__item--horizontal {
margin-bottom: 0;
}
.jyh-form-operation {
margin-left: 20px !important;
}
}
.jyh-table {
.devui-table__cell {
color: #191919;
font-family: HarmonyOS Sans SC;
font-weight: regular;
font-size: 14px;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
.devui-table__cell a {
cursor: pointer;
color: #0A59F7;
font-family: HarmonyOS Sans SC;
font-weight: regular;
font-size: 14px;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
.devui-table__row td {
padding-top: 10px !important;
padding-bottom: 10px !important;
}
}

458
src/assets/css/main.scss Normal file
View File

@@ -0,0 +1,458 @@
/* 引入全局css变量 */
@import './variable.css';
@import './devui.scss';
@import './theme.scss';
@import './jyh.scss';
@import './mixins/index.scss';
/* 引入tailwindCSS */
@tailwind base;
@tailwind components;
@tailwind utilities;
// 基础CSS
html,
body,
#app {
height: 100%;
-webkit-font-smoothing: antialiased;
// scorll 事件失效 overflow-y: overlay
}
html {
overflow-y: scroll; // html本身没有滚动 为了防止自定义滚动条出现时界面抖动,需要预留轨道
}
html body {
background-color: $devui-global-bg;
font-size: var(--text-sm);
color: var(--color-font);
}
input::placeholder,
textarea::placeholder {
color: var(--color-lighter);
}
// 解决滚动条占用内容宽度
// html {
// overflow-y: scroll;
// }
// :root {
// overflow-y: auto;
// overflow-x: hidden;
// }
// :root body {
// position: absolute;
// }
// body {
// width: 100vw;
// overflow: hidden;
// }
// 兼容火狐浏览器
:focus-visible {
outline: none;
}
// 自定义class
.g-border {
border: 1px solid var(--devui-line);
border-radius: var(--border-radius);
&-light {
border: 1px solid var(--color-border-light);
border-radius: var(--border-radius);
}
}
.g-card,
.g-content-card {
background-color: $devui-base-bg;
box-shadow: $devui-shadow-length-base $devui-light-shadow;
border-radius: var(--border-radius);
}
.g-main-content {
line-height: 30px;
}
.g-sub-content {
line-height: 20px;
}
.g-border-bottom {
border-bottom: solid 1px var(--color-G200);
}
.g-icon-pointer {
cursor: pointer;
&:hover {
color: var(--color-link) !important;
}
}
.g-border-radius-top-no {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.g-icon-right {
vertical-align: middle;
margin-right: 4px;
}
.g-icon-left {
vertical-align: middle;
margin-left: 8px;
}
.g-drop-menu {
width: 100px;
padding: 0 16px;
}
.g-mid-line {
width: 0.5px;
height: 16px;
background: var(--color-border-light);
}
.g-row-line {
height: 1px;
width: 100%;
background: var(--color-G300);
}
.g-max-width {
width: 90%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.g-font-bold {
font-weight: 600;
}
.g-label-font {
.devui-form__label {
font-weight: 500;
}
}
/* 滚动条样式自定义 */
body::-webkit-scrollbar, body>* ::-webkit-scrollbar {
width: 6px;
height: 4px;
}
body::-webkit-scrollbar-thumb, body>* ::-webkit-scrollbar-thumb {
border-radius: 8px;
background-color: var(--devui-disabled-text);
&:hover{
background-color: var(--devui-placeholder)
}
}
body::-webkit-scrollbar-track {
background: transparent;
}
body::-webkit-scrollbar-corner {
background: transparent;
}
.clearfix {
&:after {
content: '';
clear: both;
visibility: hidden;
display: block;
}
}
.space-y-20 > *:not(:last-child) {
margin-bottom: 20px;
}
/* 分隔符 | */
.g-delimiter {
display: inline-block;
width: 1px;
height: 20px;
background: var(--color-G300);
vertical-align: middle;
}
.g-input-border {
.devui-input__wrapper:not(.devui-input--focus) {
border-color: var(--devui-line, #d7d8da);
}
.devui-input-slot__prepend,
.devui-input-slot__append {
border-color: var(--devui-line, #d7d8da);
}
}
.devui-select__dropdown .devui-select__dropdown--empty {
padding: 4px 8px;
}
/* 输入框 去掉hover效果*/
.devui-input__wrapper:not(.devui-input--error):not(.devui-input--disabled):not(.devui-input--focus):hover {
border-color: var(--devui-line, #d7d8da);
}
/* 多行文本输入框 去掉hover效果*/
.devui-textarea:not(.devui-textarea--error):not(.devui-textarea--disabled):not(.devui-textarea--focus):hover {
border-color: var(--devui-line, #d7d8da);
}
/* 自动补全输入框 去掉hover效果*/
.devui-auto-complete-input__wrapper:not(.devui-auto-complete--disabled):not(.devui-auto-complete-input__wrapper--error):hover {
border-color: var(--devui-line, #d7d8da);
}
/* 可输入下拉选择框 去掉hover效果*/
.devui-editable-select-input__wrapper:not(.devui-editable-select-input__wrapper--disabled):not(.devui-editable-select-input__wrapper--focus):hover {
border-color: var(--devui-line, #d7d8da);
}
/* 分页 去掉hover效果*/
.devui-pagination .devui-pagination__size:hover {
border-color: var(--devui-line, #d7d8da);
}
/* 数字输入框 去掉hover效果*/
.devui-input-number:hover .devui-input-number__control-buttons:not(.disabled) {
border-color: var(--devui-line, #d7d8da);
}
.devui-input-number:hover .devui-input-number__input-box:not(.disabled) {
border: 1px solid var(--devui-line, #9b9fa8);
}
/* 下拉框 去掉hover效果*/
.devui-select__selection:hover {
border-color: var(--devui-line, #d7d8da);
}
/* 时间范围选择 去掉hover效果 */
.devui-range-date-picker-pro .devui-range-date-picker-pro__range-picker:not(.devui-range-date-picker-pro--error):not(.devui-range-date-picker-pro--disabled):hover {
border-color: var(--devui-line, #d7d8da);
}
.g-add-border {
border-color: var(--devui-line, #d7d8da);
}
.g-z-index-9 {
z-index: 9 !important;
}
.g-z-index-9999 {
z-index: 9999 !important; // 9的层级低于列表的遮罩层
}
.g-hidden-scrollbar {
scrollbar-width: none;
scrollbar-color: transparent transparent;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none;
}
&::-webkit-scrollbar-horizontal {
display: none;
}
}
.g-discussion-item .dp-md-container .dp-md-content-container {
min-height: 150px;
}
// modal相关
.g-modal-footer {
display: flex;
padding: 20px;
gap: 8px;
justify-content: flex-end;
}
.row-reverse {
display: flex;
justify-content: flex-start;
flex-direction: row-reverse;
}
.ellipsis {
white-space: nowrap;
word-break: keep-all;
text-overflow: ellipsis;
overflow: hidden;
}
.ellipsis-pre {
white-space: pre-line;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
}
.ellipsis-two-line {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.ellipsis-three-line {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
.absolute-full {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: auto;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.inline-center {
display: inline-flex;
align-items: center;
justify-content: center;
}
// 重置a标签的默认和hover色值
.reset-hover {
color: unset;
&:hover {
color: unset;
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.spin {
animation: spin 2s linear infinite;
transform-origin: center center;
}
// 重写RadioGroup样式
.g-radio-group {
&.devui-radio-group {
background-color: var(--color-G100);
padding: 2px;
.devui-radio-button {
border: none;
line-height: 22px;
height: 28px;
color: var(--color-CG600);
&:first-child {
border-left: none !important;
}
&.active {
color: #fff;
box-shadow: 0px 2px 6px 0px rgba(37, 43, 58, 0.12);
border-radius: var(--border-radius);
font-weight: 500;
}
}
}
}
.border-none {
border: none !important;
}
input {
background-color:transparent !important;
// appearance: none;
&:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
-webkit-text-fill-color: inherit !important;
background-color: transparent !important;
background-image: none;
transition: background-color 36000s ease-in-out 0s; //背景色透明 生效时长 过渡效果 启用时延迟的时间
}
&:-moz-autofill, textarea:-moz-autofill, select:-moz-autofill {
-webkit-text-fill-color: inherit !important;
background-color: transparent !important;
background-image: none;
transition: background-color 36000s ease-in-out 0s; //背景色透明 生效时长 过渡效果 启用时延迟的时间
}
}
@media screen and (max-width: 1536px) {
.g-padding-x {
padding: 0 32px;
}
}
@media screen and (max-width: 768px) {
.g-padding-x {
padding: 0 16px;
}
}
.g-content-card-v2 {
background-color: $devui-global-bg;
border-radius: $devui-border-radius-card;
border: 1px solid var(--gray-border-color);
}
.g-number {
border-radius: 4px;
padding: 0 4px;
background: var(--gray-bg-color);
font-size: 12px;
line-height: 16px;
color: var(--devui-text);
}
.font-color-t1 {
color: $devui-text;
}
.font-color-t2 {
color: $devui-aide-text;
}
.font-color-placeholder {
color: $devui-placeholder;
}
.g-large-title-font {
font-size: 22px;
line-height: 22px;
font-weight: 500;
}
.g-divide-line {
height: 1px;
width: 100%;
background: var(--devui-dividing-line);
margin: 32px 0
}
.g-tip-text {
font-size: var(--devui-font-size);
line-height: 20px;
color: $devui-placeholder;
}
// 新版设计统一设置标题样式 大小颜色行高
.unify-settingTitle-title{
font-weight: 700;
line-height: 34px;
font-size: 24px;
color: var(--devui-text);
}
// 项目设置页面标题
.repo-settings-title {
@apply text-xl mb-[12px] flex items-center justify-between font-semibold;
}
// 下拉框动效
.arrow-down{
transition: transform var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1));
transform-origin: center;
transform: rotateZ(0deg) !important;
}
.arrow-up{
transition: transform var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1));
transform-origin: center;
transform: rotateZ(180deg) !important;
}

View File

@@ -0,0 +1,147 @@
// 自定义 按钮额外主题 红绿橙
button.devui-button {
// 实心按钮
&--solid {
//绿色按钮
&--success,
&--operable {
background-color: $v2-color-success;
&:hover {
background-color: $v2-color-success-hover;
}
&:active {
background-color: $v2-color-success-active;
}
&:disabled {
background-color: $v2-color-success-disable;
}
}
// 橙色按钮
&--warning {
background-color: $v2-color-warning;
&:hover {
background-color: $v2-color-warning-hover;
}
&:active {
background-color: $v2-color-warning-active;
}
&:disabled {
background-color: $v2-color-warning-disable;
}
}
// 暗红按钮
&--error {
background-color: $v2-color-error;
&:hover {
background-color: $v2-color-error-hover;
}
&:active {
background-color: $v2-color-error-active;
}
&:disabled {
background-color: $v2-color-error-disable;
}
}
}
//镂空按钮
&--outline {
&--success,
&--operable {
color: $v2-color-success;
border-color: $v2-color-success;
&:hover {
color: $v2-color-success-hover;
border-color: $v2-color-success-hover;
}
&:active {
color: $v2-color-success-active;
border-color: $v2-color-success-active;
}
&:disabled {
color: $v2-color-success-disable;
border-color: $v2-color-success-disable;
}
}
// 橙色按钮
&--warning {
color: $v2-color-warning;
border-color: $v2-color-warning;
&:hover {
color: $v2-color-warning-hover;
border-color: $v2-color-warning-hover;
}
&:active {
color: $v2-color-warning-active;
border-color: $v2-color-warning-active;
}
&:disabled {
color: $v2-color-warning-disable;
border-color: $v2-color-warning-disable;
}
}
// 暗红按钮
&--error {
color: $v2-color-error;
border-color: $v2-color-error;
&:hover {
color: $v2-color-error-hover;
border-color: $v2-color-error-hover;
}
&:active {
color: $v2-color-error-active;
border-color: $v2-color-error-active;
}
&:disabled {
color: $v2-color-error-disable;
border-color: $v2-color-error-disable;
}
}
}
//文字按钮
&--text {
&--success,
&--operable {
color: $v2-color-success;
&:hover {
color: $v2-color-success-hover;
}
&:active {
color: $v2-color-success-active;
}
&:disabled {
color: $v2-color-success-disable;
}
}
&--warning {
color: $v2-color-warning;
&:hover {
color: $v2-color-warning-hover;
}
&:active {
color: $v2-color-warning-active;
}
&:disabled {
color: $v2-color-warning-disable;
}
}
&--error {
color: $v2-color-success;
&:hover {
color: $v2-color-success-hover;
}
&:active {
color: $v2-color-success-active;
}
&:disabled {
color: $v2-color-success-disable;
}
}
}
}

View File

@@ -0,0 +1,34 @@
@import './variables.scss';
.v2-g-card {
position: relative;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 1px solid $card-border-color;
border-radius: $card-border-radius;
color: $card-text-color;
}
.v2-g-card-header:first-child {
border-radius: $card-border-radius $card-border-radius 0 0;
}
.v2-g-card-header {
margin-bottom: 0;
padding: $card-padding;
background-color: $card-border-header-bg;
border-bottom: 1px solid $card-border-color;
border-top-left-radius: $card-border-radius;
border-top-right-radius: $card-border-radius;
}
.v2-g-card-body {
padding: $card-padding;
}
.v2-g-card-header:only-child {
border-bottom-left-radius: $card-border-radius;
border-bottom-right-radius: $card-border-radius;
margin-bottom: -1px;
}

View File

@@ -0,0 +1,2 @@
@import './card.scss';
@import './button.scss';

View File

@@ -0,0 +1,21 @@
// 按钮 scss 变量
$v2-color-success: #10a35c;
$v2-color-success-hover: #31a26c;
$v2-color-success-active: #31a26c;
$v2-color-success-disable: #d6ece2;
$v2-color-warning: #ed5f22;
$v2-color-warning-hover: #f07a47;
$v2-color-warning-active: #f07a47;
$v2-color-warning-disable: #fce4da;
$v2-color-error: #da203e;
$v2-color-error-hover: #da203e;
$v2-color-error-active: hsla(350, 74%, 44%, 1);
$v2-color-error-disable: #fce4da;
$card-border-color: #e3e3ee;
$card-padding: 16px;
$card-border-radius: 8px;
$card-border-header-bg: #f9f9fb;
$card-text-color: #3b3e55;

16
src/assets/css/theme.scss Normal file
View File

@@ -0,0 +1,16 @@
/**
* 网站主题(暂定前端控制)
*/
// 亮色
.g-theme-light {
.dp-editor-md-preview-container.dp-md-view [src$="#gh-dark-mode-only"] {
display: none;
}
}
// 暗色
.g-theme-dark {
.dp-editor-md-preview-container.dp-md-view [src$="#gh-light-mode-only"] {
display: none;
}
}

View File

@@ -0,0 +1,78 @@
:root {
--color-G100: #FBFBFB;
--color-G150: #F6F6F8;
--color-G200: #F0F1F2;
--color-G300: #E6E6E8;
--color-G400: #D1D2D4;
--color-G500: #B3B4B5;
--color-G600: #9A9B9C;
--color-G700: #7E7E80;
--color-G800: #5B5B5C;
--color-G900: #2D2D2E;
--color-G1000: #000000;
--color-CG100: #F8F9FB;
--color-CG200: #F4F7F9;
--color-CG300: #E4E9F0;
--color-CG400: #CAD0D9;
--color-CG500: #9FA7B3;
--color-CG600: #707A87;
--color-CG700: #505A69;
--color-CG800: #3B4655;
--color-CG900: #252D3B;
--color-CG950: #151A26;
--color-DP100: #FDF4F6;
--color-DP200: #FAE5EC;
--color-DP300: #F4C7D5;
--color-DP400: #EA92AD;
--color-DP500: #E05E86;
--color-DP600: #B64C6D;
--color-DP700: #963F59;
--color-DP800: #652A3C;
--color-DP900: #3E1A25;
--color-DP950: #261017;
--color-B300: #AECCFC;
--color-B400: #6FA3F7;
--color-B500: #3B82F6;
--color-B600: #2562C4;
--color-R500: #F2050D;
--color-O500: #FF6C17;
--color-Y100: #FEF6E5;
--color-Y200: #FCE7BB;
--color-Y500: #F5AB0B;
--color-GN500: #0EB07B;
--color-linear100: linear-gradient(180deg, #FCFCFC 0%, #F8F9FB 100%);
--color-linear200: linear-gradient(180deg, #F8F9FA 0%, #F0F1F2 100%);
--color-primary: var(--color-B500);
--color-primary-hover: var(--color-B400);
--color-primary-active: var(--color-B600);
--color-primary-disable: var(--color-B300);
--color-danger: var(--color-R500);
--color-success: var(--color-GN500);
--color-tip: var(--color-Y500);
--color-warning: var(--color-O500);
--color-link: var(--color-B600);
--color-font: var(--color-G900);
--color-light: var(--color-CG600);
--color-lighter: var(--color-CG500);
--color-disabled: var(--color-CG500);
--color-border: var(--color-G300);
--color-border-light: var(--color-G200);
--color-button-border: var(--color-G400);
--color-button-border-hover: var(--color-B500);
--w-normal: 1440px;
--w-sm: 1100px;
--w-xs: 720px;
--spacing-normal: 32px;
--text-xs: 12px;
--text-sm: 14px;
--text-base: 16px;
--text-lg: 18px;
--text-xl: 20px;
--text-2xl: 22px;
--border-radius: 3px;
--gray-border-color: #E3E3EE;
--gray-bg-color: #e3e3ed;
--tab-active-bg: #F1F1F8;
--checkbox-border-color: #D1D1E0;
}

View File

@@ -0,0 +1,54 @@
{
"devui-text": "#000000",
"devui-aide-text": "#3B3E55",
"devui-placeholder": "#9C9DB4",
"devui-disabled-text": "#BCBCD0",
"devui-light-text": "#FFFFFF",
"devui-icon-fill": "#000000",
"devui-icon-fill-weak": "#3B3E55",
"devui-icon-fill-hover": "#3B3E55",
"devui-icon-disabled-color": "#F1F1F8",
"devui-icon-bg": "#FFFFFF",
"devui-brand": "#DA203E",
"devui-shape-icon-fill": "#BCBCD0",
"devui-shape-icon-fill-hover": "#8B8CA7",
"devui-shape-icon-fill-disabled": "#D1D1E0",
"devui-dividing-line": "#F1F1F8",
"devui-line": "#F9F9FB",
"devui-disabled-line": "#F1F1F8",
"devui-form-control-line-hover": "#8B8CA7",
"devui-form-control-line-active": "#F1F1F8",
"devui-primary": "#000000",
"devui-primary-hover": "#323232",
"devui-primary-active": "#000000",
"devui-primary-disabled": "#E3E3EE",
"devui-btn-common-bg": "#FFFFFF",
"devui-btn-common-bg-hover": "#F9F9FB",
"devui-disabled-bg": "#F9F9FB",
"devui-btn-common-border-color": "#E3E3EE",
"devui-btn-common-border-color-hover": "#8B8CA7",
"devui-btn-common-border-disabled": "#E3E3EE",
"devui-gray-form-control-bg": "#F9F9FB",
"devui-gray-form-control-hover-bg": "#F1F1F8",
"devui-link": "#2951E0",
"devui-link-light": "#000000",
"devui-link-disabled": "#F1F1F8",
"devui-icon-hover-bg": "#F1F1F8",
"devui-icon-active-bg": "#E3E3EE",
"devui-list-item-active-bg": "#F1F1F8",
"devui-global-bg": "#F9F9FB",
"devui-connected-overlay-b": "#FFFFFF",
"devui-list-item-hover-bg": "#FFFFFF",
"devui-feedback-overlay-bg": "#3F425A",
"devui-danger-bg": "#FFECE8",
"devui-danger": "#DA203E",
"devui-contrast-hover": "#CB272D",
"devui-contrast-active": "#841527",
"devui-danger-text": "#A1151E",
"devui-warning-bg": "#FFF7E8",
"devui-warning": "#FF7D00",
"devui-warning-text": "#CC5120",
"devui-success-bg": "#E8FFEA",
"devui-success": "#10A35C",
"devui-success-text": "#006622"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

BIN
src/assets/imgs/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 519 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="38px" height="37px" viewBox="0 0 38 37" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic/gitcode-logo</title>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Git-Code整个页面-Copy" transform="translate(-821.000000, -1204.000000)" fill="#595959">
<g id="ic/gitcode-logo" transform="translate(820.000000, 1203.000000)">
<path d="M38.026863,19.9227216 C37.0709147,17.6419518 35.2163682,15.6811889 31.8116721,15.4114058 C28.8393075,15.1758971 25.5150372,15.6469146 23.3350543,16.1182714 C19.9446108,16.5896282 18.9757672,18.4747161 19.3008643,20.1253134 C19.6989216,22.1485167 22.8365495,22.0070078 24.9303375,21.7036292 C25.8082354,21.576373 28.2664851,21.1498103 28.9054807,21.0666696 C32.5382199,20.5956522 32.7940896,22.7976928 32.2962635,24.1303193 C31.3274199,26.7222728 28.7161235,28.585303 26.9681329,29.3142263 C25.112229,30.0879438 22.6034162,30.7900584 19.9999248,30.8993291 C19.9992461,30.8993291 7.35100169,32.1416886 9.04605376,19.4174298 C9.20758425,18.2073085 9.4895839,17.1512521 9.86761954,16.2302568 C10.386146,14.9661789 9.93684689,12.8574595 9.45361283,11.5804863 L9.45361283,11.5804863 C9.38913637,11.4101327 9.53845027,11.2360463 9.72203849,11.2669271 L9.8475979,11.2879668 C11.2552207,11.5238149 13.1752617,11.9985652 14.4651301,11.4023277 C15.9328179,10.7239675 17.5311553,10.4090509 19.0514422,10.3011377 C20.658942,10.1867768 22.4228821,8.61321199 23.6231622,7.56699667 L23.6231622,7.56699667 C23.7622956,7.4458488 23.9835517,7.51643355 24.0218982,7.69391348 L24.2401001,8.70551513 C24.4837532,9.78430803 25.8319899,11.2068622 26.81305,11.2594615 C27.8874314,11.3171509 29.0195022,11.0463498 29.7728587,10.4497729 C32.1710435,8.55212903 31.733961,4.9984583 29.09891,3.62816395 C21.9729043,-0.0782141739 13.3479907,0.841423688 6.89254016,6.82823223 C-0.330858928,14.1503821 -0.454382243,25.5966496 6.89254016,32.7450524 C9.94702738,35.7167383 13.8064523,37.3731045 17.7995809,37.7976311 C17.9553425,37.8176527 18.1138188,37.8285119 18.2702591,37.8454794 C18.3520423,37.8543025 18.4338256,37.8627862 18.5156089,37.8705913 C19.0555144,37.9221724 19.5991527,37.9611977 20.1516141,37.9686634 C20.2758162,37.9649305 20.3973034,37.9574648 20.520148,37.9523746 C21.6498434,37.9374432 22.7791994,37.8179921 23.8976962,37.5970754 C29.6649454,36.5946362 33.3095619,33.6198961 36.3935726,28.9545156 C37.2154777,27.7107987 37.8059463,26.3622227 38.2270793,24.9695313 C38.729317,23.3090929 38.6984362,21.5254705 38.026863,19.9227216 L38.026863,19.9227216 Z" id="logo"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="110px" height="326px" viewBox="0 0 110 326" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>组织背景</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#FFFFFF" stop-opacity="0.484871818" offset="100%"></stop>
</linearGradient>
<path d="M3,0 L107,0 C108.656854,-3.04359188e-16 110,1.34314575 110,3 L110,323 C110,324.656854 108.656854,326 107,326 L3,326 C1.34314575,326 2.02906125e-16,324.656854 0,323 L0,3 C-2.02906125e-16,1.34314575 1.34314575,3.04359188e-16 3,0 Z" id="path-2"></path>
<linearGradient x1="61.5642024%" y1="0%" x2="40.6565139%" y2="135.186954%" id="linearGradient-4">
<stop stop-color="#FFF9EF" stop-opacity="0.301023683" offset="0%"></stop>
<stop stop-color="#FFFFFF" stop-opacity="0.298845198" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="背景图切图" transform="translate(-308.000000, -3151.000000)">
<g id="组织背景" transform="translate(308.000000, 3151.000000)">
<mask id="mask-3" fill="white">
<use xlink:href="#path-2"></use>
</mask>
<use id="蒙版" fill="url(#linearGradient-1)" xlink:href="#path-2"></use>
<path d="M109.5,162.083033 C115.041362,157.128754 121.81075,153.444944 129.403864,151.548833 L144.579664,147.759214 C151.543348,146.02028 156.428571,139.770544 156.428571,132.600737 L156.428571,123.082723 C138.201634,116.647779 125.142857,99.2846692 125.142857,78.875 C125.142857,52.9866523 146.153495,32 172.071429,32 C197.989362,32 219,52.9866523 219,78.875 C219,99.2846692 205.941224,116.647779 187.714286,123.082723 L187.714286,132.600737 C187.714286,154.110158 173.058616,172.859366 152.167565,178.076167 L136.991764,181.865786 C131.97171,183.119367 128.031797,186.717136 126.223536,191.313881 C143.883763,198.043662 156.428571,215.121005 156.428571,235.125 C156.428571,261.013347 135.417934,282 109.5,282 C83.5820657,282 62.5714286,261.013347 62.5714286,235.125 C62.5714286,215.121005 75.1162371,198.043662 92.7764639,191.313881 C90.9682028,186.717136 87.0282899,183.119367 82.0082359,181.865786 L66.8324352,178.076167 C45.9413839,172.859366 31.2857143,154.110158 31.2857143,132.600737 L31.2857143,123.082723 C13.0587765,116.647779 0,99.2846692 0,78.875 C0,52.9866523 21.0106371,32 46.9285714,32 C72.8465058,32 93.8571429,52.9866523 93.8571429,78.875 C93.8571429,99.2846692 80.7983664,116.647779 62.5714286,123.082723 L62.5714286,132.600737 C62.5714286,139.770544 67.4566517,146.02028 74.4203355,147.759214 L89.5961362,151.548833 C97.1892498,153.444944 103.958638,157.128754 109.5,162.083033 L109.5,162.083033 Z M46.5,94 C55.0604136,94 62,87.0604136 62,78.5 C62,69.9395864 55.0604136,63 46.5,63 C37.9395864,63 31,69.9395864 31,78.5 C31,87.0604136 37.9395864,94 46.5,94 Z M109.5,251 C118.060414,251 125,244.060413 125,235.5 C125,226.939587 118.060414,220 109.5,220 C100.939586,220 94,226.939587 94,235.5 C94,244.060413 100.939586,251 109.5,251 Z M171.5,94 C180.060413,94 187,87.0604136 187,78.5 C187,69.9395864 180.060413,63 171.5,63 C162.939587,63 156,69.9395864 156,78.5 C156,87.0604136 162.939587,94 171.5,94 Z" id="形状" fill="url(#linearGradient-4)" fill-rule="nonzero" mask="url(#mask-3)"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1920px" height="1004px" viewBox="0 0 1920 1004" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 30</title>
<defs>
<rect id="path-1" x="0" y="0" width="1920" height="1004"></rect>
<linearGradient x1="94.3102447%" y1="43.1125208%" x2="2.84107774%" y2="56.3403538%" id="linearGradient-3">
<stop stop-color="#E4E4E4" offset="0%"></stop>
<stop stop-color="#EEEEEE" offset="100%"></stop>
</linearGradient>
<linearGradient x1="92.1439868%" y1="41.9983606%" x2="9.76165698%" y2="58.5681846%" id="linearGradient-4">
<stop stop-color="#EBEBEB" offset="0%"></stop>
<stop stop-color="#F1F1F1" offset="100%"></stop>
</linearGradient>
<path d="M2005.51527,468.98743 C2015.9237,509.769627 2002.98754,553.861381 1974.10014,599.098586 C1939.50011,653.281687 1882.08665,708.641714 1807.17044,762.467622 C1654.86518,871.896122 1431.14644,973.798924 1172.40219,1042.79814 C913.657949,1111.79736 668.716338,1134.872 481.83995,1115.89293 C389.918821,1106.55746 312.384847,1087.18381 255.199203,1057.47715 C206.893494,1032.38343 173.318045,1000.17976 162.230388,958.996865 C151.142732,917.813969 164.041208,873.217122 193.26846,827.447715 C227.868496,773.264614 285.281948,717.904587 360.198163,664.078679 C512.503425,554.650179 736.222161,452.747377 994.966407,383.748161 C1253.71065,314.748946 1498.65226,291.674297 1685.52865,310.653374 C1777.44978,319.988841 1854.98375,339.362496 1912.1694,369.069149 C1960.47511,394.162876 1994.05056,426.366541 2005.13821,467.549437 L2005.51527,468.98743 Z" id="path-5"></path>
<mask id="mask-6" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="1850.79617" height="818" fill="white">
<use xlink:href="#path-5"></use>
</mask>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Git-Code整个页面" transform="translate(0.000000, -2285.000000)">
<g id="编组-30" transform="translate(0.000000, 2285.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<use id="矩形备份-3" fill="#EDEDED" xlink:href="#path-1"></use>
<g id="下内阴影备份-8" stroke-dasharray="36,32" mask="url(#mask-2)" fill="url(#linearGradient-3)" stroke="url(#linearGradient-4)" stroke-width="100">
<use mask="url(#mask-6)" xlink:href="#path-5"></use>
</g>
<g id="编组备份" opacity="0.451587495" mask="url(#mask-2)" stroke="#E6E6E6" stroke-width="4">
<g transform="translate(77.000000, 63.000000)">
<line x1="61" y1="241.5" x2="500" y2="241.5" id="路径-3" fill="none"></line>
<line x1="211" y1="137.5" x2="650" y2="137.5" id="路径-3备份-10" fill="none"></line>
<path d="M68,241 C93.2612926,233.060117 110.446927,209.643959 110.446927,183.164256 L110.446927,182.329248 C110.446927,157.294596 130.741523,137 155.776175,137 L199,137 L199,137" id="路径-3备份" fill="none"></path>
<path d="M335,346 C360.261293,338.060117 377.446927,314.643959 377.446927,288.164256 L377.446927,287.329248 C377.446927,262.294596 397.741523,242 422.776175,242 L466,242 L466,242" id="路径-3备份-2" fill="none" opacity="0.579661051" transform="translate(400.500000, 294.000000) scale(1, -1) translate(-400.500000, -294.000000) "></path>
<circle id="椭圆形" fill="#FFFFFF" fill-rule="evenodd" cx="34.5" cy="241.5" r="32.5"></circle>
<circle id="椭圆形备份-6" fill="#F7F7F7" fill-rule="evenodd" cx="198.5" cy="241.5" r="32.5"></circle>
<circle id="椭圆形备份-10" fill="#FFFFFF" fill-rule="evenodd" cx="198.5" cy="137.5" r="32.5"></circle>
<circle id="椭圆形备份-8" fill="#F7F7F7" fill-rule="evenodd" cx="301.5" cy="241.5" r="32.5"></circle>
<circle id="椭圆形备份-9" fill="#FFFFFF" fill-rule="evenodd" cx="467.5" cy="241.5" r="32.5"></circle>
<circle id="椭圆形备份-18" fill="#F7F7F7" fill-rule="evenodd" cx="1276.5" cy="448.5" r="32.5"></circle>
<circle id="椭圆形备份-11" fill="#F7F7F7" fill-rule="evenodd" opacity="0.579661051" cx="467.5" cy="344.5" r="32.5"></circle>
<circle id="椭圆形备份-24" fill="#F7F7F7" fill-rule="evenodd" cx="618.5" cy="137.5" r="32.5"></circle>
<path d="M335,138 C360.261293,130.060117 377.446927,106.643959 377.446927,80.1642564 L377.446927,79.329248 C377.446927,54.2945956 397.741523,34 422.776175,34 L466,34 L466,34" id="路径-3备份-9" fill="none"></path>
<circle id="椭圆形备份-23" fill="#F7F7F7" fill-rule="evenodd" cx="467.5" cy="137.5" r="32.5"></circle>
<circle id="椭圆形备份-22" fill="#F7F7F7" fill-rule="evenodd" cx="467.5" cy="34.5" r="32.5"></circle>
<circle id="椭圆形备份-21" fill="#F7F7F7" fill-rule="evenodd" cx="301.5" cy="137.5" r="32.5"></circle>
</g>
</g>
<g id="编组备份-3" opacity="0.451587495" mask="url(#mask-2)" stroke="#E6E6E6" stroke-width="4">
<g transform="translate(1233.000000, 377.000000)">
<line x1="61" y1="241.5" x2="500" y2="241.5" id="路径-3" fill="none"></line>
<line x1="211" y1="137.5" x2="650" y2="137.5" id="路径-3备份-10" fill="none"></line>
<path d="M68,241 C93.2612926,233.060117 110.446927,209.643959 110.446927,183.164256 L110.446927,182.329248 C110.446927,157.294596 130.741523,137 155.776175,137 L199,137 L199,137" id="路径-3备份" fill="none"></path>
<path d="M335,346 C360.261293,338.060117 377.446927,314.643959 377.446927,288.164256 L377.446927,287.329248 C377.446927,262.294596 397.741523,242 422.776175,242 L466,242 L466,242" id="路径-3备份-2" fill="none" opacity="0.579661051" transform="translate(400.500000, 294.000000) scale(1, -1) translate(-400.500000, -294.000000) "></path>
<circle id="椭圆形" fill="#FFFFFF" fill-rule="evenodd" cx="34.5" cy="241.5" r="32.5"></circle>
<circle id="椭圆形备份-6" fill="#F7F7F7" fill-rule="evenodd" cx="198.5" cy="241.5" r="32.5"></circle>
<circle id="椭圆形备份-10" fill="#FFFFFF" fill-rule="evenodd" cx="198.5" cy="137.5" r="32.5"></circle>
<circle id="椭圆形备份-8" fill="#F7F7F7" fill-rule="evenodd" cx="301.5" cy="241.5" r="32.5"></circle>
<circle id="椭圆形备份-9" fill="#FFFFFF" fill-rule="evenodd" cx="467.5" cy="241.5" r="32.5"></circle>
<circle id="椭圆形备份-11" fill="#F7F7F7" fill-rule="evenodd" opacity="0.579661051" cx="467.5" cy="344.5" r="32.5"></circle>
<circle id="椭圆形备份-24" fill="#F7F7F7" fill-rule="evenodd" cx="618.5" cy="137.5" r="32.5"></circle>
<path d="M335,138 C360.261293,130.060117 377.446927,106.643959 377.446927,80.1642564 L377.446927,79.329248 C377.446927,54.2945956 397.741523,34 422.776175,34 L466,34 L466,34" id="路径-3备份-9" fill="none"></path>
<circle id="椭圆形备份-23" fill="#F7F7F7" fill-rule="evenodd" cx="467.5" cy="137.5" r="32.5"></circle>
<circle id="椭圆形备份-22" fill="#F7F7F7" fill-rule="evenodd" cx="467.5" cy="34.5" r="32.5"></circle>
<circle id="椭圆形备份-21" fill="#F7F7F7" fill-rule="evenodd" cx="301.5" cy="137.5" r="32.5"></circle>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>鲲鹏</title>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Git-Code整个页面-Copy" transform="translate(-900.000000, -1203.000000)" fill="#595959">
<g id="鲲鹏" transform="translate(900.000000, 1203.000000)">
<polygon id="Fill-1" points="40 0 8.71808514 16.1331432 7.28205365 20.5888833 0 19.2062108 8.56414201 25.5057454"></polygon>
<polygon id="Fill-2" points="10.0512835 26.2740008 28.9230227 40 20.8718316 26.9909806 37.4359274 3.84120751"></polygon>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 798 B

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="31px" height="36px" viewBox="0 0 31 36" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 7</title>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Git-Code整个页面-Copy" transform="translate(-983.000000, -1204.000000)">
<g id="编组-7" transform="translate(980.000000, 1203.000000)">
<rect id="矩形" x="0" y="0" width="40" height="40"></rect>
<path d="M32.8596944,1.33587843 C33.1275784,1.58010663 33.2847106,1.92713244 33.2937068,2.29439338 L33.5497538,12.7215734 C30.7068557,13.5415068 27.9496995,14.3902559 20.8408821,21.4461881 C16.1016705,26.1501429 11.6460564,31.0168171 7.47403997,36.0462109 C5.81843769,37.3179297 4.51635681,37.3179297 3.56779732,36.0462109 C2.61923783,34.7744922 2.85917255,33.5028815 4.28760147,32.2313788 L31.0300264,1.44506826 C31.5058437,0.897299609 32.325014,0.848413659 32.8596944,1.33587843 Z M22.5485194,23.572949 C26.5686871,20.7256257 30.2939198,19.4891652 33.7242177,19.8635675 L33.9991679,31.0940694 C34.0350797,32.5601308 32.9041117,33.7784333 31.4730801,33.8152242 C30.6388912,33.8366706 29.845642,33.4453557 29.3418411,32.7638702 L22.5485194,23.572949 Z" id="昇腾" fill="#595959"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 269 KiB

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="36px" height="38px" viewBox="0 0 36 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 29备份</title>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Git-Code整个页面-Copy" transform="translate(-1062.000000, -1204.000000)">
<g id="矩形" transform="translate(1080.000000, 1223.000000) scale(-1, 1) translate(-1080.000000, -1223.000000) translate(1060.000000, 1203.000000)">
<rect x="0" y="0" width="40" height="40"></rect>
<g id="蒙版" transform="translate(3.000000, 2.000000)">
<g id="编组-28备份" transform="translate(9.931612, 18.000000) scale(1, -1) translate(-9.931612, -18.000000) " stroke="#595959">
<polyline id="路径" stroke-width="1.35" points="7.40548773 6.71801948 7.40548773 2.07016101 11.1153722 -2.44412058e-14 14.8252567 2.07016101 14.8252567 6.21048304 14.8252567 7.73203831 19.8632233 7.73203831"></polyline>
<polyline id="路径" stroke-width="1.35" points="11.1153722 5.86838643 11.1153722 9.93677287 7.40548773 12.0069339 3.69560326 9.93677287 3.69560326 5.79645084 7.40548773 3.72628982"></polyline>
<polyline id="路径" stroke-width="1.35" points="7.79075738 33.929839 4.08087291 31.859678 4.08087291 26.8193559 7.79075738 24.7491949 11.5006418 26.8193559 11.5006418 30.959678"></polyline>
<polyline id="路径备份-88" stroke-width="1.35" transform="translate(13.627588, 32.381614) scale(-1, -1) translate(-13.627588, -32.381614) " points="7.79075738 36 12.0446492 36 12.0446492 30.8333881 15.7545337 28.7632271 19.4644182 30.8333881 19.4644182 34.5812466"></polyline>
<path d="M0,18.9527441 L0,11.905406 L3.89537869,9.7317369 M7.40548773,11.4913738 L7.40548773,16.8643704 L3.89537869,18.9 L3.89537869,21.4104859" id="形状" stroke-width="1.35"></path>
<polyline id="路径" stroke-width="1.35" points="7.79075738 20.8878246 7.79075738 24.7491949 3.89537869 26.922864 0 24.7491949 0 16.7284013 2.96996786 15.1173775"></polyline>
<polygon id="多边形" stroke-width="0.9" points="11.1153722 3.33084578 12.2549733 3.96675717 12.2549733 5.23857995 11.1153722 5.87449135 9.97577109 5.23857995 9.97577109 3.96675717"></polygon>
<polygon id="多边形备份-7" stroke-width="0.9" points="7.40548773 6.59478907 8.54508884 7.23070046 8.54508884 8.50252324 7.40548773 9.13843463 6.26588662 8.50252324 6.26588662 7.23070046"></polygon>
<polygon id="多边形备份-9" stroke-width="0.9" points="3.89537869 13.3195648 5.0349798 13.9554762 5.0349798 15.227299 3.89537869 15.8632104 2.75577758 15.227299 2.75577758 13.9554762"></polygon>
<polygon id="多边形备份-10" stroke-width="0.9" points="3.89537869 21.2743739 5.0349798 21.9102853 5.0349798 23.1821081 3.89537869 23.8180195 2.75577758 23.1821081 2.75577758 21.9102853"></polygon>
<polygon id="多边形备份-14" stroke-width="0.9" points="11.5437528 30.7077917 12.6833539 31.3437031 12.6833539 32.6155259 11.5437528 33.2514372 10.4041516 32.6155259 10.4041516 31.3437031"></polygon>
<polygon id="多边形备份-11" stroke-width="0.9" points="7.79075738 18.8894653 8.93035849 19.5253767 8.93035849 20.7971995 7.79075738 21.4331109 6.65115627 20.7971995 6.65115627 19.5253767"></polygon>
<polygon id="多边形备份-12" stroke-width="0.9" points="7.79075738 27.6383349 8.93035849 28.2742463 8.93035849 29.5460691 7.79075738 30.1819805 6.65115627 29.5460691 6.65115627 28.2742463"></polygon>
</g>
<g id="编组-28备份" transform="translate(26.394737, 18.000000) scale(-1, -1) translate(-26.394737, -18.000000) translate(18.789474, 0.000000)" stroke="#595959">
<polyline id="路径" stroke-width="1.35" points="7.40548773 6.71801948 7.40548773 2.07016101 11.1153722 -2.44412058e-14 14.8252567 2.07016101 14.8252567 6.21048304 14.8252567 7.73203831"></polyline>
<polyline id="路径" stroke-width="1.35" points="11.1153722 5.86838643 11.1153722 9.93677287 7.40548773 12.0069339 3.69560326 9.93677287 3.69560326 5.79645084 7.40548773 3.72628982"></polyline>
<polyline id="路径" stroke-width="1.35" points="7.79075738 33.929839 4.08087291 31.859678 4.08087291 26.8193559 7.79075738 24.7491949 11.5006418 26.8193559 11.5006418 30.959678"></polyline>
<polyline id="路径备份-88" stroke-width="1.35" transform="translate(11.500642, 32.381614) scale(-1, -1) translate(-11.500642, -32.381614) " points="7.79075738 36 7.79075738 30.8333881 11.5006418 28.7632271 15.2105263 30.8333881 15.2105263 34.5812466"></polyline>
<path d="M0,18.9527441 L0,11.905406 L3.89537869,9.7317369 M7.40548773,11.4913738 L7.40548773,16.8643704 L3.89537869,18.9 L3.89537869,21.4104859" id="形状" stroke-width="1.35"></path>
<polyline id="路径" stroke-width="1.35" points="7.79075738 20.8878246 7.79075738 24.7491949 3.89537869 26.922864 0 24.7491949 0 16.7284013 2.96996786 15.1173775"></polyline>
<polygon id="多边形" stroke-width="0.9" points="11.1153722 3.33084578 12.2549733 3.96675717 12.2549733 5.23857995 11.1153722 5.87449135 9.97577109 5.23857995 9.97577109 3.96675717"></polygon>
<polygon id="多边形备份-7" stroke-width="0.9" points="7.40548773 6.59478907 8.54508884 7.23070046 8.54508884 8.50252324 7.40548773 9.13843463 6.26588662 8.50252324 6.26588662 7.23070046"></polygon>
<polygon id="多边形备份-9" stroke-width="0.9" points="3.89537869 13.3195648 5.0349798 13.9554762 5.0349798 15.227299 3.89537869 15.8632104 2.75577758 15.227299 2.75577758 13.9554762"></polygon>
<polygon id="多边形备份-10" stroke-width="0.9" points="3.89537869 21.2743739 5.0349798 21.9102853 5.0349798 23.1821081 3.89537869 23.8180195 2.75577758 23.1821081 2.75577758 21.9102853"></polygon>
<polygon id="多边形备份-14" stroke-width="0.9" points="11.5437528 30.7077917 12.6833539 31.3437031 12.6833539 32.6155259 11.5437528 33.2514372 10.4041516 32.6155259 10.4041516 31.3437031"></polygon>
<polygon id="多边形备份-11" stroke-width="0.9" points="7.79075738 18.8894653 8.93035849 19.5253767 8.93035849 20.7971995 7.79075738 21.4331109 6.65115627 20.7971995 6.65115627 19.5253767"></polygon>
<polygon id="多边形备份-12" stroke-width="0.9" points="7.79075738 27.6383349 8.93035849 28.2742463 8.93035849 29.5460691 7.79075738 30.1819805 6.65115627 29.5460691 6.65115627 28.2742463"></polygon>
</g>
<path d="M13.1654135,21.6 L11.6315789,21.6 L11.6315789,14.9727273 L13.1654135,14.9727273 L13.1654135,17.1818182 L16.2330827,17.1818182 L16.2330827,14.9727273 L17.7669173,14.9727273 L17.7669173,21.6 L16.2330827,21.6 L16.2330827,18.6545455 L13.1654135,18.6545455 L13.1654135,21.6 Z M16.2330827,13.5 L16.2330827,14.9727273 L13.1654135,14.9727273 L13.1654135,13.5 L16.2330827,13.5 Z M22.3684211,13.5 L22.3684211,14.9727273 L21.202367,14.9727273 L21.2135789,20.127 L22.3684211,20.1272727 L22.3684211,21.6 L18.5338346,21.6 L18.5338346,20.1272727 L19.6965789,20.127 L19.6847002,14.9727273 L18.5338346,14.9727273 L18.5338346,13.5 L22.3684211,13.5 Z" id="形状结合" fill="#595959" transform="translate(17.000000, 17.550000) scale(-1, 1) translate(-17.000000, -17.550000) "></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,8 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="ic/fork">
<path id="&#232;&#183;&#175;&#229;&#190;&#132;" fill-rule="evenodd" clip-rule="evenodd" d="M3.99987 5.5L2 12.4996H6.00053L3.99987 5.5Z" stroke="black" stroke-linecap="round" stroke-linejoin="round"/>
<path id="&#232;&#183;&#175;&#229;&#190;&#132;_2" fill-rule="evenodd" clip-rule="evenodd" d="M11.9999 5.5L10 12.4996H14.0005L11.9999 5.5Z" stroke="black" stroke-linecap="round" stroke-linejoin="round"/>
<path id="&#232;&#183;&#175;&#229;&#190;&#132;_3" d="M2 3.5H14" stroke="black" stroke-linejoin="round"/>
<path id="&#232;&#183;&#175;&#229;&#190;&#132;_4" d="M7.99963 14.9992V1" stroke="black" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 747 B

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="96px" height="96px" viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>项目</title>
<defs>
<linearGradient x1="20.5821624%" y1="12.8358281%" x2="77.8617538%" y2="96.8118609%" id="linearGradient-1">
<stop stop-color="#FFFAEA" offset="0%"></stop>
<stop stop-color="#FFF6E4" offset="43.3818322%"></stop>
<stop stop-color="#F0BF9D" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-120.164401%" y1="-33.9829531%" x2="63.6366717%" y2="56.0502272%" id="linearGradient-2">
<stop stop-color="#FFDFB0" offset="0%"></stop>
<stop stop-color="#FC5533" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Git-Code整个页面" transform="translate(-780.000000, -1323.000000)">
<g id="编组-14" transform="translate(320.000000, 1323.000000)">
<g id="项目" transform="translate(460.000000, 0.000000)">
<path d="M41.4151529,11.3250598 C42.1204877,10.9202746 42.9667132,10.8198351 44.0107517,11.3792148 L44.0107517,11.3792148 L59.8913475,19.9674162 C60.8996631,20.517604 61.8763571,21.66921 62.4684524,23.1090811 L62.4684524,23.1090811 L64.3446877,27.6790781 L81.5261507,37.2393886 C82.4911698,37.7817097 83.3853798,38.7937527 84.020386,40.0237149 C84.6298226,41.2041506 85,42.5745593 85,43.851763 C85,44.1422205 84.9807831,44.4214123 84.9433917,44.6860848 C83.5966234,47.502926 77.1178773,59.9423261 65.2502009,82.6507225 C65.0022289,84.1580419 64.393437,85.2560712 63.598128,85.9429723 C63.3000382,86.8704035 62.7432622,87.4752162 62.0877403,87.7757186 C61.3523371,88.11284 60.4235877,88.1114747 59.396325,87.5176094 L59.396325,87.5176094 L30.7834629,70.8805557 L21.0937266,65.2481963 C20.5214112,64.9220532 19.9721587,64.4378933 19.4923492,63.845987 C18.2661196,62.3545447 17.4273744,60.6097735 17.0731834,58.81952 L17.0731834,58.81952 L11.1418654,28.9684132 C10.8540625,27.526172 11.0311171,26.2938293 11.476306,25.4516655 C11.7629833,24.9093579 12.1615784,24.5080086 12.633247,24.2587053 C13.1033438,24.0102328 13.6535181,23.9051905 14.2722155,23.9980328 C14.6509268,24.0548767 15.0455927,24.1878311 15.448701,24.4063704 L15.448701,24.4063704 L19.2250938,26.495991 L19.3452735,23.9890162 C19.2189461,22.5510863 19.5730026,21.4282412 20.1490446,20.7304905 C20.5273961,20.2721992 21.0064513,19.9711657 21.5541367,19.8410833 C22.0684694,19.7189226 22.6543305,19.746866 23.2889487,19.9883819 L23.2889487,19.9883819 L25.2283007,21.0302588 L25.3879254,20.2259345 C25.400785,18.7932049 25.9089698,17.7759028 26.5994655,17.2100651 C27.040802,16.8484048 27.5694053,16.6463262 28.1592227,16.6290269 C28.6589733,16.6143693 29.2125723,16.735931 29.7925746,17.0413808 L29.7925746,17.0413808 L36.2478916,20.5878781 L39.7133522,13.5115138 C40.1441793,12.524009 40.7220935,11.7228003 41.4151529,11.3250598 Z" id="形状结合" stroke="#191919" stroke-width="2"></path>
<path d="M43.6391305,12.2991397 L59.4755993,20.9010436 C60.3183159,21.3628897 61.109473,22.3485636 61.6011366,23.5494476 L63.6051547,28.4521042 L81.0438566,38.1981123 C82.6764895,39.119644 84,41.6950688 84,43.9490742 C84,44.1912522 83.9843865,44.4240696 83.9533443,44.6447638 L64.3385821,82.4958595 C63.8902456,85.6591819 61.7204407,86.8610426 59.1869468,85.3542775 L23.9256843,64.7724886 C21.7575887,63.5306969 20,60.1798339 20,57.2856394 C20,56.9636582 20.0222298,56.6549676 20.0664075,56.3634706 L40.553544,13.9670731 C41.2272113,12.2919505 42.2153065,11.5329416 43.6391305,12.2991397 Z" id="路径" fill="#C2C2C2"></path>
<path d="M28.1440991,16.4087556 C28.6237889,16.4248483 29.1353919,16.5772346 29.6624691,16.8555797 L29.6624691,16.8555797 L67.3233212,37.7244976 C68.1968444,38.2187214 68.9991631,39.1438132 69.5766114,40.2587728 C70.1489774,41.3639194 70.5005081,42.649998 70.5001755,43.8496107 L70.5001755,43.8496107 L62.9712531,83.3540709 C62.9706979,84.6510023 62.5546174,85.5729078 61.9525964,86.0616618 C61.5956046,86.3514874 61.1679444,86.5042029 60.6908368,86.4999138 C60.2732915,86.4961601 59.8117561,86.3689424 59.3269606,86.086302 L59.3269606,86.086302 L21.6737448,64.0073168 C19.9362335,63.00871 18.4997288,60.3219117 18.4998271,57.9798875 L18.4998271,57.9798875 L25.2590572,19.7174626 C25.5400891,18.1613416 26.1041701,17.2564966 26.7691396,16.8009714 C27.1853425,16.5158591 27.6498743,16.3921751 28.1440991,16.4087556 Z" id="矩形" stroke="#191919" fill="#DBDBDB"></path>
<path d="M21.3466967,20.5570085 C21.7666694,20.4570026 22.2434872,20.483457 22.7593754,20.6752046 L22.7593754,20.6752046 L60.9837267,41.7443188 C62.5805984,42.6445299 63.9604422,45.0139574 64.1680258,47.3116324 L64.1680258,47.3116324 L62.4728211,83.753987 C62.5924605,85.0836139 62.3008236,86.1201914 61.7867608,86.7458359 C61.4778049,87.1218534 61.0873976,87.3636914 60.63988,87.4573083 C60.2197181,87.5452027 59.7423606,87.5020798 59.2261777,87.2861368 L59.2261777,87.2861368 L21.0137736,65.0502861 C19.4156627,64.1372309 18.0388898,61.7986257 17.8319139,59.5587891 L17.8319139,59.5587891 L19.5271081,24.208293 C19.4076199,22.9215593 19.697964,21.9049729 20.2135976,21.278785 C20.5188571,20.9080764 20.904317,20.6623501 21.3466967,20.5570085 Z" id="矩形" stroke="#191919" fill="#FFFFFF"></path>
<path d="M12.6151996,23.2965569 C13.0838006,23.0454841 13.6322137,22.9394578 14.2489818,23.0332778 C14.6253979,23.0905507 15.0177743,23.2243673 15.4185171,23.4445987 L15.4185171,23.4445987 L53.5029793,44.8050165 C54.9993268,45.6618098 56.368814,47.7488378 56.79678,49.9926013 L56.79678,49.9926013 L62.8615077,81.9241197 C63.1424627,83.4097265 62.9684929,84.6676471 62.533665,85.5157436 C62.2467873,86.0752755 61.8455586,86.4809518 61.3742869,86.7263733 C60.8982032,86.9743007 60.3408767,87.0690109 59.713665,86.9490795 C59.3387034,86.8773959 58.9474509,86.7268883 58.5629193,86.4959098 L58.5629193,86.4959098 L21.2111709,64.4820261 C19.2885372,63.3712605 17.5490269,60.7165277 17.000791,57.9075403 L17.000791,57.9075403 L11.1399061,28.0070727 C10.8562638,26.5662209 11.0305636,25.3346658 11.4694247,24.4931062 C11.753214,23.9489121 12.14841,23.5466593 12.6151996,23.2965569 Z" id="矩形" stroke="#191919" stroke-width="2" fill="url(#linearGradient-1)" fill-rule="nonzero"></path>
<path d="M24.9257269,41.1078597 L20.863558,43.7247413 L20.4300477,44.0029704 C19.8956586,44.3456675 19.8535493,45.4137373 20.3359941,46.3893965 C20.407526,46.5341087 20.4885192,46.6720601 20.5771546,46.8001525 L21.4411547,48.0495171 L27.0016104,56.122363 C27.5994091,56.9935945 28.4092576,57.2387517 28.8104575,56.6690395 C28.8338046,56.6358756 28.855461,56.6002834 28.8753514,56.562387 L29.2615509,55.826355 C29.5802715,55.2186111 29.3981359,54.1346347 28.8407105,53.3224795 L25.3219843,48.2087482 L27.6906599,46.6854594 C28.2250315,46.3409772 28.2671106,45.2666781 27.7846464,44.2867709 C27.7816399,44.2806664 27.7786162,44.2745731 27.7755754,44.2684911 L26.7577648,42.2340638 C26.2733802,41.266796 25.456205,40.7648193 24.9257269,41.1078597 Z M43.9982653,51.6766571 L49.558721,59.8650379 L50.4227212,61.1423913 C51.0205199,62.0269778 51.1798948,63.2136953 50.7786949,63.7921019 C50.7192092,63.8778326 50.6490617,63.9471045 50.569828,63.9983622 L50.1363178,64.2786893 L46.0741488,66.8957081 C45.5436707,67.2361621 44.7264955,66.7159481 44.242111,65.7302469 L43.2243003,63.6610074 C42.7363446,62.669921 42.7699108,61.5798943 43.2992726,61.2255319 C43.3025714,61.2233226 43.3058858,61.2211453 43.3092158,61.2189999 L45.6778914,59.6899498 L42.1591652,54.5130279 C41.6017399,53.6949708 41.4196042,52.6026648 41.7383249,51.9884125 L42.1245244,51.24373 C42.4663236,50.5843121 43.2570724,50.7114797 43.890711,51.5286336 C43.9275845,51.5762057 43.9634776,51.6256042 43.9982653,51.6766571 Z M35.7302699,47.8219217 L36.9265292,49.0068279 C37.5272131,49.6024416 37.9035262,50.6119299 37.8200208,51.4032434 L36.9603376,59.5444589 C36.8650467,60.4462695 36.2093,60.7446089 35.4956864,60.2113071 C35.4189623,60.1539942 35.3433032,60.0881738 35.2696059,60.0146272 L34.0733465,58.8217017 C33.4726626,58.2233224 33.0963495,57.2146162 33.1798549,56.4262569 L34.0395381,48.3048249 C34.134829,47.4040144 34.7905757,47.1003828 35.5041893,47.6271332 C35.5809134,47.6837918 35.6565725,47.7489784 35.7302699,47.8219217 Z" id="形状结合" fill="url(#linearGradient-2)"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,12 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="&#229;&#164;&#180;&#229;&#131;&#143;/&#231;&#187;&#132;&#231;&#187;&#135;&#229;&#164;&#180;&#229;&#131;&#143;1">
<rect id="&#231;&#159;&#169;&#229;&#189;&#162;" width="40" height="40" fill="url(#paint0_linear_125_1511)"/>
<path id="&#229;&#189;&#162;&#231;&#138;&#182;" fill-rule="evenodd" clip-rule="evenodd" d="M20.7039 24.6415C20.7679 24.6415 20.8319 24.5775 20.8319 24.5775C21.5997 23.4897 24.8631 18.5626 25.567 15.5551C25.567 15.5551 25.9509 14.0834 25.567 13.1235C25.567 13.1235 25.0551 11.2679 23.0075 10.756C23.0075 10.756 22.4316 10.628 21.7917 10.5C21.7917 10.5 19.4881 13.4435 20.6399 24.5135C20.6399 24.6415 20.7039 24.6415 20.7039 24.6415ZM16.9285 10.8199C16.9285 10.8199 17.8244 10.564 18.1443 10.564C18.1443 10.564 20.4479 13.4435 19.2961 24.6415C19.2961 24.6415 19.2961 24.7055 19.2321 24.7055L19.1681 24.6415C18.4643 23.6177 15.1369 18.6266 14.433 15.6191C14.433 15.6191 14.0491 14.3393 14.433 13.1875C14.433 13.1875 14.8809 11.3319 16.9285 10.8199ZM18.2723 25.2174C18.3363 25.2174 18.2723 25.2814 18.2723 25.2814H18.1443C17.0565 24.7695 12.4493 22.4019 10.5297 20.5462C10.5297 20.5462 9.31389 19.6504 9.2499 18.0507C9.12193 15.939 11.2975 13.8914 11.2975 13.8914C11.2975 13.8914 15.3288 18.8185 18.2723 25.2174ZM17.3765 26.8171C17.3765 26.8171 17.5044 26.8171 17.5044 26.8811C17.5044 26.8811 17.5684 26.8811 17.4405 27.0091C16.7366 27.521 14.433 29.1207 13.4092 29.3767C11.9374 29.6966 10.5297 28.5448 9.69783 27.0731L17.3765 26.8171ZM17.6324 26.1772C17.6964 26.1132 17.6324 26.0492 17.6324 26.0492C14.241 23.7457 7.71418 20.2903 7.71418 20.2903C7.13828 22.1459 7.90614 23.6177 7.90614 23.6177C8.738 25.4094 10.3377 25.9213 10.3377 25.9213C11.0416 26.2412 11.8095 26.2412 11.8095 26.2412H17.5684C17.6324 26.2412 17.6324 26.1772 17.6324 26.1772ZM22.4316 26.8811C22.4316 26.8171 22.4956 26.8171 22.4956 26.8171L30.1742 27.0731C28.4465 30.0805 26.4629 29.3767 26.4629 29.3767C25.552 29.1623 23.8784 28.0058 22.9073 27.3348L22.9072 27.3347C22.7186 27.2044 22.5565 27.0923 22.4316 27.0091V26.8811ZM32.2858 20.2263C32.2858 20.2263 25.759 23.7457 22.3676 26.0492C22.3676 26.0492 22.3036 26.1132 22.3036 26.1772C22.3036 26.1772 22.3036 26.2412 22.3676 26.2412H28.2545C28.2545 26.2412 28.8304 26.2412 29.5983 25.9213C29.5983 25.9213 31.198 25.4094 32.0939 23.5537C32.0939 23.5458 32.1055 23.5165 32.1249 23.4679C32.2627 23.122 32.7907 21.7971 32.2858 20.2263ZM21.8557 25.2814C21.7917 25.3454 21.7277 25.2814 21.7277 25.2814C21.6637 25.2174 21.7277 25.1534 21.7277 25.1534C24.6712 18.6905 28.7025 13.8914 28.7025 13.8914C28.7025 13.8914 30.8781 15.875 30.7501 18.0507C30.6861 19.5864 29.4703 20.5462 29.4703 20.5462C27.7383 22.2205 23.8186 24.2593 22.2698 25.065C22.102 25.1523 21.962 25.2251 21.8557 25.2814Z" fill="white"/>
</g>
<defs>
<linearGradient id="paint0_linear_125_1511" x1="-20" y1="20" x2="20" y2="60" gradientUnits="userSpaceOnUse">
<stop stop-color="#A855F7"/>
<stop offset="1" stop-color="#818CF8"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="114px" height="278px" viewBox="0 0 114 278" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>项目背景</title>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#FFFFFF" stop-opacity="0.484871818" offset="100%"></stop>
</linearGradient>
<path d="M24,0 L90,0 C103.254834,-1.06548173e-14 114,10.745166 114,24 L114,254 C114,267.254834 103.254834,278 90,278 L24,278 C10.745166,278 5.17596268e-15,267.254834 0,254 L0,24 C1.92946468e-15,10.745166 10.745166,5.98758718e-15 24,0 Z" id="path-2"></path>
<linearGradient x1="225.036277%" y1="-70.7791996%" x2="37.6671026%" y2="84.3333409%" id="linearGradient-4">
<stop stop-color="#FFF5F1" offset="0%"></stop>
<stop stop-color="#FFEEC5" stop-opacity="0.213228666" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="背景图切图" transform="translate(-703.000000, -3158.000000)">
<g id="项目背景" transform="translate(703.000000, 3158.000000)">
<mask id="mask-3" fill="white">
<use xlink:href="#path-2"></use>
</mask>
<use id="蒙版" fill="url(#linearGradient-1)" xlink:href="#path-2"></use>
<path d="M109.5,162.083033 C115.041362,157.128754 121.81075,153.444944 129.403864,151.548833 L144.579664,147.759214 C151.543348,146.02028 156.428571,139.770544 156.428571,132.600737 L156.428571,123.082723 C138.201634,116.647779 125.142857,99.2846692 125.142857,78.875 C125.142857,52.9866523 146.153495,32 172.071429,32 C197.989362,32 219,52.9866523 219,78.875 C219,99.2846692 205.941224,116.647779 187.714286,123.082723 L187.714286,132.600737 C187.714286,154.110158 173.058616,172.859366 152.167565,178.076167 L136.991764,181.865786 C131.97171,183.119367 128.031797,186.717136 126.223536,191.313881 C143.883763,198.043662 156.428571,215.121005 156.428571,235.125 C156.428571,261.013347 135.417934,282 109.5,282 C83.5820657,282 62.5714286,261.013347 62.5714286,235.125 C62.5714286,215.121005 75.1162371,198.043662 92.7764639,191.313881 C90.9682028,186.717136 87.0282899,183.119367 82.0082359,181.865786 L66.8324352,178.076167 C45.9413839,172.859366 31.2857143,154.110158 31.2857143,132.600737 L31.2857143,123.082723 C13.0587765,116.647779 0,99.2846692 0,78.875 C0,52.9866523 21.0106371,32 46.9285714,32 C72.8465058,32 93.8571429,52.9866523 93.8571429,78.875 C93.8571429,99.2846692 80.7983664,116.647779 62.5714286,123.082723 L62.5714286,132.600737 C62.5714286,139.770544 67.4566517,146.02028 74.4203355,147.759214 L89.5961362,151.548833 C97.1892498,153.444944 103.958638,157.128754 109.5,162.083033 L109.5,162.083033 Z M46.5,94 C55.0604136,94 62,87.0604136 62,78.5 C62,69.9395864 55.0604136,63 46.5,63 C37.9395864,63 31,69.9395864 31,78.5 C31,87.0604136 37.9395864,94 46.5,94 Z M109.5,251 C118.060414,251 125,244.060413 125,235.5 C125,226.939587 118.060414,220 109.5,220 C100.939586,220 94,226.939587 94,235.5 C94,244.060413 100.939586,251 109.5,251 Z M171.5,94 C180.060413,94 187,87.0604136 187,78.5 C187,69.9395864 180.060413,63 171.5,63 C162.939587,63 156,69.9395864 156,78.5 C156,87.0604136 162.939587,94 171.5,94 Z" id="形状" fill="url(#linearGradient-4)" fill-rule="nonzero" mask="url(#mask-3)"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

Some files were not shown because too many files have changed in this diff Show More