header.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <template>
  2. <Header :action-groups="actions" :title="title" no-back :draw="draw">
  3. <template #saves>
  4. <el-button type="primary" @click="saveHandler" :disabled="draw.drawing">
  5. 保存
  6. </el-button>
  7. <el-button @click="gotoTabulation" color="#E6E6E6" :disabled="draw.drawing">
  8. 图纸
  9. </el-button>
  10. </template>
  11. </Header>
  12. </template>
  13. <script lang="ts" setup>
  14. import Header from "../../../components/header/index.vue";
  15. import { ElButton } from "element-plus";
  16. import { useDraw } from "../../../components/container/use-draw.ts";
  17. import { selectScene } from "../../../dialog/vr/index.ts";
  18. import { Scene } from "../../../platform/platform-resource.ts";
  19. import { getHeaderActions, getImage } from "../../../components/header/actions.ts";
  20. import {
  21. tabulationData,
  22. refreshTabulationData,
  23. tableCoverWidth,
  24. tableCoverHeight,
  25. overviewData,
  26. } from "../../store.ts";
  27. import { nextTick, onUnmounted } from "vue";
  28. import { DataGroupId } from "@/constant/index.ts";
  29. import { Group } from "konva/lib/Group";
  30. import { Mode } from "@/constant/mode.ts";
  31. import { lineLen } from "@/utils/math.ts";
  32. import { repTabulationStore } from "../tabulation/gen-tab.ts";
  33. import { router } from "../../router.ts";
  34. import { overviewId, params, tabulationId } from "@/example/env.ts";
  35. import { listener } from "@/utils/event.ts";
  36. import { repeatedlyOnly } from "@/utils/shared.ts";
  37. const props = defineProps<{ title: string }>();
  38. const draw = useDraw();
  39. const emit = defineEmits<{
  40. (e: "selectVR", v: Scene): void;
  41. }>();
  42. const baseActions = getHeaderActions(draw);
  43. const actions = [
  44. [baseActions.undo, baseActions.redo],
  45. [
  46. baseActions.clear,
  47. baseActions.rotateView,
  48. { ...baseActions.initViewport, handler: () => draw.initViewport(40) },
  49. baseActions.toggleShow,
  50. ],
  51. [
  52. {
  53. handler: async () => {
  54. const scene = await selectScene();
  55. emit("selectVR", scene);
  56. },
  57. text: "VR辅助",
  58. icon: "VR",
  59. },
  60. ],
  61. [
  62. {
  63. ...baseActions.expose,
  64. children: baseActions.expose.children.map((item) => ({
  65. ...item,
  66. handler() {
  67. return item.handler(props.title);
  68. },
  69. })),
  70. },
  71. ],
  72. ];
  73. const setViewToTableCover = async () => {
  74. const oldViewMat = draw.viewer.viewMat;
  75. const oldShowGrid = draw.config.showGrid;
  76. const oldSize = draw.config.size;
  77. const oldBack = draw.config.back;
  78. const oldShowCompass = draw.config.showCompass;
  79. const oldLabelLineConfig = { ...draw.config.labelLineConfig };
  80. const oldShowOffset = draw.config.labelLineConfig.showOffset;
  81. const getRect = () => draw.stage!.findOne<Group>(`#${DataGroupId}`)!.getClientRect();
  82. const pop = draw.mode.push(Mode.readonly);
  83. const rect = getRect();
  84. const rectScale = (rect.width || 1080) / (rect.height || 850);
  85. const tableCoverScale = tableCoverWidth / tableCoverHeight;
  86. const padding = 70;
  87. let width: number, height: number;
  88. if (rectScale > tableCoverScale) {
  89. width = 1080;
  90. height = width / rectScale;
  91. } else {
  92. height = 850;
  93. width = rectScale * height;
  94. }
  95. if (width < padding * 2) {
  96. width += padding * 2;
  97. }
  98. if (height < padding * 2) {
  99. height += padding * 2;
  100. }
  101. draw.config.size = { width, height };
  102. draw.config.showGrid = false;
  103. draw.config.back = undefined;
  104. draw.config.showCompass = false;
  105. draw.config.labelLineConfig.type = "auto";
  106. draw.config.labelLineConfig.strokeWidth = 2;
  107. draw.config.labelLineConfig.fontSize = 10;
  108. await nextTick();
  109. draw.config.labelLineConfig.showOffset = padding;
  110. draw.initViewport(padding);
  111. await nextTick();
  112. return [
  113. {
  114. width,
  115. height,
  116. },
  117. () => {
  118. pop();
  119. draw.config.size = oldSize;
  120. draw.config.showGrid = oldShowGrid;
  121. draw.config.back = oldBack;
  122. draw.config.showCompass = oldShowCompass;
  123. draw.config.labelLineConfig = oldLabelLineConfig;
  124. draw.config.labelLineConfig.showOffset = oldShowOffset;
  125. draw.viewer.setViewMat(oldViewMat);
  126. },
  127. ] as const;
  128. };
  129. const saveHandler = repeatedlyOnly(async () => {
  130. const storeData = draw.getData();
  131. const [blob, scale, rect] = await draw.enterTemp(async () => {
  132. const [rect, recover] = await setViewToTableCover();
  133. await nextTick();
  134. const mat = draw.viewer.transform.invert();
  135. const scale =
  136. lineLen(mat.point({ x: 1, y: 0 }), mat.point({ x: 0, y: 0 })) *
  137. draw.store.config.proportion.scale;
  138. const blob = await getImage(draw, "image/png");
  139. recover();
  140. await nextTick();
  141. return [blob, scale, rect] as const;
  142. });
  143. const url = await window.platform.uploadResourse(
  144. new File([blob], `tabulation-cover.png`)
  145. );
  146. overviewId.value = await window.platform.saveOverviewData(overviewId.value, {
  147. ...overviewData.value,
  148. listCover: url,
  149. store: storeData,
  150. viewport: draw!.viewer.transform.m,
  151. });
  152. const cover = {
  153. url,
  154. width: rect.width,
  155. height: rect.height,
  156. proportion: { ...draw.store.config.proportion, scale },
  157. };
  158. tabulationId.value = await window.platform.getTabulationId(overviewId.value);
  159. await refreshTabulationData();
  160. const tabStore = await repTabulationStore(
  161. tabulationData.value.paperKey,
  162. storeData.config.compass.rotation,
  163. cover,
  164. tabulationData.value.isAutoGen ? undefined : tabulationData.value.store
  165. );
  166. tabStore.config.compass = storeData.config.compass;
  167. tabulationId.value = await window.platform.saveTabulationData(tabulationId.value, {
  168. ...tabulationData.value,
  169. title: overviewData.value.title,
  170. cover,
  171. store: tabStore,
  172. overviewId: overviewId.value,
  173. });
  174. console.log("保存完毕");
  175. });
  176. onUnmounted(
  177. listener(document.documentElement, "keydown", (ev) => {
  178. if (ev.ctrlKey && ev.key.toUpperCase() === "S") {
  179. saveHandler();
  180. }
  181. })
  182. );
  183. const gotoTabulation = repeatedlyOnly(async () => {
  184. await saveHandler();
  185. router.push({
  186. ...router.currentRoute.value,
  187. name: "tabulation",
  188. query: params.value,
  189. } as any);
  190. });
  191. defineExpose({ gotoTabulation, saveHandler });
  192. </script>