web-map/src/hooks/useMapConversion.ts

116 lines
4.2 KiB
TypeScript
Raw Normal View History

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';
// Create a new Axios instance specifically for map conversion APIs
// to avoid conflicts with the global instance's baseURL.
const mapConverterHttp = axios.create();
export function useMapConversion() {
const isConverting = ref(false);
const convertSmapToScene = async (smapFile: File): Promise<string | null> => {
isConverting.value = true;
try {
const formData = new FormData();
formData.append('smap_file', smapFile);
const response = await mapConverterHttp.post<any>(`${API_BASE_URL}/smap-to-scene`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
// Note: axios wraps the response in a `data` object.
if (response.data.code === 200 || response.data.success) {
message.success('SMAP 转换为 Scene 成功!');
return JSON.stringify(response.data.data, null, 2);
} else {
throw new Error(response.data.message || '转换失败');
}
} catch (error: any) {
const errorMessage = error.response?.data?.message || error.message || 'SMAP 转换为 Scene 失败';
message.error(errorMessage);
return null;
} finally {
isConverting.value = false;
}
};
const convertSceneToSmap = async (sceneJson: string, filename: string) => {
isConverting.value = true;
try {
const formData = new FormData();
const sceneBlob = new Blob([sceneJson], { type: 'application/json' });
formData.append('scene_file', sceneBlob, `${filename}.scene`);
const response = await mapConverterHttp.post<any>(`${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('Scene 转换为 SMAP 并下载成功!');
} else {
throw new Error(response.data.message || '转换失败');
}
} catch (error: any) {
const errorMessage = error.response?.data?.message || error.message || 'Scene 转换为 SMAP 失败';
message.error(errorMessage);
} finally {
isConverting.value = false;
}
};
const convertSceneToIray = async (sceneJson: string, filename: string) => {
isConverting.value = true;
try {
const formData = new FormData();
const sceneBlob = new Blob([sceneJson], { type: 'application/json' });
formData.append('scene_file', sceneBlob, `${filename}.scene`);
const response = await mapConverterHttp.post(`${API_BASE_URL}/scene-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`; // Default
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,
convertSceneToSmap,
convertSceneToIray,
};
}