2025-03-12 18:41:20 +08:00
|
|
|
|
import { emitEvent } from '@/utils/eventBus';
|
|
|
|
|
|
import { repoPathSuffix } from '@/utils/regex';
|
|
|
|
|
|
import { useRepoId } from '@/utils/hooks/useRepoId';
|
|
|
|
|
|
import { useOrgId } from '@/utils/hooks/useOrgId';
|
|
|
|
|
|
import { usePageTitle } from '@/utils/hooks/useTitle';
|
|
|
|
|
|
import { repoInfoStore } from '@/stores/Repo';
|
|
|
|
|
|
import { orgInfoStore } from '@/stores/Org';
|
|
|
|
|
|
import { useAccountStore } from '@/stores/user';
|
|
|
|
|
|
import { getRepoRole, getRepo } from '@/api/repo';
|
|
|
|
|
|
import { getOrg, getPathType } from '@/api/org';
|
|
|
|
|
|
// import { globalFeaturedGroups } from '@/api/home';
|
|
|
|
|
|
import { reqCatch } from '@/utils/catch';
|
|
|
|
|
|
import { useReport } from '@/utils/hooks/useReport';
|
|
|
|
|
|
import { useGlobalInfoStore } from '@/stores/Global';
|
|
|
|
|
|
import { Message } from 'vue-devui';
|
|
|
|
|
|
// import cookie from 'js-cookie';
|
|
|
|
|
|
|
|
|
|
|
|
let currentOrgId = ''; // 当前组织路径
|
|
|
|
|
|
let currentRepoId = ''; // 当前项目路径
|
|
|
|
|
|
const visitedRepoList = 'visited_repo_list'; // 用于保存用户访问过哪些项目的代码
|
|
|
|
|
|
|
|
|
|
|
|
const setRepoVisited = (id: string): void => {
|
|
|
|
|
|
let visitedRepoIds = localStorage.getItem(visitedRepoList)?.split(',') || [];
|
|
|
|
|
|
visitedRepoIds.push(`${id}`);
|
|
|
|
|
|
visitedRepoIds = Array.from(new Set(visitedRepoIds));
|
|
|
|
|
|
localStorage.setItem(visitedRepoList, visitedRepoIds.join());
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const isRepoVisited = (id: string): boolean => {
|
|
|
|
|
|
return localStorage.getItem(visitedRepoList)?.includes(id) || false;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 若uuid不存在,则调用接口写入uuid
|
|
|
|
|
|
*/
|
|
|
|
|
|
// const checkUuid = () => {
|
|
|
|
|
|
// const uuid = cookie.get('uuid_tt_dd');
|
|
|
|
|
|
// if (!uuid) {
|
|
|
|
|
|
// globalFeaturedGroups(); // 这个接口并不是专门写入uuid的,实际上任意一个接口都行
|
|
|
|
|
|
// }
|
|
|
|
|
|
// };
|
|
|
|
|
|
const fromHomeWeb = ['home', 'search', 'gStar', 'gStarApply', 'explore'];
|
|
|
|
|
|
|
2025-03-15 15:40:06 +08:00
|
|
|
|
export const injectRouter = (router) => {
|
2025-03-12 18:41:20 +08:00
|
|
|
|
const account = useAccountStore();
|
|
|
|
|
|
|
|
|
|
|
|
router.beforeEach(async (to, from) => {
|
|
|
|
|
|
// 如果是从blog跳转过来的判断是否登陆,如果登陆则写入storage
|
|
|
|
|
|
// await account.checkIsLogin();
|
|
|
|
|
|
// 判断命名空间类型
|
|
|
|
|
|
const globalStore = useGlobalInfoStore();
|
|
|
|
|
|
globalStore.setNamespaceType(-1); // 重置namespaceType,防止非组织路由请求组织信息
|
|
|
|
|
|
if (to.meta.pageType === 'userOrOrg') {
|
|
|
|
|
|
const { namespace } = to.params;
|
|
|
|
|
|
const params = {
|
|
|
|
|
|
path_name: Array.isArray(namespace) ? namespace.join('/') : namespace
|
|
|
|
|
|
};
|
|
|
|
|
|
let res = await reqCatch(getPathType, params);
|
2025-03-15 15:40:06 +08:00
|
|
|
|
if (!res.error && res.data) {
|
2025-03-12 18:41:20 +08:00
|
|
|
|
res = res?.data?.data;
|
|
|
|
|
|
|
|
|
|
|
|
if (res?.type === null) {
|
|
|
|
|
|
return { name: '404' };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const { type } = res; // 0-用户 1-组织
|
|
|
|
|
|
const typeConfig = {
|
|
|
|
|
|
0: 'user',
|
|
|
|
|
|
1: 'org'
|
|
|
|
|
|
};
|
|
|
|
|
|
globalStore.setMenuType(typeConfig[type], namespace);
|
|
|
|
|
|
globalStore.setNamespaceType(type);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 上报ref设置
|
|
|
|
|
|
const BASE_URL = (import.meta as any).env.VITE_HOST;
|
|
|
|
|
|
const beforeRef = sessionStorage.getItem('ref');
|
|
|
|
|
|
const ref = beforeRef || document.referrer || '';
|
2025-03-15 15:40:06 +08:00
|
|
|
|
if (!fromHomeWeb.includes(to.name)) {
|
|
|
|
|
|
// 设置全局ref
|
2025-03-12 18:41:20 +08:00
|
|
|
|
window.page_ref = ref;
|
|
|
|
|
|
sessionStorage.setItem('ref', BASE_URL + to.fullPath);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取组织详情
|
2025-03-15 15:40:06 +08:00
|
|
|
|
if (to.meta.type === 'org' || globalStore.namespaceType === 1) {
|
|
|
|
|
|
// 组织相关页面 || 组织主页
|
2025-03-12 18:41:20 +08:00
|
|
|
|
const { orgId } = useOrgId('%2F', to.params.namespace);
|
2025-03-15 15:40:06 +08:00
|
|
|
|
if (orgId.value !== currentOrgId) {
|
|
|
|
|
|
// 第一次进入或切换组织时调用接口
|
2025-03-12 18:41:20 +08:00
|
|
|
|
const { setOrgInfo, setAccessLevel, setVisibility } = orgInfoStore();
|
|
|
|
|
|
const res = await reqCatch(getOrg, { orgId: orgId.value, with_full_path: true });
|
|
|
|
|
|
if (!res.error) {
|
|
|
|
|
|
setOrgInfo(res?.data?.data);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (res?.error?.error_code === 404) {
|
|
|
|
|
|
return { name: '404' };
|
|
|
|
|
|
}
|
2025-03-15 15:40:06 +08:00
|
|
|
|
if (res?.error?.error_code === 403) {
|
|
|
|
|
|
// 403代表无私有组织权限
|
2025-03-12 18:41:20 +08:00
|
|
|
|
setAccessLevel(0);
|
|
|
|
|
|
setVisibility('private');
|
|
|
|
|
|
return { name: '403' };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
currentOrgId = orgId.value;
|
|
|
|
|
|
const { orgInfo } = orgInfoStore();
|
|
|
|
|
|
usePageTitle(String(to.meta.title || ''), orgInfo?.name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取项目详情和项目权限
|
|
|
|
|
|
if (to.meta.type === 'repo') {
|
|
|
|
|
|
const repoStore = repoInfoStore();
|
|
|
|
|
|
|
|
|
|
|
|
const { repoId } = useRepoId('%2F', to.params.namespace, to.params.repoName);
|
|
|
|
|
|
// 禁止访问以某些结尾的仓库(如:wiki仓)
|
|
|
|
|
|
if (!repoPathSuffix.test(repoId.value)) {
|
|
|
|
|
|
return { name: '404' };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (repoId.value !== currentRepoId) {
|
|
|
|
|
|
// 0. 第一次进入或切换项目时调用接口
|
|
|
|
|
|
const promises = [getRepo({ repoId: repoId.value, statistics: true }, { customError: true })];
|
|
|
|
|
|
account.isLogin && promises.push(reqCatch(getRepoRole, { repoId: repoId.value }));
|
|
|
|
|
|
const [repoRes, roleRes] = await Promise.all(promises);
|
|
|
|
|
|
|
|
|
|
|
|
// 1. repo信息处理
|
|
|
|
|
|
const { setRepoInfo, setAccessLevel, setVisibility } = repoStore;
|
|
|
|
|
|
if (!repoRes.error) {
|
|
|
|
|
|
const { data } = repoRes.data;
|
|
|
|
|
|
setRepoInfo(data);
|
|
|
|
|
|
// 访问未开启模块显示404
|
|
|
|
|
|
const modules = data.module_setting.modules;
|
|
|
|
|
|
const moduleRouteConfig = new Map([
|
|
|
|
|
|
['WIKI', 'repoWiki'],
|
|
|
|
|
|
['ISSUE', 'repoIssues'],
|
|
|
|
|
|
['MERGE_REQUEST', 'repoMerge'],
|
|
|
|
|
|
['FORK', 'repoFork'],
|
|
|
|
|
|
['ANALYSIS', 'repoAnalysis'],
|
|
|
|
|
|
['DISCUSSION', 'repoDiscussion'],
|
|
|
|
|
|
['COMMUNITY', 'reqCommunity']
|
|
|
|
|
|
]);
|
2025-03-15 15:40:06 +08:00
|
|
|
|
modules.forEach((item) => {
|
|
|
|
|
|
if (to.name === moduleRouteConfig.get(item.key) && item.value === '0') {
|
2025-03-12 18:41:20 +08:00
|
|
|
|
globalStore.setIsNotFound(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
const errorCode = repoRes?.error?.error_code;
|
|
|
|
|
|
|
|
|
|
|
|
// 项目不存在
|
|
|
|
|
|
if (errorCode === 404) {
|
|
|
|
|
|
return { name: '404' };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 403代表无私有项目权限
|
|
|
|
|
|
if (errorCode === 403) {
|
|
|
|
|
|
setAccessLevel(0);
|
|
|
|
|
|
setVisibility('private');
|
|
|
|
|
|
return { name: '403' };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Message.error(repoRes?.error?.error_message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. role信息处理
|
|
|
|
|
|
if (account.isLogin && !roleRes.error) {
|
|
|
|
|
|
setAccessLevel(roleRes.data.data?.access_level);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 更新currentRepoId
|
|
|
|
|
|
currentRepoId = repoId.value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
usePageTitle(String(to.meta.title || ''), repoStore?.repoInfo?.name);
|
|
|
|
|
|
|
|
|
|
|
|
if (to.name === 'repo') {
|
|
|
|
|
|
const repoId = repoStore.repoInfo?.id;
|
|
|
|
|
|
|
|
|
|
|
|
// 是否跳转项目dashboard
|
|
|
|
|
|
let isGotoRepoDashboard = false;
|
|
|
|
|
|
|
|
|
|
|
|
// 非visitor权限,首次进入repoDashboard,后续进入代码
|
|
|
|
|
|
if (!account.isLogin || !repoStore.isVisitor) {
|
|
|
|
|
|
isGotoRepoDashboard = !isRepoVisited(repoId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 当前路由配置默认进入代码tab,未登录、非个人项目或非组织开发者成员项目,进入首页,导入失败项目进入代码页
|
|
|
|
|
|
if (isGotoRepoDashboard && repoStore.repoInfo.import_status !== 'failed') {
|
|
|
|
|
|
// 标记当前的repoId已访问
|
|
|
|
|
|
setRepoVisited(repoId);
|
|
|
|
|
|
|
|
|
|
|
|
// ref保存为跳转之前的
|
|
|
|
|
|
sessionStorage.setItem('ref', ref);
|
|
|
|
|
|
// 跳转repoDashboard
|
|
|
|
|
|
router.replace({
|
|
|
|
|
|
...to,
|
|
|
|
|
|
name: 'repoDashboard'
|
|
|
|
|
|
});
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (to.meta.type !== 'repo' && to.meta.type !== 'org') {
|
|
|
|
|
|
usePageTitle(String(to.meta.title || ''));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证登录权限
|
2025-03-15 15:40:06 +08:00
|
|
|
|
if (to.meta.needLogin) {
|
|
|
|
|
|
// 是否需要登录
|
|
|
|
|
|
if (account.isLogin) {
|
|
|
|
|
|
// 已登录
|
2025-03-12 18:41:20 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
emitEvent('login', { triggerType: to.meta?.loginType, Authorization: Boolean(to?.meta?.Authorization) });
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2025-03-15 15:40:06 +08:00
|
|
|
|
if (account.isLogin && to.meta.loginHidden) {
|
|
|
|
|
|
// 已登录,不能访问某些页面,进行跳转处理(如:登录注册)
|
2025-03-12 18:41:20 +08:00
|
|
|
|
const toOauth = to.name === 'oauth' && /(.*)_(.*)/.exec(to.query?.state); // 三方授权不跳转
|
|
|
|
|
|
const fromAtomGit = to.query.installation_id && /atomgit.com/.test(document.referrer); // 来自AtomGit应用的跳转
|
|
|
|
|
|
if (toOauth || fromAtomGit) return true;
|
|
|
|
|
|
return { name: 'dashboard' };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
});
|
|
|
|
|
|
router.afterEach((to, from) => {
|
|
|
|
|
|
// 上报PV
|
2025-03-15 15:40:06 +08:00
|
|
|
|
if (to.fullPath === '/' || to.fullPath !== from.fullPath) {
|
|
|
|
|
|
// 同地址切换不上报
|
2025-03-12 18:41:20 +08:00
|
|
|
|
if (!(to.name === 'repo' || to.name === 'repoDir') || (from.fullPath === '/' && to.name === 'repoDir')) {
|
|
|
|
|
|
// 子应用单独处理
|
|
|
|
|
|
if (fromHomeWeb.includes(to.name)) return;
|
|
|
|
|
|
// 项目中代码点击tab单独上报(从其他地方跳转除外)
|
2025-03-13 16:09:33 +08:00
|
|
|
|
// useReport('pageview', {});
|
2025-03-12 18:41:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|