tangning il y a 4 mois
Parent
commit
da24dd2a59

+ 4 - 3
src/request/index.ts

@@ -50,12 +50,13 @@ axios.interceptors.request.use(async (config) => {
   }
 
   const { token, userId } = getAuth();
+  const route = router.currentRoute.value;
   let caseId = router.currentRoute.value?.params?.caseId
-  if (!token && !~notLoginUrls.indexOf(config.url)) {
+  if (!token && !~notLoginUrls.indexOf(config.url) && route.name !== 'drawShareFile') {
     // router.replace({ name: RouteName.login });
     let redirect = encodeURIComponent(`${window.location.href}`);
-    // window.location.href = window.location.origin + "/admin/#/login?redirect=" + redirect;
-    // throw "用户未登录";
+    window.location.href = window.location.origin + "/admin/#/login?redirect=" + redirect;
+    throw "用户未登录";
   }
   config.headers.token = token;
   config.headers['caseid'] = caseId;

+ 1 - 0
src/request/urls.ts

@@ -246,6 +246,7 @@ export const getByTree = "/fusion/caseFilesType/getByTree";
 export const updateFileType = "/fusion/caseFiles/updateFileType";
 export const addByMediaLibrary = "/fusion/caseFiles/addByMediaLibrary";
 export const addByMediaLibrarys = "/fusion/caseFiles/addByMediaLibrarys";
+export const addUserOrUpdate = "/service/manage/userFile/addOrUpdate";
 export const addmodelByMediaLibrary = "/fusion/model/addByMediaLibrary";
 export const criminalInfo = "/fusion/caseInquestCriminal/info";
 export const getMapConfig = "/fusion/notAuth/getMapConfig";

+ 6 - 0
src/router/config.ts

@@ -148,4 +148,10 @@ export const routes: Routes = [
     component: () => import("@/view/case/draw/index.vue"),
     meta: { title: "绘制卷宗图" },
   },
+  {
+    name: 'drawShareFile',
+    path: "/share/file/:caseId/:type/:id",
+    component: () => import("@/view/case/draw/share.vue"),
+    meta: { title: "绘制卷宗图" },
+  },
 ];

+ 5 - 0
src/store/case.ts

@@ -40,6 +40,7 @@ import {
   getTipsName,
   getByImage,
   getFloor,
+  addUserOrUpdate,
 } from "@/request";
 import { router } from "@/router";
 import { ModelScene, QuoteScene, Scene, SceneType } from "./scene";
@@ -81,6 +82,10 @@ export const addByMediaLiBrary = async (params) =>{
   return (await axios.post<string>(newUrl, params)).data;
 }
 
+export const addUserOrUpDate = async (params) =>{
+  return (await axios.post<string>(addUserOrUpdate, params)).data;
+}
+
 export const AddsaveOrUpdate = async (params) =>
   (await axios.post<string>(saveOrUpdate, params)).data;
 

+ 15 - 1
src/store/caseFile.ts

@@ -70,7 +70,21 @@ export const getCaseFileImageInfo = async (fileId: number) => {
     } as CaseFile)
   );
 };
