import axios from "@/dbo/main"; import { list } from "@/store/measure"; import { baseLines } from "@/store/baseLine"; import { basePoints } from "@/store/basePoint"; import { fixPoints } from "@/store/fixPoint"; import { photos } from "@/store/photos"; import { accidentPhotos } from "@/store/accidentPhotos"; import { roadPhotos } from "@/store/roadPhotos"; import { base64ToBlob, blobToBase64, debounce, getId } from "@/utils"; import { watch } from "vue"; import { genUseLoading, params } from "@/hook"; import router, { writeRouteName } from "@/router"; import { baseURL } from "@/dbo/main"; import { defaultUses, uses } from "@/store/SVGLabel"; import { imageRotate } from "@/utils/image-rotate"; import { sceneSeting } from "./sceneSeting"; import { tables } from "./tables"; const global = window as any; const normalImage = async (url: string) => { const getUrl = await api.getFile(url); const blob = await imageRotate(getUrl); if (!blob) { return url; } else { return await api.uploadImage(new File([blob], getId())); } }; let count = 0; export const api = !global.android ? // true // const api = import.meta.env.DEV { async setStore(data) { return axios.post("sceneStore", data); }, async getStore() { return (await axios.get("/attach/sceneStore")).data; }, async uploadImage(file) { return ( await axios({ url: "/upload", headers: { "Content-Type": "multipart/form-data" }, method: "post", data: { file }, }) ).data.data as string; }, async downloadImage(file) { window.open(URL.createObjectURL(file)); return true; }, async shareImage(filename: string) { await window.open(await api.getFile(filename)); }, async getFile(url) { if (url.includes(baseURL)) { url = url.substring(baseURL.length); } url = url.trim(); const paths = url.split("/"); const notBase64BaseTypes = [".png", ".jpg"]; const notBase64 = notBase64BaseTypes.some((type) => paths[paths.length - 1].includes(type)); if (notBase64) { // await new Promise((resolve) => setTimeout(resolve, 2000)); return baseURL + url; } else { const data = await axios.get(url, { responseType: "blob" }); const base64 = await blobToBase64(data.data); return URL.createObjectURL(base64ToBlob(base64)); } }, async photograph(rotate = true) { const file = await new Promise((resolve) => { const input = document.createElement("input"); input.type = "file"; input.click(); input.addEventListener("change", (ev) => { resolve(input.files[0]); }); }); const url = await this.uploadImage(file); return rotate ? await normalImage(url) : url; }, async selectPhotoAlbum(rotate = true) { return await this.photograph(rotate); }, async closePage() { return router.push({ name: writeRouteName.scene }); }, } : { shareImage(filename: string) { return new Promise((resolve) => { global.shareImageCallback = (data) => { delete global.shareImageCallback; resolve(data); }; global.android.shareImage(filename, "shareImageCallback"); }); }, setStore(data) { return new Promise((resolve) => { global.setSceneStoreCallback = (data) => { resolve(data); }; global.android.setSceneStore(params.m + "/store.json", JSON.stringify(data), "setSceneStoreCallback"); }); }, getStore() { return new Promise((resolve) => { global.getSceneStoreCallback = (data) => { resolve(data); }; global.android.getSceneStore(params.m + "/store.json", "getSceneStoreCallback"); }); }, // genUseLoading() async getFile(fileUrl: string) { fileUrl = fileUrl.trim(); if (fileUrl.includes(params.m)) { fileUrl = fileUrl.substring(fileUrl.indexOf(params.m) + params.m.length); } fileUrl = new URL(fileUrl, "http://www.a.com").pathname; fileUrl = (params.realPath || params.m) + fileUrl; const paths = fileUrl.split("/"); const notBase64BaseTypes = [ // ".png", ".jpg" // , ".bin" ]; const notBase64 = notBase64BaseTypes.some((type) => paths[paths.length - 1].includes(type)); if (!notBase64) { return await new Promise((resolve) => { const apiName = `getImageCallback${count++}`; global[apiName] = (base64) => { console.error("请求url:" + fileUrl, "返回:" + base64.substring(0, 60)); resolve(URL.createObjectURL(base64ToBlob(base64))); delete global[apiName]; }; global.android.getImage(fileUrl, apiName); }); } else { return fileUrl; } }, uploadImage(file: File) { return new Promise(async (resolve) => { const apiName = `uploadImageCallback${count++}`; global[apiName] = (data) => { resolve(data); delete global[apiName]; }; const data = await blobToBase64(file); global.android.uploadImage(params.m + "/attach/upload/" + file.name, data, apiName); }); }, downloadImage(file: File) { return new Promise(async (resolve) => { const apiName = `downloadImageCallback${count++}`; global[apiName] = () => { resolve(true); delete global[apiName]; }; const data = await blobToBase64(file); // file为base64 global.android.downloadImage(file.name, data, apiName); }); }, photograph(rotate = true) { return new Promise((resolve) => { const apiName = `photograph${count++}`; global[apiName] = (data) => { data ? (rotate ? normalImage(data).then(resolve) : resolve(data)) : resolve(null); delete global[apiName]; }; global.android.cameraPhotograph(params.m, apiName); }); }, selectPhotoAlbum(rotate = true) { return new Promise((resolve) => { const apiName = `selectPhotoAlbum${count++}`; global[apiName] = (data) => { data ? (rotate ? normalImage(data).then(resolve) : resolve(data)) : resolve(null); delete global[apiName]; }; global.android.selectPhotoAlbum(params.m, apiName); }); }, closePage() { return new Promise((resolve) => { global.closeWebViewCallback = resolve; global.android.closeWebView("closeWebViewCallback"); }); }, }; export const back = () => { api.closePage(); }; const loadStore = async () => { const data: any = await api.getStore(); list.value = data?.measures || []; baseLines.value = data?.baseLines || []; basePoints.value = data?.basePoints || []; sceneSeting.value = data?.sceneSeting; fixPoints.value = data?.fixPoints || []; photos.value = data?.photos || []; accidentPhotos.value = data?.accidentPhotos || []; roadPhotos.value = data?.roadPhotos || []; uses.value = data?.uses || defaultUses; tables.value = data?.tables || {}; syncSceneStore(); }; export const updateSceneStore = debounce(api.setStore, 300); export const uploadImage = (blob: Blob, name = `${getId()}.jpg`) => { const file = new File([blob], name); return api.uploadImage(file); }; export const downloadImage = async (data: Blob | string, name = `${getId()}.jpg`) => { const blob: Blob = typeof data === "string" ? (await axios.get(data, { responseType: "blob" })).data : data; const file = new File([blob], name, { type: "image/jpeg" }); return await api.downloadImage(file); }; const syncSceneStore = () => { return watch( () => ({ measures: list.value, baseLines: baseLines.value, sceneSeting: sceneSeting.value, basePoints: basePoints.value, fixPoints: fixPoints.value, photos: photos.value, uses: uses.value, accidentPhotos: accidentPhotos.value, roadPhotos: roadPhotos.value, tables: tables.value, }), (data) => { console.error("收到数据源更新") updateSceneStore(data); }, { deep: true, flush: 'sync' } ); }; loadStore().catch((e) => { console.error(e); alert("场景数据加载失败"); });