瀏覽代碼

Merge branch 'master' of http://192.168.0.115:3000/bill/traffic-laser

xushiting 2 年之前
父節點
當前提交
0c0eccc2f9

文件差異過大導致無法顯示
+ 1 - 1
server/test/a0k4xu045_202305311600080410/attach/sceneStore


+ 2 - 2
src/components/base/assets/scss/_base.scss

@@ -317,7 +317,7 @@ progress {
 .fun-ctrl {
     transition: color .3s ease;
     cursor: pointer;
-    color: rgba(255,255,255,0.7) !important;
+    color: rgba(255,255,255,1) !important;
     &:hover {
       color: rgba(255,255,255,1) !important;
     }
@@ -328,4 +328,4 @@ progress {
 
   .iconfont {
       font-weight: 400;
-  }
+  }

+ 1 - 1
src/components/base/assets/scss/components/_dialog.scss

@@ -60,7 +60,7 @@
         justify-content: center;
     }
     footer{
-        padding: 20px;
+        padding: 18px 0 24px;
         display: flex;
         align-items: center;
         justify-content: center;

+ 4 - 4
src/components/base/assets/scss/components/_icon.scss

@@ -17,7 +17,7 @@
 
 .icon {
   position: relative;
-  
+
 
   .tip {
     color: rgba(255,255,255,1);
@@ -36,14 +36,14 @@
 
   &.fore-show,
   &:hover {
-    z-index: 999;
+    //z-index: 999;
     .tip {
       opacity: 0.8;
     }
   }
 }
 
-  
+
 .tip-h-right .tip{
   right: 0;
   margin-right: 0;
@@ -72,4 +72,4 @@
 
 .tip-v-bottom .tip {
   top: 100%;
-}
+}

+ 1 - 1
src/components/base/components/input/select.vue

@@ -17,7 +17,7 @@
     @click="clickShowHandler"
   >
     <template v-slot:icon>
-      <icon type="pull-down" small v-if="!$slots.icon" />
+      <icon type="unfold" small v-if="!$slots.icon"  />
       <slot name="icon" v-else />
     </template>
     <template v-slot:preIcon v-if="$slots.preIcon">

+ 6 - 6
src/components/base/components/message/message.vue

@@ -1,14 +1,14 @@
 <template>
   <teleport to="body">
     <transition name="fade">
-      <div 
-        class="ui-message" 
-        :style="{ zIndex: zIndex, marginTop: `${index.value * 60}px` }" 
+      <div
+        class="ui-message"
+        :style="{ zIndex: zIndex, marginTop: `${index.value * 60}px` }"
         :class="type" v-if="show">
 <!--        <ui-icon :type="icons[type]" class="icon" v-if="type" />-->
         <p>{{ msg }}</p>
 
-        <ui-icon ctrl type="close" v-if="!time" @click="destroy" class="message-close" />
+<!--        <ui-icon ctrl type="close" v-if="!time" @click="destroy" class="message-close" />-->
       </div>
     </transition>
   </teleport>
@@ -48,7 +48,7 @@ if (props.time) {
     () => {
       show.value = false
       setTimeout(props.destroy, 500)
-    }, 
+    },
     props.time
   )
 }
@@ -56,4 +56,4 @@ if (props.time) {
 onMounted(() => nextTick(() => show.value = true))
 </script>
 
-<script> export default { name: 'ui-message' } </script>
+<script> export default { name: 'ui-message' } </script>

+ 11 - 5
src/components/button-pane/index.vue

@@ -1,23 +1,29 @@
 <template>
-  <div class="button-pane" :style="style">
+  <div class="button-pane" :style="style" ref="pane">
     <slot />
   </div>
 </template>
 
 <script setup lang="ts">
-import {computed} from "vue";
+import {computed, onMounted, ref} from "vue";
 
 const props = withDefaults(
-  defineProps<{ dire?: 'row' | 'column', size?: number }>(),
+  defineProps<{ dire?: 'row' | 'column', size?: number, auto?: boolean }>(),
   { dire: 'row', size: 64 }
 );
 
+const pane = ref<HTMLDivElement>()
+const height = ref<number>(1000)
+onMounted(() => height.value = props.dire === 'row' ? pane.value.offsetWidth : pane.value.offsetHeight)
+
 const style = computed(() => {
   const isRow = props.dire === 'row';
   const bound = isRow ? { height: `${props.size}px` } : { width: `${props.size}px` }
+  const psize = height.value > props.size ? "10px" : `${props.size / 2}px`
 
+  console.log(height.value)
   return {
-    padding: isRow ? `4px ${props.size / 2}px` : `${props.size / 2}px 4px`,
+    padding: isRow ? `4px ${psize}` : `${psize} 4px`,
     borderRadius: `${props.size / 2}px`,
     ...bound,
     flexDirection: props.dire
@@ -33,4 +39,4 @@ const style = computed(() => {
   display: flex;
   align-items: center;
 }
-</style>
+</style>

+ 14 - 2
src/components/group-button/index.vue

@@ -5,7 +5,7 @@
       :key="menu.key"
       class="menu"
       :style="menuStyle"
-      :class="{ active: activeKey === menu.key, dire, disabled: disabledMap[menu.key] }"
+      :class="{ active: activeKey === menu.key, dire, disabled: disabledMap[menu.key], border: menu.border }"
       @click="menu.onClick && menu.onClick(menu)"
     >
       <template v-if="$slots.default">
@@ -25,6 +25,7 @@ import {computed} from "vue";
 type Menu =  {
   key: any,
   text?: string,
+  border?: boolean
   icon?: string,
   disabled?: boolean | (() => boolean)
   onClick?: (menu: Menu) => void
@@ -61,6 +62,13 @@ const menuStyle = computed(() => {
 
 <style lang="scss" scoped>
 .menu {
+  &:first-child:last-child {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    height: 80%;
+    transform: translate(-50%, -50%);
+  }
   min-width: 56px;
   display: flex;
   flex-direction: column;
@@ -71,6 +79,10 @@ const menuStyle = computed(() => {
   color: #fff;
   border-radius: 4px;
 
+  &.border {
+  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
+}
+
   &.active {
     color: var(--colors-primary-base);
   }
@@ -93,4 +105,4 @@ const menuStyle = computed(() => {
     white-space:nowrap;
   }
 }
-</style>
+</style>

+ 17 - 1
src/components/photos/header.vue

@@ -1,7 +1,13 @@
 <template>
   <div class="photos-header">
     <div>
-      <ui-icon :type="type || 'return_l'" ctrl style="margin-right: 10px" @click="() => onBack ? onBack() : back()" />
+      <ui-icon
+          class="back-icon"
+          :type="type || 'return_l'"
+          ctrl
+          style="margin-right: 10px"
+          @click="() => onBack ? onBack() : back()"
+      />
       <span>{{ title }}</span>
     </div>
     <span class="center" v-if="count">
@@ -42,5 +48,15 @@ defineProps<{ count?: number, title: string, onBack?: () => void, type?: string
   }
 }
 
+.back-icon {
+  display: inline-flex;
+  width: 32px;
+  height: 32px;
+  background: rgba(255,255,255,0.1);
+  border-radius: 24px 24px 24px 24px;
+  align-items: center;
+  justify-content: center;
+}
+
 
 </style>

+ 86 - 86
src/graphic/CanvasStyle/ImageLabels/SVGIcons.js

@@ -2088,10 +2088,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2101,7 +2101,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2125,10 +2125,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2139,7 +2139,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2150,7 +2150,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2161,7 +2161,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2172,7 +2172,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2183,7 +2183,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2203,10 +2203,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2220,7 +2220,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2231,7 +2231,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2242,7 +2242,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineJoin="round";
       // ctx.font="   15px ''";
@@ -2254,7 +2254,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2266,7 +2266,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2287,7 +2287,7 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
       // ctx.fillStyle="white";
@@ -2302,7 +2302,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2312,7 +2312,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2331,10 +2331,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2344,7 +2344,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2354,7 +2354,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2364,7 +2364,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2408,7 +2408,7 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
       // ctx.fillStyle="white";
@@ -2421,7 +2421,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2433,7 +2433,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2445,7 +2445,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2458,7 +2458,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2479,10 +2479,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2495,7 +2495,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2517,7 +2517,7 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
       // ctx.fillStyle="white";
@@ -2532,7 +2532,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2542,7 +2542,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2554,7 +2554,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2566,7 +2566,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2579,7 +2579,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2600,7 +2600,7 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
       // ctx.fillStyle="white";
@@ -2615,7 +2615,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2628,7 +2628,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2647,10 +2647,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2675,7 +2675,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2697,10 +2697,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2714,7 +2714,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2728,7 +2728,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2739,7 +2739,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2759,10 +2759,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2775,7 +2775,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2794,10 +2794,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.beginPath();
       ctx.moveTo(0,0);
@@ -2812,7 +2812,7 @@ const SVGIcons = {
       ctx.closePath();
       ctx.clip();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2824,7 +2824,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2839,7 +2839,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2854,7 +2854,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2865,7 +2865,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -2879,7 +2879,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2894,7 +2894,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -2916,7 +2916,7 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
       // ctx.fillStyle="white";
@@ -2931,7 +2931,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2944,7 +2944,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2963,10 +2963,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2976,7 +2976,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -2986,7 +2986,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -3005,10 +3005,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -3018,7 +3018,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -3030,7 +3030,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -3042,7 +3042,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -3055,7 +3055,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";
@@ -3076,10 +3076,10 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -3090,7 +3090,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -3101,7 +3101,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -3112,7 +3112,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -3123,7 +3123,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -3134,7 +3134,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       // ctx.font="   15px ''";
@@ -3145,7 +3145,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineJoin="round";
       // ctx.font="   15px ''";
@@ -3166,7 +3166,7 @@ const SVGIcons = {
       // ctx.strokeStyle="rgba(0,0,0,0)";
       ctx.miterLimit=4;
       // ctx.font="15px ''";
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.font="   15px ''";
       ctx.save();
       // ctx.fillStyle="white";
@@ -3181,7 +3181,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       // ctx.font="   15px ''";
       ctx.beginPath();
@@ -3194,7 +3194,7 @@ const SVGIcons = {
       ctx.stroke();
       ctx.restore();
       ctx.save();
-      // ctx.fillStyle="rgba(0,0,0,0)";
+      ctx.fillStyle="rgba(0,0,0,0)";
       // ctx.strokeStyle="white";
       ctx.lineCap="round";
       ctx.lineJoin="round";

+ 7 - 1
src/graphic/CanvasStyle/default.js

@@ -81,6 +81,11 @@ const Point = {
   radius: 4 * coordinate.ratio,
   lineWidth: 4 * coordinate.ratio,
 };
+const NormalPoint = {
+  ...Point,
+  fillStyle: "#fff",
+
+}
 
 const RoadPoint = {
   ...Point,
@@ -201,7 +206,7 @@ const TestPoint = {
 };
 
 const SVG = {
-  fillStyle: "rgba(0,0,0,0)",
+  fillStyle: "#3290FF",
   strokeStyle: "#3290FF",
   lineWidth: 1 * coordinate.ratio,
 };
@@ -228,6 +233,7 @@ export default {
   MeasureLine,
   FreeMeasureLine: MeasureLine,
   PositionLine: MeasureLine,
+  NormalPoint,
   Measure,
   Element,
   TestPoint,

+ 1 - 1
src/graphic/CanvasStyle/focus.js

@@ -111,7 +111,7 @@ const BaseLine = {
 };
 
 const SVG = {
-  fillStyle: "rgba(0,0,0,0)",
+  fillStyle: "#3290FF",
   strokeStyle: "#3290FF",
   lineWidth: 2 * coordinate.ratio,
 };

+ 6 - 1
src/graphic/Renderer/Draw.js

@@ -26,6 +26,7 @@ const help = {
     ];
     let currentAttr;
 
+    console.log(itemsEntry)
     return [
       itemsEntry.reduce((prev, [item, attr]) => {
         if (!item) return prev;
@@ -962,6 +963,7 @@ export default class Draw {
       };
     }
 
+    console.log(vector, style, Settings.selectBasePointId)
     draw(style);
     if (style.out) {
       draw(style.out);
@@ -1048,6 +1050,7 @@ export default class Draw {
     const dires = [points[0], { ...points[0], x: 10000 }, points[1]];
     let angle = mathUtil.Angle(...dires) * (Math.PI / 180);
     angle = mathUtil.isClockwise(dires) ? angle : -angle;
+    console.log(angle)
     this.context.save();
     this.context.translate(points[0].x, points[0].y);
     this.context.rotate(angle);
@@ -1143,7 +1146,9 @@ export default class Draw {
     const ctx = this.context;
     ctx.save();
     help.setVectorStyle(ctx, vector);
-    help.drawCoves(ctx, help.transformCoves([vector.points]));
+    help.transformCoves([vector.curves]).forEach(coves => {
+      help.drawCoves(ctx, coves);
+    })
     ctx.restore();
 
     if (import.meta.env.DEV) {

+ 1 - 5
src/store/sync.ts

@@ -193,11 +193,7 @@ export const api =
       };
 
 export const back = () => {
-  if (history.state.back) {
-    router.back();
-  } else {
-    api.closePage();
-  }
+  api.closePage();
 };
 
 const loadStore = async () => {

+ 2 - 4
src/views/accidents/index.vue

@@ -1,7 +1,7 @@
 <template>
   <MainPanel>
     <template v-slot:header>
-      <Header type="return_l" :count="selects.length" :title="`已标注照片(${sortPhotos.length})`">
+      <Header type="return_l" :count="selects.length" :title="`已标注照片(${sortPhotos.length})`" :on-back="() => api.closePage()">
         <ui-button
             :type="selectMode ? 'primary' : 'normal'"
             @click="selectMode = !selectMode"
@@ -58,17 +58,15 @@ import MainPanel from '@/components/main-panel/index.vue'
 import FillSlide from '@/components/fill-slide/index.vue'
 import ActionMenus from "@/components/group-button/index.vue";
 import {types, accidentPhotos, AccidentPhoto} from '@/store/accidentPhotos'
-import UiIcon from "@/components/base/components/icon/index.vue";
 import {router, writeRouteName} from '@/router'
 import {computed, onDeactivated, reactive, ref, watchEffect} from "vue";
 import {Mode} from '@/views/graphic/menus'
 import UiButton from "@/components/base/components/button/index.vue";
 import Photos from "@/components/photos/index.vue";
 import Header from "@/components/photos/header.vue";
-import ButtonPane from "@/components/button-pane/index.vue";
 import {useConfirm} from "@/hook";
-import {roadPhotos} from "@/store/roadPhotos";
 import Undata from "@/components/photos/undata.vue";
+import {api} from "@/store/sync";
 
 const sortPhotos = computed(() => {
   const photos = [...accidentPhotos.value]

+ 25 - 10
src/views/accidents/print.vue

@@ -12,10 +12,10 @@
       </Header>
     </template>
 
-    <div class="print-layout">
-      <div class="content" ref="layoutRef">
+    <div class="print-layout" :class="{downMode}">
+      <div class="content " ref="layoutRef" >
         <div v-for="accidentPhoto in genAccidentPhotos" :key="accidentPhoto.id" class="item">
-          <h4>{{accidentPhoto.title}}</h4>
+<!--          <h4>{{accidentPhoto.title}}</h4>-->
           <img :src="useStaticUrl(accidentPhoto.url).value">
         </div>
       </div>
@@ -26,7 +26,7 @@
 import UiButton from "@/components/base/components/button/index.vue";
 import Header from "@/components/photos/header.vue";
 import MainPanel from "@/components/main-panel/index.vue";
-import {computed, ref} from "vue";
+import {computed, nextTick, ref} from "vue";
 import html2canvas from "html2canvas";
 import {router, writeRouteName} from "@/router";
 import {AccidentPhoto, accidentPhotos} from "@/store/accidentPhotos";
@@ -49,13 +49,17 @@ const genAccidentPhotos = computed<AccidentPhoto[]>(() => {
 })
 
 const layoutRef = ref<HTMLDivElement>()
+const downMode = ref(false)
 const saveHandler = async () => {
+  downMode.value = true
+  await nextTick()
   const canvas = await html2canvas(layoutRef.value)
   const blob = await new Promise<Blob>(
     resolve => canvas.toBlob(resolve, "image/jpeg", 0.95)
   )
   const success = await downloadImage(blob)
-  const hide = Message.success({ msg: success  ? "照片已生成" : "照片生成失败" })
+  const hide = Message.success({ msg: success  ? "已保存至相册" : "照片生成失败" })
+  downMode.value = false
   setTimeout(() => {
     hide()
     back()
@@ -68,7 +72,6 @@ const saveHandler = async () => {
   top: calc(var(--header-top) + var(--editor-head-height));
   position: absolute;
   background: #16181A;
-  padding: 65px;
   bottom: 0;
   left: 0;
   right: 0;
@@ -76,15 +79,19 @@ const saveHandler = async () => {
 
 }
 .content {
-  width: 1066px;
-  max-width: 100%;
+  width: 100%;
   height: 1514px;
-  padding: 0 64px;
+  padding: 125px 100px;
   margin: 0 auto;
   background: #fff;
+  display: flex;
+  flex-direction: column;
 }
 
 .item {
+  height: 50%;
+  display: flex;
+  align-items: center;
   h4 {
     font-size: 32px;
     color: #000000;
@@ -96,8 +103,16 @@ const saveHandler = async () => {
 
   img {
     width: 100%;
-    height: 600px;
+    max-height: 90%;
     object-fit: cover;
   }
 }
+
+.downMode {
+  .content {
+    width: 1050px;
+    height: 1485px;
+    padding: 125px 100px;
+  }
+}
 </style>

+ 2 - 1
src/views/graphic/confirm.vue

@@ -33,6 +33,7 @@ import {uiType, drawRef} from '@/hook/useGraphic'
   width: 64px;
   font-size: 22px;
   justify-content: center;
-  background-color: #fff
+  background-color: #fff;
+  box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.5);
 }
 </style>

+ 38 - 20
src/views/graphic/header.vue

@@ -1,47 +1,48 @@
 <template>
-  <div class="graphic-header" v-if="data">
+  <div v-if="data" class="graphic-header">
     <div class="title">
-      <ui-icon type="return" @click="back" class="head-icon" />
+      <ui-icon class="head-icon" type="return" @click="back"/>
       <p>{{ isRoad ? '现场绘图' : '事故照片' }}</p>
     </div>
     <div class="actions">
       <div
           v-for="menu in menus"
           :key="menu.text"
-          class="action fun-ctrl"
           :class="{disabled: menu.disable}"
+          class="action fun-ctrl"
           @click="menu.onClick"
       >
-        <ui-icon :type="menu.icon"  />
+        <ui-icon :type="menu.icon"/>
         <p>{{ menu.text }}</p>
         <ui-input
-            type="checkbox"
+            v-if="menu.icon === 'map'"
             :modelValue="graphicState.showBackImage"
             class="map-status"
-            v-if="menu.icon === 'map'"
+            type="checkbox"
         />
       </div>
     </div>
 
     <div class="table">
       <ui-input
-          width="120px"
+          v-if="options"
+          v-model="(data as AccidentPhoto).type"
+          :options="options"
           height="32px"
           type="select"
-          :options="options"
-          v-model="(data as AccidentPhoto).type"
-          v-if="options"
+          width="120px"
       />
-      <ui-button width="100px" class="save save-file" @click="saveHandler">
+      <ui-button :class="{['save-file']: isRoad}" :type="isRoad ? undefined : 'primary'" class="save" width="100px"
+                 @click="saveHandler">
         保存
       </ui-button>
-      <ui-button width="100px" type="primary" class="save" @click="createTable" v-if="isRoad">
+      <ui-button v-if="isRoad" class="save" type="primary" width="100px" @click="createTable">
         制表
       </ui-button>
     </div>
   </div>
 </template>
-<script setup lang="ts">
+<script lang="ts" setup>
 import UiIcon from "@/components/base/components/icon/index.vue";
 import UiButton from "@/components/base/components/button/index.vue";
 import {Mode} from './menus'
@@ -60,7 +61,7 @@ const data = useData()
 const mode = computed(() => Number(router.currentRoute.value.params.mode) as Mode)
 const isRoad = computed(() => mode.value === Mode.Road)
 const options = computed(() =>
-  !isRoad.value ? types.map(t => ({ label: t, value: t })) : null
+  !isRoad.value ? types.map(t => ({label: t, value: t})) : null
 )
 const backImageChang = (show) => {
   dataService.setGridDisplay(!show)
@@ -73,7 +74,7 @@ watchEffect(() => {
   }
 })
 
-type Menu = {disable?: boolean, text: string, icon: string, onClick: () => void}
+type Menu = { disable?: boolean, text: string, icon: string, onClick: () => void }
 const menus = computed<Menu[]>(() => {
   const menus = [
     {
@@ -142,13 +143,13 @@ const saveHandler = async () => {
 
 const createTable = async () => {
   await saveStore()
-  await router.replace({name: writeRouteName.tabulation, params: {id: data.value.id} })
+  await router.replace({name: writeRouteName.tabulation, params: {id: data.value.id}})
 }
 
 
 </script>
 
-<style scoped lang="scss">
+<style lang="scss" scoped>
 .graphic-header {
   display: flex;
   position: relative;
@@ -161,6 +162,7 @@ const createTable = async () => {
 .actions {
   display: flex;
 }
+
 .action {
   font-size: 20px;
   margin: 0 15px;
@@ -169,6 +171,7 @@ const createTable = async () => {
   align-items: center;
   position: relative;
   justify-content: center;
+
   p {
     font-size: 14px;
     text-align: center;
@@ -186,6 +189,7 @@ const createTable = async () => {
   left: 0;
   display: flex;
   align-items: center;
+
   p {
     margin-left: 10px;
   }
@@ -196,7 +200,7 @@ const createTable = async () => {
 }
 
 .save {
-  margin-left: 24px;
+  margin-left: 16px;
 }
 
 .map-status {
@@ -207,15 +211,27 @@ const createTable = async () => {
   bottom: 0;
   z-index: 1;
 }
+.head-icon {
+  width: 32px;
+  height: 32px;
+  background: rgba(255,255,255,0.1);
+  border-radius: 24px 24px 24px 24px;
+  font-size: 16px !important;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-left: -3px;
+}
 </style>
 
 <style lang="scss">
 .map-status.ui-input,
-.map-status.ui-input .checkbox{
+.map-status.ui-input .checkbox {
   width: 12px;
   height: 7px;
 
 }
+
 .map-status.ui-input .checkbox input + .replace {
   border-radius: 4px;
   background-color: #7E7E7E;
@@ -234,12 +250,14 @@ const createTable = async () => {
     left: 1px;
     transition: all .3s ease;
   }
+
   i {
     display: none;
   }
 
-  &.checked{
+  &.checked {
     background-color: var(--colors-primary-base) !important;
+
     &:before {
       left: calc(100% - 6px);
     }

+ 1 - 1
src/views/graphic/menus.ts

@@ -165,7 +165,7 @@ export const mainMenusRaw: MenusRaw = [
   {
     key: UITypeExtend.image,
     text: '图例',
-    icon: 'road',
+    icon: 'legend',
     // children: [
     //   { key: UIType.BusPlane, text: "客车平面图" }
     // ]

+ 1 - 1
src/views/photos/index.vue

@@ -1,7 +1,7 @@
 <template>
   <MainPanel>
     <template v-slot:header>
-      <Header :count="selects.length" :title="`全部照片(${photos.length})`">
+      <Header :count="selects.length" :title="`全部照片(${photos.length})`" type="return">
         <ui-button type="primary" @click="selectMode = !selectMode" width="96px" v-if="sortPhotos.length">
           {{ selectMode ? '取消' : '选择' }}
         </ui-button>

+ 2 - 1
src/views/roads/index.vue

@@ -1,7 +1,7 @@
 <template>
   <MainPanel>
     <template v-slot:header>
-      <Header :count="selects.length" :title="`现场图管理(${sortPhotos.length})`" type="return_l">
+      <Header :count="selects.length" :title="`现场图管理(${sortPhotos.length})`" type="return_l" :on-back="() => api.closePage()">
         <ui-button
             :type="selectMode ? 'primary' : 'normal'"
             @click="selectMode = !selectMode"
@@ -66,6 +66,7 @@ import Photos from "@/components/photos/index.vue";
 import ButtonPane from "@/components/button-pane/index.vue";
 import UiIcon from "@/components/base/components/icon/index.vue";
 import {useConfirm} from "@/hook";
+import {api} from "@/store/sync";
 
 
 const sortPhotos = computed(() => [...roadPhotos.value].reverse())

+ 40 - 3
src/views/roads/tabulation.vue

@@ -12,7 +12,7 @@
       </Header>
     </template>
 
-    <div class="tab-layout" v-if="roadPhoto">
+    <div class="tab-layout" v-if="roadPhoto" :class="{downMode}">
       <div class="content" ref="layoutRef">
         <table>
           <tr>
@@ -139,6 +139,7 @@ import Header from "@/components/photos/header.vue";
 import MainPanel from "@/components/main-panel/index.vue";
 import {downloadImage, uploadImage} from "@/store/sync";
 import {Mode} from "@/views/graphic/menus";
+import Message from "@/components/base/components/message/message.vue";
 
 const roadPhoto = computed<RoadPhoto>(() => {
   let route, params, data
@@ -207,6 +208,7 @@ const getLayoutImage = async () => {
   downMode.value = true
   await nextTick()
   const canvas = await html2canvas(layoutRef.value)
+  Message.success({ msg: "已保存至相册", time: 2000 } )
   downMode.value = false
   const blob = await new Promise<Blob>(resolve => canvas.toBlob(resolve, "image/jpeg", 0.95))
   await downloadImage(blob)
@@ -235,8 +237,7 @@ const saveHandler = async () => {
 }
 
 .content {
-  box-sizing: content-box;
-  width: 1066px;
+  width: 100%;
   padding: 20px 20px 60px;
   margin: 0 auto;
 }
@@ -329,6 +330,42 @@ const saveHandler = async () => {
   }
 }
 
+.downMode {
+  .content {
+    width: 1485px;
+    height: 1050px;
+    padding: 125px 100px 75px 100px;
+    overflow: hidden;
+  }
+  .content table {
+    .value {
+      background: none;
+    }
+
+    tr:not(:first-child) {
+      td {
+        border-right: 5px solid #000;
+        border-bottom: 5px solid #000;
+      }
+
+      &:nth-child(2) td {
+        border-top: 7.5px solid #000;
+      }
+
+      td:first-child {
+        border-left: 7.5px solid #000;
+      }
+      td:last-child {
+        border-right: 7.5px solid #000;
+      }
+
+      &:last-child td {
+        border-bottom: 7.5px solid #000;
+      }
+    }
+  }
+}
+
 .signatures {
   margin-top: 13px;
   display: flex;

+ 26 - 1
src/views/scene/covers/basePoints.vue

@@ -9,7 +9,14 @@
     @focus="() => active = point"
   />
 
-  <ActionsPanel :menus="activeActionMenus" v-if="active" />
+<!--  <ActionsPanel :menus="activeActionMenus" v-if="active" />-->
+  <div ref="menu" @touchstart.stop class="action-menus">
+    <ActionMenus
+        v-if="active"
+        :menus="activeActionMenus"
+        dire="row"
+    />
+  </div>
 </template>
 
 <script setup lang="ts">
@@ -18,12 +25,15 @@ import BasePoint from './basePoint.vue'
 import {ref} from "vue";
 import {FixPoint} from "@/store/fixPoint";
 import ActionsPanel from "@/views/scene/covers/actions.vue";
+import {customMap} from "@/hook";
+import ActionMenus from "@/components/group-button/index.vue";
 
 const active = ref<BasePoint>()
 const activeActionMenus = [
   {
     key: "delete",
     icon: "del",
+    text: "删除",
     color: "#FF4D4F",
     iconColor: "#fff",
     action() {
@@ -36,3 +46,18 @@ const activeActionMenus = [
   }
 ]
 </script>
+
+<style scoped>
+
+.action-menus {
+  position: absolute;
+  bottom: var(--boundMargin);
+  left: 50%;
+  transform: translateX(-50%);
+  display: flex;
+  z-index: 2;
+  .menus {
+    position: static;
+  }
+}
+</style>

+ 31 - 4
src/views/scene/covers/fixPoints.vue

@@ -9,8 +9,14 @@
     @blur="() => customMap.activeFixPoint = customMap.activeFixPoint === point ? null : customMap.activeFixPoint"
   />
 
-  <div ref="menu" @touchstart.stop>
-    <ActionsPanel :menus="activeActionMenus" v-show="customMap.activeFixPoint" />
+  <div ref="menu" @touchstart.stop class="action-menus">
+<!--    <ActionsPanel :menus="activeActionMenus" v-show="customMap.activeFixPoint" />-->
+    <ActionMenus
+        v-if="customMap.activeFixPoint"
+        :menus="activeActionMenus"
+        :active-key="edit ? 'edit' : null"
+        dire="row"
+    />
   </div>
 
   <div class="edit-fix-point" v-if="edit" ref="dom"  @touchstart.stop>
@@ -42,6 +48,7 @@ import {ref, watch, watchEffect} from "vue";
 import {customMap} from '@/hook'
 import UiIcon from "@/components/base/components/icon/index.vue";
 import UiInput from "@/components/base/components/input/index.vue";
+import ActionMenus from "@/components/group-button/index.vue";
 
 const edit = ref<FixPoint>()
 const options = [
@@ -62,18 +69,20 @@ const activeActionMenus = [
   {
     key: "edit",
     icon: "edit",
+    text: "编辑",
     color: "#161A1A",
     iconColor: "#2F8FFF",
-    action() {
+    onClick() {
       edit.value = customMap.activeFixPoint
     }
   },
   {
     key: "delete",
     icon: "del",
+    text: "删除",
     color: "#FF4D4F",
     iconColor: "#fff",
-    action() {
+    onClick() {
       const index = fixPoints.value.indexOf(customMap.activeFixPoint)
       if (~index) {
         fixPoints.value.splice(index, 1)
@@ -143,4 +152,22 @@ watchEffect((onCleanup) => {
     }
   }
 }
+
+.action-menus {
+  position: absolute;
+  bottom: var(--boundMargin);
+  left: 50%;
+  transform: translateX(-50%);
+  display: flex;
+  z-index: 2;
+  .menus {
+    position: static;
+  }
+}
+</style>
+
+<style>
+.action-menus .menu.active {
+  background: none;
+}
 </style>

+ 2 - 2
src/views/scene/menus/actions.ts

@@ -47,11 +47,11 @@ const trackMeasureMenuAction = (
   let hide
   const startTip = () => {
     hide && hide()
-    hide = Message.success({ msg: "请选择一个位置单击,确定基准线的起点" })
+    hide = Message.success({ msg: `请选择一个位置单击,确定${name}的起点` })
   }
   const firstTip = () => {
     hide && hide()
-    hide = Message.success({ msg: "再选择一个位置单击,确定基准线的终点" })
+    hide = Message.success({ msg: `再选择一个位置单击,确定${name}的终点` })
   }
   startTip()
   // customMap.magnifier = true

+ 6 - 1
src/views/scene/menus/menus.ts

@@ -4,6 +4,8 @@ import {useSDK} from "@/hook";
 import {laserModeStack, modeDisabled} from '@/hook/custom/index'
 import {Mode} from "@/sdk";
 import {baseLines} from "@/store/baseLine";
+import {fixPoints} from "@/store/fixPoint";
+import {basePoints} from "@/store/basePoint";
 
 export type MenuRaw = {
   key: string,
@@ -12,6 +14,7 @@ export type MenuRaw = {
   defaultSelect?: true | (() => boolean),
   icon?: string,
   disabled?: boolean | (() => boolean),
+  border?: boolean,
   children?: MenuRaw[],
   onClick?: () => void | (() => void)
 }
@@ -36,7 +39,9 @@ export const menus: MenuRaw[] = [
   {
     icon: "clear",
     text: "清除",
-    key: menuEnum.CLEAR
+    key: menuEnum.CLEAR,
+    disabled: () => (baseLines.value.length + fixPoints.value.length + basePoints.value.length) === 0,
+    border: true
   },
   {
     icon: "measure",

+ 5 - 3
src/views/scene/menus/pane.vue

@@ -98,16 +98,18 @@ onMounted(() => {
 }
 </style>
 
-<style>
+<style lang="scss">
 .level div:first-child {
   background-color: rgba(255, 255, 255, .3);
   height: 50px;
   width: 50px;
   min-width: 50px;
-  margin-top: -26px;
   border-radius: 50%;
   margin-bottom: 30px !important;
   position: relative;
+  i {
+    font-size: 16px !important;
+  }
 
   &:after {
     position: absolute;
@@ -115,7 +117,7 @@ onMounted(() => {
     width: 100%;
     height: 1px;
     bottom: -15px;
-    background-color: rgba(255, 255, 255, .3);
+    background-color: rgba(255, 255, 255, .2);
 
   }
 }

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

@@ -7,7 +7,8 @@
     </ButtonPane>
 
     <img
-        :src="showCoverUrl"
+        v-if="showCoverUrl"
+        :src="showCoverUrl.value"
         class="cover"
         :style="{opacity: showCoverUrl ? '1' : 0}"
         @click="router.push(writeRouteName.photos)"
@@ -27,16 +28,17 @@ import { useSDK } from '@/hook/useLaser'
 import {genUseLoading} from "@/hook";
 import {disabledMap} from "@/hook/custom";
 import {base64ToBlob, getId} from "@/utils";
-import {nextTick, ref} from "vue";
+import {computed, nextTick, ref} from "vue";
 import {api, downloadImage, uploadImage} from "@/store/sync";
 import {router, writeRouteName} from "@/router";
 import {LaserSDK, Pos, Pos3D} from "@/sdk";
+import {useStaticUrl} from "@/hook/useStaticUrl";
 
-const showCoverUrl = ref<string>()
-if (photos.value[photos.value.length - 1]?.url) {
-  api.getFile(photos.value[photos.value.length - 1]?.url)
-    .then(url => showCoverUrl.value = url)
-}
+const showCoverUrl = computed(() => {
+  if (photos.value[photos.value.length - 1]?.url) {
+    return useStaticUrl(photos.value[photos.value.length - 1].url)
+  }
+})
 
 const tempPhoto = ref<string>();
 const coverRef = ref<HTMLImageElement>()
@@ -89,7 +91,6 @@ const photo = genUseLoading(async () => {
 
   const handler = async () => {
     coverRef.value.removeEventListener("animationend", handler)
-    showCoverUrl.value = tempPhoto.value
     tempPhoto.value = null
 
     photos.value.push({