init
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import http from './http';
|
||||
import { Response } from '@/types';
|
||||
import { useMenuStore } from './menu';
|
||||
import { useAuthStore } from '@/plugins';
|
||||
|
||||
export interface Profile {
|
||||
account: Account;
|
||||
permissions: string[];
|
||||
role: string;
|
||||
}
|
||||
export interface Account {
|
||||
username: string;
|
||||
avatar: string;
|
||||
gender: number;
|
||||
}
|
||||
|
||||
export type TokenResult = {
|
||||
token: string;
|
||||
expires: number;
|
||||
code: number,
|
||||
erro: string,
|
||||
};
|
||||
export const useAccountStore = defineStore('account', {
|
||||
state() {
|
||||
return {
|
||||
account: {} as Account,
|
||||
permissions: [] as string[],
|
||||
role: '',
|
||||
logged: true,
|
||||
logged2: false
|
||||
};
|
||||
},
|
||||
actions: {
|
||||
async login(username: string, password: string) {
|
||||
return http
|
||||
.request<TokenResult, Response<TokenResult>>('api/auth/login', 'post_json', { username, password })
|
||||
.then(async (response) => {
|
||||
if (response.code === 200 && response.data.code === 0) {
|
||||
this.logged = true;
|
||||
this.logged2 = true
|
||||
console.log(response)
|
||||
http.setAuthorization(`Bearer ${response.data.token}`, response.data.expires);
|
||||
// await useMenuStore().getMenuList();
|
||||
return response.data;
|
||||
} else {
|
||||
this.logged2 = false
|
||||
return Promise.reject(response);
|
||||
}
|
||||
});
|
||||
},
|
||||
async logout() {
|
||||
return new Promise<boolean>((resolve) => {
|
||||
localStorage.removeItem('stepin-menu');
|
||||
http.removeAuthorization();
|
||||
// this.logged = false;
|
||||
resolve(true);
|
||||
});
|
||||
},
|
||||
async profile() {
|
||||
return http.request<Account, Response<Profile>>('/account', 'get').then((response) => {
|
||||
if (response.code === 0) {
|
||||
const { setAuthorities } = useAuthStore();
|
||||
const { account, permissions, role } = response.data;
|
||||
this.account = account;
|
||||
this.permissions = permissions;
|
||||
this.role = role;
|
||||
setAuthorities(permissions);
|
||||
return response.data;
|
||||
} else {
|
||||
return Promise.reject(response);
|
||||
}
|
||||
});
|
||||
},
|
||||
setLogged(logged: boolean) {
|
||||
this.logged = logged;
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,181 @@
|
||||
import { defineStore, storeToRefs } from 'pinia';
|
||||
import http from './http';
|
||||
import { ref, watch } from 'vue';
|
||||
import { Response } from '@/types';
|
||||
// import { RouteOption } from '@/router/interface';
|
||||
// import { addRoutes, removeRoute } from '@/router/dynamicRoutes';
|
||||
// import { useSettingStore } from './setting';
|
||||
// import { RouteRecordRaw, RouteMeta } from 'vue-router';
|
||||
// import { useAuthStore } from '@/plugins';
|
||||
// import router from '@/router';
|
||||
|
||||
// export interface MenuProps {
|
||||
// id?: number;
|
||||
// name: string;
|
||||
// path: string;
|
||||
// title?: string;
|
||||
// icon?: string;
|
||||
// badge?: number | string;
|
||||
// target?: '_self' | '_blank';
|
||||
// link?: string;
|
||||
// component: string;
|
||||
// renderMenu?: boolean;
|
||||
// permission?: string;
|
||||
// parent?: string;
|
||||
// children?: MenuProps[];
|
||||
// cacheable?: boolean;
|
||||
// view?: string;
|
||||
// }
|
||||
|
||||
export const useApiStore = defineStore('coreapi', () => {
|
||||
//检查是否已经初始化过了
|
||||
async function apiCheckInitStatus() {
|
||||
|
||||
return { code: 0 }
|
||||
// const initStatus = localStorage.getItem('ddns-init');
|
||||
// if (initStatus && initStatus === '1') {
|
||||
// return { code: 0 }
|
||||
// } else {
|
||||
// return http
|
||||
// .request<any, Response<any>>('/api/init/Check', 'GET')
|
||||
// .then((res) => {
|
||||
// // console.log(res)
|
||||
// if (res.data.code === 0) {
|
||||
// // localStorage.setItem('ddns-init', '1')
|
||||
// }
|
||||
// return res.data;
|
||||
// })
|
||||
// .finally(() => {
|
||||
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
//初始化系统配置
|
||||
async function apiInit(request: object) {
|
||||
console.log(request)
|
||||
return http
|
||||
.request<any, Response<any>>('/api/init/Init', 'post_json', request)
|
||||
.then((res) => {
|
||||
// console.log(res)
|
||||
|
||||
return res.data;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
//获取配置
|
||||
async function apiGetConfig() {
|
||||
return http
|
||||
.request<any, Response<any>>('/api/config/GetConfig', 'GET')
|
||||
.then((res) => {
|
||||
console.log(res)
|
||||
return res.data;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
//修改配置
|
||||
async function apiUpdateConfig(request: object) {
|
||||
return http
|
||||
.request<any, Response<any>>('/api/config/UpdateConfig', 'post_json', request)
|
||||
.then((res) => {
|
||||
console.log(res)
|
||||
return res.data;
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
//后台日志
|
||||
async function apiGetLogs(param: string) {
|
||||
return http.request<any, Response<any>>('/api/logs/GetLog?' + param, 'get').then(r => {
|
||||
// console.log(r)
|
||||
return r.data;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
//用户信息-头像
|
||||
async function apiUserInfo() {
|
||||
return http.request<any, Response<any>>('/api/auth/GetUserAvatar', 'get').then(r => {
|
||||
return r.data;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
//密码修改
|
||||
async function apiChangePwd(param: object) {
|
||||
return http.request<any, Response<any>>('/api/auth/UpdatePwd', 'post_json', param).then(r => {
|
||||
return r.data;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
//StartJobNow
|
||||
async function StartJobNow() {
|
||||
return http.request<any, Response<any>>('/api/config/ExecuteJobNow', 'get').then(r => {
|
||||
return r.data;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
async function VideoStatics() {
|
||||
return http.request<any, Response<any>>('/api/video/statics', 'get').then(r => {
|
||||
return r.data;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//视频查询
|
||||
async function VideoPageList(param: object) {
|
||||
return http.request<any, Response<any>>('/api/video/paged', 'post_json', param).then(r => {
|
||||
return r.data;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
//cookies
|
||||
async function CookiePageList(param: object) {
|
||||
return http.request<any, Response<any>>('/api/config/paged', 'post_json', param).then(r => {
|
||||
return r.data;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
async function UpdateConfig(param: object) {
|
||||
return http.request<any, Response<any>>('/api/config/update', 'post_json', param).then(r => {
|
||||
return r.data;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteCookie(id: string) {
|
||||
return http.request<any, Response<any>>('/api/config/delete?id=' + id, 'get').then(r => {
|
||||
return r.data;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
deleteCookie,
|
||||
UpdateConfig,
|
||||
apiCheckInitStatus,
|
||||
apiInit,
|
||||
apiGetConfig,
|
||||
apiUpdateConfig,
|
||||
apiGetLogs,
|
||||
apiUserInfo,
|
||||
apiChangePwd,
|
||||
StartJobNow,
|
||||
VideoStatics,
|
||||
VideoPageList,
|
||||
CookiePageList
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,76 @@
|
||||
import { AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
import createHttp from '@/utils/axiosHttp';
|
||||
import { isResponse } from '@/types';
|
||||
import NProgress from 'nprogress';
|
||||
import { useAccountStore } from '@/store';
|
||||
|
||||
const http = createHttp({
|
||||
timeout: 60000,
|
||||
baseURL: '/',
|
||||
withCredentials: true,
|
||||
xsrfCookieName: 'Authorization',
|
||||
xsrfHeaderName: 'Authorization',
|
||||
});
|
||||
|
||||
const isAxiosResponse = (obj: any): obj is AxiosResponse => {
|
||||
return typeof obj === 'object' && obj.status && obj.statusText && obj.headers && obj.config;
|
||||
};
|
||||
|
||||
// progress 进度条 -- 开启
|
||||
http.interceptors.request.use((req: AxiosRequestConfig) => {
|
||||
if (!NProgress.isStarted()) {
|
||||
NProgress.start();
|
||||
}
|
||||
return req;
|
||||
});
|
||||
|
||||
// 解析响应结果
|
||||
http.interceptors.response.use(
|
||||
(rep: AxiosResponse<String>) => {
|
||||
const { data } = rep;
|
||||
// if (data.code != null)
|
||||
// console.log(data)
|
||||
// if (data.code === 401) {
|
||||
// console.log(data)
|
||||
// }
|
||||
if (isResponse(data)) {
|
||||
return data.code === 0 ? data : Promise.reject(data);
|
||||
}
|
||||
return Promise.reject({ message: rep.statusText, code: rep.status, data });
|
||||
},
|
||||
(error) => {
|
||||
// console.log(error)
|
||||
// debugger
|
||||
if (error.response.status === 401) {
|
||||
useAccountStore().setLogged(false)
|
||||
} else {
|
||||
if (error.response && isAxiosResponse(error.response)) {
|
||||
return Promise.reject({
|
||||
message: error.response.statusText,
|
||||
code: error.response.status,
|
||||
data: error.response.data,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// progress 进度条 -- 关闭
|
||||
http.interceptors.response.use(
|
||||
(rep) => {
|
||||
if (NProgress.isStarted()) {
|
||||
NProgress.done();
|
||||
}
|
||||
return rep;
|
||||
},
|
||||
(error) => {
|
||||
if (NProgress.isStarted()) {
|
||||
NProgress.done();
|
||||
}
|
||||
return error;
|
||||
}
|
||||
);
|
||||
|
||||
export default http;
|
||||
@@ -0,0 +1,10 @@
|
||||
import { createPinia } from 'pinia';
|
||||
export { storeToRefs } from 'pinia';
|
||||
export * from './account';
|
||||
export * from './menu';
|
||||
export * from './setting';
|
||||
export * from './coreapi';
|
||||
|
||||
const pinia = createPinia();
|
||||
|
||||
export default pinia;
|
||||
@@ -0,0 +1,266 @@
|
||||
import { defineStore, storeToRefs } from 'pinia';
|
||||
import http from './http';
|
||||
import { ref, watch } from 'vue';
|
||||
import { Response } from '@/types';
|
||||
import { RouteOption } from '@/router/interface';
|
||||
import { addRoutes, removeRoute } from '@/router/dynamicRoutes';
|
||||
import { useSettingStore } from './setting';
|
||||
import { RouteRecordRaw, RouteMeta } from 'vue-router';
|
||||
import { useAuthStore } from '@/plugins';
|
||||
import router from '@/router';
|
||||
|
||||
export interface MenuProps {
|
||||
id?: number;
|
||||
name: string;
|
||||
path: string;
|
||||
title?: string;
|
||||
icon?: string;
|
||||
badge?: number | string;
|
||||
target?: '_self' | '_blank';
|
||||
link?: string;
|
||||
component: string;
|
||||
renderMenu?: boolean;
|
||||
permission?: string;
|
||||
parent?: string;
|
||||
children?: MenuProps[];
|
||||
cacheable?: boolean;
|
||||
view?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤菜单
|
||||
* @param routes
|
||||
* @param parentPermission
|
||||
*/
|
||||
function doMenuFilter(routes: Readonly<RouteRecordRaw[]>, parentPermission?: string) {
|
||||
const { hasAuthority } = useAuthStore();
|
||||
|
||||
const setCache = (meta: RouteMeta) => {
|
||||
meta._cache = {
|
||||
renderMenu: meta.renderMenu,
|
||||
};
|
||||
};
|
||||
|
||||
routes.forEach((route) => {
|
||||
const required = route.meta?.permission ?? parentPermission;
|
||||
// if (route.meta?.renderMenu === undefined && required) {
|
||||
if (required) {
|
||||
route.meta = route.meta ?? {};
|
||||
setCache(route.meta);
|
||||
route.meta.renderMenu = hasAuthority(route.meta.permission);
|
||||
}
|
||||
if (route.children) {
|
||||
doMenuFilter(route.children, required);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置过滤
|
||||
* @param routes
|
||||
*/
|
||||
function resetMenuFilter(routes: Readonly<RouteRecordRaw[]>) {
|
||||
const resetCache = (meta: RouteMeta) => {
|
||||
if (meta._cache) {
|
||||
meta.renderMenu = meta._cache?.renderMenu;
|
||||
}
|
||||
delete meta._cache;
|
||||
};
|
||||
routes.forEach((route) => {
|
||||
if (route.meta) {
|
||||
resetCache(route.meta);
|
||||
}
|
||||
if (route.children) {
|
||||
resetMenuFilter(route.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 菜单数据转为路由数据
|
||||
const toRoutes = (list: MenuProps[]): RouteOption[] => {
|
||||
return list.map((item) => ({
|
||||
name: item.name,
|
||||
path: item.path,
|
||||
component: item.component,
|
||||
children: item.children && toRoutes(item.children),
|
||||
meta: {
|
||||
title: item.title,
|
||||
permission: item.permission,
|
||||
icon: item.icon,
|
||||
renderMenu: item.renderMenu,
|
||||
cacheable: item.cacheable,
|
||||
href: item.link,
|
||||
badge: /^(false|true)$/i.test(item.badge + '') ? JSON.parse(item.badge + '') : item.badge,
|
||||
target: item.target,
|
||||
view: item.view,
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
export const useMenuStore = defineStore('menu', () => {
|
||||
const menuList = ref<MenuProps[]>([]);
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const { filterMenu } = storeToRefs(useSettingStore());
|
||||
|
||||
const checkMenuPermission = () => {
|
||||
if (filterMenu.value) {
|
||||
doMenuFilter(router.options.routes);
|
||||
console.log(router.options.routes);
|
||||
} else {
|
||||
resetMenuFilter(router.options.routes);
|
||||
}
|
||||
};
|
||||
|
||||
checkMenuPermission();
|
||||
|
||||
watch(filterMenu, checkMenuPermission);
|
||||
|
||||
const presetList = [
|
||||
// {
|
||||
// id: 1,
|
||||
// name: 'workplace',
|
||||
// title: '变更记录',
|
||||
// icon: 'DashboardOutlined',
|
||||
// badge: '',
|
||||
// target: '_self',
|
||||
// path: '/workplace',
|
||||
// component: '@/pages/workplace',
|
||||
// renderMenu: true,
|
||||
// parent: null,
|
||||
// permission: null,
|
||||
// cacheable: true,
|
||||
// },
|
||||
// {
|
||||
// id: 2,
|
||||
// name: 'set',
|
||||
// title: '我的配置',
|
||||
// icon: 'SettingOutlined',
|
||||
// badge: '',
|
||||
// target: '_self',
|
||||
// path: '/set',
|
||||
// component: '@/pages/set',
|
||||
// renderMenu: true,
|
||||
// parent: null,
|
||||
// permission: null,
|
||||
// cacheable: true,
|
||||
// },
|
||||
// {
|
||||
// id: 3,
|
||||
// name: 'logs',
|
||||
// title: '系统日志',
|
||||
// icon: 'UnorderedListOutlined',
|
||||
// badge: '',
|
||||
// target: '_self',
|
||||
// path: '/logs',
|
||||
// component: '@/pages/logs',
|
||||
// renderMenu: true,
|
||||
// parent: null,
|
||||
// permission: null,
|
||||
// // cacheable: true,
|
||||
// }
|
||||
];
|
||||
|
||||
|
||||
function getlocalMenus() {
|
||||
const menuStr = localStorage.getItem('stepin-menu');
|
||||
// debugger;
|
||||
let menus = [];
|
||||
if (!menuStr) {
|
||||
menus = presetList;
|
||||
localStorage.setItem('stepin-menu', JSON.stringify(menus));
|
||||
} else {
|
||||
menus = JSON.parse(menuStr);
|
||||
}
|
||||
// menus = presetList;
|
||||
// console.log('menus', menus)
|
||||
return menus;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function getMenuList() {
|
||||
loading.value = true;
|
||||
let localMenus = getlocalMenus();
|
||||
const menuMap = localMenus.reduce((p, c) => {
|
||||
p[c.name] = c;
|
||||
return p;
|
||||
}, {});
|
||||
localMenus.forEach((menu) => {
|
||||
menu.renderMenu = !!menu.renderMenu;
|
||||
if (menu.parent) {
|
||||
const parent = menuMap[menu.parent];
|
||||
parent.children = parent.children ?? [];
|
||||
parent.children.push(menu);
|
||||
}
|
||||
});
|
||||
const res = {
|
||||
message: 'success',
|
||||
code: 0,
|
||||
data: localMenus.filter((menu) => !menu.parent),
|
||||
};
|
||||
const { data } = res;
|
||||
menuList.value = data;
|
||||
// console.log(data)
|
||||
addRoutes(toRoutes(data));
|
||||
checkMenuPermission();
|
||||
|
||||
// loading.value = false;
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
}, 100);
|
||||
|
||||
return data;
|
||||
|
||||
// return http
|
||||
// .request<MenuProps[], Response<MenuProps[]>>('/menu', 'GET')
|
||||
// .then((res) => {
|
||||
// const { data } = res;
|
||||
// menuList.value = data;
|
||||
// addRoutes(toRoutes(data));
|
||||
// checkMenuPermission();
|
||||
// return data;
|
||||
// })
|
||||
// .finally(() => (loading.value = false));
|
||||
}
|
||||
|
||||
async function addMenu(menu: MenuProps) {
|
||||
return http
|
||||
.request<any, Response<any>>('/menu', 'POST_JSON', menu)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
})
|
||||
.finally(getMenuList);
|
||||
}
|
||||
|
||||
async function updateMenu(menu: MenuProps) {
|
||||
return http
|
||||
.request<any, Response<any>>('/menu', 'PUT_JSON', menu)
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
})
|
||||
.finally(getMenuList);
|
||||
}
|
||||
|
||||
async function removeMenu(id: number) {
|
||||
return http
|
||||
.request<any, Response<any>>('/menu', 'DELETE', { id })
|
||||
.then(async (res) => {
|
||||
if (res.code === 0) {
|
||||
removeRoute(res.data.name);
|
||||
}
|
||||
})
|
||||
.finally(getMenuList);
|
||||
}
|
||||
|
||||
return {
|
||||
loading,
|
||||
menuList,
|
||||
getMenuList,
|
||||
addMenu,
|
||||
updateMenu,
|
||||
removeMenu,
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
|
||||
export type Navigation = 'side' | 'head' | 'mix';
|
||||
|
||||
export const useSettingStore = defineStore('setting', () => {
|
||||
const navigation = ref<Navigation>('head');
|
||||
const useTabs = ref<boolean>(true);
|
||||
const theme = ref('header-purple');
|
||||
const contentClass = ref('common');
|
||||
const filterMenu = ref(false);
|
||||
|
||||
function setNavigation(nav: Navigation) {
|
||||
navigation.value = nav;
|
||||
}
|
||||
function setTheme(value: string) {
|
||||
theme.value = value;
|
||||
}
|
||||
function setContentClass(className: string) {
|
||||
contentClass.value = className;
|
||||
}
|
||||
function setFilterMenu(filter: boolean) {
|
||||
filterMenu.value = filter;
|
||||
}
|
||||
return {
|
||||
navigation,
|
||||
useTabs,
|
||||
theme,
|
||||
contentClass,
|
||||
filterMenu,
|
||||
setNavigation,
|
||||
setTheme,
|
||||
setContentClass,
|
||||
setFilterMenu,
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user