Ver código fonte

添加了主动查询的按钮

ChenYu 7 meses atrás
pai
commit
73a76a81ec

+ 4 - 0
src/api/aiOrderV2.ts

@@ -79,3 +79,7 @@ export interface WorkflowTaskMessage {
 export function queryAiOrderV2Result(taskId: string) {
   return get<WorkflowTaskMessage>("/v2/ai/order/v2/queryResult", { taskId });
 }
+
+export function getAiOrderV2TaskLog(taskId: string) {
+  return get<string[]>("/v2/ai/order/v2/taskLog", { taskId });
+}

+ 9 - 1
src/i18n/locales/en.json

@@ -764,7 +764,15 @@
     "queryStatusFailed": "Failed",
     "queryStatusRunning": "Running",
     "queryStatusPending": "Pending",
-    "queryStatusProcessing": "Processing"
+    "queryStatusProcessing": "Processing",
+    "taskLog": "Task Log",
+    "taskLogTitle": "Task Log - {{taskId}}",
+    "taskLogLoading": "Fetching logs...",
+    "taskLogSuccess": "Logs fetched successfully",
+    "taskLogFailed": "Failed to fetch logs",
+    "taskLogNoTaskId": "No task ID for this order",
+    "taskLogEmpty": "No logs found",
+    "taskLogLines": "{{count}} lines"
   },
   "aiAlbum": {
     "title": "AI Albums",

+ 9 - 1
src/i18n/locales/zh.json

@@ -764,7 +764,15 @@
     "queryStatusFailed": "失败",
     "queryStatusRunning": "执行中",
     "queryStatusPending": "等待中",
-    "queryStatusProcessing": "处理中"
+    "queryStatusProcessing": "处理中",
+    "taskLog": "执行日志",
+    "taskLogTitle": "任务日志 - {{taskId}}",
+    "taskLogLoading": "正在查询日志...",
+    "taskLogSuccess": "日志查询成功",
+    "taskLogFailed": "日志查询失败",
+    "taskLogNoTaskId": "该订单没有任务ID",
+    "taskLogEmpty": "暂无日志",
+    "taskLogLines": "共 {{count}} 行"
   },
   "aiAlbum": {
     "title": "相册管理",

+ 74 - 1
src/pages/ai-order-v2/AiOrderV2Page.tsx

@@ -28,9 +28,10 @@ import {
   PlayCircleOutlined,
   MobileOutlined,
   CloudSyncOutlined,
+  FileTextOutlined,
 } from "@ant-design/icons";
 import type { AiOrderV2Item, AiOrderV2Params, WorkflowTaskMessage } from "@/api/aiOrderV2";
-import { getAiOrderV2List, getAiOrderV2Detail, queryAiOrderV2Result } from "@/api/aiOrderV2";
+import { getAiOrderV2List, getAiOrderV2Detail, queryAiOrderV2Result, getAiOrderV2TaskLog } from "@/api/aiOrderV2";
 
 const { Title } = Typography;
 
@@ -214,6 +215,11 @@ export function AiOrderV2Page() {
   const [queryResultData, setQueryResultData] = useState<WorkflowTaskMessage | null>(null);
   const [queryResultTaskId, setQueryResultTaskId] = useState<string>("");
 
+  const [taskLogOpen, setTaskLogOpen] = useState(false);
+  const [taskLogLoading, setTaskLogLoading] = useState(false);
+  const [taskLogData, setTaskLogData] = useState<string[]>([]);
+  const [taskLogTaskId, setTaskLogTaskId] = useState<string>("");
+
   const fetchData = useCallback(async () => {
     setLoading(true);
     try {
@@ -294,6 +300,27 @@ export function AiOrderV2Page() {
     }
   }
 
+  async function handleTaskLog(taskId?: string) {
+    if (!taskId) {
+      message.warning(t("aiOrderV2.taskLogNoTaskId"));
+      return;
+    }
+    setTaskLogOpen(true);
+    setTaskLogTaskId(taskId);
+    setTaskLogData([]);
+    setTaskLogLoading(true);
+    try {
+      const res = await getAiOrderV2TaskLog(taskId);
+      setTaskLogData(res ?? []);
+      message.success(t("aiOrderV2.taskLogSuccess"));
+    } catch {
+      message.error(t("aiOrderV2.taskLogFailed"));
+      setTaskLogData([]);
+    } finally {
+      setTaskLogLoading(false);
+    }
+  }
+
   const QUERY_STATUS_MAP: Record<string, { i18nKey: string; color: string }> = {
     successes: { i18nKey: "aiOrderV2.queryStatusSuccesses", color: "green" },
     failed: { i18nKey: "aiOrderV2.queryStatusFailed", color: "red" },
@@ -605,6 +632,15 @@ export function AiOrderV2Page() {
           >
             {t("aiOrderV2.queryResult")}
           </Button>
+          <Button
+            type="link"
+            size="small"
+            icon={<FileTextOutlined />}
+            onClick={() => handleTaskLog(r.taskId)}
+            disabled={!r.taskId}
+          >
+            {t("aiOrderV2.taskLog")}
+          </Button>
         </div>
       ),
     },
@@ -970,6 +1006,43 @@ export function AiOrderV2Page() {
           <span className="text-gray-300">—</span>
         )}
       </Modal>
+
+      <Modal
+        title={t("aiOrderV2.taskLogTitle", { taskId: taskLogTaskId })}
+        open={taskLogOpen}
+        onCancel={() => setTaskLogOpen(false)}
+        footer={null}
+        width={800}
+      >
+        {taskLogLoading ? (
+          <div className="py-8 text-center text-gray-500">
+            {t("aiOrderV2.taskLogLoading")}
+          </div>
+        ) : taskLogData.length > 0 ? (
+          <div>
+            <div className="mb-2 text-xs text-gray-400">
+              {t("aiOrderV2.taskLogLines", { count: taskLogData.length })}
+            </div>
+            <div
+              className="rounded-lg border border-gray-200 bg-gray-950 p-4 overflow-auto"
+              style={{ maxHeight: 480 }}
+            >
+              <pre className="m-0 text-xs leading-5 text-green-400 whitespace-pre-wrap font-mono">
+                {taskLogData.map((line, idx) => (
+                  <div key={idx} className="hover:bg-gray-800/50 px-1 -mx-1 rounded">
+                    <span className="select-none text-gray-600 mr-3">{String(idx + 1).padStart(3, " ")}</span>
+                    {line}
+                  </div>
+                ))}
+              </pre>
+            </div>
+          </div>
+        ) : (
+          <div className="py-8 text-center text-gray-400">
+            {t("aiOrderV2.taskLogEmpty")}
+          </div>
+        )}
+      </Modal>
     </div>
   );
 }