Explorar el Código

新增接口实现,完善接口描述文档;修改的文件有
modified: docs/DR.md
new file: src/API/imageActions.ts
new file: src/API/output/pacsNodeActions.ts
new file: src/API/output/sendJobActions.ts

sw hace 3 días
padre
commit
7a141dc458
Se han modificado 4 ficheros con 854 adiciones y 176 borrados
  1. 176 176
      docs/DR.md
  2. 77 0
      src/API/imageActions.ts
  3. 250 0
      src/API/output/pacsNodeActions.ts
  4. 351 0
      src/API/output/sendJobActions.ts

+ 176 - 176
docs/DR.md

@@ -671,64 +671,7 @@ zh_CN
 请求示例
 
 
-## 13.2	获取PACS节点列表
-
-> GET  /api/v1/auth/scp/pacs
-### 接口说明
-> 获取PACS节点列表
-### 请求头
-| 参数名称 | 默认值 | 描述 |
-| ------ | ------ | ------ |
-|Authorization|Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTEyNzc5NzAsImlkIjoxLCJuYW1lIjoiYWRtaW4ifQ.ooTGwBXaNhtunbKbpqteWbjDwJLjnRmSIl80r5dp1pY||
-|Language||en_US 或 zh_CN|
-|Product|DROS|DROS 或 VETDROS|
-|Source|Electron|Electron 或 Browser 或 Android|
-### 响应体
-● 200: OK 响应数据格式:JSON
-```json
-{
-  "code": "0x000000",
-  "description": "Success",
-  "solution": "",
-  "data": {
-    "@type": "type.googleapis.com/dr.study.ScpList",
-    "scp": [
-      {
-        "id": 3,
-        "name": "pacs2",
-        "type": "PACS",
-        "address": "192.168.1.4",
-        "port": 6299,
-        "aet": "testscp",
-        "aec": "testscu",
-        "is_enabled": true,
-        "is_default": false,
-        "params": {
-          "a": "b"
-        }
-      },
-      {
-        "id": 1,
-        "name": "pacs1",
-        "type": "PACS",
-        "address": "192.168.1.3",
-        "port": 6299,
-        "aet": "testscp",
-        "aec": "testscu",
-        "is_enabled": true,
-        "is_default": false,
-        "params": {
-          "a": "b"
-        }
-      }
-    ]
-  }
-}
-```
-请求示例
-
-
-## 13.3	增加PACS节点
+## 13.2	增加PACS节点
 
 > POST  /api/v1/auth/manage/pacs
 ### 接口说明
