前端重构
This commit is contained in:
parent
f4fcdaa322
commit
cf16ab6448
133
web/src/app.tsx
133
web/src/app.tsx
|
|
@ -3,6 +3,7 @@
|
|||
* 应用运行时配置
|
||||
*/
|
||||
import { AvatarDropdown, AvatarName, Footer } from '@/components';
|
||||
import CommandMenu from '@/components/CommandMenu';
|
||||
import { getUserInfo } from '@/services/kratos/user';
|
||||
import { getToken, removeToken } from '@/utils/auth';
|
||||
import {
|
||||
|
|
@ -12,12 +13,14 @@ import {
|
|||
SettingOutlined,
|
||||
UserOutlined,
|
||||
QuestionCircleOutlined,
|
||||
SearchOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import type { Settings as LayoutSettings } from '@ant-design/pro-components';
|
||||
import { SettingDrawer } from '@ant-design/pro-components';
|
||||
import type { RequestConfig, RunTimeLayoutConfig } from '@umijs/max';
|
||||
import { history } from '@umijs/max';
|
||||
import { message, Tooltip } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import defaultSettings from '../config/defaultSettings';
|
||||
import { errorConfig } from './requestErrorConfig';
|
||||
|
||||
|
|
@ -114,69 +117,69 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) =
|
|||
}));
|
||||
};
|
||||
|
||||
// 打开设置
|
||||
const handleOpenSetting = () => {
|
||||
const settingBtn = document.querySelector('.ant-pro-setting-drawer-handle');
|
||||
if (settingBtn) {
|
||||
(settingBtn as HTMLElement).click();
|
||||
}
|
||||
};
|
||||
|
||||
const iconStyle: React.CSSProperties = {
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: '50%',
|
||||
border: '1px solid #d9d9d9',
|
||||
cursor: 'pointer',
|
||||
};
|
||||
|
||||
return {
|
||||
// 先展开 settings,让后面的配置可以覆盖
|
||||
...initialState?.settings,
|
||||
|
||||
// 右上角操作区
|
||||
actionsRender: () => {
|
||||
const isDark = initialState?.settings?.navTheme === 'realDark';
|
||||
const isDarkTheme = initialState?.settings?.navTheme === 'realDark';
|
||||
return [
|
||||
// 帮助文档
|
||||
<Tooltip title="帮助文档" key="doc">
|
||||
<a
|
||||
href="https://github.com/go-kratos/kratos"
|
||||
href="https://go-kratos.dev/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: '50%',
|
||||
border: '1px solid #d9d9d9',
|
||||
cursor: 'pointer',
|
||||
color: 'inherit',
|
||||
}}
|
||||
style={{ ...iconStyle, color: 'inherit' }}
|
||||
>
|
||||
<QuestionCircleOutlined style={{ fontSize: 16 }} />
|
||||
</a>
|
||||
</Tooltip>,
|
||||
// 搜索 (Ctrl+K)
|
||||
<Tooltip title="搜索 (Ctrl+K)" key="search">
|
||||
<span
|
||||
onClick={() => window.dispatchEvent(new CustomEvent('openCommandMenu'))}
|
||||
style={iconStyle}
|
||||
>
|
||||
<SearchOutlined style={{ fontSize: 16 }} />
|
||||
</span>
|
||||
</Tooltip>,
|
||||
// 系统设置
|
||||
<Tooltip title="系统设置" key="setting">
|
||||
<span onClick={handleOpenSetting} style={iconStyle}>
|
||||
<SettingOutlined style={{ fontSize: 16 }} />
|
||||
</span>
|
||||
</Tooltip>,
|
||||
// 刷新
|
||||
<Tooltip title="刷新" key="refresh">
|
||||
<span
|
||||
onClick={handleRefresh}
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: '50%',
|
||||
border: '1px solid #d9d9d9',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
<span onClick={handleRefresh} style={iconStyle}>
|
||||
<ReloadOutlined style={{ fontSize: 16 }} />
|
||||
</span>
|
||||
</Tooltip>,
|
||||
// 切换主题
|
||||
<Tooltip title="切换主题" key="theme">
|
||||
<span
|
||||
onClick={handleToggleTheme}
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: '50%',
|
||||
border: '1px solid #d9d9d9',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
{isDark ? (
|
||||
<span onClick={handleToggleTheme} style={iconStyle}>
|
||||
{isDarkTheme ? (
|
||||
<BulbFilled style={{ fontSize: 16, color: '#faad14' }} />
|
||||
) : (
|
||||
<BulbOutlined style={{ fontSize: 16 }} />
|
||||
|
|
@ -188,7 +191,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) =
|
|||
|
||||
// 头像配置
|
||||
avatarProps: {
|
||||
src: initialState?.currentUser?.avatar || initialState?.currentUser?.headerImg,
|
||||
src: initialState?.currentUser?.avatar || initialState?.currentUser?.headerImg || '/default-avatar.svg',
|
||||
title: <AvatarName />,
|
||||
icon: <UserOutlined />,
|
||||
render: (_, avatarChildren) => <AvatarDropdown menu>{avatarChildren}</AvatarDropdown>,
|
||||
|
|
@ -231,25 +234,47 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) =
|
|||
return (
|
||||
<>
|
||||
{children}
|
||||
{isDev && (
|
||||
<SettingDrawer
|
||||
disableUrlParams
|
||||
enableDarkTheme
|
||||
settings={initialState?.settings}
|
||||
onSettingChange={(settings) => {
|
||||
setInitialState((preInitialState) => ({
|
||||
...preInitialState,
|
||||
settings,
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<CommandMenuWrapper />
|
||||
<SettingDrawer
|
||||
disableUrlParams
|
||||
enableDarkTheme
|
||||
settings={initialState?.settings}
|
||||
onSettingChange={(settings) => {
|
||||
setInitialState((preInitialState) => ({
|
||||
...preInitialState,
|
||||
settings,
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// CommandMenu包装组件
|
||||
const CommandMenuWrapper: React.FC = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleOpen = () => setOpen(true);
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.ctrlKey && e.key === 'k') {
|
||||
e.preventDefault();
|
||||
setOpen(true);
|
||||
}
|
||||
};
|
||||
window.addEventListener('openCommandMenu', handleOpen);
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => {
|
||||
window.removeEventListener('openCommandMenu', handleOpen);
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <CommandMenu open={open} onClose={() => setOpen(false)} />;
|
||||
};
|
||||
|
||||
/**
|
||||
* 请求配置
|
||||
* @see https://umijs.org/docs/max/request#配置
|
||||
|
|
|
|||
|
|
@ -0,0 +1,193 @@
|
|||
/**
|
||||
* KRA - Command Menu Component
|
||||
* 快捷搜索菜单,支持Ctrl+K快捷键
|
||||
*/
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { Modal, Input, List, Typography, Space, Tag } from 'antd';
|
||||
import { SearchOutlined, ArrowRightOutlined, BulbOutlined, LogoutOutlined } from '@ant-design/icons';
|
||||
import { history, useModel } from '@umijs/max';
|
||||
import { createStyles } from 'antd-style';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
const useStyles = createStyles(({ token }) => ({
|
||||
searchInput: {
|
||||
fontSize: 16,
|
||||
padding: '12px 16px',
|
||||
},
|
||||
categoryTitle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 600,
|
||||
color: token.colorTextSecondary,
|
||||
marginTop: 8,
|
||||
marginBottom: 4,
|
||||
},
|
||||
listItem: {
|
||||
padding: '8px 12px',
|
||||
cursor: 'pointer',
|
||||
borderRadius: 4,
|
||||
'&:hover': {
|
||||
backgroundColor: token.colorBgTextHover,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
interface CommandMenuProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
interface MenuItem {
|
||||
label: string;
|
||||
path?: string;
|
||||
action?: () => void;
|
||||
icon?: React.ReactNode;
|
||||
}
|
||||
|
||||
interface MenuCategory {
|
||||
label: string;
|
||||
items: MenuItem[];
|
||||
}
|
||||
|
||||
const CommandMenu: React.FC<CommandMenuProps> = ({ open, onClose }) => {
|
||||
const { styles } = useStyles();
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const { initialState, setInitialState } = useModel('@@initialState');
|
||||
|
||||
// 菜单项
|
||||
const menuCategories: MenuCategory[] = useMemo(() => {
|
||||
const categories: MenuCategory[] = [
|
||||
{
|
||||
label: '跳转',
|
||||
items: [
|
||||
{ label: '仪表盘', path: '/dashboard' },
|
||||
{ label: '用户管理', path: '/admin/user' },
|
||||
{ label: '角色管理', path: '/admin/authority' },
|
||||
{ label: '菜单管理', path: '/admin/menu' },
|
||||
{ label: 'API管理', path: '/admin/api' },
|
||||
{ label: '操作日志', path: '/admin/operation' },
|
||||
{ label: '字典管理', path: '/admin/dictionary' },
|
||||
{ label: '参数配置', path: '/admin/params' },
|
||||
{ label: '系统配置', path: '/systemTools/system' },
|
||||
{ label: '个人信息', path: '/person' },
|
||||
{ label: '关于', path: '/about' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '操作',
|
||||
items: [
|
||||
{
|
||||
label: '亮色主题',
|
||||
icon: <BulbOutlined />,
|
||||
action: () => {
|
||||
setInitialState((s) => ({
|
||||
...s,
|
||||
settings: { ...s?.settings, navTheme: 'light' },
|
||||
}));
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '暗色主题',
|
||||
icon: <BulbOutlined />,
|
||||
action: () => {
|
||||
setInitialState((s) => ({
|
||||
...s,
|
||||
settings: { ...s?.settings, navTheme: 'realDark' },
|
||||
}));
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '退出登录',
|
||||
icon: <LogoutOutlined />,
|
||||
action: () => {
|
||||
history.push('/user/login');
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
return categories;
|
||||
}, [setInitialState]);
|
||||
|
||||
// 过滤菜单
|
||||
const filteredCategories = useMemo(() => {
|
||||
if (!searchValue) return menuCategories;
|
||||
return menuCategories
|
||||
.map((category) => ({
|
||||
...category,
|
||||
items: category.items.filter((item) =>
|
||||
item.label.toLowerCase().includes(searchValue.toLowerCase())
|
||||
),
|
||||
}))
|
||||
.filter((category) => category.items.length > 0);
|
||||
}, [menuCategories, searchValue]);
|
||||
|
||||
// 处理点击
|
||||
const handleItemClick = (item: MenuItem) => {
|
||||
if (item.path) {
|
||||
history.push(item.path);
|
||||
} else if (item.action) {
|
||||
item.action();
|
||||
}
|
||||
onClose();
|
||||
setSearchValue('');
|
||||
};
|
||||
|
||||
// 监听Ctrl+K快捷键
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.ctrlKey && e.key === 'k') {
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
onCancel={onClose}
|
||||
footer={null}
|
||||
width={500}
|
||||
closable={false}
|
||||
styles={{ body: { maxHeight: '50vh', overflow: 'auto', padding: '12px' } }}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入你需要快捷到达的功能"
|
||||
prefix={<SearchOutlined />}
|
||||
value={searchValue}
|
||||
onChange={(e) => setSearchValue(e.target.value)}
|
||||
className={styles.searchInput}
|
||||
autoFocus
|
||||
allowClear
|
||||
/>
|
||||
{filteredCategories.map((category, index) => (
|
||||
<div key={index}>
|
||||
{category.items.length > 0 && (
|
||||
<>
|
||||
<div className={styles.categoryTitle}>{category.label}</div>
|
||||
<List
|
||||
size="small"
|
||||
dataSource={category.items}
|
||||
renderItem={(item) => (
|
||||
<div
|
||||
className={styles.listItem}
|
||||
onClick={() => handleItemClick(item)}
|
||||
>
|
||||
<Space>
|
||||
{item.icon || <ArrowRightOutlined />}
|
||||
<Text>{item.label}</Text>
|
||||
</Space>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommandMenu;
|
||||
|
|
@ -134,7 +134,7 @@ const AboutPage: React.FC = () => {
|
|||
</Helmet>
|
||||
|
||||
{/* 头部信息 */}
|
||||
<Card className={styles.headerCard} bordered={false}>
|
||||
<Card className={styles.headerCard} variant="borderless">
|
||||
<div className={styles.logoWrapper}>
|
||||
<Logo size={80} />
|
||||
</div>
|
||||
|
|
@ -166,7 +166,7 @@ const AboutPage: React.FC = () => {
|
|||
<Row gutter={[24, 24]}>
|
||||
{/* 系统信息 */}
|
||||
<Col xs={24} lg={12}>
|
||||
<Card title="系统信息" className={styles.infoCard} bordered={false}>
|
||||
<Card title="系统信息" className={styles.infoCard} variant="borderless">
|
||||
<Descriptions column={1} labelStyle={{ width: '120px' }}>
|
||||
<Descriptions.Item label="系统名称">Kratos Admin</Descriptions.Item>
|
||||
<Descriptions.Item label="当前版本">
|
||||
|
|
@ -200,7 +200,7 @@ const AboutPage: React.FC = () => {
|
|||
|
||||
{/* 技术栈 */}
|
||||
<Col xs={24} lg={12}>
|
||||
<Card title="技术栈" className={styles.infoCard} bordered={false}>
|
||||
<Card title="技术栈" className={styles.infoCard} variant="borderless">
|
||||
<Descriptions column={1} labelStyle={{ width: '120px' }}>
|
||||
<Descriptions.Item label="后端语言">Go 1.21+</Descriptions.Item>
|
||||
<Descriptions.Item label="微服务框架">Kratos v2</Descriptions.Item>
|
||||
|
|
@ -215,7 +215,7 @@ const AboutPage: React.FC = () => {
|
|||
|
||||
{/* 核心特性 */}
|
||||
<Col xs={24}>
|
||||
<Card title="核心特性" className={styles.infoCard} bordered={false}>
|
||||
<Card title="核心特性" className={styles.infoCard} variant="borderless">
|
||||
<Row gutter={[24, 0]}>
|
||||
{features.map((feature, index) => (
|
||||
<Col xs={24} md={12} lg={8} key={index}>
|
||||
|
|
@ -239,7 +239,7 @@ const AboutPage: React.FC = () => {
|
|||
|
||||
{/* 鸣谢 */}
|
||||
<Col xs={24}>
|
||||
<Card title="鸣谢" className={styles.infoCard} bordered={false}>
|
||||
<Card title="鸣谢" className={styles.infoCard} variant="borderless">
|
||||
<Paragraph>
|
||||
Kratos Admin 的开发离不开以下优秀的开源项目:
|
||||
</Paragraph>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ const Notice: React.FC = () => {
|
|||
<Card
|
||||
title="公告"
|
||||
className="kra-dashboard-card"
|
||||
bordered={false}
|
||||
variant="borderless"
|
||||
extra={<a href="#">更多</a>}
|
||||
>
|
||||
<List
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ const PluginTable: React.FC = () => {
|
|||
<Card
|
||||
title="最新插件"
|
||||
className="kra-dashboard-card"
|
||||
bordered={false}
|
||||
variant="borderless"
|
||||
extra={
|
||||
<Space>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const QuickLinks: React.FC = () => {
|
|||
<Card
|
||||
title="快捷功能"
|
||||
className="kra-dashboard-card"
|
||||
bordered={false}
|
||||
variant="borderless"
|
||||
>
|
||||
<Row gutter={[12, 12]}>
|
||||
{links.map((link, index) => (
|
||||
|
|
|
|||
|
|
@ -227,22 +227,22 @@ const PersonPage: React.FC = () => {
|
|||
<Row gutter={[16, 16]} style={{ padding: '24px 0' }}>
|
||||
<Col xs={12} md={6}>
|
||||
<div className={styles.statCard}>
|
||||
<Statistic title="项目参与" value={138} valueStyle={{ color: '#1890ff' }} />
|
||||
<Statistic title="项目参与" value={138} styles={{ content: { color: '#1890ff' } }} />
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={12} md={6}>
|
||||
<div className={styles.statCard}>
|
||||
<Statistic title="代码提交" value={2300} suffix="+" valueStyle={{ color: '#52c41a' }} />
|
||||
<Statistic title="代码提交" value={2300} suffix="+" styles={{ content: { color: '#52c41a' } }} />
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={12} md={6}>
|
||||
<div className={styles.statCard}>
|
||||
<Statistic title="任务完成" value={95} suffix="%" valueStyle={{ color: '#722ed1' }} />
|
||||
<Statistic title="任务完成" value={95} suffix="%" styles={{ content: { color: '#722ed1' } }} />
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={12} md={6}>
|
||||
<div className={styles.statCard}>
|
||||
<Statistic title="获得勋章" value={12} valueStyle={{ color: '#faad14' }} />
|
||||
<Statistic title="获得勋章" value={12} styles={{ content: { color: '#faad14' } }} />
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
@ -281,7 +281,7 @@ const PersonPage: React.FC = () => {
|
|||
</Helmet>
|
||||
|
||||
{/* 顶部个人信息卡片 */}
|
||||
<Card className={styles.profileCard} bordered={false} bodyStyle={{ padding: 0 }}>
|
||||
<Card className={styles.profileCard} variant="borderless" styles={{ body: { padding: 0 } }}>
|
||||
<div className={styles.coverBg} />
|
||||
<div className={styles.profileInfo}>
|
||||
<div className={styles.avatarWrapper}>
|
||||
|
|
@ -329,7 +329,7 @@ const PersonPage: React.FC = () => {
|
|||
<Row gutter={24}>
|
||||
{/* 左侧信息栏 */}
|
||||
<Col xs={24} lg={8}>
|
||||
<Card className={styles.infoCard} bordered={false}>
|
||||
<Card className={styles.infoCard} variant="borderless">
|
||||
<div className={styles.infoTitle}>
|
||||
<UserOutlined style={{ color: '#1890ff' }} /> 基本信息
|
||||
</div>
|
||||
|
|
@ -368,7 +368,7 @@ const PersonPage: React.FC = () => {
|
|||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className={styles.infoCard} bordered={false}>
|
||||
<Card className={styles.infoCard} variant="borderless">
|
||||
<div className={styles.infoTitle}>
|
||||
<TrophyOutlined style={{ color: '#faad14' }} /> 技能特长
|
||||
</div>
|
||||
|
|
@ -383,7 +383,7 @@ const PersonPage: React.FC = () => {
|
|||
|
||||
{/* 右侧内容区 */}
|
||||
<Col xs={24} lg={16}>
|
||||
<Card className={styles.infoCard} bordered={false}>
|
||||
<Card className={styles.infoCard} variant="borderless">
|
||||
<Tabs items={tabItems} />
|
||||
</Card>
|
||||
</Col>
|
||||
|
|
|
|||
|
|
@ -46,9 +46,10 @@ const AuthorityPage: React.FC = () => {
|
|||
const fetchTableData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await getAuthorityList({ page: 1, pageSize: 1000 });
|
||||
const res = await getAuthorityList();
|
||||
if (res.code === 0) {
|
||||
setTableData(res.data?.list || []);
|
||||
// GVA接口直接返回树形数组,不是分页格式
|
||||
setTableData(res.data || []);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch authority list:', error);
|
||||
|
|
|
|||
|
|
@ -84,9 +84,10 @@ const UserPage: React.FC = () => {
|
|||
|
||||
const fetchAuthorityOptions = async () => {
|
||||
try {
|
||||
const res = await getAuthorityList({ page: 1, pageSize: 1000 });
|
||||
const res = await getAuthorityList();
|
||||
if (res.code === 0) {
|
||||
const options = buildAuthorityOptions(res.data?.list || []);
|
||||
// GVA接口直接返回树形数组,不是分页格式
|
||||
const options = buildAuthorityOptions(res.data || []);
|
||||
setAuthOptions(options);
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -4,42 +4,63 @@
|
|||
import request from '@/utils/request';
|
||||
|
||||
export interface Authority {
|
||||
authorityId: string;
|
||||
authorityId: number | string;
|
||||
authorityName: string;
|
||||
parentId?: string;
|
||||
parentId?: number | string;
|
||||
defaultRouter?: string;
|
||||
children?: Authority[];
|
||||
dataAuthorityId?: Authority[];
|
||||
}
|
||||
|
||||
/** 获取角色列表 */
|
||||
export const getAuthorityList = (data: { page: number; pageSize: number }) => {
|
||||
return request.post('/authority/getAuthorityList', data);
|
||||
export const getAuthorityList = (data?: { page?: number; pageSize?: number }) => {
|
||||
return request.post('/authority/getAuthorityList', data || {});
|
||||
};
|
||||
|
||||
/** 删除角色 */
|
||||
export const deleteAuthority = (data: { authorityId: string }) => {
|
||||
return request.post('/authority/deleteAuthority', data);
|
||||
export const deleteAuthority = (data: { authorityId: number | string }) => {
|
||||
return request.post('/authority/deleteAuthority', { authorityId: Number(data.authorityId) });
|
||||
};
|
||||
|
||||
/** 创建角色 */
|
||||
export const createAuthority = (data: Authority) => {
|
||||
return request.post('/authority/createAuthority', data);
|
||||
return request.post('/authority/createAuthority', {
|
||||
...data,
|
||||
authorityId: Number(data.authorityId),
|
||||
parentId: data.parentId ? Number(data.parentId) : 0,
|
||||
});
|
||||
};
|
||||
|
||||
/** 拷贝角色 */
|
||||
export const copyAuthority = (data: { authority: Authority; oldAuthorityId: string }) => {
|
||||
return request.post('/authority/copyAuthority', data);
|
||||
export const copyAuthority = (data: { authority: Authority; oldAuthorityId: number | string }) => {
|
||||
return request.post('/authority/copyAuthority', {
|
||||
authority: {
|
||||
...data.authority,
|
||||
authorityId: Number(data.authority.authorityId),
|
||||
parentId: data.authority.parentId ? Number(data.authority.parentId) : 0,
|
||||
},
|
||||
oldAuthorityId: Number(data.oldAuthorityId),
|
||||
});
|
||||
};
|
||||
|
||||
/** 设置角色资源权限 */
|
||||
export const setDataAuthority = (data: { authorityId: string; dataAuthorityId: Authority[] }) => {
|
||||
return request.post('/authority/setDataAuthority', data);
|
||||
export const setDataAuthority = (data: { authorityId: number | string; dataAuthorityId: Authority[] }) => {
|
||||
return request.post('/authority/setDataAuthority', {
|
||||
authorityId: Number(data.authorityId),
|
||||
dataAuthorityId: data.dataAuthorityId?.map(item => ({
|
||||
...item,
|
||||
authorityId: Number(item.authorityId),
|
||||
})),
|
||||
});
|
||||
};
|
||||
|
||||
/** 修改角色 */
|
||||
export const updateAuthority = (data: Authority) => {
|
||||
return request.put('/authority/updateAuthority', data);
|
||||
return request.put('/authority/updateAuthority', {
|
||||
...data,
|
||||
authorityId: Number(data.authorityId),
|
||||
parentId: data.parentId ? Number(data.parentId) : 0,
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -5,13 +5,19 @@ import request from '@/utils/request';
|
|||
import type { ApiResponse } from '@/types/api';
|
||||
|
||||
/** 获取角色按钮权限 */
|
||||
export const getAuthorityBtn = (data: { authorityId: string; menuID: number }) => {
|
||||
return request.post<ApiResponse<any>>('/authorityBtn/getAuthorityBtn', data);
|
||||
export const getAuthorityBtn = (data: { authorityId: number | string; menuID: number }) => {
|
||||
return request.post<ApiResponse<any>>('/authorityBtn/getAuthorityBtn', {
|
||||
...data,
|
||||
authorityId: Number(data.authorityId),
|
||||
});
|
||||
};
|
||||
|
||||
/** 设置角色按钮权限 */
|
||||
export const setAuthorityBtn = (data: { authorityId: string; menuID: number; selected: string[] }) => {
|
||||
return request.post<ApiResponse<any>>('/authorityBtn/setAuthorityBtn', data);
|
||||
export const setAuthorityBtn = (data: { authorityId: number | string; menuID: number; selected: string[] }) => {
|
||||
return request.post<ApiResponse<any>>('/authorityBtn/setAuthorityBtn', {
|
||||
...data,
|
||||
authorityId: Number(data.authorityId),
|
||||
});
|
||||
};
|
||||
|
||||
/** 检查是否可以移除按钮权限 */
|
||||
|
|
|
|||
|
|
@ -10,13 +10,18 @@ export interface CasbinInfo {
|
|||
}
|
||||
|
||||
/** 更新角色API权限 */
|
||||
export const updateCasbin = (data: { authorityId: string; casbinInfos: CasbinInfo[] }) => {
|
||||
return request.post<ApiResponse<any>>('/casbin/updateCasbin', data);
|
||||
export const updateCasbin = (data: { authorityId: number | string; casbinInfos: CasbinInfo[] }) => {
|
||||
return request.post<ApiResponse<any>>('/casbin/updateCasbin', {
|
||||
...data,
|
||||
authorityId: Number(data.authorityId),
|
||||
});
|
||||
};
|
||||
|
||||
/** 获取角色API权限列表 */
|
||||
export const getPolicyPathByAuthorityId = (data: { authorityId: string }) => {
|
||||
return request.post<ApiResponse<{ paths: CasbinInfo[] }>>('/casbin/getPolicyPathByAuthorityId', data);
|
||||
export const getPolicyPathByAuthorityId = (data: { authorityId: number | string }) => {
|
||||
return request.post<ApiResponse<{ paths: CasbinInfo[] }>>('/casbin/getPolicyPathByAuthorityId', {
|
||||
authorityId: Number(data.authorityId),
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -44,13 +44,18 @@ export const getBaseMenuTree = () => {
|
|||
};
|
||||
|
||||
/** 添加菜单权限关联 */
|
||||
export const addMenuAuthority = (data: { menus: number[]; authorityId: string }) => {
|
||||
return request.post('/menu/addMenuAuthority', data);
|
||||
export const addMenuAuthority = (data: { menus: number[]; authorityId: number | string }) => {
|
||||
return request.post('/menu/addMenuAuthority', {
|
||||
...data,
|
||||
authorityId: Number(data.authorityId),
|
||||
});
|
||||
};
|
||||
|
||||
/** 获取菜单权限关联 */
|
||||
export const getMenuAuthority = (data: { authorityId: string }) => {
|
||||
return request.post('/menu/getMenuAuthority', data);
|
||||
export const getMenuAuthority = (data: { authorityId: number | string }) => {
|
||||
return request.post('/menu/getMenuAuthority', {
|
||||
authorityId: Number(data.authorityId),
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除菜单 */
|
||||
|
|
|
|||
|
|
@ -48,8 +48,11 @@ export const getUserList = (data: PageParams) => {
|
|||
};
|
||||
|
||||
/** 设置用户权限 */
|
||||
export const setUserAuthority = (data: { uuid: string; authorityId: string }) => {
|
||||
return request.post<ApiResponse<any>>('/user/setUserAuthority', data);
|
||||
export const setUserAuthority = (data: { uuid: string; authorityId: string | number }) => {
|
||||
return request.post<ApiResponse<any>>('/user/setUserAuthority', {
|
||||
...data,
|
||||
authorityId: Number(data.authorityId),
|
||||
});
|
||||
};
|
||||
|
||||
/** 删除用户 */
|
||||
|
|
@ -73,8 +76,11 @@ export const setSelfSetting = (data: any) => {
|
|||
};
|
||||
|
||||
/** 设置用户多角色权限 */
|
||||
export const setUserAuthorities = (data: { ID: number; authorityIds: string[] }) => {
|
||||
return request.post<ApiResponse<any>>('/user/setUserAuthorities', data);
|
||||
export const setUserAuthorities = (data: { ID: number; authorityIds: (number | string)[] }) => {
|
||||
return request.post<ApiResponse<any>>('/user/setUserAuthorities', {
|
||||
...data,
|
||||
authorityIds: data.authorityIds.map(id => Number(id)),
|
||||
});
|
||||
};
|
||||
|
||||
/** 获取用户信息 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue