Compare commits

...

2 Commits

12 changed files with 121 additions and 60 deletions

View File

@ -5,6 +5,7 @@ const fix = '/menu';
const url = { const url = {
insert: `${fix}/insert`, // 分页查询 insert: `${fix}/insert`, // 分页查询
tree: `${fix}/tree`, // 查询菜单 tree: `${fix}/tree`, // 查询菜单
treeAll: `${fix}/treeAll`, // 查询所有菜单
update: `${fix}/update`, // 修改菜单 update: `${fix}/update`, // 修改菜单
delete: `${fix}/delete`, // 删除菜单 delete: `${fix}/delete`, // 删除菜单
}; };
@ -16,6 +17,9 @@ export const insertMenu = (params: Object) => {
export const getMenuTree = (params?: any) => { export const getMenuTree = (params?: any) => {
return get(url.tree, params); return get(url.tree, params);
}; };
export const getMenuTreeAll = (params?: any) => {
return get(url.treeAll, params);
};
export const updateMenu = (params: Object) => { export const updateMenu = (params: Object) => {
return post(url.update, params); return post(url.update, params);

View File

@ -7,6 +7,7 @@ const url = {
page: `${fix}/page`, page: `${fix}/page`,
update: `${fix}/update`, update: `${fix}/update`,
delete: `${fix}/delete`, delete: `${fix}/delete`,
userRole: `/userRole/getRoles`,
}; };
export const insertRule = (params: Object) => { export const insertRule = (params: Object) => {
@ -20,6 +21,11 @@ export const getRuleList = (params: Object) => {
export const updateRule = (params: Object) => { export const updateRule = (params: Object) => {
return post(url.update, params); return post(url.update, params);
}; };
export const deleteRule = (params: Object) => { export const deleteRule = (params: Object) => {
return post(url.delete, params); return post(url.delete, params);
}; };
export const getUserRole = (params: Object) => {
return get(url.userRole, params);
};

View File

@ -149,6 +149,8 @@ import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
import { websiteConfig } from '@/config/website.config'; import { websiteConfig } from '@/config/website.config';
import { zsDialog } from '@/utils'; import { zsDialog } from '@/utils';
import { DialogEnum } from '@/enums/pluginEnum'; import { DialogEnum } from '@/enums/pluginEnum';
import { PageEnum } from '@/enums/pageEnum';
export default defineComponent({ export default defineComponent({
name: 'PageHeader', name: 'PageHeader',
components: { ...components, ProjectSetting, AsideMenu }, components: { ...components, ProjectSetting, AsideMenu },
@ -166,12 +168,12 @@ export default defineComponent({
const { navMode, navTheme, headerSetting, menuSetting, crumbsSetting } = const { navMode, navTheme, headerSetting, menuSetting, crumbsSetting } =
useProjectSetting(); useProjectSetting();
const { name } = userStore?.info || {}; const { realname } = userStore?.info || {};
const drawerSetting = ref(); const drawerSetting = ref();
const state = reactive({ const state = reactive({
username: name ?? '', username: realname ?? '',
fullscreenIcon: 'FullscreenOutlined', fullscreenIcon: 'FullscreenOutlined',
navMode, navMode,
navTheme, navTheme,
@ -252,7 +254,7 @@ export default defineComponent({
localStorage.removeItem(StorageEnum.ZS_TABS_ROUTES); localStorage.removeItem(StorageEnum.ZS_TABS_ROUTES);
router router
.replace({ .replace({
name: 'Login', name: PageEnum.BASE_LOGIN_NAME,
query: { query: {
redirect: route.fullPath, redirect: route.fullPath,
}, },
@ -260,7 +262,6 @@ export default defineComponent({
.finally(() => location.reload()); .finally(() => location.reload());
}); });
}, },
onNegativeClick: () => {},
}); });
}; };

View File

@ -120,7 +120,7 @@ import {
RightOutlined, RightOutlined,
} from '@vicons/antd'; } from '@vicons/antd';
import { renderIcon } from '@/utils'; import { renderIcon } from '@/utils';
// import elementResizeDetectorMaker from 'element-resize-detector'; import elementResizeDetectorMaker from 'element-resize-detector';
import { useDesignSetting } from '@/hooks/setting/useDesignSetting'; import { useDesignSetting } from '@/hooks/setting/useDesignSetting';
import { useProjectSettingStore } from '@/store/modules/projectSetting'; import { useProjectSettingStore } from '@/store/modules/projectSetting';
import { useThemeVars } from 'naive-ui'; import { useThemeVars } from 'naive-ui';
@ -510,14 +510,14 @@ export default defineComponent({
} }
onMounted(() => { onMounted(() => {
// onElementResize(); onElementResize();
}); });
// function onElementResize() { function onElementResize() {
// let observer; let observer;
// observer = elementResizeDetectorMaker(); observer = elementResizeDetectorMaker();
// observer.listenTo(navWrap.value, handleResize); observer.listenTo(navWrap.value, handleResize);
// } }
return { return {
...toRefs(state), ...toRefs(state),

View File

@ -47,9 +47,10 @@ export const generateRoutes = (routerMap, parent?): any[] => {
!item.redirect && !item.redirect &&
(currentRoute.redirect = `${item.path}/${item.children[0].path}`); (currentRoute.redirect = `${item.path}/${item.children[0].path}`);
// Recursion // Recursion
console.log(currentRoute.redirect, 'currentRoute.redirect');
currentRoute.children = generateRoutes(item.children, currentRoute); currentRoute.children = generateRoutes(item.children, currentRoute);
// currentRoute.redirect = `${item.path}/${item.children[0].path}`;
// console.log(currentRoute.redirect, 'currentRoute.redirect');
} }
return currentRoute; return currentRoute;
}); });
@ -60,7 +61,7 @@ export const generateRoutes = (routerMap, parent?): any[] => {
* @returns {Promise<Router>} * @returns {Promise<Router>}
*/ */
export const generateDynamicRoutes = async (): Promise<RouteRecordRaw[]> => { export const generateDynamicRoutes = async (): Promise<RouteRecordRaw[]> => {
const { data } = await getMenuTree({ mode: 1 }); const { data } = await getMenuTree();
const router = generateRoutes(data); const router = generateRoutes(data);
asyncImportRoute(router); asyncImportRoute(router);
return router; return router;

View File

@ -26,18 +26,11 @@ export const RootRoute: RouteRecordRaw = {
path: '/', path: '/',
name: 'Root', name: 'Root',
redirect: '/system/menu', redirect: '/system/menu',
// async beforeEnter(to, from, next) {
// next(await reqRedirectUrl());
// },
meta: { meta: {
title: 'Root', title: 'Root',
}, },
}; };
// async function reqRedirectUrl() {
// return "/system/role";
// }
//需要验证权限 //需要验证权限
export const asyncRoutes = []; export const asyncRoutes = [];

View File

@ -6,6 +6,7 @@ import { useAsyncRoute } from '@/store/modules/asyncRoute';
import { PageEnum } from '@/enums/pageEnum'; import { PageEnum } from '@/enums/pageEnum';
import { ErrorPageRoute } from '@/router/base'; import { ErrorPageRoute } from '@/router/base';
import { useProjectSetting } from '@/store/modules/projectSetting'; import { useProjectSetting } from '@/store/modules/projectSetting';
import { getUserStyleSetting } from '@/api/system/user';
const LOGIN_PATH = PageEnum.BASE_LOGIN; const LOGIN_PATH = PageEnum.BASE_LOGIN;
const whitePathList = [LOGIN_PATH]; // 没有重定向白名单 const whitePathList = [LOGIN_PATH]; // 没有重定向白名单
@ -63,7 +64,6 @@ export async function createRouterGuards(router: Router) {
try { try {
await userStore.getInfo(); await userStore.getInfo();
await useProjectSettingStore.setProjectSetting();
const routes = await asyncRouteStore.generateRoutes(); const routes = await asyncRouteStore.generateRoutes();
// 动态添加可访问路由表 // 动态添加可访问路由表
routes.forEach((item: unknown) => { routes.forEach((item: unknown) => {

View File

@ -7,7 +7,6 @@ import type {
IMultiTabsSetting, IMultiTabsSetting,
ICrumbsSetting, ICrumbsSetting,
} from '/#/config'; } from '/#/config';
import { getUserStyleSetting } from '@/api/system/user';
import { useDesignSetting } from './designSetting'; import { useDesignSetting } from './designSetting';
const { const {
navMode, navMode,
@ -88,21 +87,38 @@ export const useProjectSettingStore = defineStore({
}, },
}, },
actions: { actions: {
async setProjectSetting() { async setProjectSetting(data: any) {
const useDesignSettingStore = useDesignSetting(); const useDesignSettingStore = useDesignSetting();
const { data } = await getUserStyleSetting(); this.navMode = data.navMode ?? 'vertical';
this.navMode = data.navMode; this.navTheme = data.navTheme ?? 'light';
this.navTheme = data.navTheme; this.isMobile = data.isMobile ?? false;
this.isMobile = data.isMobile; this.headerSetting = data.headerSetting ?? {
this.headerSetting = data.headerSetting; bgColor: '#fff',
this.showFooter = data.showFooter; fixed: true,
this.menuSetting = data.menuSetting; isReload: true,
this.multiTabsSetting = data.multiTabsSetting; };
this.crumbsSetting = data.crumbsSetting; this.showFooter = data.showFooter ?? true;
this.isPageAnimate = data.isPageAnimate; this.menuSetting = data.menuSetting ?? {
this.pageAnimateType = data.pageAnimateType; minMenuWidth: 64,
menuWidth: 200,
fixed: true,
mixMenu: false,
mobileWidth: 800,
collapsed: false,
};
this.multiTabsSetting = data.multiTabsSetting ?? {
bgColor: '#fff',
show: true,
fixed: true,
};
this.crumbsSetting = data.crumbsSetting ?? {
show: true,
showIcon: false,
};
this.isPageAnimate = data.isPageAnimate ?? true;
this.pageAnimateType = data.pageAnimateType ?? 'fade-bottom';
useDesignSettingStore.setAppTheme(data.appTheme); useDesignSettingStore.setAppTheme(data.appTheme ?? '#2d8cf0');
}, },
setIsMobile(value: boolean): void { setIsMobile(value: boolean): void {

View File

@ -1,20 +1,28 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { store } from '@/store'; import { store } from '@/store';
import { useAsyncRoute } from '@/store/modules/asyncRoute';
import { StorageEnum } from '@/enums/storageEnum'; import { StorageEnum } from '@/enums/storageEnum';
import { ResultEnum } from '@/enums/httpEnum'; import { ResultEnum } from '@/enums/httpEnum';
import { storage, routerTurnByName } from '@/utils'; import { storage, routerTurnByName } from '@/utils';
import { login, getUserInfo } from '@/api/system/user'; import { login, getUserInfo } from '@/api/system/user';
import { PageEnum } from '@/enums/pageEnum'; import { PageEnum } from '@/enums/pageEnum';
import router from '@/router';
import type { RouteRecordRaw } from 'vue-router';
import { useProjectSetting } from '@/store/modules/projectSetting';
export type UserInfoType = { export type UserInfoType = {
// TODO: add your own data // TODO: add your own data
name: string; realname: string;
email: string; email: string;
token: string;
menuTree: any[];
userStyleSetting: object;
userId: number;
}; };
export interface IUserState { export interface IUserState {
token: string; token: string;
username: string; username: string;
welcome: string;
avatar: string; avatar: string;
permissions: any[]; permissions: any[];
info: UserInfoType; info: UserInfoType;
@ -25,7 +33,6 @@ export const useUserStore = defineStore({
state: (): IUserState => ({ state: (): IUserState => ({
token: storage.get(StorageEnum.ZS_ACCESS_TOKEN, ''), token: storage.get(StorageEnum.ZS_ACCESS_TOKEN, ''),
username: '', username: '',
welcome: '',
avatar: '', avatar: '',
permissions: [], permissions: [],
info: storage.get(StorageEnum.ZS_CURRENT_USER, {}), info: storage.get(StorageEnum.ZS_CURRENT_USER, {}),
@ -51,24 +58,32 @@ export const useUserStore = defineStore({
setToken(token: string) { setToken(token: string) {
this.token = token; this.token = token;
}, },
setAvatar(avatar: string) {
this.avatar = avatar; // setPermissions(permissions) {
}, // this.permissions = permissions;
setPermissions(permissions) { // },
this.permissions = permissions;
}, async setUserInfo(info: UserInfoType) {
setUserInfo(info: UserInfoType) {
this.info = info; this.info = info;
const useProjectSettingStore = useProjectSetting();
useProjectSettingStore.setProjectSetting(info.userStyleSetting);
}, },
// 登录 // 登录
async login(params: any) { async login(params: { username: string; password: string }) {
const res = await login(params); const res = await login(params);
const { data } = res; const { data } = res;
if (res.status === ResultEnum.STATUS) { if (res.status === ResultEnum.STATUS) {
const ex = 7 * 24 * 60 * 60; const ex = 7 * 24 * 60 * 60;
storage.set(StorageEnum.ZS_ACCESS_TOKEN, data, ex); storage.set(StorageEnum.ZS_ACCESS_TOKEN, data, ex);
this.setToken(data); this.setToken(data);
// this.setUserInfo(result); this.getInfo();
const asyncRouteStore = useAsyncRoute();
const routes = await asyncRouteStore.generateRoutes();
// 动态添加可访问路由表;
routes.forEach((item: unknown) => {
router.addRoute(item as unknown as RouteRecordRaw);
});
} }
return res; return res;
}, },
@ -76,7 +91,6 @@ export const useUserStore = defineStore({
// 获取用户信息 // 获取用户信息
async getInfo() { async getInfo() {
const { data } = await getUserInfo(); const { data } = await getUserInfo();
console.log(data, '用户信息');
// if (result.permissions && result.permissions.length) { // if (result.permissions && result.permissions.length) {
// const permissionsList = result.permissions; // const permissionsList = result.permissions;
@ -85,14 +99,20 @@ export const useUserStore = defineStore({
// } else { // } else {
// throw new Error("getInfo: permissionsList must be a non-null array !"); // throw new Error("getInfo: permissionsList must be a non-null array !");
// } // }
this.setAvatar(data.avatar);
return data; return data;
}, },
// 登出 // 登出
async logout() { async logout() {
this.setPermissions([]); // this.setPermissions([]);
this.setUserInfo({ name: '', email: '' }); this.setUserInfo({
realname: '',
email: '',
token: '',
menuTree: [],
userStyleSetting: {},
userId: null as any,
});
storage.remove(StorageEnum.ZS_ACCESS_TOKEN); storage.remove(StorageEnum.ZS_ACCESS_TOKEN);
storage.remove(StorageEnum.ZS_CURRENT_USER); storage.remove(StorageEnum.ZS_CURRENT_USER);
routerTurnByName(PageEnum.BASE_LOGIN_NAME); routerTurnByName(PageEnum.BASE_LOGIN_NAME);

View File

@ -236,7 +236,7 @@ import {
} from '@vicons/antd'; } from '@vicons/antd';
import { getTreeItem } from '@/utils'; import { getTreeItem } from '@/utils';
import CreateDrawer from './CreateDrawer.vue'; import CreateDrawer from './CreateDrawer.vue';
import { getMenuTree, updateMenu, deleteMenu } from '@/api/system/menu'; import { getMenuTreeAll, updateMenu, deleteMenu } from '@/api/system/menu';
interface TreeNode { interface TreeNode {
key: string; key: string;
children?: TreeNode[]; children?: TreeNode[];
@ -395,7 +395,7 @@ const getKeys = (data: TreeNode[]): string[] => {
const getMenuTreeApi = async () => { const getMenuTreeApi = async () => {
try { try {
loading.value = true; loading.value = true;
const treeMenuList = await getMenuTree(); const treeMenuList = await getMenuTreeAll();
const res = mapTreeData(treeMenuList.data); const res = mapTreeData(treeMenuList.data);
Object.assign(formParams, getKeys(res)); Object.assign(formParams, getKeys(res));

View File

@ -83,7 +83,7 @@ import { columns } from './columns';
import { PlusOutlined } from '@vicons/antd'; import { PlusOutlined } from '@vicons/antd';
import { getTreeAll } from '@/utils'; import { getTreeAll } from '@/utils';
import { getRuleList } from '@/api/system/role'; import { getRuleList } from '@/api/system/role';
import { getMenuTree } from '@/api/system/menu'; import { getMenuTreeAll } from '@/api/system/menu';
import { queryMenuByRole, saveRoleMenu } from '@/api/system/roleMenu'; import { queryMenuByRole, saveRoleMenu } from '@/api/system/roleMenu';
const actionRef = ref(); const actionRef = ref();
@ -237,7 +237,7 @@ function checkedAllHandle() {
} }
onMounted(async () => { onMounted(async () => {
const treeMenuList = await getMenuTree(); const treeMenuList = await getMenuTreeAll();
const res = mapTreeData(treeMenuList.data); const res = mapTreeData(treeMenuList.data);
expandedKeys.value = treeMenuList.data.map((item) => item.key); expandedKeys.value = treeMenuList.data.map((item) => item.key);
treeData.value = res; treeData.value = res;

View File

@ -90,9 +90,11 @@ import { BasicTable, TableAction } from '@/components/Table';
import { columns } from './columns'; import { columns } from './columns';
import { PlusOutlined } from '@vicons/antd'; import { PlusOutlined } from '@vicons/antd';
import { getUserList, updateUser } from '@/api/system/user'; import { getUserList, updateUser, deleteUser } from '@/api/system/user';
import { getRuleList } from '@/api/system/role'; import { getRuleList, getUserRole } from '@/api/system/role';
import { saveUserRole } from '@/api/system/userrole'; import { saveUserRole } from '@/api/system/userrole';
import { zsDialog } from '@/utils';
import { DialogEnum } from '@/enums/pluginEnum';
const actionRef = ref(); const actionRef = ref();
const formRef = ref(); const formRef = ref();
const formRole = ref(); const formRole = ref();
@ -104,7 +106,7 @@ const rules = {
// trigger: ["blur", "change"], // trigger: ["blur", "change"],
// }, // },
}; };
const roleIds = ref([]);
const formRoleValue = reactive({ const formRoleValue = reactive({
id: null, id: null,
username: '', username: '',
@ -211,16 +213,34 @@ function handleEdit(record: Recordable) {
formRole.value.init('edit'); formRole.value.init('edit');
} }
function handleDelete(record: Recordable) {} async function handleDelete(record: Recordable) {
zsDialog({
type: DialogEnum.ERROR,
message: `您确定要删除 ${record.username} 用户吗?`,
positiveButtonProps: { type: 'primary', ghost: false },
onPositiveCallback: async () => {
const data = await deleteUser({ id: record.id });
if (data.status === 200) reloadTable();
window['$message'].success('删除成功');
},
});
}
async function handleMenuAuth(record: Recordable) { async function handleMenuAuth(record: Recordable) {
const { data } = await getUserRole({ userId: record.id });
formRoleValue.roleIds = data;
editRoleTitle.value = `分配 ${record.realname} 的角色权限`; editRoleTitle.value = `分配 ${record.realname} 的角色权限`;
Object.assign(formRoleValue, record); Object.assign(formRoleValue, record);
showModal.value = true; showModal.value = true;
} }
onMounted(async () => { const getRuleListApi = async () => {
const { data } = await getRuleList({ current: 1, size: 100 }); const { data } = await getRuleList({ current: 1, size: 100 });
roleOptions.value = data.records; roleOptions.value = data.records;
};
onMounted(() => {
getRuleListApi();
}); });
</script> </script>