123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- <template>
- <div class="df-layout">
- <Header
- class="df-header"
- :type="props.type"
- @back-page="backPageHandler"
- @back="board.back()"
- @forward="board.forward()"
- @view-init="board.viewInit()"
- @save="saveHandler"
- @export="exportHandler"
- :back-disabled="state.backDisabled"
- :forward-disabled="state.forwardDisabled"
- v-if="props && board"
- />
- <div class="df-layout-child">
- <Eshape v-model:shape="state.selectShape" v-if="state.selectShape" @cropping="handleCropping" />
- <div class="df-sider">
- <Slider
- :type="props.type"
- :add-shape="state.addShape"
- :exists-bg-image="state.exixtsBgImage"
- @update:add-shape="updateAddShape"
- @track-image="trackImage"
- @selectImage="setBackImage"
- v-if="props"
- />
- </div>
- <div class="df-content">
- <div class="df-content-layout">
- <div class="df-board">
- <canvas ref="dom" />
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import Header from "./header.vue";
- import Slider from "./slider.vue";
- import Eshape from "./eshape.vue";
- import { computed, nextTick, ref } from "vue";
- import { RouteName, router } from "@/router";
- import { useBoard, title } from "./board/useBoard";
- import { selectFuseImage, selectMapImage } from "@/view/case/quisk";
- import { CaseTagging } from "@/store/caseTagging";
- import saveAs from "@/util/file-serve";
- import { BoardTypeDesc } from "@/constant/caseFile";
- import { addByMediaLiBrary, updateByTreeFileLists, uploadNewFile } from "@/store/case";
- import { imageCropper } from "@/view/system/quisk";
- import {
- BoardType,
- SaveCaseFileImageInfo,
- TitleShapeData,
- saveCaseFileImageInfo,
- } from "@/store/caseFile";
- import { uploadFile } from "@/store/system";
- const list = ref({
- xct:[],
- xczp:[],
- klbj:[],
- });
- const fmtId = ref(0);
- const pmtId = ref(0);
- const ognFilesUrl = ref('')
- const dom = ref<HTMLCanvasElement>();
- const props = computed(() => {
- const route = router.currentRoute.value;
- if (route.name !== RouteName.drawCaseFile || !dom.value) {
- return null;
- } else {
- const params = route.params;
- const fileId = Number(params.id);
- return {
- caseId: Number(params.caseId),
- inAdd: fileId === -1,
- fileId,
- type: params.type.toString() as BoardType,
- dom: dom.value!,
- };
- }
- });
- function getList() {
- updateByTreeFileLists(props.caseId).then(res => {
- let newlist = res.find(ele => ele.filesTypeName == '三录材料')?.childrenList || [];
- list.value.xct = newlist.find(ele => ele.filesTypeName == '现场图')?.childrenList || [];
- pmtId.value = list.value.xct.find(ele => ele.filesTypeName == '平面图').filesTypeId
- fmtId.value = list.value.xct.find(ele => ele.filesTypeName == '方位图').filesTypeId
- console.log('list.value', list.value)
- })
- }
- getList()
- const backPageHandler = () => {
- board.value && board.value.clear();
- router.back();
- };
- const setBackImage = (blob: Blob) => {
- board.value!.setImage(URL.createObjectURL(blob));
- };
- const updateAddShape = async (s, d) => {
- if (d) {
- state.value.addData = await uploadFile(d);
- }
- state.value.addShape = s;
- };
- const trackImage = async () => {
- const data =
- props.value!.type === BoardType.scene
- ? await selectFuseImage(props.value!)
- : await selectMapImage({});
- console.log('户型图', data);
- if (data?.ognFilesUrl) {
- ognFilesUrl.value = data.ognFilesUrl;
- }
- if (data?.blob) {
- setBackImage(data.blob);
- if ("taggings" in data) {
- const tags = data.taggings as CaseTagging[];
- const table = await board.value!.calcTableShape([
- ["序号", "标注"],
- ...tags.map((tag, index) => [`序号${index + 1}`, tag.tagTitle]),
- ]);
- board.value!.setDefaultTable(null, table.content);
- }
- }
- };
- const { board, state } = useBoard(props);
- console.log('board', board, state, props);
- // 获取通用数据
- const getStore = async () => {
- const store = await board.value!.getStore();
- console.log('getStore', store, board.value, state.value);
- const titleShape = store.shapes.find(
- (shape: any) => shape.type === title
- ) as TitleShapeData;
- return { store, titleShape, ognFilesUrl: store.ognFilesUrl };
- };
- //裁剪
- const handleCropping = async (data) => {
- const appStore = await getStore();
- const args = props.value!;
- console.log('titleShape', appStore, board.value, args);
- const {width, height } = appStore.store.floors?.[0].bgImage;
- const blob = await fetch(appStore.store.ognFilesUrl || state.value.selectShape.data.url).then(res => res.blob());
- const cropBlob = await imageCropper({
- img: blob,
- fixed: [width, height]
- })
- console.log(cropBlob)
- setBackImage(cropBlob)
- // if (data) {
- // state.value.croppingData = data;
- // board.value!.setCropping(data);
- // }
- };
- // 保存数据
- const saveHandler = async () => {
- const { store, titleShape } = await getStore();
- const args = props.value!;
- console.log('titleShape', store, titleShape);
- const blob = await board.value!.export();
- let filesTitle = titleShape?.text || `${args.caseId}_${BoardTypeDesc[args.type]}`
- const body: SaveCaseFileImageInfo = {
- caseId: args.caseId,
- imgType: args.type,
- file: new File([blob], `${filesTitle}.jpg`),
- filesTitle: filesTitle,
- content: store && JSON.stringify(store),
- ognFileUrl: ognFilesUrl.value || store.ognFilesUrl,
- };
- args.inAdd || (body.filesId = props.value!.fileId);
- const { data } = await uploadNewFile(body);
- const rse = await addByMediaLiBrary({ ...body, caseId: args.caseId,filesTypeId: args.type != BoardType.scene ? fmtId.value : pmtId.value, uploadId: data.id });
- if (args.inAdd) {
- router.replace({
- name: RouteName.drawCaseFile,
- params: { caseId: args.caseId, type: args.type, id: rse.filesId },
- });
- }
- await nextTick();
- setTimeout(() => {
- // location.reload();
- }, 100);
- };
- // 导出图片
- const exportHandler = async () => {
- const { titleShape } = await getStore();
- const blob = await board.value!.export();
- saveAs(blob, `${titleShape.text}.jpg`);
- };
- </script>
- <style lang="scss" scoped>
- .df-layout {
- display: flex;
- flex-direction: column;
- height: 100vh;
- background: #f0f2f5;
- }
- .df-header {
- flex: none;
- }
- .df-layout-child {
- width: 100%;
- height: calc(100% - 5.4rem);
- display: flex;
- position: relative;
- }
- .df-sider {
- flex: 0 0 340px;
- overflow-y: auto;
- box-sizing: border-box;
- background: #fff;
- }
- .df-content {
- flex: 1;
- display: grid;
- align-items: center;
- justify-content: center;
- height: 100%;
- overflow: auto;
- }
- .df-content-layout {
- --w: 297px;
- --h: 210px;
- --padding: 0;
- --calc: 3.5;
- border: calc(var(--padding) * var(--calc)) solid #fff;
- }
- .df-board {
- // border: 1px solid #000;
- width: calc(var(--w) * var(--calc));
- height: calc(var(--h) * var(--calc));
- box-sizing: border-box;
- canvas {
- background: #fff;
- width: 100%;
- height: 100%;
- }
- }
- </style>
|