-
+export const getuserFileInfo = async () => {
+  const data = (
+    await axios.get<CaseFile | null>('/service/manage/userFile/info', {
+      params: { imgType: 0 },
+    })
+  ).data;
+  let item = data && data[0] || data
+  return (
+    item &&
+    ({
+      ...item,
+      content: item.content && JSON.parse(item.content as any),
+    } as CaseFile)
+  );
+};
 export type SaveCaseFileImageInfo = Pick<CaseFile, "caseId" | "filesTitle"> & {
   filesId?: number;
   imgType: BoardType;

+ 6 - 3
src/view/case/draw/board/useBoard.ts

@@ -1,6 +1,6 @@
 import boardFactory, { BoardShape, MetaShapeType, bgImage } from "./";
 import { getCaseInfo } from "@/store/case";
-import { BoardData, getCaseFileImageInfo } from "@/store/caseFile";
+import { BoardData, getCaseFileImageInfo, getuserFileInfo } from "@/store/caseFile";
 import { Board } from "./";
 import { Ref, ref, watch, watchEffect } from "vue";
 import { BoardType } from "@/store/caseFile";
@@ -56,7 +56,8 @@ const defaultStore = {
 
 const getStore = async (caseId: number, fileId: number, type: BoardType) => {
   let data: BoardData;
-  if (fileId === -1) {
+  const route = router.currentRoute.value;
+  if (fileId === -1 && route.name != 'drawShareFile') {
     const info = await getCaseInfo(caseId);
     if (info) {
       defaultStore.floors[0].title.value =
@@ -68,7 +69,9 @@ const getStore = async (caseId: number, fileId: number, type: BoardType) => {
     }
   } else {
     try {
-      const fileInfo = await getCaseFileImageInfo(fileId);
+      const getFunction = route.name == 'drawShareFile'?getuserFileInfo:getCaseFileImageInfo
+      const fileInfo = await getFunction(fileId);
+      console.log('fileInfo', fileInfo);
       if (fileInfo) {
       data = {
         ...fileInfo.content,

+ 0 - 1
src/view/case/draw/index.vue

@@ -1,6 +1,5 @@
 <template>
   <div class="df-layout">
-    <login />
     <Header
       class="df-header"
       :type="props.type"

+ 286 - 0
src/view/case/draw/share.vue

@@ -0,0 +1,286 @@
+<template>
+  <div class="df-layout">
+    <login />
+    <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 login from "./login.vue";
+import { computed, nextTick, ref, watch, onMounted } 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, getUrlSrc, addUserOrUpDate } 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 board = ref(null);
+// const state = ref({});
+const ognFilesUrl = ref('')
+const dom = ref<HTMLCanvasElement>();
+const props = computed(() => {
+  const route = router.currentRoute.value;
+  if (route.name !== 'drawShareFile' || !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!,
+    };
+  }
+});
+console.log('listprops', props.value);
+const {board, state} = useBoard(props);
+async 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)
+    // if(pmtId.value || fmtId.value) {
+    // }
+  })
+}
+const backPageHandler = () => {
+  board.value && board.value.clear();
+  router.replace({ name: RouteName.material, params: { caseId: props.caseId } });
+  // router.back();
+};
+
+const setBackImage = (blob: Blob) => {
+  console.log('setBackImage', blob, board.value);
+  board.value!.setImage(URL.createObjectURL(blob));
+};
+
+const updateAddShape = async (s, d) => {
+  if (d) {
+    state.value.addData = getUrlSrc({type: 102}) + '/' + await uploadFile(d);
+    console.log('state.value', state.value.addData);
+  }
+  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);
+    }
+  }
+};
+// watch(props, (newValue) => {
+//   if(!newValue) return;
+//   const BoardData = useBoard(props)
+//   board.value = BoardData.board;
+//   state.value = BoardData.state;
+//   console.log('watchEffect111', newValue, props, board.value)
+// // const board = ref(null);
+// // const state = ref(null);
+// })
+console.log('useBoard', board, state)
+
+// 获取通用数据
+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 isUrl = (string) => {
+        try {
+          new URL(string);
+          return true;
+        } catch (err) {
+          return false;
+        }
+      }
+//裁剪
+const handleCropping = async (data) => {
+  const appStore = await getStore();
+  const args = props.value!;
+  let imgUrl = args.inAdd ? ognFilesUrl.value : appStore.store.ognFilesUrl;
+  const {width, height } = appStore.store.floors?.[0].bgImage;
+  const blob = await fetch(imgUrl || 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 route = router.currentRoute.value;
+  const getFunction = route.name == 'drawShareFile' ? addUserOrUpDate : addByMediaLiBrary
+  const rse = await getFunction({ ...body, caseId: args.caseId,filesTypeId: args.type != BoardType.scene ? fmtId.value : pmtId.value, uploadId: data.id, fileUrl: data.fileUrl, imgType: 0 });
+  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`);
+};
+onMounted(() => {
+  getList()
+})
+</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>