You've already forked DataMate
fix: data collection create task page (#33)
* feat: Update site name to DataMate and refine text for AI data processing * feat: Refactor settings page and implement model access functionality - Created a new ModelAccess component for managing model configurations. - Removed the old Settings component and replaced it with a new SettingsPage component that integrates ModelAccess, SystemConfig, and WebhookConfig. - Added SystemConfig component for managing system settings. - Implemented WebhookConfig component for managing webhook configurations. - Updated API functions for model management in settings.apis.ts. - Adjusted routing to point to the new SettingsPage component. * feat: Implement Data Collection Page with Task Management and Execution Log - Created DataCollectionPage component to manage data collection tasks. - Added TaskManagement and ExecutionLog components for task handling and logging. - Integrated task operations including start, stop, edit, and delete functionalities. - Implemented filtering and searching capabilities in task management. - Introduced SimpleCronScheduler for scheduling tasks with cron expressions. - Updated CreateTask component to utilize new scheduling and template features. - Enhanced BasicInformation component to conditionally render fields based on visibility settings. - Refactored ImportConfiguration component to remove NAS import section. * feat: Update task creation API endpoint and enhance task creation form with new fields and validation
This commit is contained in:
@@ -3,7 +3,7 @@ const { addMockPrefix } = require("./mock-core/util.cjs");
|
||||
const MockAPI = {
|
||||
// 数据归集接口
|
||||
queryTasksUsingGet: "/data-collection/tasks", // 获取数据源任务列表
|
||||
createTaskUsingPost: "/data-collection/tasks/create", // 创建数据源任务
|
||||
createTaskUsingPost: "/data-collection/tasks", // 创建数据源任务
|
||||
queryTaskByIdUsingGet: "/data-collection/tasks/:id", // 根据ID获取数据源任务详情
|
||||
updateTaskByIdUsingPut: "/data-collection/tasks/:id", // 更新数据源任务
|
||||
queryDataXTemplatesUsingGet: "/data-collection/templates", // 获取DataX数据源模板列表
|
||||
|
||||
@@ -4,19 +4,14 @@ import { Link, useNavigate } from "react-router";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import { createTaskUsingPost } from "../collection.apis";
|
||||
import SimpleCronScheduler from "@/pages/DataCollection/Create/SimpleCronScheduler";
|
||||
import RadioCard from "@/components/RadioCard";
|
||||
import { datasetTypes } from "@/pages/DataManagement/dataset.const";
|
||||
import { SyncModeMap } from "../collection.const";
|
||||
import { SyncMode } from "../collection.model";
|
||||
import { DatasetSubType } from "@/pages/DataManagement/dataset.model";
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
interface ScheduleConfig {
|
||||
type: "immediate" | "scheduled";
|
||||
scheduleType?: "day" | "week" | "month" | "custom";
|
||||
time?: string;
|
||||
dayOfWeek?: string;
|
||||
dayOfMonth?: string;
|
||||
cronExpression?: string;
|
||||
maxRetries?: number;
|
||||
}
|
||||
|
||||
const defaultTemplates = [
|
||||
{
|
||||
id: "nas",
|
||||
@@ -47,6 +42,8 @@ const defaultTemplates = [
|
||||
},
|
||||
];
|
||||
|
||||
const syncModeOptions = Object.values(SyncModeMap);
|
||||
|
||||
enum TemplateType {
|
||||
NAS = "nas",
|
||||
OBS = "obs",
|
||||
@@ -64,36 +61,40 @@ export default function CollectionTaskCreate() {
|
||||
const [selectedTemplate, setSelectedTemplate] = useState("nas");
|
||||
const [customConfig, setCustomConfig] = useState("");
|
||||
|
||||
const [scheduleConfig, setScheduleConfig] = useState<ScheduleConfig>({
|
||||
type: "immediate",
|
||||
const [newTask, setNewTask] = useState({
|
||||
name: "",
|
||||
description: "",
|
||||
syncMode: SyncMode.ONCE,
|
||||
cronExpression: "",
|
||||
maxRetries: 10,
|
||||
scheduleType: "daily",
|
||||
dataset: {},
|
||||
});
|
||||
const [scheduleExpression, setScheduleExpression] = useState({
|
||||
type: SyncMode.SCHEDULED,
|
||||
time: "00:00",
|
||||
cronExpression: "0 0 0 * * ?",
|
||||
});
|
||||
|
||||
const [isCreateDataset, setIsCreateDataset] = useState(false);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const formData = await form.validateFields();
|
||||
if (templateType === "default" && !selectedTemplate) {
|
||||
window.alert("请选择默认模板");
|
||||
return;
|
||||
try {
|
||||
const formData = await form.validateFields();
|
||||
if (templateType === "default" && !selectedTemplate) {
|
||||
window.alert("请选择默认模板");
|
||||
return;
|
||||
}
|
||||
if (templateType === "custom" && !customConfig.trim()) {
|
||||
window.alert("请填写自定义配置");
|
||||
return;
|
||||
}
|
||||
// Create task logic here
|
||||
await createTaskUsingPost(newTask);
|
||||
message.success("任务创建成功");
|
||||
navigate("/data/collection");
|
||||
} catch (error) {
|
||||
message.error(`${error?.data?.message}:${error?.data?.data}`);
|
||||
}
|
||||
if (templateType === "custom" && !customConfig.trim()) {
|
||||
window.alert("请填写自定义配置");
|
||||
return;
|
||||
}
|
||||
// Create task logic here
|
||||
const params = {
|
||||
...formData,
|
||||
templateType,
|
||||
selectedTemplate: templateType === "default" ? selectedTemplate : null,
|
||||
customConfig: templateType === "custom" ? customConfig : null,
|
||||
scheduleConfig,
|
||||
};
|
||||
console.log("Creating task:", params);
|
||||
await createTaskUsingPost(params);
|
||||
message.success("任务创建成功");
|
||||
navigate("/data/collection");
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -114,17 +115,16 @@ export default function CollectionTaskCreate() {
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
initialValues={scheduleConfig}
|
||||
initialValues={newTask}
|
||||
onValuesChange={(_, allValues) => {
|
||||
// 文件格式变化时重置模板选择
|
||||
if (_.fileFormat !== undefined) setSelectedTemplate("");
|
||||
setNewTask({ ...newTask, ...allValues });
|
||||
}}
|
||||
>
|
||||
{/* 基本信息 */}
|
||||
<h2 className="font-medium text-gray-900 text-lg mb-2">基本信息</h2>
|
||||
|
||||
<Form.Item
|
||||
label="任务名称"
|
||||
label="名称"
|
||||
name="name"
|
||||
rules={[{ required: true, message: "请输入任务名称" }]}
|
||||
>
|
||||
@@ -138,32 +138,37 @@ export default function CollectionTaskCreate() {
|
||||
<h2 className="font-medium text-gray-900 pt-6 mb-2 text-lg">
|
||||
同步配置
|
||||
</h2>
|
||||
<Form.Item label="同步方式">
|
||||
<Form.Item name="syncMode" label="同步方式">
|
||||
<Radio.Group
|
||||
value={scheduleConfig.type}
|
||||
onChange={(e) =>
|
||||
setScheduleConfig({
|
||||
type: e.target.value as ScheduleConfig["type"],
|
||||
})
|
||||
}
|
||||
>
|
||||
<Radio value="immediate">立即同步</Radio>
|
||||
<Radio value="scheduled">定时同步</Radio>
|
||||
</Radio.Group>
|
||||
value={newTask.syncMode}
|
||||
options={syncModeOptions}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
setNewTask({
|
||||
...newTask,
|
||||
scheduleExpression:
|
||||
value === SyncMode.SCHEDULED
|
||||
? scheduleExpression.cronExpression
|
||||
: "",
|
||||
});
|
||||
}}
|
||||
></Radio.Group>
|
||||
</Form.Item>
|
||||
{scheduleConfig.type === "scheduled" && (
|
||||
{newTask.syncMode === SyncMode.SCHEDULED && (
|
||||
<Form.Item
|
||||
label=""
|
||||
name="cronExpression"
|
||||
rules={[{ required: true, message: "请输入Cron表达式" }]}
|
||||
>
|
||||
<SimpleCronScheduler
|
||||
className="px-2 rounded"
|
||||
value={scheduleConfig.cronExpression || "* * * * *"}
|
||||
showYear
|
||||
onChange={(value) =>
|
||||
setScheduleConfig({ ...scheduleConfig, cron: value })
|
||||
}
|
||||
value={scheduleExpression}
|
||||
onChange={(value) => {
|
||||
setScheduleExpression(value);
|
||||
setNewTask({
|
||||
...newTask,
|
||||
scheduleExpression: value.cronExpression,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
)}
|
||||
@@ -213,29 +218,25 @@ export default function CollectionTaskCreate() {
|
||||
{selectedTemplate === TemplateType.NAS && (
|
||||
<div className="grid grid-cols-2 gap-3 px-2 rounded">
|
||||
<Form.Item
|
||||
name="nasPath"
|
||||
name={["config", "ip"]}
|
||||
rules={[{ required: true, message: "请输入NAS地址" }]}
|
||||
label="NAS地址"
|
||||
>
|
||||
<Input placeholder="192.168.1.100" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="sharePath"
|
||||
name={["config", "path"]}
|
||||
rules={[{ required: true, message: "请输入共享路径" }]}
|
||||
label="共享路径"
|
||||
>
|
||||
<Input placeholder="/share/importConfig" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="fileList"
|
||||
name={["config", "files"]}
|
||||
label="文件列表"
|
||||
className="col-span-2"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择文件列表"
|
||||
mode="tags"
|
||||
multiple
|
||||
/>
|
||||
<Select placeholder="请选择文件列表" mode="tags" />
|
||||
</Form.Item>
|
||||
</div>
|
||||
)}
|
||||
@@ -309,7 +310,19 @@ export default function CollectionTaskCreate() {
|
||||
>
|
||||
<Radio.Group
|
||||
value={isCreateDataset}
|
||||
onChange={(e) => setIsCreateDataset(e.target.value)}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (value === false) {
|
||||
form.setFieldsValue({
|
||||
dataset: {},
|
||||
});
|
||||
setNewTask({
|
||||
...newTask,
|
||||
dataset: {},
|
||||
});
|
||||
}
|
||||
setIsCreateDataset(e.target.value);
|
||||
}}
|
||||
>
|
||||
<Radio value={true}>是</Radio>
|
||||
<Radio value={false}>否</Radio>
|
||||
@@ -319,10 +332,40 @@ export default function CollectionTaskCreate() {
|
||||
<>
|
||||
<Form.Item
|
||||
label="数据集名称"
|
||||
name="datasetName"
|
||||
rules={[{ required: true, message: "请输入数据集名称" }]}
|
||||
name={["dataset", "name"]}
|
||||
required
|
||||
>
|
||||
<Input placeholder="请输入数据集名称" />
|
||||
<Input
|
||||
placeholder="输入数据集名称"
|
||||
onChange={(e) => {
|
||||
setNewTask({
|
||||
...newTask,
|
||||
dataset: {
|
||||
...newTask.dataset,
|
||||
name: e.target.value,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="数据集类型"
|
||||
name={["dataset", "datasetType"]}
|
||||
rules={[{ required: true, message: "请选择数据集类型" }]}
|
||||
>
|
||||
<RadioCard
|
||||
options={datasetTypes}
|
||||
value={newTask.dataset.datasetType}
|
||||
onChange={(type) => {
|
||||
form.setFieldValue(["dataset", "datasetType"], type);
|
||||
setNewTask({
|
||||
...newTask,
|
||||
dataset: {
|
||||
datasetType: type as DatasetSubType,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -130,14 +130,42 @@ const SimpleCronScheduler: React.FC<SimpleCronSchedulerProps> = ({
|
||||
return (
|
||||
<Space direction="vertical" className={`w-full ${className || ""}`}>
|
||||
{/* 执行周期选择 */}
|
||||
<Form.Item label="执行周期" required>
|
||||
<Select value={config.type} onChange={handleTypeChange}>
|
||||
<Select.Option value="once">仅执行一次</Select.Option>
|
||||
<Select.Option value="daily">每天执行</Select.Option>
|
||||
<Select.Option value="weekly">每周执行</Select.Option>
|
||||
<Select.Option value="monthly">每月执行</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<Form.Item label="执行周期" required>
|
||||
<Select value={config.type} onChange={handleTypeChange}>
|
||||
<Select.Option value="once">仅执行一次</Select.Option>
|
||||
<Select.Option value="daily">每天执行</Select.Option>
|
||||
<Select.Option value="weekly">每周执行</Select.Option>
|
||||
<Select.Option value="monthly">每月执行</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
{/* 周几选择 */}
|
||||
{config.type === "weekly" && (
|
||||
<Form.Item label="执行日期" required>
|
||||
<Select
|
||||
className="w-32"
|
||||
value={config.weekDay}
|
||||
onChange={(weekDay) => updateConfig({ weekDay })}
|
||||
placeholder="选择周几"
|
||||
options={weekDayOptions}
|
||||
></Select>
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* 月份日期选择 */}
|
||||
{config.type === "monthly" && (
|
||||
<Form.Item label="执行日期" required>
|
||||
<Select
|
||||
className="w-32"
|
||||
value={config.monthDay}
|
||||
onChange={(monthDay) => updateConfig({ monthDay })}
|
||||
placeholder="选择日期"
|
||||
options={monthDayOptions}
|
||||
></Select>
|
||||
</Form.Item>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 时间选择 */}
|
||||
<Form.Item label="执行时间" required>
|
||||
@@ -165,32 +193,6 @@ const SimpleCronScheduler: React.FC<SimpleCronSchedulerProps> = ({
|
||||
</Space>
|
||||
</Form.Item>
|
||||
|
||||
{/* 周几选择 */}
|
||||
{config.type === "weekly" && (
|
||||
<Form.Item label="执行日期" required>
|
||||
<Select
|
||||
className="w-32"
|
||||
value={config.weekDay}
|
||||
onChange={(weekDay) => updateConfig({ weekDay })}
|
||||
placeholder="选择周几"
|
||||
options={weekDayOptions}
|
||||
></Select>
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* 月份日期选择 */}
|
||||
{config.type === "monthly" && (
|
||||
<Form.Item label="执行日期" required>
|
||||
<Select
|
||||
className="w-32"
|
||||
value={config.monthDay}
|
||||
onChange={(monthDay) => updateConfig({ monthDay })}
|
||||
placeholder="选择日期"
|
||||
options={monthDayOptions}
|
||||
></Select>
|
||||
</Form.Item>
|
||||
)}
|
||||
|
||||
{/* Cron 表达式预览 */}
|
||||
{/* <div className="mt-4 pt-4 border-t border-gray-200">
|
||||
<Text>生成的 Cron 表达式</Text>
|
||||
|
||||
@@ -4,14 +4,11 @@ import { PlusOutlined } from "@ant-design/icons";
|
||||
import TaskManagement from "./TaskManagement";
|
||||
import ExecutionLog from "./ExecutionLog";
|
||||
import { useNavigate } from "react-router";
|
||||
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
||||
|
||||
export default function DataCollection() {
|
||||
const navigate = useNavigate();
|
||||
const [activeTab, setActiveTab] = useState("task-management");
|
||||
|
||||
// return <DevelopmentInProgress showTime="2025.10.30" />;
|
||||
|
||||
return (
|
||||
<div className="gap-4 h-full flex flex-col">
|
||||
<div className="flex justify-between items-end">
|
||||
@@ -32,7 +29,7 @@ export default function DataCollection() {
|
||||
activeKey={activeTab}
|
||||
items={[
|
||||
{ label: "任务管理", key: "task-management" },
|
||||
{ label: "执行日志", key: "execution-log" },
|
||||
// { label: "执行日志", key: "execution-log" },
|
||||
]}
|
||||
onChange={(tab) => {
|
||||
setActiveTab(tab);
|
||||
|
||||
@@ -87,15 +87,15 @@ export default function TaskManagement() {
|
||||
onClick: () => handleStopTask(record.id),
|
||||
};
|
||||
const items = [
|
||||
isStopped ? startButton : stopButton,
|
||||
{
|
||||
key: "edit",
|
||||
label: "编辑",
|
||||
icon: <EditOutlined />,
|
||||
onClick: () => {
|
||||
showEditTaskModal(record);
|
||||
},
|
||||
},
|
||||
// isStopped ? startButton : stopButton,
|
||||
// {
|
||||
// key: "edit",
|
||||
// label: "编辑",
|
||||
// icon: <EditOutlined />,
|
||||
// onClick: () => {
|
||||
// showEditTaskModal(record);
|
||||
// },
|
||||
// },
|
||||
{
|
||||
key: "delete",
|
||||
label: "删除",
|
||||
@@ -119,11 +119,15 @@ export default function TaskManagement() {
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
fixed: "left",
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
dataIndex: "status",
|
||||
key: "status",
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
render: (status: string) => (
|
||||
<Badge text={status.label} color={status.color} />
|
||||
),
|
||||
@@ -132,28 +136,37 @@ export default function TaskManagement() {
|
||||
title: "同步方式",
|
||||
dataIndex: "syncMode",
|
||||
key: "syncMode",
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
render: (text: string) => <span>{SyncModeMap[text]?.label}</span>,
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
dataIndex: "createdAt",
|
||||
key: "createdAt",
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
dataIndex: "updatedAt",
|
||||
key: "updatedAt",
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "最近执行ID",
|
||||
dataIndex: "lastExecutionId",
|
||||
key: "lastExecutionId",
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "描述",
|
||||
dataIndex: "description",
|
||||
key: "description",
|
||||
ellipsis: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
@@ -215,6 +228,7 @@ export default function TaskManagement() {
|
||||
filters: {},
|
||||
}))
|
||||
}
|
||||
onReload={fetchData}
|
||||
/>
|
||||
|
||||
{/* Tasks Table */}
|
||||
|
||||
@@ -13,7 +13,7 @@ import TaskUpload from "./TaskUpload";
|
||||
const AsiderAndHeaderLayout = () => {
|
||||
const { pathname } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const [activeItem, setActiveItem] = useState<string>("management");
|
||||
const [activeItem, setActiveItem] = useState<string>("");
|
||||
const [sidebarOpen, setSidebarOpen] = useState(true);
|
||||
const [taskCenterVisible, setTaskCenterVisible] = useState(false);
|
||||
|
||||
@@ -33,6 +33,7 @@ const AsiderAndHeaderLayout = () => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log(pathname);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -134,7 +135,15 @@ const AsiderAndHeaderLayout = () => {
|
||||
任务中心
|
||||
</Button>
|
||||
</Popover>
|
||||
<Button block onClick={() => navigate("/data/settings")}>
|
||||
<Button
|
||||
block
|
||||
color={pathname === "/data/settings" ? "primary" : "default"}
|
||||
variant={pathname === "/data/settings" ? "filled" : "outlined"}
|
||||
onClick={() => {
|
||||
setActiveItem("");
|
||||
navigate("/data/settings");
|
||||
}}
|
||||
>
|
||||
设置
|
||||
</Button>
|
||||
</div>
|
||||
@@ -156,7 +165,15 @@ const AsiderAndHeaderLayout = () => {
|
||||
></Button>
|
||||
</Popover>
|
||||
</div>
|
||||
<Button block onClick={() => navigate("/data/settings")}>
|
||||
<Button
|
||||
block
|
||||
color={pathname === "/data/settings" ? "primary" : "default"}
|
||||
variant={pathname === "/data/settings" ? "filled" : "outlined"}
|
||||
onClick={() => {
|
||||
setActiveItem("");
|
||||
navigate("/data/settings");
|
||||
}}
|
||||
>
|
||||
<SettingOutlined />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -79,14 +79,18 @@ export default function EnvironmentAccess() {
|
||||
} = useFetchData(queryModelListUsingGet);
|
||||
|
||||
const handleAddModel = async () => {
|
||||
const formValues = await form.validateFields();
|
||||
const fn = isEditMode
|
||||
? () => updateModelByIdUsingPut(newModel.id, formValues)
|
||||
: () => createModelUsingPost(formValues);
|
||||
await fn();
|
||||
setShowModelDialog(false);
|
||||
fetchData();
|
||||
message.success("模型添加成功");
|
||||
try {
|
||||
const formValues = await form.validateFields();
|
||||
const fn = isEditMode
|
||||
? () => updateModelByIdUsingPut(newModel.id, formValues)
|
||||
: () => createModelUsingPost(formValues);
|
||||
await fn();
|
||||
setShowModelDialog(false);
|
||||
fetchData();
|
||||
message.success("模型添加成功");
|
||||
} catch (error) {
|
||||
message.error(`${error?.data?.message}:${error?.data?.data}`);
|
||||
}
|
||||
};
|
||||
const [providerOptions, setProviderOptions] = useState<ProviderI[]>([]);
|
||||
|
||||
@@ -303,14 +307,6 @@ export default function EnvironmentAccess() {
|
||||
}}
|
||||
layout="vertical"
|
||||
>
|
||||
<Form.Item
|
||||
name="modelName"
|
||||
label="模型名称"
|
||||
required
|
||||
rules={[{ required: true, message: "请输入模型名称" }]}
|
||||
>
|
||||
<Input placeholder="输入模型名称" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="provider"
|
||||
label="服务提供商"
|
||||
@@ -342,6 +338,15 @@ export default function EnvironmentAccess() {
|
||||
>
|
||||
<Input placeholder="输入接口地址,如:https://api.openai.com" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="modelName"
|
||||
label="模型名称"
|
||||
required
|
||||
tooltip="请输入模型名称"
|
||||
rules={[{ required: true, message: "请输入模型名称" }]}
|
||||
>
|
||||
<Input placeholder="输入模型名称" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="apiKey"
|
||||
label="API密钥"
|
||||
|
||||
@@ -201,7 +201,7 @@ class Request {
|
||||
try {
|
||||
const errorData = await processedResponse.json();
|
||||
error.data = errorData;
|
||||
// message.error(`请求失败,错误信息: ${processedResponse.statusText}`);
|
||||
// message.error(`请求失败,错误信息: ${errorData.message}`);
|
||||
} catch {
|
||||
// 忽略JSON解析错误
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user