1
This commit is contained in:
parent
684e682bcd
commit
64220aef44
@ -155,6 +155,25 @@ export const getCurrentUserMenus = async () => {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 添加X6测试菜单
|
||||||
|
// const x6Test: MenuResponse = {
|
||||||
|
// id: -1,
|
||||||
|
// createTime: new Date().toISOString(),
|
||||||
|
// updateTime: new Date().toISOString(),
|
||||||
|
// version: 0,
|
||||||
|
// name: "X6测试",
|
||||||
|
// path: "/x6-test",
|
||||||
|
// component: "/X6Test/index",
|
||||||
|
// icon: "experiment",
|
||||||
|
// type: MenuTypeEnum.MENU,
|
||||||
|
// parentId: 0,
|
||||||
|
// sort: 1,
|
||||||
|
// hidden: false,
|
||||||
|
// enabled: true,
|
||||||
|
// createBy: "system",
|
||||||
|
// updateBy: "system"
|
||||||
|
// };
|
||||||
|
|
||||||
// 处理组件路径格式
|
// 处理组件路径格式
|
||||||
const processMenu = (menu: MenuResponse): MenuResponse => {
|
const processMenu = (menu: MenuResponse): MenuResponse => {
|
||||||
const processed = { ...menu };
|
const processed = { ...menu };
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
import { PageContainer } from '@ant-design/pro-components';
|
||||||
import { Row, Col, Menu, Tabs, Card } from 'antd';
|
import { Row, Col, Menu, Tabs, Card, Button, message } from 'antd';
|
||||||
import { BetaSchemaForm, ProForm, ProFormGroup } from '@ant-design/pro-form';
|
import { BetaSchemaForm, ProForm, ProFormGroup, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
|
||||||
import type { NodeDefinitionData } from './types';
|
import type { NodeDefinitionData } from './types';
|
||||||
import * as service from './service';
|
import * as service from './service';
|
||||||
|
|
||||||
@ -22,6 +22,9 @@ const NodeDesignForm: React.FC = () => {
|
|||||||
// 当前选中的 tab
|
// 当前选中的 tab
|
||||||
const [activeTab, setActiveTab] = useState<string>('panel');
|
const [activeTab, setActiveTab] = useState<string>('panel');
|
||||||
|
|
||||||
|
const formRef = useRef<any>();
|
||||||
|
const uiFormRef = useRef<any>(); // 添加 UI 配置表单的 ref
|
||||||
|
|
||||||
// 加载节点定义数据
|
// 加载节点定义数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadNodeDefinitions = async () => {
|
const loadNodeDefinitions = async () => {
|
||||||
@ -173,6 +176,22 @@ const NodeDesignForm: React.FC = () => {
|
|||||||
'boolean': 'switch'
|
'boolean': 'switch'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 判断是否是颜色字段
|
||||||
|
const isColorField = value.type === 'string' &&
|
||||||
|
(value.title?.includes('颜色') || value.description?.includes('颜色'));
|
||||||
|
|
||||||
|
if (isColorField) {
|
||||||
|
return {
|
||||||
|
...baseField,
|
||||||
|
valueType: 'color',
|
||||||
|
placeholder: `请选择${value.title}`,
|
||||||
|
fieldProps: {
|
||||||
|
showText: true,
|
||||||
|
format: 'hex'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...baseField,
|
...baseField,
|
||||||
valueType: typeMap[value.type] || 'text',
|
valueType: typeMap[value.type] || 'text',
|
||||||
@ -182,127 +201,175 @@ const NodeDesignForm: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 渲染 Tab 内容
|
// 渲染 Tab 内容
|
||||||
const renderTabContent = (tabKey: string) => {
|
const renderTabContent = (schemaKey: string) => {
|
||||||
if (!selectedNode) return null;
|
if (!selectedNode) return null;
|
||||||
|
const schema = selectedNode[schemaKey as keyof NodeDefinitionData];
|
||||||
const content = selectedNode[tabKey as keyof NodeDefinitionData];
|
if (!schema) return null;
|
||||||
if (!content) return null;
|
|
||||||
|
|
||||||
const currentTab = TAB_CONFIG.find(tab => tab.schemaKey === tabKey);
|
|
||||||
const isReadOnly = currentTab?.readonly ?? true;
|
|
||||||
|
|
||||||
// 判断是否是 schema 格式
|
|
||||||
const isSchema = typeof content === 'object' && 'type' in content && 'properties' in content;
|
|
||||||
console.log('Is Schema:', isSchema);
|
|
||||||
console.log('Content:', content);
|
|
||||||
|
|
||||||
const schema = isSchema ? content : {
|
|
||||||
type: 'object',
|
|
||||||
properties: Object.entries(content).reduce((acc, [key, value]) => ({
|
|
||||||
...acc,
|
|
||||||
[key]: {
|
|
||||||
title: key,
|
|
||||||
type: typeof value,
|
|
||||||
default: value
|
|
||||||
}
|
|
||||||
}), {})
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('Final Schema:', schema);
|
|
||||||
// 获取默认值
|
|
||||||
const defaultValues = getDefaultValues(schema);
|
|
||||||
console.log('Default Values:', defaultValues);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card bordered={false}>
|
<BetaSchemaForm
|
||||||
<BetaSchemaForm
|
formRef={schemaKey === 'uiVariables' ? uiFormRef : undefined}
|
||||||
layoutType="Form"
|
layoutType="Form"
|
||||||
readonly={isReadOnly}
|
initialValues={getDefaultValues(schema)}
|
||||||
onFinish={handleFormSubmit}
|
columns={convertToProFormSchema(schema)}
|
||||||
columns={convertToProFormSchema(schema)}
|
submitter={false}
|
||||||
initialValues={defaultValues}
|
/>
|
||||||
submitter={!isReadOnly}
|
);
|
||||||
grid={false}
|
};
|
||||||
layout="vertical"
|
|
||||||
style={{ maxWidth: '100%' }}
|
// 将扁平的对象转换为嵌套对象
|
||||||
formItemProps={{
|
const flatToNested = (obj: Record<string, any>) => {
|
||||||
labelCol: { span: 24 },
|
const result: Record<string, any> = {};
|
||||||
wrapperCol: { span: 24 },
|
|
||||||
style: {
|
Object.keys(obj).forEach(key => {
|
||||||
marginBottom: 16
|
const parts = key.split('.');
|
||||||
}
|
let current = result;
|
||||||
}}
|
|
||||||
/>
|
parts.forEach((part, index) => {
|
||||||
</Card>
|
if (index === parts.length - 1) {
|
||||||
|
current[part] = obj[key];
|
||||||
|
} else {
|
||||||
|
current[part] = current[part] || {};
|
||||||
|
current = current[part];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSave = async () => {
|
||||||
|
if (!selectedNode) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const formValues = await formRef.current?.validateFields();
|
||||||
|
const uiValues = await uiFormRef.current?.validateFields();
|
||||||
|
|
||||||
|
const saveData = {
|
||||||
|
nodeType: formValues.nodeType,
|
||||||
|
nodeCode: formValues.nodeCode,
|
||||||
|
nodeName: formValues.nodeName,
|
||||||
|
category: formValues.category,
|
||||||
|
description: formValues.description,
|
||||||
|
uiVariables: flatToNested(uiValues), // 将扁平结构转换为嵌套结构
|
||||||
|
localVariablesSchema: selectedNode.localVariablesSchema,
|
||||||
|
panelVariablesSchema: selectedNode.panelVariablesSchema,
|
||||||
|
formVariablesSchema: selectedNode.formVariablesSchema
|
||||||
|
};
|
||||||
|
|
||||||
|
await service.saveNodeDefinition(saveData);
|
||||||
|
message.success('保存成功');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Save failed:', error);
|
||||||
|
message.error('保存失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderBasicForm = () => {
|
||||||
|
if (!selectedNode) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ProForm
|
||||||
|
formRef={formRef}
|
||||||
|
key={selectedNode.nodeCode}
|
||||||
|
layout="horizontal"
|
||||||
|
submitter={false}
|
||||||
|
initialValues={{
|
||||||
|
nodeType: selectedNode.nodeCode,
|
||||||
|
nodeCode: selectedNode.nodeCode,
|
||||||
|
nodeName: selectedNode.nodeName,
|
||||||
|
category: selectedNode.category,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="nodeType"
|
||||||
|
label="节点类型"
|
||||||
|
disabled
|
||||||
|
colProps={{ span: 12 }}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="nodeCode"
|
||||||
|
label="节点编码"
|
||||||
|
disabled
|
||||||
|
colProps={{ span: 12 }}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormText
|
||||||
|
name="nodeName"
|
||||||
|
label="节点名称"
|
||||||
|
disabled
|
||||||
|
colProps={{ span: 12 }}
|
||||||
|
/>
|
||||||
|
<ProFormText
|
||||||
|
name="category"
|
||||||
|
label="节点类别"
|
||||||
|
disabled
|
||||||
|
colProps={{ span: 12 }}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
<ProForm.Group>
|
||||||
|
<ProFormTextArea
|
||||||
|
name="description"
|
||||||
|
label="节点描述"
|
||||||
|
placeholder="请输入节点描述"
|
||||||
|
colProps={{ span: 24 }}
|
||||||
|
/>
|
||||||
|
</ProForm.Group>
|
||||||
|
</ProForm>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainer
|
||||||
loading={loading}
|
loading={loading}
|
||||||
header={{
|
extra={[
|
||||||
title: '节点设计',
|
<Button
|
||||||
breadcrumb: {
|
key="save"
|
||||||
items: [
|
type="primary"
|
||||||
{ title: '工作流' },
|
onClick={handleSave}
|
||||||
{ title: '节点设计', path: '/workflow/node-design' }
|
disabled={!selectedNode}
|
||||||
],
|
>
|
||||||
},
|
保存
|
||||||
}}
|
</Button>
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<div style={{ background: '#fff', minHeight: 'calc(100vh - 200px)' }}>
|
<div style={{ display: 'flex', height: '100%' }}>
|
||||||
<Row>
|
<div style={{ width: 200, borderRight: '1px solid #f0f0f0', marginRight: 24 }}>
|
||||||
<Col span={5} style={{ borderRight: '1px solid #f0f0f0', padding: '16px 0' }}>
|
<div style={{
|
||||||
<div style={{
|
padding: '8px 16px',
|
||||||
padding: '0 24px 16px',
|
fontWeight: 'bold',
|
||||||
fontSize: '16px',
|
borderBottom: '1px solid #f0f0f0'
|
||||||
fontWeight: 500,
|
}}>
|
||||||
color: '#000000d9',
|
节点类型
|
||||||
borderBottom: '1px solid #f0f0f0',
|
</div>
|
||||||
marginBottom: '8px'
|
<Menu
|
||||||
}}>
|
mode="vertical"
|
||||||
节点类型
|
selectedKeys={[selectedNode?.nodeCode || '']}
|
||||||
</div>
|
items={nodeDefinitions.map(node => ({
|
||||||
<Menu
|
key: node.nodeCode,
|
||||||
mode="vertical"
|
label: `${node.nodeName}(${node.nodeCode})`,
|
||||||
selectedKeys={[selectedNode?.nodeCode || '']}
|
}))}
|
||||||
items={nodeDefinitions.map(node => ({
|
onClick={({ key }) => handleNodeSelect(key)}
|
||||||
key: node.nodeCode,
|
style={{
|
||||||
label: node.nodeName,
|
border: 'none',
|
||||||
}))}
|
padding: '0 16px'
|
||||||
onClick={({ key }) => handleNodeSelect(key)}
|
}}
|
||||||
style={{
|
/>
|
||||||
border: 'none',
|
</div>
|
||||||
padding: '0 16px'
|
<div style={{ flex: 1 }}>
|
||||||
}}
|
{renderBasicForm()}
|
||||||
/>
|
<Tabs
|
||||||
</Col>
|
activeKey={activeTab}
|
||||||
<Col span={19}>
|
onChange={handleTabChange}
|
||||||
<div style={{ padding: '16px 24px' }}>
|
items={getAvailableTabs(selectedNode).map(tab => ({
|
||||||
{selectedNode && getAvailableTabs(selectedNode).length > 0 ? (
|
key: tab.schemaKey,
|
||||||
<Tabs
|
label: tab.label,
|
||||||
activeKey={activeTab}
|
children: renderTabContent(tab.schemaKey)
|
||||||
onChange={handleTabChange}
|
}))}
|
||||||
type="card"
|
/>
|
||||||
items={getAvailableTabs(selectedNode).map(tab => ({
|
</div>
|
||||||
key: tab.key,
|
|
||||||
label: tab.label,
|
|
||||||
children: renderTabContent(tab.schemaKey)
|
|
||||||
}))}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div style={{
|
|
||||||
textAlign: 'center',
|
|
||||||
padding: '32px',
|
|
||||||
color: '#00000073',
|
|
||||||
fontSize: '14px'
|
|
||||||
}}>
|
|
||||||
暂无可配置项
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</div>
|
</div>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -100,20 +100,13 @@ const NodeDesignList: React.FC = () => {
|
|||||||
...rest,
|
...rest,
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
data: response.list,
|
data: response.content,
|
||||||
success: true,
|
success: true,
|
||||||
total: response.total,
|
total: response.totalElements
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
rowKey="nodeCode"
|
rowKey="nodeCode"
|
||||||
search={{
|
search={false}
|
||||||
labelWidth: 'auto',
|
|
||||||
}}
|
|
||||||
pagination={{
|
|
||||||
pageSize: 10,
|
|
||||||
}}
|
|
||||||
dateFormatter="string"
|
|
||||||
headerTitle="节点设计列表"
|
|
||||||
toolBarRender={() => [
|
toolBarRender={() => [
|
||||||
<Button
|
<Button
|
||||||
key="create"
|
key="create"
|
||||||
@ -121,15 +114,7 @@ const NodeDesignList: React.FC = () => {
|
|||||||
icon={<PlusOutlined />}
|
icon={<PlusOutlined />}
|
||||||
onClick={() => navigate('/workflow/node-design/create')}
|
onClick={() => navigate('/workflow/node-design/create')}
|
||||||
>
|
>
|
||||||
新增节点
|
新建节点
|
||||||
</Button>,
|
|
||||||
<Button
|
|
||||||
key="export"
|
|
||||||
onClick={() => {
|
|
||||||
// TODO: 实现导出功能
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
导出配置
|
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -3,20 +3,24 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
import type { NodeDesignQuery, NodeDesignResponse, NodeDesignData, NodeDefinitionData } from './types';
|
import type { NodeDesignQuery, NodeDesignResponse, NodeDesignData, NodeDefinitionData } from './types';
|
||||||
|
|
||||||
const BASE_URL = '/api/v1/workflow';
|
const BASE_URL = '/api/v1/workflow/node-definition';
|
||||||
|
|
||||||
// 获取节点设计列表
|
// 获取节点设计列表
|
||||||
export const getNodeDesigns = (params: NodeDesignQuery) =>
|
export const getNodeDesigns = (params: NodeDesignQuery) =>
|
||||||
request.get<NodeDesignResponse>(`${BASE_URL}/node-design/list`, { params });
|
request.get<NodeDesignResponse>(`${BASE_URL}/page`, { params });
|
||||||
|
|
||||||
// 获取节点设计详情
|
// 获取节点设计详情
|
||||||
export const getNodeDesign = (nodeCode: string) =>
|
export const getNodeDesign = (nodeCode: string) =>
|
||||||
request.get<NodeDesignData>(`${BASE_URL}/node-design/${nodeCode}`);
|
request.get<NodeDesignData>(`${BASE_URL}/${nodeCode}`);
|
||||||
|
|
||||||
// 更新节点UI配置
|
// 更新节点UI配置
|
||||||
export const updateNodeUIConfig = (nodeCode: string, uiVariables: any) =>
|
export const updateNodeUIConfig = (nodeCode: string, uiVariables: any) =>
|
||||||
request.put(`${BASE_URL}/node-design/${nodeCode}/ui`, uiVariables);
|
request.put(`${BASE_URL}/${nodeCode}/ui`, uiVariables);
|
||||||
|
|
||||||
// 获取已定义的节点类型配置
|
// 获取已定义的节点类型配置
|
||||||
export const getNodeDefinitionsDefined = () =>
|
export const getNodeDefinitionsDefined = () =>
|
||||||
request.get<NodeDefinitionData[]>(`${BASE_URL}/node-definition/defined`);
|
request.get<NodeDefinitionData[]>(`${BASE_URL}/defined`);
|
||||||
|
|
||||||
|
// 保存节点定义
|
||||||
|
export const saveNodeDefinition = (data: NodeDefinitionData) =>
|
||||||
|
request.post<void>(`${BASE_URL}`, data);
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
// 节点设计相关类型定义
|
// 节点设计相关类型定义
|
||||||
|
|
||||||
// 基础Schema接口
|
// 基础Schema接口
|
||||||
|
import {BaseQuery, BaseResponse} from "@/types/base";
|
||||||
|
|
||||||
export interface BaseSchema {
|
export interface BaseSchema {
|
||||||
type: string;
|
type: string;
|
||||||
properties: Record<string, any>;
|
properties: Record<string, any>;
|
||||||
@ -68,20 +70,11 @@ export interface UIVariables extends BaseSchema {
|
|||||||
style: NodeStyle;
|
style: NodeStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 节点定义数据接口
|
|
||||||
export interface NodeDefinitionData {
|
|
||||||
nodeCode: string;
|
|
||||||
nodeName: string;
|
|
||||||
panelVariablesSchema: NodeVariablesSchema | null;
|
|
||||||
localVariablesSchema: NodeVariablesSchema | null;
|
|
||||||
formVariablesSchema: NodeVariablesSchema | null;
|
|
||||||
uiVariables: UIVariables;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 节点设计数据
|
// 节点设计数据
|
||||||
export interface NodeDesignData {
|
export interface NodeDesignData {
|
||||||
nodeCode: string;
|
nodeCode: string;
|
||||||
nodeName: string;
|
nodeName: string;
|
||||||
|
category: string;
|
||||||
panelVariablesSchema: NodeVariablesSchema | null;
|
panelVariablesSchema: NodeVariablesSchema | null;
|
||||||
localVariablesSchema: NodeVariablesSchema | null;
|
localVariablesSchema: NodeVariablesSchema | null;
|
||||||
formVariablesSchema: NodeVariablesSchema | null;
|
formVariablesSchema: NodeVariablesSchema | null;
|
||||||
@ -96,15 +89,12 @@ export enum NodeTypeEnum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查询参数接口
|
// 查询参数接口
|
||||||
export interface NodeDesignQuery {
|
export interface NodeDesignQuery extends BaseQuery{
|
||||||
nodeCode?: string;
|
nodeCode?: string;
|
||||||
nodeName?: string;
|
nodeName?: string;
|
||||||
pageSize?: number;
|
|
||||||
current?: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页响应接口
|
// 分页响应接口
|
||||||
export interface NodeDesignResponse {
|
export interface NodeDesignResponse extends BaseResponse{
|
||||||
total: number;
|
|
||||||
list: NodeDesignData[];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,94 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
||||||
import { message } from 'antd';
|
|
||||||
|
|
||||||
interface Response<T = any> {
|
|
||||||
code: number;
|
|
||||||
message: string;
|
|
||||||
data: T;
|
|
||||||
success: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Http {
|
|
||||||
private instance: AxiosInstance;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.instance = axios.create({
|
|
||||||
baseURL: import.meta.env.VITE_API_URL,
|
|
||||||
timeout: 10000,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setupInterceptors();
|
|
||||||
}
|
|
||||||
|
|
||||||
private setupInterceptors() {
|
|
||||||
// 请求拦截器
|
|
||||||
this.instance.interceptors.request.use(
|
|
||||||
(config) => {
|
|
||||||
const token = localStorage.getItem('token');
|
|
||||||
if (token) {
|
|
||||||
config.headers.Authorization = `Bearer ${token}`;
|
|
||||||
}
|
|
||||||
return config;
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 响应拦截器
|
|
||||||
this.instance.interceptors.response.use(
|
|
||||||
(response: AxiosResponse<Response>) => {
|
|
||||||
const { data: res } = response;
|
|
||||||
if (res.success) {
|
|
||||||
return res.data;
|
|
||||||
}
|
|
||||||
message.error(res.message);
|
|
||||||
return Promise.reject(new Error(res.message));
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
if (error.response?.status === 401) {
|
|
||||||
// 处理未授权
|
|
||||||
localStorage.removeItem('token');
|
|
||||||
window.location.href = '/login';
|
|
||||||
}
|
|
||||||
message.error(error.response?.data?.message || '网络错误');
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get<T = any>(url: string, config?: AxiosRequestConfig) {
|
|
||||||
return this.instance.get<Response<T>, T>(url, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig) {
|
|
||||||
return this.instance.post<Response<T>, T>(url, data, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig) {
|
|
||||||
return this.instance.put<Response<T>, T>(url, data, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete<T = any>(url: string, config?: AxiosRequestConfig) {
|
|
||||||
return this.instance.delete<Response<T>, T>(url, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
download(url: string, filename?: string, config?: AxiosRequestConfig) {
|
|
||||||
return this.instance
|
|
||||||
.get(url, { ...config, responseType: 'blob' })
|
|
||||||
.then((response) => {
|
|
||||||
const blob = new Blob([response]);
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = window.URL.createObjectURL(blob);
|
|
||||||
link.download = filename || 'download';
|
|
||||||
link.click();
|
|
||||||
window.URL.revokeObjectURL(link.href);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const http = new Http();
|
|
||||||
Loading…
Reference in New Issue
Block a user