sync.ts 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import axios from "@/dbo/main";
  2. import { list } from "@/store/measure";
  3. import { baseLines } from "@/store/baseLine";
  4. import { basePoints } from "@/store/basePoint";
  5. import { fixPoints } from "@/store/fixPoint";
  6. import { photos } from "@/store/photos";
  7. import { accidentPhotos } from "@/store/accidentPhotos";
  8. import { roadPhotos } from "@/store/roadPhotos";
  9. import { base64ToBlob, blobToBase64, debounce, getId } from "@/utils";
  10. import { watch } from "vue";
  11. import { genUseLoading, params } from "@/hook";
  12. import router, { writeRouteName } from "@/router";
  13. import { baseURL } from "@/dbo/main";
  14. import { defaultUses, uses } from "@/store/SVGLabel";
  15. import { imageRotate } from "@/utils/image-rotate";
  16. import { sceneSeting } from "./sceneSeting";
  17. import { tables } from "./tables";
  18. const global = window as any;
  19. const normalImage = async (url: string) => {
  20. const getUrl = await api.getFile(url);
  21. const blob = await imageRotate(getUrl);
  22. if (!blob) {
  23. return url;
  24. } else {
  25. return await api.uploadImage(new File([blob], getId()));
  26. }
  27. };
  28. let count = 0;
  29. export const api = !global.android
  30. ? // true
  31. // const api = import.meta.env.DEV
  32. {
  33. async setStore(data) {
  34. return axios.post("sceneStore", data);
  35. },
  36. async getStore() {
  37. return (await axios.get("/attach/sceneStore")).data;
  38. },
  39. async uploadImage(file) {
  40. return (
  41. await axios({
  42. url: "/upload",
  43. headers: { "Content-Type": "multipart/form-data" },
  44. method: "post",
  45. data: { file },
  46. })
  47. ).data.data as string;
  48. },
  49. async downloadImage(file) {
  50. window.open(URL.createObjectURL(file));
  51. return true;
  52. },
  53. async shareImage(filename: string) {
  54. await window.open(await api.getFile(filename));
  55. },
  56. async getFile(url) {
  57. if (url.includes(baseURL)) {
  58. url = url.substring(baseURL.length);
  59. }
  60. url = url.trim();
  61. const paths = url.split("/");
  62. const notBase64BaseTypes = [".png", ".jpg"];
  63. const notBase64 = notBase64BaseTypes.some((type) => paths[paths.length - 1].includes(type));
  64. if (notBase64) {
  65. // await new Promise((resolve) => setTimeout(resolve, 2000));
  66. return baseURL + url;
  67. } else {
  68. const data = await axios.get(url, { responseType: "blob" });
  69. const base64 = await blobToBase64(data.data);
  70. return URL.createObjectURL(base64ToBlob(base64));
  71. }
  72. },
  73. async photograph(rotate = true) {
  74. const file = await new Promise<File>((resolve) => {
  75. const input = document.createElement("input");
  76. input.type = "file";
  77. input.click();
  78. input.addEventListener("change", (ev) => {
  79. resolve(input.files[0]);
  80. });
  81. });
  82. const url = await this.uploadImage(file);
  83. return rotate ? await normalImage(url) : url;
  84. },
  85. async selectPhotoAlbum(rotate = true) {
  86. return await this.photograph(rotate);
  87. },
  88. async closePage() {
  89. return router.push({ name: writeRouteName.scene });
  90. },
  91. }
  92. : {
  93. shareImage(filename: string) {
  94. return new Promise((resolve) => {
  95. global.shareImageCallback = (data) => {
  96. delete global.shareImageCallback;
  97. resolve(data);
  98. };
  99. global.android.shareImage(filename, "shareImageCallback");
  100. });
  101. },
  102. setStore(data) {
  103. return new Promise((resolve) => {
  104. global.setSceneStoreCallback = (data) => {
  105. resolve(data);
  106. };
  107. global.android.setSceneStore(params.m + "/store.json", JSON.stringify(data), "setSceneStoreCallback");
  108. });
  109. },
  110. getStore() {
  111. return new Promise((resolve) => {
  112. global.getSceneStoreCallback = (data) => {
  113. resolve(data);
  114. };
  115. global.android.getSceneStore(params.m + "/store.json", "getSceneStoreCallback");
  116. });
  117. },
  118. // genUseLoading()
  119. async getFile(fileUrl: string) {
  120. fileUrl = fileUrl.trim();
  121. if (fileUrl.includes(params.m)) {
  122. fileUrl = fileUrl.substring(fileUrl.indexOf(params.m) + params.m.length);
  123. }
  124. fileUrl = new URL(fileUrl, "http://www.a.com").pathname;
  125. fileUrl = (params.realPath || params.m) + fileUrl;
  126. const paths = fileUrl.split("/");
  127. const notBase64BaseTypes = [
  128. // ".png", ".jpg"
  129. // , ".bin"
  130. ];
  131. const notBase64 = notBase64BaseTypes.some((type) => paths[paths.length - 1].includes(type));
  132. if (!notBase64) {
  133. return await new Promise<string>((resolve) => {
  134. const apiName = `getImageCallback${count++}`;
  135. global[apiName] = (base64) => {
  136. console.error("请求url:" + fileUrl, "返回:" + base64.substring(0, 60));
  137. resolve(URL.createObjectURL(base64ToBlob(base64)));
  138. delete global[apiName];
  139. };
  140. global.android.getImage(fileUrl, apiName);
  141. });
  142. } else {
  143. return fileUrl;
  144. }
  145. },
  146. uploadImage(file: File) {
  147. return new Promise<string>(async (resolve) => {
  148. const apiName = `uploadImageCallback${count++}`;
  149. global[apiName] = (data) => {
  150. resolve(data);
  151. delete global[apiName];
  152. };
  153. const data = await blobToBase64(file);
  154. global.android.uploadImage(params.m + "/attach/upload/" + file.name, data, apiName);
  155. });
  156. },
  157. downloadImage(file: File) {
  158. return new Promise<boolean>(async (resolve) => {
  159. const apiName = `downloadImageCallback${count++}`;
  160. global[apiName] = () => {
  161. resolve(true);
  162. delete global[apiName];
  163. };
  164. const data = await blobToBase64(file);
  165. // file为base64
  166. global.android.downloadImage(file.name, data, apiName);
  167. });
  168. },
  169. photograph(rotate = true) {
  170. return new Promise<string>((resolve) => {
  171. const apiName = `photograph${count++}`;
  172. global[apiName] = (data) => {
  173. data ? (rotate ? normalImage(data).then(resolve) : resolve(data)) : resolve(null);
  174. delete global[apiName];
  175. };
  176. global.android.cameraPhotograph(params.m, apiName);
  177. });
  178. },
  179. selectPhotoAlbum(rotate = true) {
  180. return new Promise<string>((resolve) => {
  181. const apiName = `selectPhotoAlbum${count++}`;
  182. global[apiName] = (data) => {
  183. data ? (rotate ? normalImage(data).then(resolve) : resolve(data)) : resolve(null);
  184. delete global[apiName];
  185. };
  186. global.android.selectPhotoAlbum(params.m, apiName);
  187. });
  188. },
  189. closePage() {
  190. return new Promise((resolve) => {
  191. global.closeWebViewCallback = resolve;
  192. global.android.closeWebView("closeWebViewCallback");
  193. });
  194. },
  195. };
  196. export const back = () => {
  197. api.closePage();
  198. };
  199. const loadStore = async () => {
  200. const data: any = await api.getStore();
  201. list.value = data?.measures || [];
  202. baseLines.value = data?.baseLines || [];
  203. basePoints.value = data?.basePoints || [];
  204. sceneSeting.value = data?.sceneSeting;
  205. fixPoints.value = data?.fixPoints || [];
  206. photos.value = data?.photos || [];
  207. accidentPhotos.value = data?.accidentPhotos || [];
  208. roadPhotos.value = data?.roadPhotos || [];
  209. uses.value = data?.uses || defaultUses;
  210. tables.value = data?.tables || {};
  211. syncSceneStore();
  212. };
  213. export const updateSceneStore = debounce(api.setStore, 300);
  214. export const uploadImage = (blob: Blob, name = `${getId()}.jpg`) => {
  215. const file = new File([blob], name);
  216. return api.uploadImage(file);
  217. };
  218. export const downloadImage = async (data: Blob | string, name = `${getId()}.jpg`) => {
  219. const blob: Blob = typeof data === "string" ? (await axios.get(data, { responseType: "blob" })).data : data;
  220. const file = new File([blob], name, { type: "image/jpeg" });
  221. return await api.downloadImage(file);
  222. };
  223. const syncSceneStore = () => {
  224. return watch(
  225. () => ({
  226. measures: list.value,
  227. baseLines: baseLines.value,
  228. sceneSeting: sceneSeting.value,
  229. basePoints: basePoints.value,
  230. fixPoints: fixPoints.value,
  231. photos: photos.value,
  232. uses: uses.value,
  233. accidentPhotos: accidentPhotos.value,
  234. roadPhotos: roadPhotos.value,
  235. tables: tables.value,
  236. }),
  237. (data) => {
  238. console.error("收到数据源更新")
  239. updateSceneStore(data);
  240. },
  241. { deep: true, flush: 'sync' }
  242. );
  243. };
  244. loadStore().catch((e) => {
  245. console.error(e);
  246. alert("场景数据加载失败");
  247. });