浏览代码

查漏补缺

bill 2 年之前
父节点
当前提交
a410819eb3

文件差异内容过多而无法显示
+ 1 - 1
server/test/SS-t-P1d6CwREny2/attach/sceneStore


+ 2 - 0
src/graphic/Controls/UIControl.js

@@ -226,6 +226,8 @@ export default class UIControl {
     //
     const backgroundImg = dataService.getBackgroundImg();
     backgroundImg.setDisplay(value);
+
+    this.graphicStateUI.showBackImage = value;
     this.layer.renderer.autoRedraw();
   }
 

+ 3 - 0
src/graphic/Renderer/Draw.js

@@ -127,6 +127,9 @@ export default class Draw {
   }
 
   drawBackGroundImg(vector) {
+    if (!vector.display) {
+      return;
+    }
     const img = vector.imageData;
     const width = help.getReal(img.width);
     const height = help.getReal(img.height);

+ 2 - 2
src/graphic/enum/UIEvents.js

@@ -16,9 +16,9 @@ const UIEvents = {
   // 自由测量
   MeasureFree: "MeasureFree",
   // 直角定位法
-  MeasureCartesianMethod: "MeasureCartesianMethod",
+  AngleLocationMode: "AngleLocationMode",
   // 综合定位法
-  MeasureComprehensiveMethod: "MeasureComprehensiveMethod",
+  AllLocationMode: "AllLocationMode",
 
 
   // 文字

+ 3 - 1
src/hook/useGraphic.ts

@@ -31,7 +31,9 @@ export const useChange = (fn: () => void) => {
 export const graphicState = ref({
   canRevoke: false,
   canRecovery: false,
-  showBackImage: false
+  showBackImage: true,
+  canAngleLocationMode: false,
+  canAllLocationMode: false
 })
 
 export const setCanvas = async (canvas: HTMLCanvasElement, data: Ref<AccidentPhoto | RoadPhoto>) => {

+ 1 - 1
src/router/info.ts

@@ -53,7 +53,7 @@ export const writeRoutesRaw: RoutesRaw<typeof modeFlags.LOGIN> = [
     path: "/gena4/:id1/:id2",
     name: readyRouteName.gena4,
     meta: readyRouteMeta.gena4,
-    component: () => import("@/views/accidents/index.vue"),
+    component: () => import("@/views/accidents/print.vue"),
   },
   {
     path: "/roads",

+ 1 - 1
src/sdk/types/sdk.ts

@@ -39,7 +39,7 @@ export type Base = Emitter<SceneEventMap> & {
     slide?: boolean
   ) => { pos: Pos; trueSide: boolean };
 
-  screenshot: (width: number, height: number) => Promise<{ dataUrl: string }>;
+  screenshot: (width: number, height: number) => {finishPromise: Promise<{ dataUrl: string }>, meterPerPixel: number};
   el: HTMLElement;
 };
 

+ 1 - 0
src/store/accidentPhotos.ts

@@ -10,6 +10,7 @@ export type AccidentPhoto = {
   data: any,
   type?: string
   sceneData: {
+    meterPerPixel: number
     measures: PhotoRaw['measures'],
     fixPoints: PhotoRaw['fixPoints'],
     basePoints: PhotoRaw['basePoints']

+ 1 - 0
src/store/photos.ts

@@ -4,6 +4,7 @@ import {Pos} from "@/sdk";
 export type PhotoRaw = {
   id: string
   url: string
+  meterPerPixel: number
   time: number,
   measures: Array<Pos[]>,
   fixPoints: Array<Pos>,

+ 1 - 0
src/store/roadPhotos.ts

@@ -23,6 +23,7 @@ export type RoadPhoto = {
   table?: RoadPhotoTable,
   data: any
   sceneData: {
+    meterPerPixel: number
     measures: PhotoRaw['measures'],
     fixPoints: PhotoRaw['fixPoints'],
     basePoints: PhotoRaw['basePoints']

+ 12 - 0
src/store/sync.ts

@@ -46,6 +46,18 @@ export const uploadImage = async (blob: Blob) => {
   return res.data.data
 }
 
+export const downloadImage = async (data: Blob | string, name: string = getId()) => {
+  const blob: Blob = typeof data === "string"
+    ? (await axios.get(data, { responseType: "blob" })).data
+    : data
+
+  if (import.meta.env.DEV) {
+    window.open(URL.createObjectURL(blob))
+  } else {
+    const file = new File([blob], name)
+  }
+}
+
 const syncSceneStore = () => {
   return watch(
     () => ({

+ 52 - 7
src/views/accidents/print.vue

@@ -12,10 +12,12 @@
       </Header>
     </template>
 
-    <div class="content" ref="layoutRef">
-      <div v-for="accidentPhoto in accidentPhotos" :key="accidentPhoto.id">
-        <h4>{{accidentPhoto.title}}</h4>
-        <img :src="getStaticFile(accidentPhoto.url)">
+    <div class="print-layout">
+      <div class="content" ref="layoutRef">
+        <div v-for="accidentPhoto in genAccidentPhotos" :key="accidentPhoto.id" class="item">
+          <h4>{{accidentPhoto.title}}</h4>
+          <img :src="getStaticFile(accidentPhoto.url)">
+        </div>
       </div>
     </div>
   </MainPanel>
@@ -29,18 +31,20 @@ import html2canvas from "html2canvas";
 import {router, writeRouteName} from "@/router";
 import {AccidentPhoto, accidentPhotos} from "@/store/accidentPhotos";
 import {getStaticFile} from "@/dbo/main";
+import {downloadImage} from "@/store/sync";
+import Message from "@/components/base/components/message/message.vue";
 
 const back = () => {
   router.replace({name: writeRouteName.accidents})
 }
 
-const accidentPhotos = computed<AccidentPhoto[]>(() => {
+const genAccidentPhotos = computed<AccidentPhoto[]>(() => {
   let route, params
   if (((route = router.currentRoute.value).name === writeRouteName.gena4)
     && (params = route.params)
     && params.id1 
     && params.id2) {
-    return accidentPhotos.value.filter(data => [params.id1, params.id2].includes(data.id))
+    return accidentPhotos.value?.filter(data => [params.id1, params.id2].includes(data.id))
   }
 })
 
@@ -50,9 +54,50 @@ const saveHandler = async () => {
   const blob = await new Promise<Blob>(
     resolve => canvas.toBlob(resolve, "image/jpeg", 0.95)
   )
-  back()
+  await downloadImage(blob)
+  const hide = Message.success({ msg: "照片已生成" })
+  setTimeout(() => {
+    hide()
+    back()
+  }, 3000)
 }
 </script>
 
 <style lang="scss" scoped>
+.print-layout {
+  top: calc(var(--header-top) + var(--editor-head-height));
+  position: absolute;
+  background: #16181A;
+  padding: 65px;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  overflow-y: auto;
+
+}
+.content {
+  width: 1066px;
+  max-width: 100%;
+  height: 1514px;
+  padding: 0 64px;
+  margin: 0 auto;
+  background: #fff;
+}
+
+.item {
+  h4 {
+    font-size: 32px;
+    color: #000000;
+    padding-top: 64px;
+    box-sizing: content-box;
+    height: 38px;
+    line-height: 38px;
+  }
+
+  img {
+    width: 100%;
+    height: 600px;
+    object-fit: cover;
+  }
+}
 </style>

+ 1 - 0
src/views/graphic/data.ts

@@ -20,6 +20,7 @@ export const useData = () => {
           title: "",
           type: types[0],
           sceneData: {
+            meterPerPixel: photo.meterPerPixel,
             measures: photo.measures,
             basePoints: photo.basePoints,
             baseLines: photo.baseLines,

+ 36 - 8
src/views/graphic/menus.ts

@@ -1,9 +1,10 @@
-import {uiType, UIType, VectorType} from "@/hook/useGraphic";
+import {uiType, UIType, VectorType, graphicState} from "@/hook/useGraphic";
 import {
   findMenuByAttr,
   generateByMenus as generateByMenusRaw,
   generateMixMenus as generateMixMenusRaw
 } from '@/utils/menus'
+import Message from "@/components/base/components/message/message.vue";
 
 export enum Mode {
   Road,
@@ -26,6 +27,7 @@ export const UITypeExtend = {
 export type MenuRaw = {
   key: string,
   text: string,
+  onClick?: (data: MenuRaw) => void,
   icon?: string,
   children?: MenusRaw
   extend?: MenusRaw
@@ -76,8 +78,28 @@ export const measureMenusRaw = [
   { key: UIType.MeasureLine, text: "基准线" },
   { key: UIType.MeasurePoint, text: "基准点" },
   { key: UIType.MeasureFree, text: "自由测量" },
-  { key: UIType.MeasureCartesianMethod, text: "直角定位法" },
-  { key: UIType.MeasureComprehensiveMethod, text: "综合定位法" },
+  {
+    key: UIType.AngleLocationMode,
+    text: "直角定位法",
+    onClick(data) {
+      if (graphicState.value.canAllLocationMode) {
+        uiType.change(data.key)
+      } else {
+        Message.success({ msg: "请添加基准线及基准点后再执行此操作", time: 3000 })
+      }
+    }
+  },
+  {
+    key: UIType.AllLocationMode,
+    text: "综合定位法",
+    onClick(data) {
+      if (graphicState.value.canAllLocationMode) {
+        uiType.change(data.key)
+      } else {
+        Message.success({ msg: "请添加基准线及基准点后再执行此操作", time: 3000 })
+      }
+    }
+  },
 ]
 
 export const mainMenusRaw: MenusRaw = [
@@ -155,8 +177,8 @@ export const focusMenuRaw : { [key in string]: MenusRaw } = {
 
       ]
     },
-    { key: UIType.AddControlPoint, text: "加控制点" },
-    { key: UIType.MinusControlPoint, text: "减控制点" },
+    { key: UIType.AddCrossPoint, text: "加控制点" },
+    { key: UIType.MinusCrossPoint, text: "减控制点" },
     { key: UIType.Copy, text: "复制" },
     { key: UIType.Delete, text: "删除" }
   ],
@@ -166,8 +188,8 @@ export const focusMenuRaw : { [key in string]: MenusRaw } = {
     { key: UIType.AddNarrowRoad, text: "加窄路" },
     { key: UIType.AddLane, text: "加车道" },
     { key: UIType.DelLane, text: "减车道" },
-    { key: UIType.AddControlPoint, text: "加控制点" },
-    { key: UIType.MinusControlPoint, text: "减控制点" },
+    { key: UIType.AddCrossPoint, text: "加控制点" },
+    { key: UIType.MinusCrossPoint, text: "减控制点" },
     { key: UIType.Copy, text: "复制" },
     { key: UIType.Delete, text: "删除" }
   ],
@@ -196,6 +218,12 @@ export const generateMixMenus = <T extends {}, K extends keyof MenuRaw>(
   childKey,
   generateFn,
   mainMenus,
-    menu => uiType.change(menu.key as any),
+    menu => {
+      if (menu.onClick) {
+        menu.onClick(menu)
+      } else {
+        uiType.change(menu.key as any)
+      }
+    },
   () => uiType.current
 );

+ 8 - 2
src/views/scene/photo.vue

@@ -10,7 +10,7 @@
         :src="showCoverUrl"
         class="cover"
         :style="{opacity: showCoverUrl ? '1' : 0}"
-        @click="router.replace(writeRouteName.photos)"
+        @click="router.push(writeRouteName.photos)"
     >
   </div>
 </template>
@@ -51,7 +51,12 @@ const photo = genUseLoading(async () => {
   const dom = sdk.scene.el
   dom.style.pointerEvents = "none"
 
-  const {dataUrl: base64} = await sdk.scene.screenshot(dom.offsetWidth, dom.offsetHeight)
+  const data = sdk.scene.screenshot(
+    dom.offsetWidth,
+    dom.offsetHeight
+  )
+  const {dataUrl: base64} = await data.finishPromise
+  console.log(data)
   const blob = base64ToBlob(base64)
   tempPhoto.value = URL.createObjectURL(blob)
 
@@ -67,6 +72,7 @@ const photo = genUseLoading(async () => {
         id: getId(),
         url: url,
         time: new Date().getTime(),
+        meterPerPixel: data.meterPerPixel,
         measures: list.value
           .map(data => getCurrentScreens(data.points))
           .filter(poss => poss.length),