import axiosInstance from './interceptor'; import { API_BASE_URL } from './config'; /** * 发送图像请求参数 */ 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 => { try { const response = await axiosInstance.post( '/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; } }; /** * 按 Study 批量发送图像到 PACS 节点 * @param studyId Study 实例 UID (Study Instance UID) * @param pacsName PACS 节点名称 * @returns 发送结果,包含成功状态和输出信息 * @throws 当发送失败时抛出错误 * * @example * ```typescript * const result = await sendStudyToPacs( * '1.2.276.0.1000000.5.1.2.701601461.33458.1750833219.482097', * 'pacs1' * ); * console.log('发送成功:', result.data.ok); * ``` */ export const sendStudyToPacs = async ( studyId: string, pacsName: string ): Promise => { try { const response = await axiosInstance.post( '/auth/scp/study_store', { instance_uid: studyId, pacs_name: pacsName, } ); if (response.data.code !== '0x000000') { throw new Error(`按 Study 发送图像失败: ${response.data.description}`); } return response.data; } catch (error) { console.error('Error sending study to PACS:', error); throw error; } }; /** * 图像另存为响应类型 */ export interface SaveImageAsResponse { /** 响应码 */ code: string; /** 描述信息 */ description: string; /** 解决方案 */ solution: string; /** 数据内容 */ data: Record; } /** * 图像另存为 * 复制选中的图像到同一个 Study 中 * * @param sopInstanceUid 图像实例 UID (SOP Instance UID) * @returns 另存为结果 * @throws 当另存为失败时抛出错误 * * @example * ```typescript * await saveImageAs('1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671'); * ``` */ export const saveImageAs = async ( sopInstanceUid: string ): Promise => { try { const response = await axiosInstance.post( '/auth/image/save_as', { instance_uid: sopInstanceUid, } ); if (response.data.code !== '0x000000') { throw new Error(`图像另存为失败: ${response.data.description}`); } return response.data; } catch (error) { console.error('Error saving image as:', error); throw error; } }; /** * 图像处理参数响应类型 */ export interface GetProcessingParamsResponse { /** 响应码 */ code: string; /** 描述信息 */ description: string; /** 解决方案 */ solution: string; /** 数据内容 */ data: { /** 增益 */ contrast: number; /** 细节 */ detail: number; /** 动态范围 */ latitude: number; /** 噪声模式 */ noise: number; }; } /** * 获取当前图像处理参数 * 完成图像处理准备工作,并返回增益、细节、动态范围、噪声模式当前值 * * @param sopInstanceUid 图像实例 UID (SOP Instance UID) * @returns 当前图像处理参数 * @throws 当获取失败时抛出错误 * * @example * ```typescript * const params = await getImageProcessingParams('1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671'); * console.log('当前增益:', params.data.contrast); * ``` */ export const getImageProcessingParams = async ( sopInstanceUid: string ): Promise => { try { const response = await axiosInstance.get( `/auth/image/${sopInstanceUid}/preparation` ); if (response.data.code !== '0x000000') { throw new Error(`获取图像处理参数失败: ${response.data.description}`); } return response.data; } catch (error) { console.error('Error getting image processing params:', error); throw error; } }; /** * 保存图像处理参数请求类型 */ export interface SaveProcessingParamsRequest { /** 增益 */ contrast: number; /** 细节 */ detail: number; /** 动态范围 */ latitude: number; /** 噪声模式 */ noise: number; } /** * 获取处理的dcm */ export interface GetProcessedDcmRequest { /** 增益 */ contrast: string; /** 细节 */ detail: string; /** 动态范围 */ latitude: string; /** 噪声模式 */ noise: string; } /** * 构建处理后的dcm URL(不发送请求) * @param sopInstanceUid 图像实例 UID (SOP Instance UID) * @param params 图像处理参数 * @returns 处理后的dcm URL字符串 * @example * ```typescript * const url = buildProcessedDcmUrl('1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671', { * contrast: '5.0', * detail: '9.0', * latitude: '25.0', * noise: '12.0' * }); * console.log('处理后图像URL:', url); * ``` */ export const buildProcessedDcmUrl = ( sopInstanceUid: string, params: GetProcessedDcmRequest ): string => { const queryParams = new URLSearchParams({ contrast: params.contrast, detail: params.detail, latitude: params.latitude, noise: params.noise, }); return `${API_BASE_URL}pub/image/${sopInstanceUid}/proc?${queryParams.toString()}`;//暂时使用公开的访问方式,不需要token // return `${API_BASE_URL}auth/image/${sopInstanceUid}/proc?${queryParams.toString()}`; }; /** * 保存图像处理参数响应类型 */ export interface SaveProcessingParamsResponse { /** 响应码 */ code: string; /** 描述信息 */ description: string; /** 解决方案 */ solution: string; /** 数据内容 */ data: Record; } /** * 获取处理后的 dcm 文件 * 实时获取应用指定参数后的 dcm 文件(用于预览) * * @param sopInstanceUid 图像实例 UID (SOP Instance UID) * @param params 图像处理参数 * @returns 处理后的 dcm 文件 Blob * @throws 当获取失败时抛出错误 * * @example * ```typescript * const dcmBlob = await getProcessedDcm('1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671', { * contrast: 5.0, * detail: 9.0, * latitude: 25.0, * noise: 12.0 * }); * const blobUrl = URL.createObjectURL(dcmBlob); * ``` */ export const getProcessedDcm = async ( sopInstanceUid: string, params: GetProcessedDcmRequest ): Promise => { try { const response = await axiosInstance.get( `/auth/image/${sopInstanceUid}/proc`, { params: { contrast: params.contrast, detail: params.detail, latitude: params.latitude, noise: params.noise, }, responseType: 'blob', // 重要:指定响应类型为blob } ); return response.data; } catch (error) { console.error('Error getting processed dcm:', error); throw error; } }; /** * 保存图像处理参数 * 保存应用增益、细节、动态范围、噪声模式后的 dcm * * @param sopInstanceUid 图像实例 UID (SOP Instance UID) * @param params 图像处理参数 * @returns 保存结果 * @throws 当保存失败时抛出错误 * * @example * ```typescript * await saveImageProcessingParams('1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671', { * contrast: 5.0, * detail: 9.0, * latitude: 25.0, * noise: 12.0 * }); * ``` */ export const saveImageProcessingParams = async ( sopInstanceUid: string, params: SaveProcessingParamsRequest ): Promise => { try { const response = await axiosInstance.post( `/auth/image/${sopInstanceUid}/proc`, params ); if (response.data.code !== '0x000000') { throw new Error(`保存图像处理参数失败: ${response.data.description}`); } return response.data; } catch (error) { console.error('Error saving image processing params:', error); throw error; } }; /** * 保存窗宽窗位请求类型 */ export interface SaveWindowCenterWidthRequest { /** 窗位 */ window_center: number; /** 窗宽 */ window_width: number; } /** * 保存窗宽窗位响应类型 */ export interface SaveWindowCenterWidthResponse { /** 响应码 */ code: string; /** 描述信息 */ description: string; /** 解决方案 */ solution: string; /** 数据内容 */ data: Record; } /** * 保存窗位到 dcm * * @param sopInstanceUid 图像实例 UID (SOP Instance UID) * @param windowCenter 窗位 * @param windowWidth 窗宽 * @returns 保存结果 * @throws 当保存失败时抛出错误 * * @example * ```typescript * await saveWindowCenterWidth('1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671', 50, 100); * ``` */ export const saveWindowCenterWidth = async ( sopInstanceUid: string, windowCenter: number, windowWidth: number ): Promise => { try { const response = await axiosInstance.post( `/auth/image/${sopInstanceUid}/wcww`, { window_center: windowCenter, window_width: windowWidth, } ); if (response.data.code !== '0x000000') { throw new Error(`保存窗宽窗位失败: ${response.data.description}`); } return response.data; } catch (error) { console.error('Error saving window center/width:', error); throw error; } }; // ============================================================================= // 图像处理v2 API // ============================================================================= /** * 获取tiff图像响应类型 */ export interface GetTiffResponse { /** 响应码 */ code: string; /** 描述信息 */ description: string; /** 解决方案 */ solution: string; /** 文件数据 */ data: File; } /** * 获取tiff图像(公开接口) * * @param filename tiff文件名 * @returns tiff文件 Blob * @throws 当获取失败时抛出错误 * * @example * ```typescript * const tiffBlob = await getTiffImagePublic('1.2.276.0.1000000.5.1.4.dcm.tiff'); * const blobUrl = URL.createObjectURL(tiffBlob); * ``` */ export const getTiffImagePublic = async ( filename: string ): Promise => { try { const response = await axiosInstance.get( `/pub/tif/${filename}`, { responseType: 'blob', // 重要:指定响应类型为blob } ); return response.data; } catch (error) { console.error('Error getting tiff image (public):', error); throw error; } }; /** * 获取tiff图像(认证接口) * * @param filename tiff文件名 * @returns tiff文件 Blob * @throws 当获取失败时抛出错误 * * @example * ```typescript * const tiffBlob = await getTiffImageAuth('1.2.276.0.1000000.5.1.4.dcm.tiff'); * const blobUrl = URL.createObjectURL(tiffBlob); * ``` */ export const getTiffImageAuth = async ( filename: string ): Promise => { try { const response = await axiosInstance.get( `/auth/f/tif/${filename}`, { responseType: 'blob', // 重要:指定响应类型为blob } ); return response.data; } catch (error) { console.error('Error getting tiff image (auth):', error); throw error; } }; /** * 图像处理参数v2响应类型 */ export interface GetImageProcessingParamsV2Response { /** 响应码 */ code: string; /** 描述信息 */ description: string; /** 解决方案 */ solution: string; /** 数据内容 */ data: { /** 增益 */ contrast: number; /** 细节 */ detail: number; /** 动态范围 */ latitude: number; /** 噪声模式 */ noise: number; /** 对比度 */ ww_coef: number; /** 亮度 */ wl_coef: number; }; } /** * 获取当前dcm所用的图像处理参数(v2) * * @param sopInstanceUid 图像实例 UID (SOP Instance UID) * @returns 当前图像处理参数 * @throws 当获取失败时抛出错误 * * @example * ```typescript * const params = await getImageProcessingParamsV2('1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671'); * console.log('当前增益:', params.data.contrast); * console.log('当前对比度:', params.data.ww_coef); * ``` */ export const getImageProcessingParamsV2 = async ( sopInstanceUid: string ): Promise => { try { const response = await axiosInstance.get( `/auth/image/${sopInstanceUid}/img_proc_params` ); if (response.data.code !== '0x000000') { throw new Error(`获取图像处理参数失败: ${response.data.description}`); } return response.data; } catch (error) { console.error('Error getting image processing params v2:', error); throw error; } }; /** * 重建dcm请求类型 */ export interface RebuildDcmRequest { /** 增益 */ contrast: number; /** 细节 */ detail: number; /** 动态范围 */ latitude: number; /** 噪声模式 */ noise: number; /** 对比度 */ ww_coef: number; /** 亮度 */ wl_coef: number; } /** * 重建dcm响应类型 */ export interface RebuildDcmResponse { /** 响应码 */ code: string; /** 描述信息 */ description: string; /** 解决方案 */ solution: string; /** 数据内容 */ data: Record; } /** * 重建dcm(保存应用增强参数后的dcm) * * @param sopInstanceUid 图像实例 UID (SOP Instance UID) * @param params 图像处理参数 * @returns 重建结果 * @throws 当重建失败时抛出错误 * * @example * ```typescript * await rebuildDcm('1.2.276.0.1000000.5.1.4.701601461.19649.1749545373.668671', { * contrast: 5.0, * detail: 8.0, * latitude: 6.0, * noise: 4.0, * ww_coef: 1.2, * wl_coef: -0.5 * }); * ``` */ export const rebuildDcm = async ( sopInstanceUid: string, params: RebuildDcmRequest ): Promise => { try { const response = await axiosInstance.post( `/auth/image/${sopInstanceUid}/rebuild_dcm`, params ); if (response.data.code !== '0x000000') { throw new Error(`重建dcm失败: ${response.data.description}`); } return response.data; } catch (error) { console.error('Error rebuilding dcm:', error); throw error; } };