搜索结果列表页面开发
This commit is contained in:
119
src/stores/Global/index.ts
Normal file
119
src/stores/Global/index.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { ref, computed } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import menu from '@/constant/menu';
|
||||
import { type listType, type itemProps } from '@/components/NavTabs/types';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { getCustomMenuList } from '@/api/org/devIndex';
|
||||
|
||||
export const useGlobalInfoStore = defineStore('globalInfo', () => {
|
||||
const route = useRoute();
|
||||
const globalMenuInfo = ref<listType>(menu); // 全部菜单信息
|
||||
const menuType = ref(route?.meta?.type || 'repo'); // 当前菜单类型
|
||||
const customMenuInfo = ref([]); // org自定义菜单
|
||||
const isNotFound = ref(false); // 是否展示404页面
|
||||
const showTools = ref(true); // 是否展示工具栏
|
||||
const namespaceType = ref(-1); // 0 - 用户 1 - 组织
|
||||
const globalTheme = ref('light'); // 网站主题
|
||||
|
||||
const menuInfo = computed(() => {
|
||||
// 当前菜单
|
||||
return globalMenuInfo.value[menuType.value] || [];
|
||||
});
|
||||
|
||||
// 设置单类菜单信息
|
||||
const setNamespaceType = (val: number) => {
|
||||
namespaceType.value = val;
|
||||
};
|
||||
|
||||
// 设置全部菜单信息
|
||||
const setGlobalMenuInfo = (val: listType) => {
|
||||
globalMenuInfo.value = {
|
||||
...globalMenuInfo.value,
|
||||
...val
|
||||
};
|
||||
};
|
||||
|
||||
// 设置单类菜单信息
|
||||
const setMenuInfo = (val: itemProps) => {
|
||||
globalMenuInfo.value[menuType.value] = val;
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置菜单类型
|
||||
* @param val 类型
|
||||
* @param routeNamespace 路由中的命名空间(某些地方获取不到,需要手动传入)
|
||||
*/
|
||||
const setMenuType = async(val: string, routeNamespace?: string) => {
|
||||
if (val) {
|
||||
menuType.value = val;
|
||||
// 组织 需要加载自定义菜单
|
||||
if (val === 'org') {
|
||||
const namespace = routeNamespace || route.params.namespace;
|
||||
const res = await getCustomMenuList({
|
||||
namespace: Array.isArray(namespace) ? namespace.join('/') : namespace
|
||||
});
|
||||
customMenuInfo.value = (res?.data?.data || []).map((item) => ({
|
||||
...item,
|
||||
id: item.id || item.name,
|
||||
label: item.name,
|
||||
icon: item.link || 'gt-link',
|
||||
link: item.content
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置菜单标题旁的数字(如:mr数量,成员数量)
|
||||
* @param id 菜单id
|
||||
* @param val 增加或减少的数量
|
||||
* @param actionType 类型 add增加 reduce减少 equal等于
|
||||
*/
|
||||
const updateMenuNum = (id: string, val: number, actionType: 'add' | 'reduce' | 'equal' = 'equal') => {
|
||||
const list = [...(globalMenuInfo.value[menuType.value] || []), ...customMenuInfo.value];
|
||||
const item = list.find((item) => item.id === id) || {};
|
||||
if (actionType === 'equal') {
|
||||
item.num = val;
|
||||
}
|
||||
if (actionType === 'add') {
|
||||
item.num = item.num ? item.num + val : val; // 新增前判断num是否存在
|
||||
}
|
||||
if (actionType === 'reduce') {
|
||||
item.num = item.num <= 0 ? 0 : item.num - val; // 防止刷成负数
|
||||
}
|
||||
};
|
||||
|
||||
const setIsNotFound = (val: boolean) => {
|
||||
isNotFound.value = val;
|
||||
};
|
||||
|
||||
const setShowTools = (val: boolean) => {
|
||||
showTools.value = val;
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO: 设置主题,模仿github用于设置仓库项目markdown图片;
|
||||
* 前端暂时固定单一主题,后续可能会提供设置功能
|
||||
*/
|
||||
const setGlobalTheme = (val: string) => {
|
||||
globalTheme.value = val;
|
||||
};
|
||||
|
||||
return {
|
||||
customMenuInfo,
|
||||
menuInfo,
|
||||
menuType,
|
||||
isNotFound,
|
||||
showTools,
|
||||
namespaceType,
|
||||
globalTheme,
|
||||
setMenuType,
|
||||
updateMenuNum,
|
||||
setMenuInfo,
|
||||
setGlobalMenuInfo,
|
||||
setIsNotFound,
|
||||
setShowTools,
|
||||
setNamespaceType,
|
||||
setGlobalTheme
|
||||
};
|
||||
});
|
||||
183
src/stores/Org/index.ts
Normal file
183
src/stores/Org/index.ts
Normal file
@@ -0,0 +1,183 @@
|
||||
import { acceptHMRUpdate, defineStore } from 'pinia';
|
||||
import { reactive, ref, computed } from 'vue';
|
||||
import setting from '@/setting';
|
||||
export interface OrgInfo {
|
||||
avatar?: string
|
||||
name?: string
|
||||
description?: string
|
||||
path?: string;
|
||||
email?: string
|
||||
location?: string
|
||||
orgId?: string
|
||||
repoId?: string
|
||||
visibility?: string
|
||||
web_url?: string
|
||||
module_setting?: {
|
||||
group_id: string,
|
||||
modules: {
|
||||
key: string,
|
||||
type: string,
|
||||
value: string
|
||||
}[]
|
||||
}
|
||||
my_role?: {
|
||||
access_level: number,
|
||||
}
|
||||
[proName: string]: any
|
||||
}
|
||||
|
||||
export interface memObj {
|
||||
name: string, username: string, iam_id: string, avatar_url: string, [p: string]: any
|
||||
}
|
||||
|
||||
const { visitor, developer, admin } = setting.role;
|
||||
|
||||
export const orgInfoStore = defineStore('globalOrgInfo', () => {
|
||||
const orgInfo = ref<OrgInfo>({});
|
||||
const isFollow = ref<boolean>(false);
|
||||
const orgNameSpace = ref<string>('');
|
||||
const isCommunity = ref<boolean>(false);
|
||||
const communityUrl = ref<string>('');
|
||||
const communityactivityUrl = ref<string>('');
|
||||
const communityInfo = ref<Record<string, any>>({});
|
||||
const memList = ref<memObj[]>([]);
|
||||
const memCount = ref(0);
|
||||
const orgDevArticle = ref<Record<string, any>>({});
|
||||
const isDevLogin = ref<boolean>(false);
|
||||
const advertisementData = ref<any[]>([]);
|
||||
const articleTotal = ref<number>(0);
|
||||
const fansTotal = ref<number>(0);
|
||||
const access_level = computed(() => {
|
||||
return orgInfo.value?.my_role?.access_level || 0;
|
||||
});
|
||||
const group_quota = localStorage.getItem('group_quota') || 1;
|
||||
const manageable_group_num = localStorage.getItem('manageable_group_num') || 0;
|
||||
const isCreateOrg = ref<boolean>(parseInt(group_quota as any) - parseInt(manageable_group_num as any) > 0);
|
||||
|
||||
const isPrivate = computed(() => { // 是否私有
|
||||
return orgInfo.value?.visibility === 'private';
|
||||
});
|
||||
|
||||
const isAdmin = computed(() => {
|
||||
return access_level?.value >= admin;
|
||||
});
|
||||
|
||||
const isDeveloper = computed(() => {
|
||||
return access_level?.value >= developer;
|
||||
});
|
||||
|
||||
const isVisitor = computed(() => {
|
||||
return access_level?.value >= visitor;
|
||||
});
|
||||
|
||||
const setOrgInfo = (info?: OrgInfo) => {
|
||||
if (info) {
|
||||
info['email'] = info.group_extend.email;
|
||||
info['home_page'] = info.group_extend.home_page;
|
||||
info['location'] = info.group_extend.location;
|
||||
info['avatar_url1'] = info.avatar;
|
||||
// isFollow.value = !!info?.starred;
|
||||
orgInfo.value = {
|
||||
...orgInfo.value,
|
||||
...info
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const setAccessLevel = (val: number) => {
|
||||
orgInfo.value = {
|
||||
...orgInfo.value,
|
||||
my_role: {
|
||||
access_level: val
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const setVisibility = (val: string) => {
|
||||
orgInfo.value = {
|
||||
...orgInfo.value,
|
||||
visibility: val
|
||||
};
|
||||
};
|
||||
|
||||
const setFollow = (val?: boolean) => {
|
||||
isFollow.value = !!val;
|
||||
};
|
||||
|
||||
const setNameSpace = (orgId: string) => {
|
||||
orgNameSpace.value = orgId;
|
||||
};
|
||||
|
||||
const setCommunity = (val: boolean) => {
|
||||
isCommunity.value = val;
|
||||
};
|
||||
|
||||
const setCommunityUrl = (param: { communityUrl: string, communityactivityUrl: string }) => {
|
||||
communityUrl.value = param.communityUrl;
|
||||
communityactivityUrl.value = param.communityactivityUrl;
|
||||
};
|
||||
const setCommunityInfo = (obj:Record<string, any>) => {
|
||||
communityInfo.value = obj;
|
||||
};
|
||||
|
||||
const setOrgMember = (num: number, list: memObj[]) => {
|
||||
memCount.value = num;
|
||||
memList.value = list;
|
||||
};
|
||||
|
||||
const setDevLogin = (val:boolean) => {
|
||||
isDevLogin.value = val;
|
||||
};
|
||||
const setAdvertisementData = (val:any[]) => {
|
||||
advertisementData.value = val;
|
||||
};
|
||||
const setArticleTotal = (num:number) => {
|
||||
articleTotal.value = num;
|
||||
};
|
||||
const setFansTotal = (num:number) => {
|
||||
fansTotal.value = num;
|
||||
};
|
||||
const setIsCreateOrg = (val:boolean) => {
|
||||
isCreateOrg.value = val;
|
||||
};
|
||||
return {
|
||||
isPrivate,
|
||||
isAdmin,
|
||||
isDeveloper,
|
||||
isVisitor,
|
||||
access_level,
|
||||
orgInfo,
|
||||
isFollow,
|
||||
orgNameSpace,
|
||||
isCommunity,
|
||||
communityUrl,
|
||||
communityInfo,
|
||||
communityactivityUrl,
|
||||
memList,
|
||||
memCount,
|
||||
orgDevArticle,
|
||||
advertisementData,
|
||||
isDevLogin,
|
||||
articleTotal,
|
||||
fansTotal,
|
||||
isCreateOrg,
|
||||
setOrgInfo,
|
||||
setAccessLevel,
|
||||
setVisibility,
|
||||
setFollow,
|
||||
setNameSpace,
|
||||
setCommunity,
|
||||
setCommunityUrl,
|
||||
setCommunityInfo,
|
||||
setOrgMember,
|
||||
setAdvertisementData,
|
||||
setDevLogin,
|
||||
setArticleTotal,
|
||||
setFansTotal,
|
||||
setIsCreateOrg
|
||||
};
|
||||
});
|
||||
|
||||
if ((import.meta as any).hot) {
|
||||
(import.meta as any).hot.accept(acceptHMRUpdate(orgInfoStore, (import.meta as any).hot));
|
||||
};
|
||||
31
src/stores/Repo/examine.ts
Normal file
31
src/stores/Repo/examine.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { reactive } from 'vue';
|
||||
import { fetchPrExaminePerson } from '@/api/merge';
|
||||
import keyBy from 'lodash/keyBy';
|
||||
import type { IAuthor } from '@/api/issue/types.ts';
|
||||
|
||||
export const useExamineData = defineStore('repoExamineData', () => {
|
||||
const examineData = reactive<{ reviewers: IAuthor[], approvers: IAuthor[], testers: IAuthor[]; }>({
|
||||
reviewers: [],
|
||||
approvers: [],
|
||||
testers: []
|
||||
});
|
||||
|
||||
const fetchExamineData = async(data: { repoId: string, prId: string; }) => {
|
||||
const res = await fetchPrExaminePerson({ repoId: data.repoId, iid: data.prId });
|
||||
if (!res.error) {
|
||||
const data: { [type: 'reviewer' | 'approver' | 'tester' | string]: { persons: IAuthor[]; }; } = keyBy(
|
||||
res.data || [],
|
||||
'type'
|
||||
);
|
||||
examineData.reviewers = data.reviewer.persons || [];
|
||||
examineData.approvers = data.approver.persons || [];
|
||||
examineData.testers = data.tester.persons || [];
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
examineData,
|
||||
fetchExamineData
|
||||
};
|
||||
});
|
||||
131
src/stores/Repo/index.ts
Normal file
131
src/stores/Repo/index.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { getRepo } from '@/api/repo';
|
||||
import getRepoId from '@/utils/getRepoId';
|
||||
import setting from '@/setting';
|
||||
|
||||
export interface repoInfoType {
|
||||
id?: number;
|
||||
name?:string;
|
||||
path?:string;
|
||||
path_with_namespace?:string;
|
||||
created_at?:string;
|
||||
star_count?:number;
|
||||
starred?:boolean;
|
||||
creator?:{
|
||||
id:number;
|
||||
iam_id:string;
|
||||
username:string;
|
||||
nick_name:string;
|
||||
};
|
||||
description?:string;
|
||||
module_setting?:{
|
||||
repo_id:string;
|
||||
modules:{
|
||||
key: string,
|
||||
type: string,
|
||||
value: string
|
||||
}[]
|
||||
};
|
||||
web_url?:string;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
const { visitor, developer, admin } = setting.role;
|
||||
|
||||
export const repoInfoStore = defineStore('globalRepoInfo', () => {
|
||||
const repoInfo = ref<repoInfoType>({});
|
||||
const access_level = ref<number>(0);
|
||||
|
||||
const setAccessLevel = (val: number) => {
|
||||
access_level.value = val;
|
||||
};
|
||||
|
||||
const setVisibility = (val: string) => {
|
||||
repoInfo.value = {
|
||||
...repoInfo.value,
|
||||
visibility: val
|
||||
};
|
||||
};
|
||||
|
||||
const isPrivate = computed(() => { // 是否私有
|
||||
return repoInfo.value?.visibility === 'private';
|
||||
});
|
||||
|
||||
const isArchived = computed(() => { // 是否归档
|
||||
return repoInfo.value?.archived;
|
||||
});
|
||||
|
||||
const isAdminOperate = computed(() => { // 操作权限(管理者且未归档,为了兼容未考虑归档时的权限)
|
||||
return access_level?.value >= admin && !repoInfo.value?.archived;
|
||||
});
|
||||
|
||||
const isDeveloperOperate = computed(() => { // 操作权限(开发者且未归档,为了兼容未考虑归档时的权限)
|
||||
return access_level?.value >= developer && !repoInfo.value?.archived;
|
||||
});
|
||||
|
||||
const isVisitorOperate = computed(() => { // 操作权限(浏览者且未归档,为了兼容未考虑归档时的权限)
|
||||
return access_level?.value >= visitor && !repoInfo.value?.archived;
|
||||
});
|
||||
|
||||
const isAdmin = computed(() => {
|
||||
return access_level?.value >= admin;
|
||||
});
|
||||
|
||||
const isDeveloper = computed(() => {
|
||||
return access_level?.value >= developer;
|
||||
});
|
||||
|
||||
const isVisitor = computed(() => {
|
||||
return access_level?.value >= visitor;
|
||||
});
|
||||
|
||||
const setRepoInfo = (data: repoInfoType) => {
|
||||
repoInfo.value = {
|
||||
...repoInfo.value,
|
||||
...data
|
||||
};
|
||||
};
|
||||
const setReleaseCount = (count: number) => {
|
||||
repoInfo.value.release_count = count;
|
||||
};
|
||||
const setTagsCount = (count: number) => {
|
||||
repoInfo.value.tag_count = count;
|
||||
};
|
||||
const setForkVisible = (visible: boolean)=> {
|
||||
repoInfo.value.module_setting?.modules.forEach((item)=> {
|
||||
if (item.key === 'FORK' && item.type === 'PROJECT_MODULE') {
|
||||
item.value = visible ? '1' : '0'
|
||||
}
|
||||
})
|
||||
}
|
||||
const getRepoInfo = async(namePath?: string) => {
|
||||
const res = await getRepo({ repoId: namePath || getRepoId(), statistics: true });
|
||||
if (!res.error) {
|
||||
const { data } = res.data;
|
||||
setRepoInfo(data);
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
return {
|
||||
isPrivate,
|
||||
isAdmin,
|
||||
isDeveloper,
|
||||
isVisitor,
|
||||
isArchived,
|
||||
isAdminOperate,
|
||||
isDeveloperOperate,
|
||||
isVisitorOperate,
|
||||
access_level,
|
||||
repoInfo,
|
||||
setRepoInfo,
|
||||
setVisibility,
|
||||
setAccessLevel,
|
||||
setReleaseCount,
|
||||
setTagsCount,
|
||||
setForkVisible,
|
||||
getRepoInfo
|
||||
};
|
||||
});
|
||||
12
src/stores/Repo/member.store.ts
Normal file
12
src/stores/Repo/member.store.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { defineStore } from 'pinia';
|
||||
export const useRepoMemberStore = defineStore('repoMemberState',{
|
||||
state:()=>({
|
||||
|
||||
}),
|
||||
getters:{},
|
||||
actions:{
|
||||
getOrgList(){//项目成员列表
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
16
src/stores/UserSetting/Organization.ts
Normal file
16
src/stores/UserSetting/Organization.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import type { OrgItem } from '@/stores/UserSetting/type';
|
||||
interface OrgState{
|
||||
orgList:Array<OrgItem>;
|
||||
}
|
||||
export const useOrganizationStore = defineStore('organizationState', {
|
||||
state: ():OrgState => ({
|
||||
orgList: []// 组织列表
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
getOrgList() { // 获取个人的组织列表
|
||||
return [];
|
||||
}
|
||||
}
|
||||
});
|
||||
11
src/stores/UserSetting/type.ts
Normal file
11
src/stores/UserSetting/type.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export interface OrgItem{//组织
|
||||
id: string;// id
|
||||
name: string;//名字
|
||||
namespace?: string;
|
||||
avatar: string; // 个人头像
|
||||
description?: string;//描述
|
||||
memberCount?: number;//成员
|
||||
type:String;//类型
|
||||
role:String|Number;//角色
|
||||
[key:string]:any;
|
||||
}
|
||||
24
src/stores/merge.ts
Normal file
24
src/stores/merge.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { ref, computed } from 'vue';
|
||||
import { getStore, setStore } from '@/utils/storage';
|
||||
import { defineStore } from 'pinia';
|
||||
import { localStorageKeys } from '@/constant/index';
|
||||
|
||||
// mr 详情页 文件变更
|
||||
export const useMrChangeStore = defineStore('merge-change-db', () => {
|
||||
// 记录正在添加 issue 的 diff 文件: `文件名-行号-左/右`
|
||||
const addingDiscussionsFile = ref('');
|
||||
// 记录 diff 文件是否折叠 issue
|
||||
const foldDiscussionsFile = ref({ curClickFile: '', record: {} });
|
||||
|
||||
// 显示设置
|
||||
const setting = getStore(localStorageKeys.merge_showformat_setting);
|
||||
const mergeDiffOutputFormat = ref(setting ? setting.mergeDiffOutputFormat : 'side-by-side');
|
||||
const ignore_whitespace_change = ref(setting ? setting.ignore_whitespace_change : false);
|
||||
|
||||
return {
|
||||
addingDiscussionsFile,
|
||||
foldDiscussionsFile,
|
||||
mergeDiffOutputFormat,
|
||||
ignore_whitespace_change
|
||||
};
|
||||
});
|
||||
93
src/stores/ui/resize.ts
Normal file
93
src/stores/ui/resize.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
import { useThrottleFn } from '@vueuse/core';
|
||||
import mitt, { EventType } from 'mitt';
|
||||
|
||||
interface Events extends Record<EventType, unknown> {
|
||||
resize: [number, number];
|
||||
}
|
||||
|
||||
class WindowResize {
|
||||
private active = false;
|
||||
|
||||
isActive() {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
start() {
|
||||
if (this.active) {
|
||||
this.stop();
|
||||
}
|
||||
window.addEventListener('resize', this.onResizeDebounced);
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
stop() {
|
||||
window.removeEventListener('resize', this.onResizeDebounced);
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初次进入页面且已通过 onWindowResize 注册后,需手动触发一遍
|
||||
*/
|
||||
onResize() {
|
||||
// [window.innerWidth, window.innerHeight]
|
||||
const size: [number, number] = [
|
||||
document.documentElement.clientWidth,
|
||||
document.documentElement.clientHeight
|
||||
];
|
||||
emitter.emit('resize', size);
|
||||
}
|
||||
|
||||
private onResizeDebounced = useThrottleFn(this.onResize, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册响应窗口大小变化的回调函数,自动启停优化性能
|
||||
* @example
|
||||
* // vue steup 里面使用
|
||||
* onBeforeUnmount(
|
||||
* onWindowResize((size) => console.log('屏幕尺寸', size))
|
||||
* )
|
||||
*/
|
||||
const onWindowResize = (cb: (size: [number, number]) => void) => {
|
||||
if (!windowResizeObserver.isActive()) {
|
||||
windowResizeObserver.start();
|
||||
}
|
||||
|
||||
emitter.on('resize', cb);
|
||||
|
||||
return () => {
|
||||
emitter.off('resize', cb);
|
||||
if (emitter.all.size === 0) {
|
||||
windowResizeObserver.stop();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const emitter = mitt<Events>();
|
||||
const windowResizeObserver = new WindowResize();
|
||||
|
||||
export const useResizeStore = defineStore('windowResize', () => {
|
||||
const MOBILE_WIDTH_LIMIT = 1200;
|
||||
|
||||
const isMobile = ref(false);
|
||||
|
||||
const isMobileDevice = (size: [number, number]) => {
|
||||
const [width] = size;
|
||||
return width <= MOBILE_WIDTH_LIMIT;
|
||||
};
|
||||
|
||||
// 全局可用
|
||||
onWindowResize((size) => {
|
||||
isMobile.value = isMobileDevice(size);
|
||||
});
|
||||
windowResizeObserver.onResize();
|
||||
|
||||
return {
|
||||
isMobile,
|
||||
onWindowResize,
|
||||
isMobileDevice,
|
||||
windowResizeObserver
|
||||
};
|
||||
});
|
||||
143
src/stores/user.ts
Normal file
143
src/stores/user.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import { acceptHMRUpdate, defineStore } from 'pinia';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { getUserToken, getUserInfo } from '@/api/user';
|
||||
|
||||
export interface AccountInfo {
|
||||
domain_id?: string;
|
||||
email?: string;
|
||||
id?: string;
|
||||
arts_id?: string;
|
||||
mobile?: string;
|
||||
avatar?: string;
|
||||
nickname?: string;
|
||||
username?: string;
|
||||
access_token?: string;
|
||||
refresh_token?: string;
|
||||
xauth_token?: string;
|
||||
isFollow?: boolean;
|
||||
atomgit_username?: string;
|
||||
[x: string]: any;
|
||||
}
|
||||
|
||||
export const useAccountStore = defineStore('accountInfo', () => {
|
||||
const cacheInfo = localStorage.getItem('userInfo');
|
||||
const isLogin = ref(Boolean(localStorage.getItem('access_token')));
|
||||
const userInfo = cacheInfo ? JSON.parse(cacheInfo) : {};
|
||||
const accountInfo = reactive<AccountInfo>({
|
||||
access_token: localStorage.getItem('access_token') || '',
|
||||
refresh_token: localStorage.getItem('refresh_token') || '',
|
||||
xauth_token: localStorage.getItem('xauth_token') || '',
|
||||
...userInfo
|
||||
});
|
||||
|
||||
const refresh = () => {
|
||||
/** 重定向跳转时强刷使用 */
|
||||
const info = localStorage.getItem('userInfo');
|
||||
isLogin.value = Boolean(localStorage.getItem('access_token'));
|
||||
const userData = info ? JSON.parse(info) : {};
|
||||
for (const key in userData) {
|
||||
accountInfo[key] = userData[key];
|
||||
}
|
||||
accountInfo.access_token = localStorage.getItem('access_token') || '';
|
||||
accountInfo.refresh_token = localStorage.getItem('refresh_token') || '';
|
||||
accountInfo.xauth_token = localStorage.getItem('xauth_token') || '';
|
||||
};
|
||||
|
||||
const saveStatus = (status: boolean) => {
|
||||
isLogin.value = status;
|
||||
};
|
||||
|
||||
const saveAccountInfo = (info?: AccountInfo) => {
|
||||
if (info) {
|
||||
for (const key in info) {
|
||||
accountInfo[key] = info[key];
|
||||
}
|
||||
} else {
|
||||
for (const key in accountInfo) {
|
||||
accountInfo[key] = '';
|
||||
}
|
||||
}
|
||||
};
|
||||
// 可能有从博客跳转过来的,通过接口判断是否登陆
|
||||
const checkIsLogin = async () => {
|
||||
const { data, error } = await getUserToken();
|
||||
if (data?.data) {
|
||||
const { access_token, refresh_token } = data.data;
|
||||
localStorage.setItem('access_token', access_token);
|
||||
localStorage.setItem('refresh_token', refresh_token);
|
||||
saveStatus(true);
|
||||
const userRes = await getUserInfo();
|
||||
if (userRes.data?.data) {
|
||||
localStorage.setItem('userInfo', JSON.stringify(userRes.data?.data));
|
||||
saveAccountInfo({
|
||||
access_token: localStorage.getItem('access_token') || '',
|
||||
refresh_token: localStorage.getItem('refresh_token') || '',
|
||||
...userRes.data?.data
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
localStorage.removeItem('access_token');
|
||||
localStorage.removeItem('refresh_token');
|
||||
localStorage.removeItem('userInfo');
|
||||
saveAccountInfo({});
|
||||
return false;
|
||||
};
|
||||
const saveAtomgitUserName = (username: string) => {
|
||||
accountInfo.atomgit_username = username;
|
||||
};
|
||||
|
||||
return {
|
||||
isLogin,
|
||||
accountInfo,
|
||||
checkIsLogin,
|
||||
saveStatus,
|
||||
refresh,
|
||||
saveAccountInfo,
|
||||
saveAtomgitUserName
|
||||
};
|
||||
});
|
||||
|
||||
export const otherAccountStore = defineStore('otherInfo', () => {
|
||||
const isLogin = ref(Boolean(localStorage.getItem('access_token')));
|
||||
const userInfo = {};
|
||||
const accountInfo = reactive<AccountInfo>({
|
||||
...userInfo
|
||||
});
|
||||
|
||||
const saveAccountInfo = (info?: AccountInfo) => {
|
||||
if (info) {
|
||||
for (const key in info) {
|
||||
accountInfo[key] = info[key];
|
||||
}
|
||||
} else {
|
||||
for (const key in accountInfo) {
|
||||
accountInfo[key] = '';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const saveFollowed = (isFollowed?: boolean) => {
|
||||
accountInfo.isFollow = isFollowed;
|
||||
};
|
||||
|
||||
return {
|
||||
isLogin,
|
||||
accountInfo,
|
||||
saveAccountInfo,
|
||||
saveFollowed
|
||||
};
|
||||
});
|
||||
|
||||
export const entranceData = defineStore('entrance', () => {
|
||||
const repoList = ref([]);
|
||||
const orgList = ref([]);
|
||||
return {
|
||||
repoList,
|
||||
orgList
|
||||
};
|
||||
});
|
||||
|
||||
if ((import.meta as any).hot) {
|
||||
(import.meta as any).hot.accept(acceptHMRUpdate(useAccountStore, (import.meta as any).hot));
|
||||
}
|
||||
Reference in New Issue
Block a user