ToolsLibraryDetail.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. import React, { useState, useEffect } from "react";
  2. import { Form, Input, Select, Button, Card, Descriptions, Tag, message, Spin } from "antd";
  3. import { useParams, useNavigate, useLocation } from "react-router-dom";
  4. import { ArrowLeftOutlined } from "@ant-design/icons";
  5. import { toolsLibraryApi } from "../services/api";
  6. import moment from "moment";
  7. const { TextArea } = Input;
  8. const { Option } = Select;
  9. const ToolsLibraryDetail = () => {
  10. const [form] = Form.useForm();
  11. const [data, setData] = useState(null);
  12. const [loading, setLoading] = useState(true);
  13. const [saving, setSaving] = useState(false);
  14. const { id } = useParams();
  15. const navigate = useNavigate();
  16. const location = useLocation();
  17. const isEditMode = location.search.includes("mode=edit");
  18. const getStatusColor = (status) => {
  19. const statusMap = {
  20. normal: "success",
  21. offline: "default",
  22. unpublished: "default",
  23. published: "success",
  24. };
  25. return statusMap[status] || "warning";
  26. };
  27. const getStatusText = (status) => {
  28. const statusMap = {
  29. normal: "正常",
  30. offline: "已下线",
  31. unpublished: "待发布",
  32. published: "已发布",
  33. };
  34. return statusMap[status] || status;
  35. };
  36. const getCallTypeText = (type) => {
  37. const typeMap = {
  38. api: "API调用",
  39. browser_auto_operate: "浏览器自动操作",
  40. };
  41. return typeMap[type] || type;
  42. };
  43. const getApiProviderText = (provider) => {
  44. const providerMap = {
  45. official: "官方",
  46. "302ai": "302AI",
  47. official_api: "官方API",
  48. };
  49. return providerMap[provider] || provider;
  50. };
  51. const fetchData = async () => {
  52. try {
  53. const response = await toolsLibraryApi.getDetail(id);
  54. setData(response.data);
  55. form.setFieldsValue(response.data);
  56. } catch (error) {
  57. message.error("获取详情失败");
  58. } finally {
  59. setLoading(false);
  60. }
  61. };
  62. const handleSave = async (values) => {
  63. setSaving(true);
  64. try {
  65. await toolsLibraryApi.update(id, values);
  66. message.success("更新成功");
  67. navigate("/tools-library");
  68. } catch (error) {
  69. message.error("更新失败");
  70. } finally {
  71. setSaving(false);
  72. }
  73. };
  74. useEffect(() => {
  75. fetchData();
  76. }, [id]);
  77. if (loading) {
  78. return (
  79. <div style={{ textAlign: "center", padding: "50px" }}>
  80. <Spin size="large" />
  81. </div>
  82. );
  83. }
  84. if (!data) {
  85. return <div>数据不存在</div>;
  86. }
  87. return (
  88. <div className="detail-container">
  89. <Button
  90. icon={<ArrowLeftOutlined />}
  91. onClick={() => navigate("/tools-library")}
  92. style={{ marginBottom: 16 }}
  93. >
  94. 返回列表
  95. </Button>
  96. {isEditMode ? (
  97. <Card
  98. title="编辑工具"
  99. style={{ marginBottom: 24 }}
  100. >
  101. <Form
  102. form={form}
  103. layout="vertical"
  104. onFinish={handleSave}
  105. className="form-container"
  106. >
  107. <Form.Item
  108. label="工具名称"
  109. name="tools_name"
  110. rules={[{ required: true, message: "请输入工具名称" }]}
  111. >
  112. <Input />
  113. </Form.Item>
  114. <Form.Item
  115. label="工具功能名称"
  116. name="tools_function_name"
  117. rules={[{ required: true, message: "请输入工具功能名称" }]}
  118. >
  119. <Input />
  120. </Form.Item>
  121. <Form.Item
  122. label="工具全称"
  123. name="tools_full_name"
  124. >
  125. <Input />
  126. </Form.Item>
  127. <Form.Item
  128. label="工具描述"
  129. name="tools_desc"
  130. >
  131. <TextArea rows={4} />
  132. </Form.Item>
  133. <Form.Item
  134. label="工具版本"
  135. name="tools_version"
  136. >
  137. <Input />
  138. </Form.Item>
  139. <Form.Item
  140. label="自动接入任务ID"
  141. name="access_task_id"
  142. >
  143. <Input />
  144. </Form.Item>
  145. <Form.Item
  146. label="状态"
  147. name="status"
  148. rules={[{ required: true, message: "请选择状态" }]}
  149. >
  150. <Select>
  151. <Option value="normal">正常</Option>
  152. <Option value="offline">已下线</Option>
  153. <Option value="unpublished">待发布</Option>
  154. <Option value="published">已发布</Option>
  155. </Select>
  156. </Form.Item>
  157. <Form.Item
  158. label="调用方式"
  159. name="call_type"
  160. >
  161. <Select>
  162. <Option value="api">API调用</Option>
  163. <Option value="browser_auto_operate">浏览器自动操作</Option>
  164. </Select>
  165. </Form.Item>
  166. <Form.Item
  167. label="API提供方"
  168. name="api_provider"
  169. >
  170. <Select>
  171. <Option value="official">官方</Option>
  172. <Option value="302ai">302AI</Option>
  173. <Option value="official_api">官方API</Option>
  174. </Select>
  175. </Form.Item>
  176. <Form.Item
  177. label="API路径"
  178. name="api_url_path"
  179. >
  180. <Input />
  181. </Form.Item>
  182. <Form.Item
  183. label="操作路径数据"
  184. name="operate_path_data"
  185. >
  186. <TextArea rows={4} />
  187. </Form.Item>
  188. <Form.Item
  189. label="参数定义"
  190. name="params_definition"
  191. >
  192. <TextArea rows={6} />
  193. </Form.Item>
  194. <Form.Item
  195. label="响应数据说明"
  196. name="response_desc"
  197. >
  198. <TextArea rows={4} />
  199. </Form.Item>
  200. <div className="button-group">
  201. <Button onClick={() => navigate("/tools-library")}>取消</Button>
  202. <Button
  203. type="primary"
  204. htmlType="submit"
  205. loading={saving}
  206. >
  207. 保存
  208. </Button>
  209. </div>
  210. </Form>
  211. </Card>
  212. ) : (
  213. <Card title="工具详情">
  214. <Descriptions
  215. column={2}
  216. bordered
  217. >
  218. <Descriptions.Item label="工具ID">{data.tools_id}</Descriptions.Item>
  219. <Descriptions.Item label="工具名称">{data.tools_name}</Descriptions.Item>
  220. <Descriptions.Item label="工具功能名称">{data.tools_function_name}</Descriptions.Item>
  221. <Descriptions.Item label="工具全称">{data.tools_full_name}</Descriptions.Item>
  222. <Descriptions.Item label="工具版本">
  223. <Tag color="geekblue">{data.tools_version}</Tag>
  224. </Descriptions.Item>
  225. <Descriptions.Item label="自动接入任务ID">{data.access_task_id}</Descriptions.Item>
  226. <Descriptions.Item label="状态">
  227. <Tag color={getStatusColor(data.status)}>{getStatusText(data.status)}</Tag>
  228. </Descriptions.Item>
  229. <Descriptions.Item label="调用方式">
  230. <Tag color="blue">{getCallTypeText(data.call_type)}</Tag>
  231. </Descriptions.Item>
  232. <Descriptions.Item label="API提供方">
  233. <Tag color="purple">{getApiProviderText(data.api_provider)}</Tag>
  234. </Descriptions.Item>
  235. <Descriptions.Item label="API路径">{data.api_url_path}</Descriptions.Item>
  236. <Descriptions.Item
  237. label="工具描述"
  238. span={2}
  239. >
  240. {data.tools_desc}
  241. </Descriptions.Item>
  242. <Descriptions.Item
  243. label="操作路径数据"
  244. span={2}
  245. >
  246. <div style={{ maxHeight: "200px", overflow: "auto" }}>
  247. <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>{data.operate_path_data || "无"}</pre>
  248. </div>
  249. </Descriptions.Item>
  250. <Descriptions.Item
  251. label="参数定义"
  252. span={2}
  253. >
  254. <div style={{ maxHeight: "200px", overflow: "auto" }}>
  255. <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>{data.params_definition || "无"}</pre>
  256. </div>
  257. </Descriptions.Item>
  258. <Descriptions.Item
  259. label="响应数据说明"
  260. span={2}
  261. >
  262. <div style={{ maxHeight: "200px", overflow: "auto" }}>
  263. <pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>{data.response_desc || "无"}</pre>
  264. </div>
  265. </Descriptions.Item>
  266. <Descriptions.Item label="创建时间">
  267. {moment(data.create_time).format("YYYY-MM-DD HH:mm:ss")}
  268. </Descriptions.Item>
  269. <Descriptions.Item label="更新时间">
  270. {moment(data.update_time).format("YYYY-MM-DD HH:mm:ss")}
  271. </Descriptions.Item>
  272. </Descriptions>
  273. </Card>
  274. )}
  275. </div>
  276. );
  277. };
  278. export default ToolsLibraryDetail;