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 = {
|
const MockAPI = {
|
||||||
// 数据归集接口
|
// 数据归集接口
|
||||||
queryTasksUsingGet: "/data-collection/tasks", // 获取数据源任务列表
|
queryTasksUsingGet: "/data-collection/tasks", // 获取数据源任务列表
|
||||||
createTaskUsingPost: "/data-collection/tasks/create", // 创建数据源任务
|
createTaskUsingPost: "/data-collection/tasks", // 创建数据源任务
|
||||||
queryTaskByIdUsingGet: "/data-collection/tasks/:id", // 根据ID获取数据源任务详情
|
queryTaskByIdUsingGet: "/data-collection/tasks/:id", // 根据ID获取数据源任务详情
|
||||||
updateTaskByIdUsingPut: "/data-collection/tasks/:id", // 更新数据源任务
|
updateTaskByIdUsingPut: "/data-collection/tasks/:id", // 更新数据源任务
|
||||||
queryDataXTemplatesUsingGet: "/data-collection/templates", // 获取DataX数据源模板列表
|
queryDataXTemplatesUsingGet: "/data-collection/templates", // 获取DataX数据源模板列表
|
||||||
|
|||||||
@@ -4,19 +4,14 @@ import { Link, useNavigate } from "react-router";
|
|||||||
import { ArrowLeft } from "lucide-react";
|
import { ArrowLeft } from "lucide-react";
|
||||||
import { createTaskUsingPost } from "../collection.apis";
|
import { createTaskUsingPost } from "../collection.apis";
|
||||||
import SimpleCronScheduler from "@/pages/DataCollection/Create/SimpleCronScheduler";
|
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;
|
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 = [
|
const defaultTemplates = [
|
||||||
{
|
{
|
||||||
id: "nas",
|
id: "nas",
|
||||||
@@ -47,6 +42,8 @@ const defaultTemplates = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const syncModeOptions = Object.values(SyncModeMap);
|
||||||
|
|
||||||
enum TemplateType {
|
enum TemplateType {
|
||||||
NAS = "nas",
|
NAS = "nas",
|
||||||
OBS = "obs",
|
OBS = "obs",
|
||||||
@@ -64,15 +61,24 @@ export default function CollectionTaskCreate() {
|
|||||||
const [selectedTemplate, setSelectedTemplate] = useState("nas");
|
const [selectedTemplate, setSelectedTemplate] = useState("nas");
|
||||||
const [customConfig, setCustomConfig] = useState("");
|
const [customConfig, setCustomConfig] = useState("");
|
||||||
|
|
||||||
const [scheduleConfig, setScheduleConfig] = useState<ScheduleConfig>({
|
const [newTask, setNewTask] = useState({
|
||||||
type: "immediate",
|
name: "",
|
||||||
|
description: "",
|
||||||
|
syncMode: SyncMode.ONCE,
|
||||||
|
cronExpression: "",
|
||||||
maxRetries: 10,
|
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 [isCreateDataset, setIsCreateDataset] = useState(false);
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
const formData = await form.validateFields();
|
const formData = await form.validateFields();
|
||||||
if (templateType === "default" && !selectedTemplate) {
|
if (templateType === "default" && !selectedTemplate) {
|
||||||
window.alert("请选择默认模板");
|
window.alert("请选择默认模板");
|
||||||
@@ -83,17 +89,12 @@ export default function CollectionTaskCreate() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Create task logic here
|
// Create task logic here
|
||||||
const params = {
|
await createTaskUsingPost(newTask);
|
||||||
...formData,
|
|
||||||
templateType,
|
|
||||||
selectedTemplate: templateType === "default" ? selectedTemplate : null,
|
|
||||||
customConfig: templateType === "custom" ? customConfig : null,
|
|
||||||
scheduleConfig,
|
|
||||||
};
|
|
||||||
console.log("Creating task:", params);
|
|
||||||
await createTaskUsingPost(params);
|
|
||||||
message.success("任务创建成功");
|
message.success("任务创建成功");
|
||||||
navigate("/data/collection");
|
navigate("/data/collection");
|
||||||
|
} catch (error) {
|
||||||
|
message.error(`${error?.data?.message}:${error?.data?.data}`);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -114,17 +115,16 @@ export default function CollectionTaskCreate() {
|
|||||||
<Form
|
<Form
|
||||||
form={form}
|
form={form}
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
initialValues={scheduleConfig}
|
initialValues={newTask}
|
||||||
onValuesChange={(_, allValues) => {
|
onValuesChange={(_, allValues) => {
|
||||||
// 文件格式变化时重置模板选择
|
setNewTask({ ...newTask, ...allValues });
|
||||||
if (_.fileFormat !== undefined) setSelectedTemplate("");
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* 基本信息 */}
|
{/* 基本信息 */}
|
||||||
<h2 className="font-medium text-gray-900 text-lg mb-2">基本信息</h2>
|
<h2 className="font-medium text-gray-900 text-lg mb-2">基本信息</h2>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="任务名称"
|
label="名称"
|
||||||
name="name"
|
name="name"
|
||||||
rules={[{ required: true, message: "请输入任务名称" }]}
|
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 className="font-medium text-gray-900 pt-6 mb-2 text-lg">
|
||||||
同步配置
|
同步配置
|
||||||
</h2>
|
</h2>
|
||||||
<Form.Item label="同步方式">
|
<Form.Item name="syncMode" label="同步方式">
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
value={scheduleConfig.type}
|
value={newTask.syncMode}
|
||||||
onChange={(e) =>
|
options={syncModeOptions}
|
||||||
setScheduleConfig({
|
onChange={(e) => {
|
||||||
type: e.target.value as ScheduleConfig["type"],
|
const value = e.target.value;
|
||||||
})
|
setNewTask({
|
||||||
}
|
...newTask,
|
||||||
>
|
scheduleExpression:
|
||||||
<Radio value="immediate">立即同步</Radio>
|
value === SyncMode.SCHEDULED
|
||||||
<Radio value="scheduled">定时同步</Radio>
|
? scheduleExpression.cronExpression
|
||||||
</Radio.Group>
|
: "",
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
></Radio.Group>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{scheduleConfig.type === "scheduled" && (
|
{newTask.syncMode === SyncMode.SCHEDULED && (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label=""
|
label=""
|
||||||
name="cronExpression"
|
|
||||||
rules={[{ required: true, message: "请输入Cron表达式" }]}
|
rules={[{ required: true, message: "请输入Cron表达式" }]}
|
||||||
>
|
>
|
||||||
<SimpleCronScheduler
|
<SimpleCronScheduler
|
||||||
className="px-2 rounded"
|
className="px-2 rounded"
|
||||||
value={scheduleConfig.cronExpression || "* * * * *"}
|
value={scheduleExpression}
|
||||||
showYear
|
onChange={(value) => {
|
||||||
onChange={(value) =>
|
setScheduleExpression(value);
|
||||||
setScheduleConfig({ ...scheduleConfig, cron: value })
|
setNewTask({
|
||||||
}
|
...newTask,
|
||||||
|
scheduleExpression: value.cronExpression,
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -213,29 +218,25 @@ export default function CollectionTaskCreate() {
|
|||||||
{selectedTemplate === TemplateType.NAS && (
|
{selectedTemplate === TemplateType.NAS && (
|
||||||
<div className="grid grid-cols-2 gap-3 px-2 rounded">
|
<div className="grid grid-cols-2 gap-3 px-2 rounded">
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="nasPath"
|
name={["config", "ip"]}
|
||||||
rules={[{ required: true, message: "请输入NAS地址" }]}
|
rules={[{ required: true, message: "请输入NAS地址" }]}
|
||||||
label="NAS地址"
|
label="NAS地址"
|
||||||
>
|
>
|
||||||
<Input placeholder="192.168.1.100" />
|
<Input placeholder="192.168.1.100" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="sharePath"
|
name={["config", "path"]}
|
||||||
rules={[{ required: true, message: "请输入共享路径" }]}
|
rules={[{ required: true, message: "请输入共享路径" }]}
|
||||||
label="共享路径"
|
label="共享路径"
|
||||||
>
|
>
|
||||||
<Input placeholder="/share/importConfig" />
|
<Input placeholder="/share/importConfig" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="fileList"
|
name={["config", "files"]}
|
||||||
label="文件列表"
|
label="文件列表"
|
||||||
className="col-span-2"
|
className="col-span-2"
|
||||||
>
|
>
|
||||||
<Select
|
<Select placeholder="请选择文件列表" mode="tags" />
|
||||||
placeholder="请选择文件列表"
|
|
||||||
mode="tags"
|
|
||||||
multiple
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -309,7 +310,19 @@ export default function CollectionTaskCreate() {
|
|||||||
>
|
>
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
value={isCreateDataset}
|
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={true}>是</Radio>
|
||||||
<Radio value={false}>否</Radio>
|
<Radio value={false}>否</Radio>
|
||||||
@@ -319,10 +332,40 @@ export default function CollectionTaskCreate() {
|
|||||||
<>
|
<>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="数据集名称"
|
label="数据集名称"
|
||||||
name="datasetName"
|
name={["dataset", "name"]}
|
||||||
rules={[{ required: true, message: "请输入数据集名称" }]}
|
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>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ const SimpleCronScheduler: React.FC<SimpleCronSchedulerProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Space direction="vertical" className={`w-full ${className || ""}`}>
|
<Space direction="vertical" className={`w-full ${className || ""}`}>
|
||||||
{/* 执行周期选择 */}
|
{/* 执行周期选择 */}
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<Form.Item label="执行周期" required>
|
<Form.Item label="执行周期" required>
|
||||||
<Select value={config.type} onChange={handleTypeChange}>
|
<Select value={config.type} onChange={handleTypeChange}>
|
||||||
<Select.Option value="once">仅执行一次</Select.Option>
|
<Select.Option value="once">仅执行一次</Select.Option>
|
||||||
@@ -139,32 +140,6 @@ const SimpleCronScheduler: React.FC<SimpleCronSchedulerProps> = ({
|
|||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
{/* 时间选择 */}
|
|
||||||
<Form.Item label="执行时间" required>
|
|
||||||
<Space wrap>
|
|
||||||
<TimePicker
|
|
||||||
format="HH:mm"
|
|
||||||
value={config.time ? dayjs(config.time, "HH:mm") : null}
|
|
||||||
onChange={handleTimeChange}
|
|
||||||
placeholder="选择时间"
|
|
||||||
/>
|
|
||||||
<Space wrap className="mt-2">
|
|
||||||
{commonTimePresets.map((preset) => (
|
|
||||||
<Button
|
|
||||||
key={preset.value}
|
|
||||||
size="small"
|
|
||||||
className={
|
|
||||||
config.time === preset.value ? "ant-btn-primary" : ""
|
|
||||||
}
|
|
||||||
onClick={() => handleTimePreset(preset.value)}
|
|
||||||
>
|
|
||||||
{preset.label}
|
|
||||||
</Button>
|
|
||||||
))}
|
|
||||||
</Space>
|
|
||||||
</Space>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
{/* 周几选择 */}
|
{/* 周几选择 */}
|
||||||
{config.type === "weekly" && (
|
{config.type === "weekly" && (
|
||||||
<Form.Item label="执行日期" required>
|
<Form.Item label="执行日期" required>
|
||||||
@@ -190,6 +165,33 @@ const SimpleCronScheduler: React.FC<SimpleCronSchedulerProps> = ({
|
|||||||
></Select>
|
></Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 时间选择 */}
|
||||||
|
<Form.Item label="执行时间" required>
|
||||||
|
<Space wrap>
|
||||||
|
<TimePicker
|
||||||
|
format="HH:mm"
|
||||||
|
value={config.time ? dayjs(config.time, "HH:mm") : null}
|
||||||
|
onChange={handleTimeChange}
|
||||||
|
placeholder="选择时间"
|
||||||
|
/>
|
||||||
|
<Space wrap className="mt-2">
|
||||||
|
{commonTimePresets.map((preset) => (
|
||||||
|
<Button
|
||||||
|
key={preset.value}
|
||||||
|
size="small"
|
||||||
|
className={
|
||||||
|
config.time === preset.value ? "ant-btn-primary" : ""
|
||||||
|
}
|
||||||
|
onClick={() => handleTimePreset(preset.value)}
|
||||||
|
>
|
||||||
|
{preset.label}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</Space>
|
||||||
|
</Space>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
{/* Cron 表达式预览 */}
|
{/* Cron 表达式预览 */}
|
||||||
{/* <div className="mt-4 pt-4 border-t border-gray-200">
|
{/* <div className="mt-4 pt-4 border-t border-gray-200">
|
||||||
|
|||||||
@@ -4,14 +4,11 @@ import { PlusOutlined } from "@ant-design/icons";
|
|||||||
import TaskManagement from "./TaskManagement";
|
import TaskManagement from "./TaskManagement";
|
||||||
import ExecutionLog from "./ExecutionLog";
|
import ExecutionLog from "./ExecutionLog";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
|
|
||||||
|
|
||||||
export default function DataCollection() {
|
export default function DataCollection() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [activeTab, setActiveTab] = useState("task-management");
|
const [activeTab, setActiveTab] = useState("task-management");
|
||||||
|
|
||||||
// return <DevelopmentInProgress showTime="2025.10.30" />;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gap-4 h-full flex flex-col">
|
<div className="gap-4 h-full flex flex-col">
|
||||||
<div className="flex justify-between items-end">
|
<div className="flex justify-between items-end">
|
||||||
@@ -32,7 +29,7 @@ export default function DataCollection() {
|
|||||||
activeKey={activeTab}
|
activeKey={activeTab}
|
||||||
items={[
|
items={[
|
||||||
{ label: "任务管理", key: "task-management" },
|
{ label: "任务管理", key: "task-management" },
|
||||||
{ label: "执行日志", key: "execution-log" },
|
// { label: "执行日志", key: "execution-log" },
|
||||||
]}
|
]}
|
||||||
onChange={(tab) => {
|
onChange={(tab) => {
|
||||||
setActiveTab(tab);
|
setActiveTab(tab);
|
||||||
|
|||||||
@@ -87,15 +87,15 @@ export default function TaskManagement() {
|
|||||||
onClick: () => handleStopTask(record.id),
|
onClick: () => handleStopTask(record.id),
|
||||||
};
|
};
|
||||||
const items = [
|
const items = [
|
||||||
isStopped ? startButton : stopButton,
|
// isStopped ? startButton : stopButton,
|
||||||
{
|
// {
|
||||||
key: "edit",
|
// key: "edit",
|
||||||
label: "编辑",
|
// label: "编辑",
|
||||||
icon: <EditOutlined />,
|
// icon: <EditOutlined />,
|
||||||
onClick: () => {
|
// onClick: () => {
|
||||||
showEditTaskModal(record);
|
// showEditTaskModal(record);
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
key: "delete",
|
key: "delete",
|
||||||
label: "删除",
|
label: "删除",
|
||||||
@@ -119,11 +119,15 @@ export default function TaskManagement() {
|
|||||||
dataIndex: "name",
|
dataIndex: "name",
|
||||||
key: "name",
|
key: "name",
|
||||||
fixed: "left",
|
fixed: "left",
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "状态",
|
title: "状态",
|
||||||
dataIndex: "status",
|
dataIndex: "status",
|
||||||
key: "status",
|
key: "status",
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
render: (status: string) => (
|
render: (status: string) => (
|
||||||
<Badge text={status.label} color={status.color} />
|
<Badge text={status.label} color={status.color} />
|
||||||
),
|
),
|
||||||
@@ -132,28 +136,37 @@ export default function TaskManagement() {
|
|||||||
title: "同步方式",
|
title: "同步方式",
|
||||||
dataIndex: "syncMode",
|
dataIndex: "syncMode",
|
||||||
key: "syncMode",
|
key: "syncMode",
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
render: (text: string) => <span>{SyncModeMap[text]?.label}</span>,
|
render: (text: string) => <span>{SyncModeMap[text]?.label}</span>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "创建时间",
|
title: "创建时间",
|
||||||
dataIndex: "createdAt",
|
dataIndex: "createdAt",
|
||||||
key: "createdAt",
|
key: "createdAt",
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "更新时间",
|
title: "更新时间",
|
||||||
dataIndex: "updatedAt",
|
dataIndex: "updatedAt",
|
||||||
key: "updatedAt",
|
key: "updatedAt",
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "最近执行ID",
|
title: "最近执行ID",
|
||||||
dataIndex: "lastExecutionId",
|
dataIndex: "lastExecutionId",
|
||||||
key: "lastExecutionId",
|
key: "lastExecutionId",
|
||||||
|
width: 150,
|
||||||
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "描述",
|
title: "描述",
|
||||||
dataIndex: "description",
|
dataIndex: "description",
|
||||||
key: "description",
|
key: "description",
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
|
width: 200,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
@@ -215,6 +228,7 @@ export default function TaskManagement() {
|
|||||||
filters: {},
|
filters: {},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
onReload={fetchData}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Tasks Table */}
|
{/* Tasks Table */}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import TaskUpload from "./TaskUpload";
|
|||||||
const AsiderAndHeaderLayout = () => {
|
const AsiderAndHeaderLayout = () => {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [activeItem, setActiveItem] = useState<string>("management");
|
const [activeItem, setActiveItem] = useState<string>("");
|
||||||
const [sidebarOpen, setSidebarOpen] = useState(true);
|
const [sidebarOpen, setSidebarOpen] = useState(true);
|
||||||
const [taskCenterVisible, setTaskCenterVisible] = useState(false);
|
const [taskCenterVisible, setTaskCenterVisible] = useState(false);
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@ const AsiderAndHeaderLayout = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log(pathname);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -134,7 +135,15 @@ const AsiderAndHeaderLayout = () => {
|
|||||||
任务中心
|
任务中心
|
||||||
</Button>
|
</Button>
|
||||||
</Popover>
|
</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>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -156,7 +165,15 @@ const AsiderAndHeaderLayout = () => {
|
|||||||
></Button>
|
></Button>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</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 />
|
<SettingOutlined />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ export default function EnvironmentAccess() {
|
|||||||
} = useFetchData(queryModelListUsingGet);
|
} = useFetchData(queryModelListUsingGet);
|
||||||
|
|
||||||
const handleAddModel = async () => {
|
const handleAddModel = async () => {
|
||||||
|
try {
|
||||||
const formValues = await form.validateFields();
|
const formValues = await form.validateFields();
|
||||||
const fn = isEditMode
|
const fn = isEditMode
|
||||||
? () => updateModelByIdUsingPut(newModel.id, formValues)
|
? () => updateModelByIdUsingPut(newModel.id, formValues)
|
||||||
@@ -87,6 +88,9 @@ export default function EnvironmentAccess() {
|
|||||||
setShowModelDialog(false);
|
setShowModelDialog(false);
|
||||||
fetchData();
|
fetchData();
|
||||||
message.success("模型添加成功");
|
message.success("模型添加成功");
|
||||||
|
} catch (error) {
|
||||||
|
message.error(`${error?.data?.message}:${error?.data?.data}`);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const [providerOptions, setProviderOptions] = useState<ProviderI[]>([]);
|
const [providerOptions, setProviderOptions] = useState<ProviderI[]>([]);
|
||||||
|
|
||||||
@@ -303,14 +307,6 @@ export default function EnvironmentAccess() {
|
|||||||
}}
|
}}
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
>
|
>
|
||||||
<Form.Item
|
|
||||||
name="modelName"
|
|
||||||
label="模型名称"
|
|
||||||
required
|
|
||||||
rules={[{ required: true, message: "请输入模型名称" }]}
|
|
||||||
>
|
|
||||||
<Input placeholder="输入模型名称" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="provider"
|
name="provider"
|
||||||
label="服务提供商"
|
label="服务提供商"
|
||||||
@@ -342,6 +338,15 @@ export default function EnvironmentAccess() {
|
|||||||
>
|
>
|
||||||
<Input placeholder="输入接口地址,如:https://api.openai.com" />
|
<Input placeholder="输入接口地址,如:https://api.openai.com" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="modelName"
|
||||||
|
label="模型名称"
|
||||||
|
required
|
||||||
|
tooltip="请输入模型名称"
|
||||||
|
rules={[{ required: true, message: "请输入模型名称" }]}
|
||||||
|
>
|
||||||
|
<Input placeholder="输入模型名称" />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="apiKey"
|
name="apiKey"
|
||||||
label="API密钥"
|
label="API密钥"
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ class Request {
|
|||||||
try {
|
try {
|
||||||
const errorData = await processedResponse.json();
|
const errorData = await processedResponse.json();
|
||||||
error.data = errorData;
|
error.data = errorData;
|
||||||
// message.error(`请求失败,错误信息: ${processedResponse.statusText}`);
|
// message.error(`请求失败,错误信息: ${errorData.message}`);
|
||||||
} catch {
|
} catch {
|
||||||
// 忽略JSON解析错误
|
// 忽略JSON解析错误
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user