@@ -764,122 +707,7 @@ zh_CN
 请求示例
 ![  ](http://f1-xyj.fangdeco.cn/attachment/2025/10/8/2LxW6Zq9QdE/bc6cf3e6958c49099f60e15add37cac1)
 
-## 13.4	获取发送队列(PACS)
-
-> GET  /api/v1/auth/scp/store
-### 接口说明
-> 获取发送队列(PACS)
-### 请求头
-| 参数名称 | 默认值 | 描述 |
-| ------ | ------ | ------ |
-|Authorization|Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTEyNzc5NzAsImlkIjoxLCJuYW1lIjoiYWRtaW4ifQ.ooTGwBXaNhtunbKbpqteWbjDwJLjnRmSIl80r5dp1pY||
-|Language||en_US 或 zh_CN|
-|Product|DROS|DROS 或 VETDROS|
-|Source|Electron|Electron 或 Browser 或 Android|
-### 请求参数(Query Param)
-| 参数名称 | 默认值 | 描述 |
-| ------ | ------ | ------ |
-|start_time||RFC3339Nano格式|
-|end_time||RFC3339Nano格式|
-### 响应体
-● 200: OK 响应数据格式:JSON
-```json
-{
-	"code": "0x000000",
-	"data": [
-		{
-			"task_id": "0199cd46-82f0-76c5-b1d3-9399668a1a05",
-			"patient_name": "1update3",
-			"patient_id": "1update2",
-			"priority": "Medium",
-			"status": "ARRIVED",
-			"destination": "pacs3"
-		},
-		{
-			"task_id": "0199cd46-460d-770e-ac8e-549939a4a7d4",
-			"patient_name": "1update3",
-			"patient_id": "1update2",
-			"priority": "Medium",
-			"status": "ARRIVED",
-			"destination": "pacs3"
-		},
-		{
-			"task_id": "0199cd45-dff6-70e4-92e3-2339f0bee57a",
-			"patient_name": "1update3",
-			"patient_id": "1update2",
-			"priority": "Medium",
-			"status": "ARRIVED",
-			"destination": "pacs3"
-		}
-	],
-	"description": "Success",
-	"solution": ""
-}
-```
-请求示例
-![  ](http://f1-xyj.fangdeco.cn/attachment/2025/10/10/2M0ruPn3TXs/93dd3fd6fb9547379918d93652c9151e)
-
-## 13.5	发送图像
-
-> POST  /api/v1/auth/scp/store
-### 接口说明
-> 发送图像
-### 请求头
-| 参数名称 | 默认值 | 描述 |
-| ------ | ------ | ------ |
-|Authorization|Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTEyNzc5NzAsImlkIjoxLCJuYW1lIjoiYWRtaW4ifQ.ooTGwBXaNhtunbKbpqteWbjDwJLjnRmSIl80r5dp1pY||
-|Language||en_US 或 zh_CN|
-|Product|DROS|DROS 或 VETDROS|
-|Source|Electron|Electron 或 Browser 或 Android|
-### 请求体(Request Body)
-| 参数名称 | 数据类型 | 默认值 | 不为空 | 描述 |
-| ------ | ------ | ------ | ------ | ------ |
-| sop_instance_uid|string||true|图像id|
-| pacs_name|string||true|pacs节点名称|
-### 响应体
-● 200: OK 响应数据格式:JSON
-```json
-{
-  "code": "0x000000",
-  "description": "Success",
-  "solution": "",
-  "data": {
-    "@type": "type.googleapis.com/dr.task.StoreReply",
-    "ok": true,
-    "output": "...D: ======================= END DIMSE MESSAGE =======================\nI: Releasing Association\n"
-  }
-}
-```
-请求示例
-![  ](http://f1-xyj.fangdeco.cn/attachment/2025/10/10/2M0jbE69VxY/be2c33a1b0e344f1954927b726b18fa4)
-
-## 13.6	删除发送任务
-
-> DELETE  /api/v1/auth/scp/task
-### 接口说明
-> 删除发送任务
-### 请求头
-| 参数名称 | 默认值 | 描述 |
-| ------ | ------ | ------ |
-|Authorization|Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTEyNzc5NzAsImlkIjoxLCJuYW1lIjoiYWRtaW4ifQ.ooTGwBXaNhtunbKbpqteWbjDwJLjnRmSIl80r5dp1pY||
-|Language||en_US 或 zh_CN|
-|Product|DROS|DROS 或 VETDROS|
-|Source|Electron|Electron 或 Browser 或 Android|
-### 响应体
-● 200: OK 响应数据格式:JSON
-```json
-{
-	"code": "0x000000",
-	"description": "Success",
-	"solution": "",
-	"data": {}
-}
-```
-请求示例
-![  ](http://f1-xyj.fangdeco.cn/attachment/2025/10/10/2M0sbMgtryy/b22276514372464c84e062c76a47cbe3)
-
-
-## 13.7	修改PACS节点
+## 13.3	修改PACS节点
 
 > PUT  /api/v1/auth/manage/pacs/{id}
 ### 接口说明
@@ -920,7 +748,7 @@ zh_CN
 ![  ](http://f1-xyj.fangdeco.cn/attachment/2025/10/8/2LxW3RCiZqS/99516b6f16134ab0bee9bc6a47b7a749)
 
 
-## 13.8	删除PACS节点
+## 13.4	删除PACS节点
 
 > DELETE  /api/v1/auth/manage/pacs/{id}
 ### 接口说明
@@ -2141,7 +1969,179 @@ zh_CN
 请求示例
 ![  ](http://f1-xyj.fangdeco.cn/attachment/2025/10/9/2LzEU2sUaFU/57083fd3c51b416e8a2c4a7095e8edc9)
 
-## 15.2	重试发送任务
+## 15.2	获取PACS节点列表
+
+> GET  /api/v1/auth/scp/pacs
+### 接口说明
+> 获取PACS节点列表
+### 请求头
+| 参数名称 | 默认值 | 描述 |
+| ------ | ------ | ------ |
+|Authorization|Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTEyNzc5NzAsImlkIjoxLCJuYW1lIjoiYWRtaW4ifQ.ooTGwBXaNhtunbKbpqteWbjDwJLjnRmSIl80r5dp1pY||
+|Language||en_US 或 zh_CN|
+|Product|DROS|DROS 或 VETDROS|
+|Source|Electron|Electron 或 Browser 或 Android|
+### 响应体
+● 200: OK 响应数据格式:JSON
+```json
+{
+  "code": "0x000000",
+  "description": "Success",
+  "solution": "",
+  "data": {
+    "@type": "type.googleapis.com/dr.study.ScpList",
+    "scp": [
+      {
+        "id": 3,
+        "name": "pacs2",
+        "type": "PACS",
+        "address": "192.168.1.4",
+        "port": 6299,
+        "aet": "testscp",
+        "aec": "testscu",
+        "is_enabled": true,
+        "is_default": false,
+        "params": {
+          "a": "b"
+        }
+      },
+      {
+        "id": 1,
+        "name": "pacs1",
+        "type": "PACS",
+        "address": "192.168.1.3",
+        "port": 6299,
+        "aet": "testscp",
+        "aec": "testscu",
+        "is_enabled": true,
+        "is_default": false,
+        "params": {
+          "a": "b"
+        }
+      }
+    ]
+  }
+}
+```
+请求示例
+
+
+## 15.3	获取发送队列(PACS)
+
+> GET  /api/v1/auth/scp/store
+### 接口说明
+> 获取发送队列(PACS)
+### 请求头
+| 参数名称 | 默认值 | 描述 |
+| ------ | ------ | ------ |
+|Authorization|Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTEyNzc5NzAsImlkIjoxLCJuYW1lIjoiYWRtaW4ifQ.ooTGwBXaNhtunbKbpqteWbjDwJLjnRmSIl80r5dp1pY||
+|Language||en_US 或 zh_CN|
+|Product|DROS|DROS 或 VETDROS|
+|Source|Electron|Electron 或 Browser 或 Android|
+### 请求参数(Query Param)
+| 参数名称 | 默认值 | 描述 |
+| ------ | ------ | ------ |
+|start_time||RFC3339Nano格式|
+|end_time||RFC3339Nano格式|
+### 响应体
+● 200: OK 响应数据格式:JSON
+```json
+{
+	"code": "0x000000",
+	"data": [
+		{
+			"task_id": "0199cd46-82f0-76c5-b1d3-9399668a1a05",
+			"patient_name": "1update3",
+			"patient_id": "1update2",
+			"priority": "Medium",
+			"status": "ARRIVED",
+			"destination": "pacs3"
+		},
+		{
+			"task_id": "0199cd46-460d-770e-ac8e-549939a4a7d4",
+			"patient_name": "1update3",
+			"patient_id": "1update2",
+			"priority": "Medium",
+			"status": "ARRIVED",
+			"destination": "pacs3"
+		},
+		{
+			"task_id": "0199cd45-dff6-70e4-92e3-2339f0bee57a",
+			"patient_name": "1update3",
+			"patient_id": "1update2",
+			"priority": "Medium",
+			"status": "ARRIVED",
+			"destination": "pacs3"
+		}
+	],
+	"description": "Success",
+	"solution": ""
+}
+```
+请求示例
+![  ](http://f1-xyj.fangdeco.cn/attachment/2025/10/10/2M0ruPn3TXs/93dd3fd6fb9547379918d93652c9151e)
+
+## 15.4	删除发送任务
+
+> DELETE  /api/v1/auth/scp/task
+### 接口说明
+> 删除发送任务
+### 请求头
+| 参数名称 | 默认值 | 描述 |
+| ------ | ------ | ------ |
+|Authorization|Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTEyNzc5NzAsImlkIjoxLCJuYW1lIjoiYWRtaW4ifQ.ooTGwBXaNhtunbKbpqteWbjDwJLjnRmSIl80r5dp1pY||
+|Language||en_US 或 zh_CN|
+|Product|DROS|DROS 或 VETDROS|
+|Source|Electron|Electron 或 Browser 或 Android|
+### 响应体
+● 200: OK 响应数据格式:JSON
+```json
+{
+	"code": "0x000000",
+	"description": "Success",
+	"solution": "",
+	"data": {}
+}
+```
+请求示例
+![  ](http://f1-xyj.fangdeco.cn/attachment/2025/10/10/2M0sbMgtryy/b22276514372464c84e062c76a47cbe3)
+
+
+## 15.5	发送图像
+
+> POST  /api/v1/auth/scp/store
+### 接口说明
+> 发送图像
+### 请求头
+| 参数名称 | 默认值 | 描述 |
+| ------ | ------ | ------ |
+|Authorization|Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTEyNzc5NzAsImlkIjoxLCJuYW1lIjoiYWRtaW4ifQ.ooTGwBXaNhtunbKbpqteWbjDwJLjnRmSIl80r5dp1pY||
+|Language||en_US 或 zh_CN|
+|Product|DROS|DROS 或 VETDROS|
+|Source|Electron|Electron 或 Browser 或 Android|
+### 请求体(Request Body)
+| 参数名称 | 数据类型 | 默认值 | 不为空 | 描述 |
+| ------ | ------ | ------ | ------ | ------ |
+| sop_instance_uid|string||true|图像id|
+| pacs_name|string||true|pacs节点名称|
+### 响应体
+● 200: OK 响应数据格式:JSON
+```json
+{
+  "code": "0x000000",
+  "description": "Success",
+  "solution": "",
+  "data": {
+    "@type": "type.googleapis.com/dr.task.StoreReply",
+    "ok": true,
+    "output": "...D: ======================= END DIMSE MESSAGE =======================\nI: Releasing Association\n"
+  }
+}
+```
+请求示例
+![  ](http://f1-xyj.fangdeco.cn/attachment/2025/10/10/2M0jbE69VxY/be2c33a1b0e344f1954927b726b18fa4)
+
+## 15.6	重试发送任务
 
 > POST  /api/v1/auth/scp/store_reply
 ### 接口说明

+ 77 - 0
src/API/imageActions.ts

@@ -0,0 +1,77 @@
+import axiosInstance from './interceptor';
+
+/**
+ * 发送图像请求参数
+ */
+export interface SendImageRequest {
+  /** 图像实例 UID */
+  sop_instance_uid: string;
+  /** PACS 节点名称 */
+  pacs_name: string;
+}
+
+/**
+ * 存储响应数据
+ */
+export interface StoreReplyData {
+  /** 类型标识 */
+  '@type': string;
+  /** 是否成功 */
+  ok: boolean;
+  /** 输出信息 */
+  output: string;
+}
+
+/**
+ * 发送图像响应
+ */
+export interface SendImageResponse {
+  /** 响应码 */
+  code: string;
+  /** 描述信息 */
+  description: string;
+  /** 解决方案 */
+  solution: string;
+  /** 数据内容 */
+  data: StoreReplyData;
+}
+
+/**
+ * 发送图像到 PACS 节点
+ * @param sopInstanceUid 图像实例 UID (SOP Instance UID)
+ * @param pacsName PACS 节点名称
+ * @returns 发送结果,包含成功状态和输出信息
+ * @throws 当发送失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * const result = await sendImageToPacs(
+ *   '1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671',
+ *   'pacs1'
+ * );
+ * console.log('发送成功:', result.data.ok);
+ * ```
+ */
+export const sendImageToPacs = async (
+  sopInstanceUid: string,
+  pacsName: string
+): Promise<SendImageResponse> => {
+  try {
+    const response = await axiosInstance.post<SendImageResponse>(
+      '/auth/scp/store',
+      {
+        sop_instance_uid: sopInstanceUid,
+        pacs_name: pacsName,
+      }
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`发送图像失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error sending image to PACS:', error);
+    throw error;
+  }
+};

+ 250 - 0
src/API/output/pacsNodeActions.ts

@@ -0,0 +1,250 @@
+import axiosInstance from '../interceptor';
+
+/**
+ * PACS 节点数据结构
+ */
+export interface PacsNode {
+  /** 节点 ID */
+  id: number;
+  /** 节点名称 */
+  name: string;
+  /** 节点类型 (固定为 "PACS") */
+  type: string;
+  /** 节点地址 (IPv4) */
+  address: string;
+  /** 端口号 (1-65536) */
+  port: number;
+  /** 被叫节点名 (AE Title) */
+  aet: string;
+  /** 主叫节点名 (AE Calling) */
+  aec: string;
+  /** 是否启用 */
+  is_enabled: boolean;
+  /** 是否为默认节点 */
+  is_default: boolean;
+  /** 其他参数 */
+  params?: Record<string, any>;
+}
+
+/**
+ * 创建 PACS 节点请求参数
+ */
+export interface CreatePacsNodeRequest {
+  /** 节点名称 (长度 3-16) */
+  name: string;
+  /** 节点类型 (固定值 "PACS") */
+  type: string;
+  /** 节点地址 (IPv4 地址,不能为 0.0.0.0) */
+  address: string;
+  /** 端口号 (1-65536) */
+  port: number;
+  /** 被叫节点名 (长度 1-16) */
+  aet: string;
+  /** 主叫节点名 (长度 1-16) */
+  aec: string;
+  /** 是否启用 */
+  is_enabled: boolean;
+  /** 是否为默认节点 */
+  is_default: boolean;
+}
+
+/**
+ * 更新 PACS 节点请求参数
+ */
+export interface UpdatePacsNodeRequest {
+  /** 节点名称 (长度 3-16) */
+  name: string;
+  /** 节点类型 (固定值 "PACS") */
+  type: string;
+  /** 节点地址 (IPv4 地址,不能为 0.0.0.0) */
+  address: string;
+  /** 端口号 (1-65536) */
+  port: number;
+  /** 被叫节点名 (长度 1-16) */
+  aet: string;
+  /** 主叫节点名 (长度 1-16) */
+  aec: string;
+  /** 是否启用 */
+  is_enabled: boolean;
+  /** 是否为默认节点 */
+  is_default: boolean;
+}
+
+/**
+ * PACS 节点列表响应数据
+ */
+export interface PacsNodeListData {
+  /** 类型标识 */
+  '@type': string;
+  /** PACS 节点列表 */
+  scp: PacsNode[];
+}
+
+/**
+ * PACS 节点列表响应
+ */
+export interface PacsNodeListResponse {
+  /** 响应码 */
+  code: string;
+  /** 描述信息 */
+  description: string;
+  /** 解决方案 */
+  solution: string;
+  /** 数据内容 */
+  data: PacsNodeListData;
+}
+
+/**
+ * 基础响应
+ */
+export interface BaseResponse {
+  /** 响应码 */
+  code: string;
+  /** 描述信息 */
+  description: string;
+  /** 解决方案 */
+  solution: string;
+  /** 数据内容 */
+  data: Record<string, any>;
+}
+
+/**
+ * 获取 PACS 节点列表
+ * @returns PACS 节点列表
+ * @throws 当请求失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * const result = await getPacsNodeList();
+ * console.log('PACS 节点列表:', result.data.scp);
+ * ```
+ */
+export const getPacsNodeList = async (): Promise<PacsNodeListResponse> => {
+  try {
+    const response = await axiosInstance.get<PacsNodeListResponse>(
+      '/auth/manage/pacs'
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`获取 PACS 节点列表失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error fetching PACS node list:', error);
+    throw error;
+  }
+};
+
+/**
+ * 创建 PACS 节点
+ * @param data 创建节点请求参数
+ * @returns 创建结果
+ * @throws 当创建失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * const result = await createPacsNode({
+ *   name: 'pacs1',
+ *   type: 'PACS',
+ *   address: '192.168.1.3',
+ *   port: 6299,
+ *   aet: 'testscp',
+ *   aec: 'testscu',
+ *   is_enabled: true,
+ *   is_default: false
+ * });
+ * console.log('创建成功:', result);
+ * ```
+ */
+export const createPacsNode = async (
+  data: CreatePacsNodeRequest
+): Promise<BaseResponse> => {
+  try {
+    const response = await axiosInstance.post<BaseResponse>(
+      '/auth/manage/pacs',
+      data
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`创建 PACS 节点失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error creating PACS node:', error);
+    throw error;
+  }
+};
+
+/**
+ * 更新 PACS 节点
+ * @param id 节点 ID
+ * @param data 更新节点请求参数
+ * @returns 更新结果
+ * @throws 当更新失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * const result = await updatePacsNode(1, {
+ *   name: 'pacs1-updated',
+ *   type: 'PACS',
+ *   address: '192.168.1.3',
+ *   port: 6299,
+ *   aet: 'testscp',
+ *   aec: 'testscu',
+ *   is_enabled: true,
+ *   is_default: false
+ * });
+ * console.log('更新成功:', result);
+ * ```
+ */
+export const updatePacsNode = async (
+  id: number,
+  data: UpdatePacsNodeRequest
+): Promise<BaseResponse> => {
+  try {
+    const response = await axiosInstance.put<BaseResponse>(
+      `/auth/manage/pacs/${id}`,
+      data
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`更新 PACS 节点失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error updating PACS node:', error);
+    throw error;
+  }
+};
+
+/**
+ * 删除 PACS 节点
+ * @param id 节点 ID
+ * @returns 删除结果
+ * @throws 当删除失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * const result = await deletePacsNode(1);
+ * console.log('删除成功:', result);
+ * ```
+ */
+export const deletePacsNode = async (id: number): Promise<BaseResponse> => {
+  try {
+    const response = await axiosInstance.delete<BaseResponse>(
+      `/auth/manage/pacs/${id}`
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`删除 PACS 节点失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error deleting PACS node:', error);
+    throw error;
+  }
+};

+ 351 - 0
src/API/output/sendJobActions.ts

@@ -0,0 +1,351 @@
+import axiosInstance from '../interceptor';
+import type { PacsNode, PacsNodeListData } from './pacsNodeActions';
+
+/**
+ * Echo 测试请求参数
+ */
+export interface EchoTestRequest {
+  /** 返回详细信息 */
+  verbose?: boolean;
+  /** 返回调试信息 */
+  debug?: boolean;
+  /** IPv4 地址,且不能为 0.0.0.0 */
+  address: string;
+  /** 端口号 (1-65536) */
+  port: number;
+  /** 被叫节点名 (AE Title, 长度 1-16) */
+  aet: string;
+  /** 主叫节点名 (AE Calling, 长度 1-16) */
+  aec: string;
+}
+
+/**
+ * Echo 测试响应数据
+ */
+export interface EchoReplyData {
+  /** 类型标识 */
+  '@type': string;
+  /** 是否成功 */
+  ok: boolean;
+  /** 输出信息 */
+  output: string;
+}
+
+/**
+ * Echo 测试响应
+ */
+export interface EchoTestResponse {
+  /** 响应码 */
+  code: string;
+  /** 描述信息 */
+  description: string;
+  /** 解决方案 */
+  solution: string;
+  /** 数据内容 */
+  data: EchoReplyData;
+}
+
+/**
+ * 发送队列项
+ */
+export interface SendQueueItem {
+  /** 任务 ID */
+  task_id: string;
+  /** 患者姓名 */
+  patient_name: string;
+  /** 患者 ID */
+  patient_id: string;
+  /** 优先级 */
+  priority: 'High' | 'Medium' | 'Low';
+  /** 状态 */
+  status: 'ARRIVED' | 'SENDING' | 'FAILED' | 'SUCCESS';
+  /** 重试次数 */
+  retry_count?: number;
+  /** 目标 PACS 节点 */
+  destination: string;
+}
+
+/**
+ * 发送队列响应
+ */
+export interface SendQueueResponse {
+  /** 响应码 */
+  code: string;
+  /** 描述信息 */
+  description: string;
+  /** 解决方案 */
+  solution: string;
+  /** 发送队列列表 */
+  data: SendQueueItem[];
+}
+
+/**
+ * 获取发送队列查询参数
+ */
+export interface GetSendQueueParams {
+  /** 开始时间 (RFC3339Nano 格式) */
+  start_time?: string;
+  /** 结束时间 (RFC3339Nano 格式) */
+  end_time?: string;
+}
+
+/**
+ * 删除发送任务请求参数
+ */
+export interface DeleteSendTaskRequest {
+  /** 任务 ID 列表 */
+  task_ids: string[];
+}
+
+/**
+ * 重试发送任务请求参数
+ */
+export interface RetrySendTaskRequest {
+  /** 图像实例 UID */
+  instance_uid: string;
+}
+
+/**
+ * 存储响应数据
+ */
+export interface StoreReplyData {
+  /** 类型标识 */
+  '@type': string;
+  /** 是否成功 */
+  ok: boolean;
+  /** 输出信息 */
+  output: string;
+}
+
+/**
+ * 重试发送任务响应
+ */
+export interface RetrySendTaskResponse {
+  /** 响应码 */
+  code: string;
+  /** 描述信息 */
+  description: string;
+  /** 解决方案 */
+  solution: string;
+  /** 数据内容 */
+  data: StoreReplyData;
+}
+
+/**
+ * PACS 节点列表响应 (用于传输队列)
+ */
+export interface SendQueuePacsListResponse {
+  /** 响应码 */
+  code: string;
+  /** 描述信息 */
+  description: string;
+  /** 解决方案 */
+  solution: string;
+  /** 数据内容 */
+  data: PacsNodeListData;
+}
+
+/**
+ * 基础响应
+ */
+export interface BaseResponse {
+  /** 响应码 */
+  code: string;
+  /** 描述信息 */
+  description: string;
+  /** 解决方案 */
+  solution: string;
+  /** 数据内容 */
+  data: Record<string, any>;
+}
+
+/**
+ * 节点连通性测试
+ * @param request Echo 测试请求参数
+ * @returns Echo 测试结果,包含成功状态和输出信息
+ * @throws 当测试失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * const result = await echoTest({
+ *   address: '192.168.1.3',
+ *   port: 6299,
+ *   aet: 'testscp',
+ *   aec: 'testscu',
+ *   verbose: false,
+ *   debug: false
+ * });
+ * console.log('连通性测试:', result.data.ok);
+ * ```
+ */
+export const echoTest = async (
+  request: EchoTestRequest
+): Promise<EchoTestResponse> => {
+  try {
+    const response = await axiosInstance.post<EchoTestResponse>(
+      '/auth/scp/echo',
+      {
+        verbose: request.verbose ?? false,
+        debug: request.debug ?? false,
+        address: request.address,
+        port: request.port,
+        aet: request.aet,
+        aec: request.aec,
+      }
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`节点连通性测试失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error testing node connectivity:', error);
+    throw error;
+  }
+};
+
+/**
+ * 获取传输队列的 PACS 节点列表
+ * @returns PACS 节点列表
+ * @throws 当请求失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * const result = await getSendQueuePacsList();
+ * console.log('PACS 节点列表:', result.data.scp);
+ * ```
+ */
+export const getSendQueuePacsList = async (): Promise<SendQueuePacsListResponse> => {
+  try {
+    const response = await axiosInstance.get<SendQueuePacsListResponse>(
+      '/auth/scp/pacs'
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`获取 PACS 节点列表失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error fetching send queue PACS list:', error);
+    throw error;
+  }
+};
+
+/**
+ * 获取发送队列
+ * @param params 查询参数 (可选)
+ * @returns 发送队列列表
+ * @throws 当请求失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * // 获取所有发送任务
+ * const allTasks = await getSendQueue();
+ * 
+ * // 按时间范围查询
+ * const tasksInRange = await getSendQueue({
+ *   start_time: '2025-10-10T00:00:00.000+08:00',
+ *   end_time: '2025-10-10T23:59:59.999+08:00'
+ * });
+ * console.log('发送队列:', tasksInRange.data);
+ * ```
+ */
+export const getSendQueue = async (
+  params?: GetSendQueueParams
+): Promise<SendQueueResponse> => {
+  try {
+    const response = await axiosInstance.get<SendQueueResponse>(
+      '/auth/scp/store',
+      {
+        params: {
+          start_time: params?.start_time,
+          end_time: params?.end_time,
+        },
+      }
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`获取发送队列失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error fetching send queue:', error);
+    throw error;
+  }
+};
+
+/**
+ * 删除发送任务
+ * @param taskIds 任务 ID 列表
+ * @returns 删除结果
+ * @throws 当删除失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * const result = await deleteSendTask([
+ *   '0199cd46-82f0-76c5-b1d3-9399668a1a05',
+ *   '0199cd46-460d-770e-ac8e-549939a4a7d4'
+ * ]);
+ * console.log('删除成功:', result);
+ * ```
+ */
+export const deleteSendTask = async (
+  taskIds: string[]
+): Promise<BaseResponse> => {
+  try {
+    const response = await axiosInstance.delete<BaseResponse>(
+      '/auth/scp/task',
+      {
+        data: taskIds,
+      }
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`删除发送任务失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error deleting send task:', error);
+    throw error;
+  }
+};
+
+/**
+ * 重试发送任务
+ * @param instanceUid 图像实例 UID
+ * @returns 重试结果,包含成功状态和输出信息
+ * @throws 当重试失败时抛出错误
+ * 
+ * @example
+ * ```typescript
+ * const result = await retrySendTask(
+ *   '1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671'
+ * );
+ * console.log('重试成功:', result.data.ok);
+ * ```
+ */
+export const retrySendTask = async (
+  instanceUid: string
+): Promise<RetrySendTaskResponse> => {
+  try {
+    const response = await axiosInstance.post<RetrySendTaskResponse>(
+      '/auth/scp/store_reply',
+      {
+        instance_uid: instanceUid,
+      }
+    );
+
+    if (response.data.code !== '0x000000') {
+      throw new Error(`重试发送任务失败: ${response.data.description}`);
+    }
+
+    return response.data;
+  } catch (error) {
+    console.error('Error retrying send task:', error);
+    throw error;
+  }
+};