1
0

index.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <div class="df-layout">
  3. <Header
  4. class="df-header"
  5. :type="props.type"
  6. @back-page="backPageHandler"
  7. @back="board.back()"
  8. @forward="board.forward()"
  9. @view-init="board.viewInit()"
  10. @save="saveHandler"
  11. @export="exportHandler"
  12. :back-disabled="state.backDisabled"
  13. :forward-disabled="state.forwardDisabled"
  14. v-if="props && board"
  15. />
  16. <div class="df-layout-child">
  17. <Eshape v-model:shape="state.selectShape" v-if="state.selectShape" @cropping="handleCropping" />
  18. <div class="df-sider">
  19. <Slider
  20. :type="props.type"
  21. :add-shape="state.addShape"
  22. :exists-bg-image="state.exixtsBgImage"
  23. @update:add-shape="updateAddShape"
  24. @track-image="trackImage"
  25. @selectImage="setBackImage"
  26. v-if="props"
  27. />
  28. </div>
  29. <div class="df-content">
  30. <div class="df-content-layout">
  31. <div class="df-board">
  32. <canvas ref="dom" />
  33. </div>
  34. </div>
  35. </div>
  36. </div>
  37. </div>
  38. </template>
  39. <script setup lang="ts">
  40. import Header from "./header.vue";
  41. import Slider from "./slider.vue";
  42. import Eshape from "./eshape.vue";
  43. import { computed, nextTick, ref } from "vue";
  44. import { RouteName, router } from "@/router";
  45. import { useBoard, title } from "./board/useBoard";
  46. import { selectFuseImage, selectMapImage } from "@/view/case/quisk";
  47. import { CaseTagging } from "@/store/caseTagging";
  48. import saveAs from "@/util/file-serve";
  49. import { BoardTypeDesc } from "@/constant/caseFile";
  50. import { addByMediaLiBrary, updateByTreeFileLists, uploadNewFile } from "@/store/case";
  51. import { imageCropper } from "@/view/system/quisk";
  52. import {
  53. BoardType,
  54. SaveCaseFileImageInfo,
  55. TitleShapeData,
  56. saveCaseFileImageInfo,
  57. } from "@/store/caseFile";
  58. import { uploadFile } from "@/store/system";
  59. const list = ref({
  60. xct:[],
  61. xczp:[],
  62. klbj:[],
  63. });
  64. const fmtId = ref(0);
  65. const pmtId = ref(0);
  66. const ognFilesUrl = ref('')
  67. const dom = ref<HTMLCanvasElement>();
  68. const props = computed(() => {
  69. const route = router.currentRoute.value;
  70. if (route.name !== RouteName.drawCaseFile || !dom.value) {
  71. return null;
  72. } else {
  73. const params = route.params;
  74. const fileId = Number(params.id);
  75. return {
  76. caseId: Number(params.caseId),
  77. inAdd: fileId === -1,
  78. fileId,
  79. type: params.type.toString() as BoardType,
  80. dom: dom.value!,
  81. };
  82. }
  83. });
  84. function getList() {
  85. updateByTreeFileLists(props.caseId).then(res => {
  86. let newlist = res.find(ele => ele.filesTypeName == '三录材料')?.childrenList || [];
  87. list.value.xct = newlist.find(ele => ele.filesTypeName == '现场图')?.childrenList || [];
  88. pmtId.value = list.value.xct.find(ele => ele.filesTypeName == '平面图').filesTypeId
  89. fmtId.value = list.value.xct.find(ele => ele.filesTypeName == '方位图').filesTypeId
  90. console.log('list.value', list.value)
  91. })
  92. }
  93. getList()
  94. const backPageHandler = () => {
  95. board.value && board.value.clear();
  96. router.back();
  97. };
  98. const setBackImage = (blob: Blob) => {
  99. board.value!.setImage(URL.createObjectURL(blob));
  100. };
  101. const updateAddShape = async (s, d) => {
  102. if (d) {
  103. state.value.addData = await uploadFile(d);
  104. }
  105. state.value.addShape = s;
  106. };
  107. const trackImage = async () => {
  108. const data =
  109. props.value!.type === BoardType.scene
  110. ? await selectFuseImage(props.value!)
  111. : await selectMapImage({});
  112. console.log('户型图', data);
  113. if (data?.ognFilesUrl) {
  114. ognFilesUrl.value = data.ognFilesUrl;
  115. }
  116. if (data?.blob) {
  117. setBackImage(data.blob);
  118. if ("taggings" in data) {
  119. const tags = data.taggings as CaseTagging[];
  120. const table = await board.value!.calcTableShape([
  121. ["序号", "标注"],
  122. ...tags.map((tag, index) => [`序号${index + 1}`, tag.tagTitle]),
  123. ]);
  124. board.value!.setDefaultTable(null, table.content);
  125. }
  126. }
  127. };
  128. const { board, state } = useBoard(props);
  129. console.log('board', board, state, props);
  130. // 获取通用数据
  131. const getStore = async () => {
  132. const store = await board.value!.getStore();
  133. console.log('getStore', store, board.value, state.value);
  134. const titleShape = store.shapes.find(
  135. (shape: any) => shape.type === title
  136. ) as TitleShapeData;
  137. return { store, titleShape, ognFilesUrl: store.ognFilesUrl };
  138. };
  139. //裁剪
  140. const handleCropping = async (data) => {
  141. const appStore = await getStore();
  142. const args = props.value!;
  143. console.log('titleShape', appStore, board.value, args);
  144. const {width, height } = appStore.store.floors?.[0].bgImage;
  145. const blob = await fetch(appStore.store.ognFilesUrl || state.value.selectShape.data.url).then(res => res.blob());
  146. const cropBlob = await imageCropper({
  147. img: blob,
  148. fixed: [width, height]
  149. })
  150. console.log(cropBlob)
  151. setBackImage(cropBlob)
  152. // if (data) {
  153. // state.value.croppingData = data;
  154. // board.value!.setCropping(data);
  155. // }
  156. };
  157. // 保存数据
  158. const saveHandler = async () => {
  159. const { store, titleShape } = await getStore();
  160. const args = props.value!;
  161. console.log('titleShape', store, titleShape);
  162. const blob = await board.value!.export();
  163. let filesTitle = titleShape?.text || `${args.caseId}_${BoardTypeDesc[args.type]}`
  164. const body: SaveCaseFileImageInfo = {
  165. caseId: args.caseId,
  166. imgType: args.type,
  167. file: new File([blob], `${filesTitle}.jpg`),
  168. filesTitle: filesTitle,
  169. content: store && JSON.stringify(store),
  170. ognFileUrl: ognFilesUrl.value || store.ognFilesUrl,
  171. };
  172. args.inAdd || (body.filesId = props.value!.fileId);
  173. const { data } = await uploadNewFile(body);
  174. const rse = await addByMediaLiBrary({ ...body, caseId: args.caseId,filesTypeId: args.type != BoardType.scene ? fmtId.value : pmtId.value, uploadId: data.id });
  175. if (args.inAdd) {
  176. router.replace({
  177. name: RouteName.drawCaseFile,
  178. params: { caseId: args.caseId, type: args.type, id: rse.filesId },
  179. });
  180. }
  181. await nextTick();
  182. setTimeout(() => {
  183. // location.reload();
  184. }, 100);
  185. };
  186. // 导出图片
  187. const exportHandler = async () => {
  188. const { titleShape } = await getStore();
  189. const blob = await board.value!.export();
  190. saveAs(blob, `${titleShape.text}.jpg`);
  191. };
  192. </script>
  193. <style lang="scss" scoped>
  194. .df-layout {
  195. display: flex;
  196. flex-direction: column;
  197. height: 100vh;
  198. background: #f0f2f5;
  199. }
  200. .df-header {
  201. flex: none;
  202. }
  203. .df-layout-child {
  204. width: 100%;
  205. height: calc(100% - 5.4rem);
  206. display: flex;
  207. position: relative;
  208. }
  209. .df-sider {
  210. flex: 0 0 340px;
  211. overflow-y: auto;
  212. box-sizing: border-box;
  213. background: #fff;
  214. }
  215. .df-content {
  216. flex: 1;
  217. display: grid;
  218. align-items: center;
  219. justify-content: center;
  220. height: 100%;
  221. overflow: auto;
  222. }
  223. .df-content-layout {
  224. --w: 297px;
  225. --h: 210px;
  226. --padding: 0;
  227. --calc: 3.5;
  228. border: calc(var(--padding) * var(--calc)) solid #fff;
  229. }
  230. .df-board {
  231. // border: 1px solid #000;
  232. width: calc(var(--w) * var(--calc));
  233. height: calc(var(--h) * var(--calc));
  234. box-sizing: border-box;
  235. canvas {
  236. background: #fff;
  237. width: 100%;
  238. height: 100%;
  239. }
  240. }
  241. </style>