diff --git a/src/api/base/zwApi.ts b/src/api/base/zwApi.ts index 6ef4d56..661a392 100644 --- a/src/api/base/zwApi.ts +++ b/src/api/base/zwApi.ts @@ -31,6 +31,16 @@ export const findAllZw = () => { + + + + + + + + + + diff --git a/src/api/vr/index.ts b/src/api/vr/index.ts new file mode 100644 index 0000000..275f060 --- /dev/null +++ b/src/api/vr/index.ts @@ -0,0 +1,293 @@ +import { get, post, file } from '@/utils/request'; +import { config, interceptor } from '@/utils/request'; + +/** + * 获取楼栋列表(分页) + */ +export const getBuildingList = async (params?: { + buildingName?: string; + buildingType?: string; + status?: string; + pageNum?: number; + pageSize?: number; +}) => { + return await get('/api/building/findPage', params); +}; + +/** + * 获取所有启用的楼栋列表(不分页) + */ +export const getAllBuildings = async () => { + const res = await get('/api/building/findPage', { + status: 'A', + pageNum: 1, + pageSize: 1000, + }); + return res; +}; + +/** + * 获取VR位置列表(分页) + */ +export const getVRLocations = async (params?: { + buildingId?: string; + locationType?: string; + parentId?: string; + level?: number; + status?: string; + pageNum?: number; + pageSize?: number; +}) => { + return await get('/api/vrLocation/findPage', params); +}; + +/** + * 获取所有启用的VR位置列表(不分页,用于展示) + */ +export const getAllVRLocations = async (params?: { + buildingId?: string; + locationType?: string; + status?: string; +}) => { + const res = await get('/api/vrLocation/findPage', { + ...params, + status: params?.status || 'A', + pageNum: 1, + pageSize: 1000, + }); + return res; +}; + +/** + * 获取VR位置详情(通过ID查询) + */ +export const getVRLocationDetail = async (locationId: string) => { + const res = await get('/api/vrLocation/findById', { + id: locationId, + }); + + // 后端返回的数据结构:{resultCode, message, data} 或 {success, resultCode, message, data} + // 检查多种可能的返回格式 + const resultCode = res?.resultCode ?? (res?.success ? 1 : 0); + const data = res?.data ?? res?.result; + + if (resultCode === 1 && data) { + return { + resultCode: 1, + message: res?.message || '查询成功', + data: data, + }; + } + return { + resultCode: 0, + message: res?.message || '未找到数据', + data: null, + }; +}; + +/** + * 获取位置连接关系(热点) + */ +export const getVRLocationLinks = async (fromLocationId: string) => { + return await get('/api/vrLocationLink/findPage', { + fromLocationId: fromLocationId, + status: 'A', + pageNum: 1, + pageSize: 100, + }); +}; + +/** + * 保存VR位置信息 + */ +export const saveVRLocation = async (data: { + id?: string; + locationName: string; + locationType: string; + parentId?: string; + level: number; + buildingId?: string; + floorNum?: number; + roomNum?: string; + description?: string; + imageUrl: string; + thumbnailUrl?: string; + longitude?: number; + latitude?: number; + sortOrder?: number; + status?: string; +}) => { + return await post('/api/vrLocation/save', data); +}; + +/** + * 保存VR位置(包含位置、拍摄记录、位置连接) + */ +export const saveVRLocationWithDetails = async (data: { + // 位置信息 + id?: string; + locationName: string; + locationType: string; + parentId?: string; + level: number; + buildingId?: string; + floorNum?: number; + roomNum?: string; + description?: string; + imageUrl: string; + thumbnailUrl?: string; + longitude?: number; + latitude?: number; + sortOrder?: number; + status?: string; + // 拍摄记录信息 + saveShootingRecord?: boolean; + shootingMethod?: string; + doorDirection?: string; + shootTime?: string; + shootBy?: string; + // 位置连接信息 + createLocationLink?: boolean; + lastLocationId?: string; + lastLocationDoorDirection?: string; + lastLocationName?: string; +}) => { + return await post('/api/vrLocation/saveWithDetails', data); +}; + +/** + * 获取VR拍摄记录列表(分页) + */ +export const getVRShootingRecords = async (params?: { + locationId?: string; + status?: string; + pageNum?: number; + pageSize?: number; +}) => { + return await get('/api/vrShootingRecord/findPage', params); +}; + +/** + * 保存VR拍摄记录 + */ +export const saveVRShootingRecord = async (data: { + id?: string; + locationId?: string; + locationName: string; + locationType: string; + shootingMethod?: string; + imageUrl: string; + doorDirection?: string; + shootTime?: string; + shootBy?: string; + status?: string; +}) => { + return await post('/api/vrShootingRecord/save', data); +}; + +/** + * 保存VR位置连接(热点) + */ +export const saveVRLocationLink = async (data: { + id?: string; + fromLocationId: string; + toLocationId: string; + hotspotPositionX?: number; + hotspotPositionY?: number; + hotspotPositionZ?: number; + hotspotLabel?: string; + direction?: string; + sortOrder?: number; + status?: string; +}) => { + return await post('/api/vrLocationLink/save', data); +}; + +/** + * VR全景图上传(如果需要单独上传接口) + * @param filePath 图片文件路径 + * @param formData 表单数据 + */ +export const uploadVRImage = async ( + filePath: string, + formData?: Record +) => { + // 使用uni.uploadFile上传 + return new Promise((resolve, reject) => { + const uploadOption: UniNamespace.UploadFileOption = { + url: `${config.baseUrl}/api/attachment/upload`, // 使用通用的附件上传接口 + filePath: filePath, + name: 'file', + formData: formData || {}, + header: {}, + }; + + // 应用拦截器 + interceptor.request(uploadOption); + + uni.uploadFile({ + ...uploadOption, + success: (res) => { + try { + const data = JSON.parse(res.data); + if (data.resultCode === 1) { + resolve(data); + } else { + reject(new Error(data.message || '上传失败')); + } + } catch (e) { + reject(e); + } + }, + fail: (err) => { + reject(err); + }, + }); + }); +}; + +/** + * 上传视频并处理为全景图 + * @param videoPath 视频文件路径 + * @param params 其他参数(可选) + */ +export const uploadVideoAndProcess = async ( + videoPath: string, + params?: { + locationId?: string; + locationName?: string; + } +) => { + return new Promise((resolve, reject) => { + const uploadOption: UniNamespace.UploadFileOption = { + url: `${config.baseUrl}/api/vrLocation/video/processPanorama`, + filePath: videoPath, + name: 'video', + formData: params || {}, + header: {}, + }; + + // 应用拦截器 + interceptor.request(uploadOption); + + uni.uploadFile({ + ...uploadOption, + success: (res) => { + try { + const data = JSON.parse(res.data); + if (data.resultCode === 1) { + resolve(data); + } else { + reject(new Error(data.message || '视频处理失败')); + } + } catch (e) { + reject(e); + } + }, + fail: (err) => { + reject(err); + }, + }); + }); +}; + diff --git a/src/components/BasicForm/components/BasicEditor.vue b/src/components/BasicForm/components/BasicEditor.vue new file mode 100644 index 0000000..da7c879 --- /dev/null +++ b/src/components/BasicForm/components/BasicEditor.vue @@ -0,0 +1,496 @@ +