import { message } from 'ant-design-vue'; import axios from 'axios'; import { ref } from 'vue'; import { downloadFile } from '../services/utils'; const vwedApi = '/vwedApi'; const API_BASE_URL = '' + vwedApi + '/api/vwed-map-converter'; const mapConverterHttp = axios.create(); export function useMapConversion() { const isConverting = ref(false); /** * Imports or updates a Scene using an SMAP file. * Calls the smap-to-scene API endpoint. * @param smapFile The .smap file. * @param sceneFile Optional .scene file for updates. If not provided, a new scene is created. * @returns The resulting scene JSON string, or null if failed. */ const convertSmapToScene = async (smapFile: File, sceneFile?: File): Promise => { isConverting.value = true; const isUpdate = !!sceneFile; const actionText = isUpdate ? '更新' : '新建'; try { const formData = new FormData(); formData.append('smap_file', smapFile); if (sceneFile) { formData.append('scene_file', sceneFile); } const response = await mapConverterHttp.post(`${API_BASE_URL}/smap-to-scene`, formData, { headers: { 'Content-Type': 'multipart/form-data' }, }); if (response.data.code === 200 || response.data.success) { message.success(`通过 SMAP ${actionText} Scene 成功!`); return JSON.stringify(response.data.data, null, 2); } else { throw new Error(response.data.message || `${actionText}失败`); } } catch (error: any) { const errorMessage = error.response?.data?.message || error.message || `通过 SMAP ${actionText} Scene 失败`; message.error(errorMessage); return null; } finally { isConverting.value = false; } }; /** * Exports a Scene to an SMAP file format. * Requires both a scene and a base smap file. * Calls the scene-to-smap API endpoint. * @param sceneFile The .scene file to export. * @param smapFile The base .smap file to update. * @param filename The base name for the downloaded file. */ const exportSceneToSmap = async (sceneFile: File, smapFile: File, filename: string) => { isConverting.value = true; try { const formData = new FormData(); formData.append('scene_file', sceneFile); formData.append('smap_file', smapFile); const response = await mapConverterHttp.post(`${API_BASE_URL}/scene-to-smap`, formData, { headers: { 'Content-Type': 'multipart/form-data' }, }); if (response.data.code === 200 || response.data.success) { const smapContent = JSON.stringify(response.data?.data, null, 2); const blob = new Blob([smapContent], { type: 'application/json' }); const url = URL.createObjectURL(blob); const outputFilename = response.data?.output_file ? response.data.output_file.split(/[/\\]/).pop() : `${filename}.smap`; downloadFile(url, outputFilename); URL.revokeObjectURL(url); message.success('导出到 SMAP 文件成功!'); } else { throw new Error(response.data.message || '导出失败'); } } catch (error: any) { const errorMessage = error.response?.data?.message || error.message || '导出到 SMAP 文件失败'; message.error(errorMessage); } finally { isConverting.value = false; } }; const convertSceneToIray = async ( sceneJson: string, smapFile: File, filename: string, irayParams?: { mapWidth: number; mapHeight: number; xAttrMin: number; yAttrMin: number }, ) => { isConverting.value = true; try { const formData = new FormData(); const sceneBlob = new Blob([sceneJson], { type: 'application/json' }); formData.append('scene_file', sceneBlob, `${filename}.scene`); formData.append('smap_file', smapFile); // Append IRAY parameters if they exist if (irayParams) { formData.append('map_width', String(irayParams.mapWidth)); formData.append('map_height', String(irayParams.mapHeight)); formData.append('x_attr_min', String(irayParams.xAttrMin)); formData.append('y_attr_min', String(irayParams.yAttrMin)); } const response = await mapConverterHttp.post(`${API_BASE_URL}/smap-to-iray`, formData, { headers: { 'Content-Type': 'multipart/form-data' }, responseType: 'blob', }); const blob = response?.data as unknown as Blob; if (!blob || blob.size === 0) { throw new Error('返回的二进制文件为空'); } const disposition = response?.headers?.['content-disposition'] || ''; let downloadFilename = `${filename}.zip`; const filenameMatch = disposition.match(/filename=([^;]+)/i); if (filenameMatch && filenameMatch[1]) { downloadFilename = decodeURIComponent(filenameMatch[1].replace(/"/g, '')); } const url = URL.createObjectURL(blob); downloadFile(url, downloadFilename); URL.revokeObjectURL(url); message.success('Scene 转换为 IRAY 并下载成功!'); } catch (error: any) { const errorMessage = error.response?.data?.message || error.message || 'Scene 转换为 IRAY 失败'; message.error(errorMessage); } finally { isConverting.value = false; } }; return { isConverting, convertSmapToScene, exportSceneToSmap, convertSceneToIray, }; }