123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- import React, { useState, useEffect } from "react";
- import { Form, Input, Select, Button, Card, Descriptions, Tag, message, Spin, Row, Col, Tooltip } from "antd";
- import { useParams, useNavigate, useLocation } from "react-router-dom";
- import { ArrowLeftOutlined, CopyOutlined } from "@ant-design/icons";
- import { autoAccessTasksApi } from "../services/api";
- import moment from "moment";
- import { STATUS_MAP, STATUS_TAG_COLOR } from "./AutoAccessTaskList";
- import { ACCESS_PROVIDER_OPTIONS } from "./AutoAccessTaskAdd";
- const { TextArea } = Input;
- const { Option } = Select;
- // 状态枚举
- const STATUS_OPTIONS = [
- { value: 0, label: "待执行" },
- { value: 1, label: "执行中" },
- { value: 2, label: "已完成" },
- { value: 3, label: "失败" },
- { value: 4, label: "已注册" },
- { value: 5, label: "待审核" },
- { value: 6, label: "审核不通过" },
- ];
- // 状态映射(用于显示)
- const AutoAccessTaskDetail = () => {
- const [form] = Form.useForm();
- const [data, setData] = useState(null);
- const [loading, setLoading] = useState(true);
- const [saving, setSaving] = useState(false);
- const [accessType, setAccessType] = useState(undefined);
- const { id } = useParams();
- const navigate = useNavigate();
- const location = useLocation();
- const isEditMode = location.search.includes("mode=edit");
- const getStatusColor = (status) => {
- return STATUS_TAG_COLOR[status] || "default";
- };
- const getStatusText = (status) => {
- return STATUS_MAP[status] || "未知";
- };
- const getAccessTypeText = (type) => {
- const typeMap = {
- api_no_crack: "API无破解",
- api_crack: "API破解",
- browser_auto_operate: "浏览器自动操作",
- };
- return typeMap[type] || type;
- };
- const fetchData = async () => {
- try {
- const response = await autoAccessTasksApi.getDetail(id);
- setData(response.data);
- form.setFieldsValue(response.data);
- setAccessType(response.data.access_type);
- } catch (error) {
- message.error("获取详情失败");
- } finally {
- setLoading(false);
- }
- };
- const handleSave = async (values) => {
- setSaving(true);
- try {
- await autoAccessTasksApi.update(id, values);
- message.success("更新成功");
- navigate("/auto-access-tasks");
- } catch (error) {
- message.error("更新失败");
- } finally {
- setSaving(false);
- }
- };
- const handleCopyApiDoc = () => {
- const apiDoc = form.getFieldValue("api_doc");
- if (apiDoc) {
- navigator.clipboard
- .writeText(apiDoc)
- .then(() => {
- message.success("API文档已复制到剪贴板");
- })
- .catch(() => {
- message.error("复制失败,请手动复制");
- });
- } else {
- message.warning("API文档为空,无法复制");
- }
- };
- const handleAccessTypeChange = (value) => {
- setAccessType(value);
- // 当接入方式改变时,清空相关字段的值
- if (value === "browser_auto_operate") {
- form.setFieldsValue({
- api_provider: undefined,
- api_doc: undefined,
- });
- } else if (value === "api_no_crack" || value === "api_crack") {
- form.setFieldsValue({
- operate_path_data: undefined,
- });
- }
- };
- useEffect(() => {
- fetchData();
- }, [id]);
- if (loading) {
- return (
- <div style={{ textAlign: "center", padding: "50px" }}>
- <Spin size="large" />
- </div>
- );
- }
- if (!data) {
- return <div>数据不存在</div>;
- }
- return (
- <div className="detail-container">
- <Button
- icon={<ArrowLeftOutlined />}
- onClick={() => navigate("/auto-access-tasks")}
- style={{ marginBottom: 16 }}
- >
- 返回列表
- </Button>
- {isEditMode ? (
- <Card
- title="编辑自动接入任务"
- style={{ marginBottom: 24 }}
- >
- <Form
- form={form}
- layout="vertical"
- onFinish={handleSave}
- className="w-full"
- >
- <Row gutter={24}>
- {/* <Col span={12}>
- <Form.Item
- label="检索任务ID"
- name="search_task_id"
- >
- <Input />
- </Form.Item>
- </Col> */}
- <Col span={12}>
- <Form.Item
- label="工具名称"
- name="tools_name"
- rules={[{ required: true, message: "请输入工具名称" }]}
- >
- <Input />
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item
- label="工具功能名称"
- name="tools_function_name"
- rules={[{ required: false, message: "请输入工具功能名称" }]}
- >
- <Input />
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={24}>
- <Col span={12}>
- <Form.Item
- label="接入方式"
- name="access_type"
- rules={[{ required: true, message: "请选择接入方式" }]}
- >
- <Select onChange={handleAccessTypeChange}>
- <Option value="api_no_crack">API无破解</Option>
- <Option value="api_crack">API破解</Option>
- <Option value="browser_auto_operate">浏览器自动操作</Option>
- </Select>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item
- label="状态"
- name="status"
- rules={[{ required: false, message: "请选择状态" }]}
- >
- <Select>
- {STATUS_OPTIONS.map((option) => (
- <Option
- key={option.value}
- value={option.value}
- >
- {option.label}
- </Option>
- ))}
- </Select>
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={24}>
- <Col span={12}>
- <Form.Item
- label="API类名"
- name="api_class_name"
- >
- <Input />
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item
- label="补充ApiKey"
- name="api_key"
- >
- <Input />
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={24}>
- <Col span={12}>
- <Form.Item
- label="API提供方"
- name="api_provider"
- rules={[
- {
- required: accessType === "api_no_crack" || accessType === "api_crack",
- message: "请输入API提供方",
- },
- ]}
- >
- <Select placeholder="请选择API提供方">
- {ACCESS_PROVIDER_OPTIONS.map((option) => (
- <Option
- key={option.value}
- value={option.value}
- >
- {option.label}
- </Option>
- ))}
- </Select>
- </Form.Item>
- </Col>
- </Row>
- <Form.Item
- label={
- <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
- API文档
- <Tooltip title="点击复制API文档">
- <Button
- type="text"
- style={{ color: "blue" }}
- size="small"
- icon={<CopyOutlined />}
- onClick={handleCopyApiDoc}
- />
- </Tooltip>
- </div>
- }
- name="api_doc"
- rules={[
- {
- required: accessType === "api_no_crack" || accessType === "api_crack",
- message: "请输入API文档",
- },
- ]}
- >
- <TextArea rows={6} />
- </Form.Item>
- <Form.Item
- label="操作路径数据"
- name="operate_path_data"
- rules={[
- {
- required: accessType === "browser_auto_operate",
- message: "请输入操作路径数据",
- },
- ]}
- >
- <TextArea rows={4} />
- </Form.Item>
- <Form.Item
- label="源内容链接"
- name="origin_content_link"
- >
- <Input />
- </Form.Item>
- <Form.Item
- label="工具功能描述"
- name="tools_function_desc"
- >
- <TextArea rows={4} />
- </Form.Item>
- <Form.Item
- label="失败原因"
- name="fail_reason"
- >
- <TextArea rows={3} />
- </Form.Item>
- <div className="button-group">
- <Button onClick={() => navigate("/auto-access-tasks")}>取消</Button>
- <Button
- type="primary"
- htmlType="submit"
- loading={saving}
- >
- 保存
- </Button>
- </div>
- </Form>
- </Card>
- ) : (
- <Card title="自动接入任务详情">
- <Descriptions
- column={2}
- bordered
- labelStyle={{ width: "140px", minWidth: "120px" }}
- >
- <Descriptions.Item label="接入任务ID">{data.access_task_id}</Descriptions.Item>
- <Descriptions.Item label="检索任务ID">{data.search_task_id}</Descriptions.Item>
- <Descriptions.Item label="工具名称">{data.tools_name}</Descriptions.Item>
- <Descriptions.Item label="工具功能名称">{data.tools_function_name}</Descriptions.Item>
- <Descriptions.Item label="接入方式">
- <Tag color="blue">{getAccessTypeText(data.access_type)}</Tag>
- </Descriptions.Item>
- <Descriptions.Item label="状态">
- <Tag color={getStatusColor(data.status)}>{getStatusText(data.status)}</Tag>
- </Descriptions.Item>
- <Descriptions.Item label="API类名">{data.api_class_name}</Descriptions.Item>
- <Descriptions.Item label="API提供方">{data.api_provider}</Descriptions.Item>
- <Descriptions.Item
- label="补充ApiKey"
- span={2}
- >
- {data.api_key || "无"}
- </Descriptions.Item>
- <Descriptions.Item
- label="工具功能描述"
- span={2}
- >
- {data.tools_function_desc}
- </Descriptions.Item>
- <Descriptions.Item
- label={
- <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
- API文档
- <Tooltip title="点击复制API文档">
- <Button
- type="text"
- style={{ color: "blue" }}
- size="small"
- icon={<CopyOutlined />}
- onClick={() => {
- const apiDoc = data.api_doc;
- if (apiDoc) {
- navigator.clipboard
- .writeText(apiDoc)
- .then(() => {
- message.success("API文档已复制到剪贴板");
- })
- .catch(() => {
- message.error("复制失败,请手动复制");
- });
- } else {
- message.warning("API文档为空,无法复制");
- }
- }}
- />
- </Tooltip>
- </div>
- }
- span={2}
- >
- <div style={{ maxHeight: "200px", overflow: "auto" }}>
- <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>{data.api_doc || "无"}</pre>
- </div>
- </Descriptions.Item>
- <Descriptions.Item label="源内容链接">
- {data.origin_content_link ? (
- <a
- href={data.origin_content_link}
- target="_blank"
- rel="noopener noreferrer"
- >
- {data.origin_content_link}
- </a>
- ) : (
- "无"
- )}
- </Descriptions.Item>
- <Descriptions.Item
- label="操作路径数据"
- span={2}
- >
- <div style={{ maxHeight: "200px", overflow: "auto" }}>
- <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>{data.operate_path_data || "无"}</pre>
- </div>
- </Descriptions.Item>
- <Descriptions.Item
- label="失败原因"
- span={2}
- >
- {data.fail_reason || "无"}
- </Descriptions.Item>
- <Descriptions.Item label="创建时间">
- {moment(data.create_time).format("YYYY-MM-DD HH:mm:ss")}
- </Descriptions.Item>
- <Descriptions.Item label="更新时间">
- {moment(data.update_time).format("YYYY-MM-DD HH:mm:ss")}
- </Descriptions.Item>
- </Descriptions>
- </Card>
- )}
- </div>
- );
- };
- export default AutoAccessTaskDetail;
|