前端重构

This commit is contained in:
Yvan 2026-01-08 12:04:47 +08:00
parent f12f2e0f00
commit b0eb4c2fc3
24 changed files with 546 additions and 121 deletions

View File

@ -174,4 +174,6 @@ export default defineConfig({
define: {
"process.env.CI": process.env.CI,
},
// 修复 esbuild helper 冲突警告
esbuildMinifyIIFE: true,
});

View File

@ -15,9 +15,10 @@ export default {
* @doc https://github.com/chimurai/http-proxy-middleware
*/
dev: {
"/v1/": {
target: "http://localhost:8000",
"/api/": {
target: "http://localhost:8888",
changeOrigin: true,
},
pathRewrite: { "^/api": "" },
}
},
};

View File

@ -36,8 +36,9 @@ export async function getInitialState(): Promise<{
return undefined;
}
const res = await getUserInfo();
if (res.data?.code === 0 && res.data?.data?.userInfo) {
const userInfo = res.data.data.userInfo;
// request.ts 的 responseInterceptors 已经解包,直接使用 res
if (res.code === 0 && res.data?.userInfo) {
const userInfo = res.data.userInfo;
return {
uuid: userInfo.uuid,
userName: userInfo.userName,
@ -48,9 +49,9 @@ export async function getInitialState(): Promise<{
authority: userInfo.authority,
authorities: userInfo.authorities,
// 按钮权限(如果后端返回)
buttons: res.data.data.buttons || [],
buttons: res.data.buttons || [],
// 菜单权限(如果后端返回)
menus: res.data.data.menus || [],
menus: res.data.menus || [],
};
}
return undefined;

View File

@ -26,3 +26,9 @@ export * from './WarningBar';
export * from './ErrorPreview';
export * from './ArrayCtrl';
export * from './ExportExcel';
// Layout components
export { default as Footer } from './Footer';
export { AvatarDropdown, AvatarName } from './RightContent/AvatarDropdown';
export { Question, SelectLang } from './RightContent';
export { default as HeaderDropdown } from './HeaderDropdown';

View File

@ -437,7 +437,7 @@ const GeneralSettings: React.FC = () => {
<div className="kra-setting-card">
<div className="kra-about-project">
<div className="kra-about-logo">
<Logo size={48} />
<Logo size="large" />
</div>
<div className="kra-about-info">
<h4>Kratos Admin</h4>

View File

@ -22,7 +22,7 @@ const Banner: React.FC = () => {
color: '#fff',
padding: '24px',
}}>
<Logo size={48} />
<Logo size="large" />
<h3 style={{ margin: '12px 0 4px', fontSize: '18px', fontWeight: 600 }}>
Kratos Admin
</h3>

View File

@ -149,3 +149,25 @@
}
}
}
// 拖拽上传区域
.dragUploadArea {
border: 2px dashed #d9d9d9;
border-radius: 8px;
padding: 40px 20px;
text-align: center;
background-color: #fafafa;
transition: all 0.3s ease;
cursor: pointer;
&:hover {
border-color: #1890ff;
background-color: #e6f7ff;
}
&.isDragging {
border-color: #1890ff;
background-color: #e6f7ff;
transform: scale(1.02);
}
}

View File

@ -15,6 +15,9 @@ import {
Switch,
Select,
Splitter,
Modal,
Upload,
Alert,
} from 'antd';
import {
PlusOutlined,
@ -23,14 +26,18 @@ import {
DeleteOutlined,
DownloadOutlined,
UploadOutlined,
RobotOutlined,
} from '@ant-design/icons';
import {
getDictionaryList,
createDictionary,
updateDictionary,
deleteDictionary,
findDictionary,
getSysDictionaryList as getDictionaryList,
createSysDictionary as createDictionary,
updateSysDictionary as updateDictionary,
deleteSysDictionary as deleteDictionary,
findSysDictionary as findDictionary,
exportSysDictionary,
importSysDictionary,
} from '@/services/kratos/dictionary';
import { butler, eye } from '@/services/kratos/autoCode';
import DictionaryDetail from './detail';
import styles from './index.less';
@ -53,6 +60,19 @@ const DictionaryPage: React.FC = () => {
const [loading, setLoading] = useState(false);
const [form] = Form.useForm();
// 导入相关
const [importDrawerVisible, setImportDrawerVisible] = useState(false);
const [importJsonText, setImportJsonText] = useState('');
const [importing, setImporting] = useState(false);
const [jsonPreviewError, setJsonPreviewError] = useState('');
const [isDragging, setIsDragging] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
// AI相关
const [aiDialogVisible, setAiDialogVisible] = useState(false);
const [aiPrompt, setAiPrompt] = useState('');
const [aiGenerating, setAiGenerating] = useState(false);
// 获取字典列表
const fetchDictionaryList = async () => {
setLoading(true);
@ -73,6 +93,20 @@ const DictionaryPage: React.FC = () => {
fetchDictionaryList();
}, []);
// 监听JSON文本变化
useEffect(() => {
if (!importJsonText.trim()) {
setJsonPreviewError('');
return;
}
try {
JSON.parse(importJsonText);
setJsonPreviewError('');
} catch (e: any) {
setJsonPreviewError('JSON格式错误: ' + e.message);
}
}, [importJsonText]);
// 搜索
const handleSearch = () => {
fetchDictionaryList();
@ -124,9 +158,9 @@ const DictionaryPage: React.FC = () => {
const handleExport = async (record: DictionaryItem, e: React.MouseEvent) => {
e.stopPropagation();
try {
const res = await findDictionary({ ID: record.ID });
const res = await exportSysDictionary({ ID: record.ID });
if (res.code === 0) {
const jsonStr = JSON.stringify(res.data.resysDictionary, null, 2);
const jsonStr = JSON.stringify(res.data, null, 2);
const blob = new Blob([jsonStr], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
@ -175,7 +209,7 @@ const DictionaryPage: React.FC = () => {
setSelectedId(record.ID);
};
// 获取可选的父级字典(排除自己和子字典)
// 获取可选的父级字典
const getAvailableParentDictionaries = () => {
if (editType === 'update' && currentRecord) {
return dictionaryList.filter((dict) => dict.ID !== currentRecord.ID);
@ -183,6 +217,200 @@ const DictionaryPage: React.FC = () => {
return dictionaryList;
};
// 打开导入抽屉
const openImportDrawer = () => {
setImportDrawerVisible(true);
setImportJsonText('');
setJsonPreviewError('');
setIsDragging(false);
};
// 关闭导入抽屉
const closeImportDrawer = () => {
setImportDrawerVisible(false);
setImportJsonText('');
setJsonPreviewError('');
setIsDragging(false);
};
// 处理拖拽
const handleDragOver = (e: React.DragEvent) => {
e.preventDefault();
setIsDragging(true);
};
const handleDragLeave = (e: React.DragEvent) => {
e.preventDefault();
setIsDragging(false);
};
const handleDrop = (e: React.DragEvent) => {
e.preventDefault();
setIsDragging(false);
const files = e.dataTransfer.files;
if (files.length > 0) {
readJsonFile(files[0]);
}
};
// 触发文件选择
const triggerFileInput = () => {
fileInputRef.current?.click();
};
// 处理文件选择
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
const files = e.target.files;
if (files && files.length > 0) {
readJsonFile(files[0]);
e.target.value = '';
}
};
// 读取JSON文件
const readJsonFile = (file: File) => {
if (!file.name.endsWith('.json')) {
message.warning('请上传 JSON 文件');
return;
}
const reader = new FileReader();
reader.onload = (event) => {
try {
const content = event.target?.result as string;
JSON.parse(content);
setImportJsonText(content);
message.success('文件读取成功');
} catch (error) {
message.error('文件内容不是有效的 JSON 格式');
}
};
reader.onerror = () => {
message.error('文件读取失败');
};
reader.readAsText(file);
};
// 处理导入
const handleImport = async () => {
if (!importJsonText.trim()) {
message.warning('请输入JSON数据');
return;
}
if (jsonPreviewError) {
message.error('JSON格式错误请检查后重试');
return;
}
try {
setImporting(true);
const res = await importSysDictionary({ json: importJsonText });
if (res.code === 0) {
message.success('导入成功');
closeImportDrawer();
fetchDictionaryList();
}
} catch (error: any) {
message.error('导入失败: ' + error.message);
} finally {
setImporting(false);
}
};
// 打开AI对话框
const openAiDialog = () => {
setAiDialogVisible(true);
setAiPrompt('');
};
// 关闭AI对话框
const closeAiDialog = () => {
setAiDialogVisible(false);
setAiPrompt('');
};
// 处理AI生成
const handleAiGenerate = async () => {
if (!aiPrompt.trim()) {
message.warning('请输入描述内容');
return;
}
try {
setAiGenerating(true);
const aiRes = await butler({ prompt: aiPrompt, command: 'dict' });
if (aiRes && aiRes.code === 0) {
message.success('AI 生成成功');
try {
if (typeof aiRes.data === 'string') {
setImportJsonText(aiRes.data);
} else {
setImportJsonText(JSON.stringify(aiRes.data, null, 2));
}
setJsonPreviewError('');
setImportDrawerVisible(true);
closeAiDialog();
} catch (e: any) {
message.error('处理 AI 返回结果失败: ' + (e.message || e));
}
} else {
message.error(aiRes?.msg || 'AI 生成失败');
}
} catch (err: any) {
message.error('AI 调用失败: ' + (err.message || err));
} finally {
setAiGenerating(false);
}
};
// 处理粘贴图片
const handlePaste = async (e: React.ClipboardEvent) => {
const items = e.clipboardData.items;
for (let i = 0; i < items.length; i++) {
if (items[i].type.indexOf('image') !== -1) {
const file = items[i].getAsFile();
if (file) {
const reader = new FileReader();
reader.onload = async (event) => {
const base64String = event.target?.result as string;
try {
const res = await eye({ picture: base64String, command: 'dictEye' });
if (res.code === 0) {
setAiPrompt(res.data);
}
} catch (error) {
message.error('图片识别失败');
}
};
reader.readAsDataURL(file);
}
}
}
};
// 识图功能
const handleEyeFunc = () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*';
input.onchange = (event: any) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = async (e) => {
const base64String = e.target?.result as string;
try {
const res = await eye({ picture: base64String, command: 'dictEye' });
if (res.code === 0) {
setAiPrompt(res.data);
}
} catch (error) {
message.error('图片识别失败');
}
};
reader.readAsDataURL(file);
}
};
input.click();
};
return (
<PageContainer>
<div className={styles.warningBar}>
@ -202,10 +430,16 @@ const DictionaryPage: React.FC = () => {
onChange={(e) => setSearchName(e.target.value)}
onPressEnter={handleSearch}
suffix={<SearchOutlined onClick={handleSearch} />}
style={{ width: 150 }}
style={{ width: 120 }}
allowClear
/>
</Tooltip>
<Tooltip title="导入字典">
<Button type="default" icon={<UploadOutlined />} onClick={openImportDrawer} />
</Tooltip>
<Tooltip title="AI 生成字典">
<Button type="default" icon={<RobotOutlined />} onClick={openAiDialog} />
</Tooltip>
<Tooltip title="新建字典">
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd} />
</Tooltip>
@ -270,6 +504,7 @@ const DictionaryPage: React.FC = () => {
</Splitter.Panel>
</Splitter>
{/* 新增/编辑字典抽屉 */}
<Drawer
title={editType === 'create' ? '添加字典' : '修改字典'}
open={drawerVisible}
@ -323,6 +558,124 @@ const DictionaryPage: React.FC = () => {
</Form.Item>
</Form>
</Drawer>
{/* 导入字典抽屉 */}
<Drawer
title="导入字典JSON"
open={importDrawerVisible}
onClose={closeImportDrawer}
width={600}
extra={
<Space>
<Button onClick={closeImportDrawer}></Button>
<Button type="primary" onClick={handleImport} loading={importing}>
</Button>
</Space>
}
>
<Alert
message="请粘贴、编辑或拖拽JSON文件到下方区域"
type="info"
showIcon
style={{ marginBottom: 16 }}
/>
<div
className={`${styles.dragUploadArea} ${isDragging ? styles.isDragging : ''}`}
onDrop={handleDrop}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onClick={triggerFileInput}
>
<UploadOutlined style={{ fontSize: 48, color: '#8c939d', marginBottom: 16 }} />
<div>
<p> JSON </p>
<p style={{ fontSize: 12, color: '#909399' }}></p>
</div>
<input
ref={fileInputRef}
type="file"
accept=".json,application/json"
style={{ display: 'none' }}
onChange={handleFileSelect}
/>
</div>
<Input.TextArea
value={importJsonText}
onChange={(e) => setImportJsonText(e.target.value)}
rows={15}
placeholder={`请输入JSON数据例如
{
"name": "性别",
"type": "gender",
"status": true,
"desc": "性别字典",
"sysDictionaryDetails": [
{
"label": "男",
"value": "1",
"status": true,
"sort": 1
},
{
"label": "女",
"value": "2",
"status": true,
"sort": 2
}
]
}`}
style={{ marginTop: 16, fontFamily: 'monospace' }}
/>
{jsonPreviewError && (
<Alert
message={jsonPreviewError}
type="error"
showIcon
style={{ marginTop: 16 }}
/>
)}
</Drawer>
{/* AI生成字典对话框 */}
<Modal
title="AI 生成字典"
open={aiDialogVisible}
onCancel={closeAiDialog}
footer={[
<Button key="cancel" onClick={closeAiDialog}>
</Button>,
<Button key="submit" type="primary" onClick={handleAiGenerate} loading={aiGenerating}>
</Button>,
]}
width={520}
>
<div style={{ position: 'relative' }}>
<Input.TextArea
value={aiPrompt}
onChange={(e) => setAiPrompt(e.target.value)}
rows={6}
maxLength={2000}
placeholder={`请输入生成字典的描述,例如:生成一个用户状态字典(启用/禁用)
`}
onPaste={handlePaste}
onKeyDown={(e) => {
if (e.ctrlKey && e.key === 'Enter') {
handleAiGenerate();
}
}}
/>
<div style={{ position: 'absolute', right: 8, bottom: 8 }}>
<Tooltip title="粘贴或上传图片后,识别图片内容生成字典">
<Button type="primary" icon={<RobotOutlined />} onClick={handleEyeFunc}>
</Button>
</Tooltip>
</div>
</div>
</Modal>
</PageContainer>
);
};

View File

@ -155,7 +155,7 @@ const SysErrorPage: React.FC = () => {
return;
}
try {
const res = await deleteSysErrorByIds({ ids: selectedRowKeys as number[] });
const res = await deleteSysErrorByIds({ IDs: selectedRowKeys as number[] });
if (res.code === 0) {
message.success('删除成功');
setSelectedRowKeys([]);

View File

@ -168,7 +168,7 @@ const VersionPage: React.FC = () => {
return;
}
try {
const res = await deleteSysVersionByIds({ ids: selectedRowKeys as number[] });
const res = await deleteSysVersionByIds({ IDs: selectedRowKeys as number[] });
if (res.code === 0) {
message.success('删除成功');
setSelectedRowKeys([]);

View File

@ -163,12 +163,13 @@ const Login: React.FC = () => {
const fetchCaptcha = useCallback(async () => {
try {
const res = await captcha();
if (res.data?.code === 0 && res.data?.data) {
// request.ts 的 responseInterceptors 已经解包,直接使用 res
if (res.code === 0 && res.data) {
setCaptchaData({
captchaId: res.data.data.captchaId || '',
picPath: res.data.data.picPath || '',
captchaLength: res.data.data.captchaLength || 6,
openCaptcha: res.data.data.openCaptcha || false,
captchaId: res.data.captchaId || '',
picPath: res.data.picPath || '',
captchaLength: res.data.captchaLength || 6,
openCaptcha: res.data.openCaptcha || false,
});
}
} catch (error) {
@ -191,18 +192,20 @@ const Login: React.FC = () => {
captchaId: captchaData.captchaId,
});
if (res.data?.code === 0 && res.data?.data) {
const { token, user } = res.data.data;
// request.ts 的 responseInterceptors 已经解包,直接使用 res
if (res.code === 0 && res.data) {
const { token, user } = res.data;
// 保存 token 和用户信息
setToken(token);
setUserInfo(user);
// 更新全局状态
// 更新全局状态,重新获取用户信息(包含菜单权限)
const userInfo = await initialState?.fetchUserInfo?.();
flushSync(() => {
setInitialState((state) => ({
...state,
currentUser: user,
currentUser: userInfo,
}));
});
@ -213,7 +216,7 @@ const Login: React.FC = () => {
const redirect = urlParams.get('redirect') || '/';
history.push(redirect);
} else {
messageApi.error(res.data?.msg || '登录失败,请重试');
messageApi.error(res.msg || '登录失败,请重试');
fetchCaptcha();
}
} catch (error: any) {
@ -228,8 +231,9 @@ const Login: React.FC = () => {
const handleCheckInit = async () => {
try {
const res = await checkDB();
if (res.data?.code === 0) {
if (res.data?.data?.needInit) {
// request.ts 的 responseInterceptors 已经解包,直接使用 res
if (res.code === 0) {
if (res.data?.needInit) {
history.push('/init');
} else {
messageApi.info('已配置数据库信息,无法初始化');
@ -251,7 +255,7 @@ const Login: React.FC = () => {
<div className={styles.formWrapper}>
<div className={styles.logoWrapper}>
<Logo size={48} />
<Logo size="large" />
</div>
<h1 className={styles.title}>Kratos Admin</h1>

View File

@ -93,13 +93,13 @@ export async function updateInfo(data: any) {
}
// Delete info
export async function deleteInfo(data: { ID: number }) {
return request.delete('/info/deleteInfo', { data });
export async function deleteInfo(params: { ID: number }) {
return request.delete('/info/deleteInfo', { params });
}
// Delete info by IDs
export async function deleteInfoByIds(data: { IDs: number[] }) {
return request.delete('/info/deleteInfoByIds', { data });
export async function deleteInfoByIds(params: { IDs: number[] }) {
return request.delete('/info/deleteInfoByIds', { params });
}
// Find info by ID

View File

@ -2,7 +2,6 @@
* KRA - API Management Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface ApiItem {
ID?: number;
@ -13,68 +12,68 @@ export interface ApiItem {
}
/** 获取API列表 */
export const getApiList = (data: PageParams & { path?: string; description?: string; method?: string; apiGroup?: string }) => {
return request.post<ApiResponse<PageResult<ApiItem>>>('/api/getApiList', data);
export const getApiList = (data: { page: number; pageSize: number; path?: string; description?: string; method?: string; apiGroup?: string; orderKey?: string; desc?: boolean }) => {
return request.post('/api/getApiList', data);
};
/** 创建API */
export const createApi = (data: ApiItem) => {
return request.post<ApiResponse<any>>('/api/createApi', data);
return request.post('/api/createApi', data);
};
/** 根据ID获取API */
export const getApiById = (data: { id: number }) => {
return request.post<ApiResponse<{ api: ApiItem }>>('/api/getApiById', data);
return request.post('/api/getApiById', data);
};
/** 更新API */
export const updateApi = (data: ApiItem) => {
return request.post<ApiResponse<any>>('/api/updateApi', data);
return request.post('/api/updateApi', data);
};
/** 设置API权限 */
export const setAuthApi = (data: any) => {
return request.post<ApiResponse<any>>('/api/setAuthApi', data);
return request.post('/api/setAuthApi', data);
};
/** 获取所有API不分页 */
export const getAllApis = (data?: any) => {
return request.post<ApiResponse<{ apis: ApiItem[] }>>('/api/getAllApis', data);
return request.post('/api/getAllApis', data);
};
/** 删除API */
export const deleteApi = (data: { ID: number }) => {
return request.post<ApiResponse<any>>('/api/deleteApi', data);
return request.post('/api/deleteApi', data);
};
/** 批量删除API */
export const deleteApisByIds = (data: { ids: number[] }) => {
return request.delete<ApiResponse<any>>('/api/deleteApisByIds', { data });
return request.delete('/api/deleteApisByIds', { data });
};
/** 刷新Casbin缓存 */
export const freshCasbin = () => {
return request.get<ApiResponse<any>>('/api/freshCasbin');
return request.get('/api/freshCasbin');
};
/** 同步API */
export const syncApi = () => {
return request.get<ApiResponse<any>>('/api/syncApi');
return request.get('/api/syncApi');
};
/** 获取API分组 */
export const getApiGroups = () => {
return request.get<ApiResponse<{ groups: string[] }>>('/api/getApiGroups');
return request.get('/api/getApiGroups');
};
/** 忽略API */
export const ignoreApi = (data: any) => {
return request.post<ApiResponse<any>>('/api/ignoreApi', data);
return request.post('/api/ignoreApi', data);
};
/** 进入同步API */
export const enterSyncApi = (data: any) => {
return request.post<ApiResponse<any>>('/api/enterSyncApi', data);
return request.post('/api/enterSyncApi', data);
};
export default {

View File

@ -2,7 +2,6 @@
* KRA - Authority API Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface Authority {
authorityId: string;
@ -14,33 +13,33 @@ export interface Authority {
}
/** 获取角色列表 */
export const getAuthorityList = (data: PageParams) => {
return request.post<ApiResponse<PageResult<Authority>>>('/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<ApiResponse<any>>('/authority/deleteAuthority', data);
return request.post('/authority/deleteAuthority', data);
};
/** 创建角色 */
export const createAuthority = (data: Authority) => {
return request.post<ApiResponse<{ authority: Authority }>>('/authority/createAuthority', data);
return request.post('/authority/createAuthority', data);
};
/** 拷贝角色 */
export const copyAuthority = (data: { authority: Authority; oldAuthorityId: string }) => {
return request.post<ApiResponse<{ authority: Authority }>>('/authority/copyAuthority', data);
return request.post('/authority/copyAuthority', data);
};
/** 设置角色资源权限 */
export const setDataAuthority = (data: { authorityId: string; dataAuthorityId: Authority[] }) => {
return request.post<ApiResponse<any>>('/authority/setDataAuthority', data);
return request.post('/authority/setDataAuthority', data);
};
/** 修改角色 */
export const updateAuthority = (data: Authority) => {
return request.put<ApiResponse<{ authority: Authority }>>('/authority/updateAuthority', data);
return request.put('/authority/updateAuthority', data);
};
export default {

View File

@ -2,7 +2,6 @@
* KRA - Customer API Service (Example)
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface Customer {
ID?: number;
@ -20,27 +19,27 @@ export interface Customer {
/** 创建客户 */
export const createExaCustomer = (data: Customer) => {
return request.post<ApiResponse<any>>('/customer/customer', data);
return request.post('/customer/customer', data);
};
/** 更新客户 */
export const updateExaCustomer = (data: Customer) => {
return request.put<ApiResponse<any>>('/customer/customer', data);
return request.put('/customer/customer', data);
};
/** 删除客户 */
export const deleteExaCustomer = (data: { ID: number }) => {
return request.delete<ApiResponse<any>>('/customer/customer', { data });
return request.delete('/customer/customer', { data });
};
/** 获取单一客户信息 */
export const getExaCustomer = (params: { ID: number }) => {
return request.get<ApiResponse<{ customer: Customer }>>('/customer/customer', { params });
return request.get('/customer/customer', { params });
};
/** 获取客户列表 */
export const getExaCustomerList = (params: PageParams) => {
return request.get<ApiResponse<PageResult<Customer>>>('/customer/customerList', { params });
export const getExaCustomerList = (params: { page: number; pageSize: number }) => {
return request.get('/customer/customerList', { params });
};
export default {

View File

@ -2,7 +2,6 @@
* KRA - Dictionary API Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface Dictionary {
ID?: number;
@ -14,39 +13,42 @@ export interface Dictionary {
/** 创建字典 */
export const createSysDictionary = (data: Dictionary) => {
return request.post<ApiResponse<any>>('/sysDictionary/createSysDictionary', data);
return request.post('/sysDictionary/createSysDictionary', data);
};
/** 删除字典 */
export const deleteSysDictionary = (data: { ID: number }) => {
return request.delete<ApiResponse<any>>('/sysDictionary/deleteSysDictionary', { data });
return request.delete('/sysDictionary/deleteSysDictionary', { data });
};
/** 更新字典 */
export const updateSysDictionary = (data: Dictionary) => {
return request.put<ApiResponse<any>>('/sysDictionary/updateSysDictionary', data);
return request.put('/sysDictionary/updateSysDictionary', data);
};
/** 根据ID或type查询字典 */
export const findSysDictionary = (params: { ID?: number; type?: string }) => {
return request.get<ApiResponse<{ resysDictionary: Dictionary & { sysDictionaryDetails?: any[] } }>>('/sysDictionary/findSysDictionary', { params });
return request.get('/sysDictionary/findSysDictionary', { params });
};
/** 获取字典列表 */
export const getSysDictionaryList = (params: PageParams & { name?: string; type?: string; status?: boolean; desc?: string }) => {
return request.get<ApiResponse<PageResult<Dictionary>>>('/sysDictionary/getSysDictionaryList', { params });
export const getSysDictionaryList = (params?: { name?: string; type?: string; status?: boolean; desc?: string }) => {
return request.get('/sysDictionary/getSysDictionaryList', { params });
};
/** 导出字典JSON */
export const exportSysDictionary = (params: { ID: number }) => {
return request.get<ApiResponse<any>>('/sysDictionary/exportSysDictionary', { params });
return request.get('/sysDictionary/exportSysDictionary', { params });
};
/** 导入字典JSON */
export const importSysDictionary = (data: any) => {
return request.post<ApiResponse<any>>('/sysDictionary/importSysDictionary', data);
return request.post('/sysDictionary/importSysDictionary', data);
};
// 别名导出,兼容页面调用
export const getDictionaryList = getSysDictionaryList;
export default {
createSysDictionary,
deleteSysDictionary,
@ -55,4 +57,5 @@ export default {
getSysDictionaryList,
exportSysDictionary,
importSysDictionary,
getDictionaryList,
};

View File

@ -2,7 +2,6 @@
* KRA - Dictionary Detail API Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface DictionaryDetail {
ID?: number;
@ -18,49 +17,56 @@ export interface DictionaryDetail {
/** 创建字典详情 */
export const createSysDictionaryDetail = (data: DictionaryDetail) => {
return request.post<ApiResponse<any>>('/sysDictionaryDetail/createSysDictionaryDetail', data);
return request.post('/sysDictionaryDetail/createSysDictionaryDetail', data);
};
/** 删除字典详情 */
export const deleteSysDictionaryDetail = (data: { ID: number }) => {
return request.delete<ApiResponse<any>>('/sysDictionaryDetail/deleteSysDictionaryDetail', { data });
return request.delete('/sysDictionaryDetail/deleteSysDictionaryDetail', { data });
};
/** 更新字典详情 */
export const updateSysDictionaryDetail = (data: DictionaryDetail) => {
return request.put<ApiResponse<any>>('/sysDictionaryDetail/updateSysDictionaryDetail', data);
return request.put('/sysDictionaryDetail/updateSysDictionaryDetail', data);
};
/** 根据ID查询字典详情 */
export const findSysDictionaryDetail = (params: { ID: number }) => {
return request.get<ApiResponse<{ resysDictionaryDetail: DictionaryDetail }>>('/sysDictionaryDetail/findSysDictionaryDetail', { params });
return request.get('/sysDictionaryDetail/findSysDictionaryDetail', { params });
};
/** 获取字典详情列表 */
export const getSysDictionaryDetailList = (params: PageParams & { sysDictionaryID?: number; label?: string; value?: any; status?: boolean }) => {
return request.get<ApiResponse<PageResult<DictionaryDetail>>>('/sysDictionaryDetail/getSysDictionaryDetailList', { params });
export const getSysDictionaryDetailList = (params: { page: number; pageSize: number; sysDictionaryID?: number; label?: string; value?: any; status?: boolean }) => {
return request.get('/sysDictionaryDetail/getSysDictionaryDetailList', { params });
};
/** 获取字典树形结构根据字典ID */
export const getDictionaryTreeList = (params: { sysDictionaryID: number }) => {
return request.get<ApiResponse<{ list: DictionaryDetail[] }>>('/sysDictionaryDetail/getDictionaryTreeList', { params });
return request.get('/sysDictionaryDetail/getDictionaryTreeList', { params });
};
/** 获取字典树形结构(根据字典类型) */
export const getDictionaryTreeListByType = (params: { type: string }) => {
return request.get<ApiResponse<{ list: DictionaryDetail[] }>>('/sysDictionaryDetail/getDictionaryTreeListByType', { params });
return request.get('/sysDictionaryDetail/getDictionaryTreeListByType', { params });
};
/** 根据父级ID获取字典详情 */
export const getDictionaryDetailsByParent = (params: { parentID: number; includeChildren?: boolean }) => {
return request.get<ApiResponse<{ list: DictionaryDetail[] }>>('/sysDictionaryDetail/getDictionaryDetailsByParent', { params });
return request.get('/sysDictionaryDetail/getDictionaryDetailsByParent', { params });
};
/** 获取字典详情完整路径 */
export const getDictionaryPath = (params: { ID: number }) => {
return request.get<ApiResponse<{ path: DictionaryDetail[] }>>('/sysDictionaryDetail/getDictionaryPath', { params });
return request.get('/sysDictionaryDetail/getDictionaryPath', { params });
};
// 别名导出,兼容页面调用
export const getDictionaryDetailList = getSysDictionaryDetailList;
export const createDictionaryDetail = createSysDictionaryDetail;
export const updateDictionaryDetail = updateSysDictionaryDetail;
export const deleteDictionaryDetail = deleteSysDictionaryDetail;
export const findDictionaryDetail = findSysDictionaryDetail;
export default {
createSysDictionaryDetail,
deleteSysDictionaryDetail,
@ -71,4 +77,9 @@ export default {
getDictionaryTreeListByType,
getDictionaryDetailsByParent,
getDictionaryPath,
getDictionaryDetailList,
createDictionaryDetail,
updateDictionaryDetail,
deleteDictionaryDetail,
findDictionaryDetail,
};

View File

@ -2,7 +2,6 @@
* KRA - File Upload API Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface FileInfo {
ID?: number;
@ -15,59 +14,63 @@ export interface FileInfo {
categoryId?: number;
}
export interface FileSearchParams extends PageParams {
export interface FileSearchParams {
page: number;
pageSize: number;
name?: string;
tag?: string;
categoryId?: number;
keyword?: string;
classId?: number;
}
/** 分页获取文件列表 */
export const getFileList = (data: FileSearchParams) => {
return request.post<ApiResponse<PageResult<FileInfo>>>('/fileUploadAndDownload/getFileList', data);
return request.post('/fileUploadAndDownload/getFileList', data);
};
/** 删除文件 */
export const deleteFile = (data: { ID: number }) => {
return request.post<ApiResponse<any>>('/fileUploadAndDownload/deleteFile', data);
return request.post('/fileUploadAndDownload/deleteFile', data);
};
/** 编辑文件名或备注 */
export const editFileName = (data: { ID: number; name: string }) => {
return request.post<ApiResponse<any>>('/fileUploadAndDownload/editFileName', data);
return request.post('/fileUploadAndDownload/editFileName', data);
};
/** 导入URL */
export const importURL = (data: { url: string }) => {
return request.post<ApiResponse<any>>('/fileUploadAndDownload/importURL', data);
export const importURL = (data: any) => {
return request.post('/fileUploadAndDownload/importURL', data);
};
/** 上传文件 */
export const uploadFile = (data: FormData) => {
return request.post<ApiResponse<{ file: FileInfo }>>('/fileUploadAndDownload/upload', data, {
return request.post('/fileUploadAndDownload/upload', data, {
headers: { 'Content-Type': 'multipart/form-data' },
});
};
/** 查找文件(断点续传用) */
export const findFile = (params: { fileMd5: string }) => {
return request.get<ApiResponse<{ file: FileInfo }>>('/fileUploadAndDownload/findFile', { params });
return request.get('/fileUploadAndDownload/findFile', { params });
};
/** 断点续传 */
export const breakpointContinue = (data: FormData) => {
return request.post<ApiResponse<any>>('/fileUploadAndDownload/breakpointContinue', data, {
return request.post('/fileUploadAndDownload/breakpointContinue', data, {
headers: { 'Content-Type': 'multipart/form-data' },
});
};
/** 断点续传完成 */
export const breakpointContinueFinish = (params: { fileName: string; fileMd5: string }) => {
return request.post<ApiResponse<any>>('/fileUploadAndDownload/breakpointContinueFinish', undefined, { params });
return request.post('/fileUploadAndDownload/breakpointContinueFinish', undefined, { params });
};
/** 移除分片 */
export const removeChunk = (data: any, params: { fileName: string; fileMd5: string; filePath: string }) => {
return request.post<ApiResponse<any>>('/fileUploadAndDownload/removeChunk', data, { params });
return request.post('/fileUploadAndDownload/removeChunk', data, { params });
};
export default {

View File

@ -2,7 +2,6 @@
* KRA - Menu API Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface MenuItem {
ID?: number;
@ -26,47 +25,47 @@ export interface MenuItem {
/** 获取动态路由菜单 */
export const asyncMenu = () => {
return request.post<ApiResponse<{ menus: MenuItem[] }>>('/menu/getMenu');
return request.post('/menu/getMenu');
};
/** 获取菜单列表 */
export const getMenuList = (data: PageParams) => {
return request.post<ApiResponse<PageResult<MenuItem>>>('/menu/getMenuList', data);
export const getMenuList = (data?: { page?: number; pageSize?: number }) => {
return request.post('/menu/getMenuList', data || { page: 1, pageSize: 999 });
};
/** 新增基础菜单 */
export const addBaseMenu = (data: MenuItem) => {
return request.post<ApiResponse<any>>('/menu/addBaseMenu', data);
return request.post('/menu/addBaseMenu', data);
};
/** 获取基础路由树 */
export const getBaseMenuTree = () => {
return request.post<ApiResponse<{ menus: MenuItem[] }>>('/menu/getBaseMenuTree');
return request.post('/menu/getBaseMenuTree');
};
/** 添加菜单权限关联 */
export const addMenuAuthority = (data: { menus: number[]; authorityId: string }) => {
return request.post<ApiResponse<any>>('/menu/addMenuAuthority', data);
return request.post('/menu/addMenuAuthority', data);
};
/** 获取菜单权限关联 */
export const getMenuAuthority = (data: { authorityId: string }) => {
return request.post<ApiResponse<{ menus: MenuItem[] }>>('/menu/getMenuAuthority', data);
return request.post('/menu/getMenuAuthority', data);
};
/** 删除菜单 */
export const deleteBaseMenu = (data: { ID: number }) => {
return request.post<ApiResponse<any>>('/menu/deleteBaseMenu', data);
return request.post('/menu/deleteBaseMenu', data);
};
/** 更新菜单 */
export const updateBaseMenu = (data: MenuItem) => {
return request.post<ApiResponse<any>>('/menu/updateBaseMenu', data);
return request.post('/menu/updateBaseMenu', data);
};
/** 根据ID获取菜单 */
export const getBaseMenuById = (data: { id: number }) => {
return request.post<ApiResponse<{ menu: MenuItem }>>('/menu/getBaseMenuById', data);
return request.post('/menu/getBaseMenuById', data);
};
export default {

View File

@ -2,7 +2,6 @@
* KRA - Operation Record API Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface OperationRecord {
ID?: number;
@ -23,7 +22,9 @@ export interface OperationRecord {
};
}
export interface OperationRecordSearchParams extends PageParams {
export interface OperationRecordSearchParams {
page?: number;
pageSize?: number;
path?: string;
method?: string;
status?: number;
@ -32,21 +33,29 @@ export interface OperationRecordSearchParams extends PageParams {
/** 删除操作记录 */
export const deleteSysOperationRecord = (data: { ID: number }) => {
return request.delete<ApiResponse<any>>('/sysOperationRecord/deleteSysOperationRecord', { data });
return request.delete('/sysOperationRecord/deleteSysOperationRecord', { data });
};
/** 批量删除操作记录 */
export const deleteSysOperationRecordByIds = (data: { ids: number[] }) => {
return request.delete<ApiResponse<any>>('/sysOperationRecord/deleteSysOperationRecordByIds', { data });
return request.delete('/sysOperationRecord/deleteSysOperationRecordByIds', { data });
};
/** 分页获取操作记录列表 */
export const getSysOperationRecordList = (params: OperationRecordSearchParams) => {
return request.get<ApiResponse<PageResult<OperationRecord>>>('/sysOperationRecord/getSysOperationRecordList', { params });
return request.get('/sysOperationRecord/getSysOperationRecordList', { params });
};
// 别名导出,兼容页面调用
export const getOperationRecordList = getSysOperationRecordList;
export const deleteOperationRecord = deleteSysOperationRecord;
export const deleteOperationRecordByIds = deleteSysOperationRecordByIds;
export default {
deleteSysOperationRecord,
deleteSysOperationRecordByIds,
getSysOperationRecordList,
getOperationRecordList,
deleteOperationRecord,
deleteOperationRecordByIds,
};

View File

@ -2,7 +2,6 @@
* KRA - System Params API Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface SysParams {
ID?: number;
@ -25,7 +24,7 @@ export const deleteSysParams = (params: { ID: number }) => {
};
/** 批量删除参数 */
export const deleteSysParamsByIds = (params: { ids: number[] }) => {
export const deleteSysParamsByIds = (params: { IDs: number[] }) => {
return request.delete<ApiResponse<any>>('/sysParams/deleteSysParamsByIds', { params });
};
@ -49,6 +48,14 @@ export const getSysParam = (params: { key: string }) => {
return request.get<ApiResponse<{ sysParams: SysParams }>>('/sysParams/getSysParam', { params });
};
// 别名导出,兼容页面调用
export const getParamsList = getSysParamsList;
export const createParams = createSysParams;
export const updateParams = updateSysParams;
export const deleteParams = deleteSysParams;
export const deleteParamsByIds = deleteSysParamsByIds;
export const findParams = findSysParams;
export default {
createSysParams,
deleteSysParams,
@ -57,4 +64,10 @@ export default {
findSysParams,
getSysParamsList,
getSysParam,
getParamsList,
createParams,
updateParams,
deleteParams,
deleteParamsByIds,
findParams,
};

View File

@ -26,7 +26,7 @@ export async function deleteSysError(params: { ID: number }) {
}
// 批量删除错误日志
export async function deleteSysErrorByIds(params: { ids: number[] }) {
export async function deleteSysErrorByIds(params: { IDs: number[] }) {
return request.delete('/sysError/deleteSysErrorByIds', { params });
}
@ -61,3 +61,6 @@ export async function getSysErrorPublic() {
export async function getSysErrorSolution(params: { id: number }) {
return request.get('/sysError/getSysErrorSolution', { params });
}
// 别名导出,兼容页面调用
export const getSysErrorById = findSysError;

View File

@ -2,7 +2,6 @@
* KRA - User API Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface LoginParams {
username: string;

View File

@ -2,7 +2,6 @@
* KRA - Version API Service
*/
import request from '@/utils/request';
import type { ApiResponse, PageParams, PageResult } from '@/types/api';
export interface SysVersion {
ID?: number;
@ -21,7 +20,7 @@ export const deleteSysVersion = (params: { ID: number }) => {
};
/** 批量删除版本 */
export const deleteSysVersionByIds = (params: { ids: number[] }) => {
export const deleteSysVersionByIds = (params: { IDs: number[] }) => {
return request.delete<ApiResponse<any>>('/sysVersion/deleteSysVersionByIds', { params });
};