Browse Source

添加元素组件

zhoucg 1 year ago
parent
commit
9b9f65e140
58 changed files with 1197 additions and 672 deletions
  1. 24 8
      components.d.ts
  2. 1 2
      index.html
  3. 26 0
      package-lock.json
  4. 1 0
      package.json
  5. BIN
      public/favicon.ico
  6. 0 1
      public/vite.svg
  7. 1 2
      src/App.vue
  8. 2 2
      src/assets/style/main.less
  9. 2 2
      src/components/PageComponents/RoyGroup.vue
  10. 0 56
      src/components/PageComponents/RoyStar.vue
  11. 1 1
      src/components/PageComponents/RoyTable/RoyComplexTable.vue
  12. 3 7
      src/components/PageComponents/RoyTable/RoySimpleTextInTable.vue
  13. 2 2
      src/components/PageComponents/RoyTable/RoySimpleTable.vue
  14. 60 0
      src/components/PageComponents/YvanBarcode.vue
  15. 51 0
      src/components/PageComponents/YvanBarcodeProps.vue
  16. 10 8
      src/components/PageComponents/RoyCircle.vue
  17. 55 0
      src/components/PageComponents/YvanCircleProps.vue
  18. 10 8
      src/components/PageComponents/RoyImage.vue
  19. 51 0
      src/components/PageComponents/YvanImageProps.vue
  20. 10 8
      src/components/PageComponents/RoyLine.vue
  21. 44 0
      src/components/PageComponents/YvanLineProps.vue
  22. 27 0
      src/components/PageComponents/YvanLinePropsTemplate.vue
  23. 14 11
      src/components/PageComponents/RoyRect.vue
  24. 55 0
      src/components/PageComponents/YvanRectProps.vue
  25. 11 4
      src/components/PageComponents/RoyText.vue
  26. 53 0
      src/components/PageComponents/YvanRichTextProps.vue
  27. 33 29
      src/components/PageComponents/RoySimpleText.vue
  28. 128 0
      src/components/PageComponents/YvanSimpleTextProps.vue
  29. 17 0
      src/components/PageComponents/index.js
  30. 1 1
      src/components/PageComponents/style.js
  31. 1 81
      src/components/PageToc.vue
  32. 28 25
      src/components/config/componentList.ts
  33. 15 0
      src/components/config/globalConfig.ts
  34. 0 47
      src/components/config/menuConfig.ts
  35. 2 2
      src/components/config/toolbarConfig.ts
  36. 1 1
      src/components/sketch-ruler/sketchRuler.vue
  37. 41 31
      src/components/yvan-context/components/Context.vue
  38. 4 4
      src/components/yvan-context/components/ContextItem.vue
  39. 1 0
      src/components/yvan-context/directive.js
  40. 14 14
      src/components/yvan-editor/ComponentAdjuster.vue
  41. 35 52
      src/components/yvan-editor/Editor.vue
  42. 11 11
      src/components/yvan-print-designer-left-component.vue
  43. 155 9
      src/components/yvan-print-designer-left-structure.vue
  44. 5 5
      src/components/yvan-print-designer-left.vue
  45. 2 9
      src/components/yvan-print-designer-main.vue
  46. 93 0
      src/components/yvan-print-designer-props.vue
  47. 0 160
      src/components/yvan-print-designer-right.vue
  48. 5 5
      src/components/yvan-print-designer.vue
  49. 3 2
      src/components/yvan-print-page-format.vue
  50. 2 2
      src/components/yvan-ui/yvan-print-dialog/index.ts
  51. 2 2
      src/components/yvan-ui/yvan-print-toast/index.ts
  52. 11 2
      src/main.ts
  53. 33 33
      src/store/copy.ts
  54. 8 8
      src/store/global.ts
  55. 12 12
      src/store/layer.ts
  56. 2 2
      src/store/ruler-things.ts
  57. 18 0
      src/style.css
  58. 0 1
      src/utils/system.ts

+ 24 - 8
components.d.ts

@@ -28,11 +28,13 @@ declare module 'vue' {
     ElCol: typeof import('element-plus/es')['ElCol']
     ElCollapse: typeof import('element-plus/es')['ElCollapse']
     ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
+    ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
     ElDialog: typeof import('element-plus/es')['ElDialog']
     ElDivider: typeof import('element-plus/es')['ElDivider']
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElIcon: typeof import('element-plus/es')['ElIcon']
+    ElInput: typeof import('element-plus/es')['ElInput']
     ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
@@ -42,21 +44,19 @@ declare module 'vue' {
     ElSpace: typeof import('element-plus/es')['ElSpace']
     GlobalSetting: typeof import('./src/components/GlobalSetting.vue')['default']
     Line: typeof import('./src/components/sketch-ruler/line.vue')['default']
-    PageComponent: typeof import('./src/components/PageComponent.vue')['default']
     PagePalette: typeof import('./src/components/PagePalette.vue')['default']
     PageToc: typeof import('./src/components/PageToc.vue')['default']
     RoyCircle: typeof import('./src/components/PageComponents/RoyCircle.vue')['default']
     RoyComplexTable: typeof import('./src/components/PageComponents/RoyTable/RoyComplexTable.vue')['default']
     RoyGroup: typeof import('./src/components/PageComponents/RoyGroup.vue')['default']
-    RoyImage: typeof import('./src/components/PageComponents/RoyImage.vue')['default']
-    RoyLine: typeof import('./src/components/PageComponents/RoyLine.vue')['default']
+    RoyImage: typeof import('./src/components/PageComponents/YvanImage.vue')['default']
+    RoyLine: typeof import('./src/components/PageComponents/YvanLine.vue')['default']
     RoyModal: typeof import('./src/components/yvan-ui/yvan-model/RoyModal.vue')['default']
     RoyRect: typeof import('./src/components/PageComponents/RoyRect.vue')['default']
     RoySimpleTable: typeof import('./src/components/PageComponents/RoyTable/RoySimpleTable.vue')['default']
-    RoySimpleText: typeof import('./src/components/PageComponents/RoySimpleText.vue')['default']
+    RoySimpleText: typeof import('./src/components/PageComponents/YvanSimpleText.vue')['default']
     RoySimpleTextInTable: typeof import('./src/components/PageComponents/RoyTable/RoySimpleTextInTable.vue')['default']
     RoyStar: typeof import('./src/components/PageComponents/RoyStar.vue')['default']
-    RoyText: typeof import('./src/components/PageComponents/RoyText.vue')['default']
     RoyTextInTable: typeof import('./src/components/PageComponents/RoyTable/RoyTextInTable.vue')['default']
     RulerWrapper: typeof import('./src/components/sketch-ruler/rulerWrapper.vue')['default']
     SidebarMenu: typeof import('./src/components/yvan-ui/yvan-sidebar-menu/SidebarMenu.vue')['default']
@@ -69,19 +69,35 @@ declare module 'vue' {
     Toast: typeof import('./src/components/yvan-ui/yvan-print-toast/toast.vue')['default']
     WangEditor: typeof import('./src/components/PageComponents/WangEditorVue/WangEditor.vue')['default']
     WangToolbar: typeof import('./src/components/PageComponents/WangEditorVue/WangToolbar.vue')['default']
+    YvanBarcode: typeof import('./src/components/PageComponents/YvanBarcode.vue')['default']
+    YvanBarcodeProps: typeof import('./src/components/PageComponents/YvanBarcodeProps.vue')['default']
+    YvanCircle: typeof import('./src/components/PageComponents/YvanCircle.vue')['default']
+    YvanCircleProps: typeof import('./src/components/PageComponents/YvanCircleProps.vue')['default']
+    YvanImage: typeof import('./src/components/PageComponents/YvanImage.vue')['default']
+    YvanImageProps: typeof import('./src/components/PageComponents/YvanImageProps.vue')['default']
+    YvanLine: typeof import('./src/components/PageComponents/YvanLine.vue')['default']
+    YvanLineProps: typeof import('./src/components/PageComponents/YvanLineProps.vue')['default']
+    YvanLinePropsTemplate: typeof import('./src/components/PageComponents/YvanLinePropsTemplate.vue')['default']
     YvanPrintAside: typeof import('./src/components/yvan-ui/yvan-print-aside.vue')['default']
     YvanPrintContainer: typeof import('./src/components/yvan-ui/yvan-print-container.vue')['default']
     YvanPrintDesigner: typeof import('./src/components/yvan-print-designer.vue')['default']
     YvanPrintDesignerAside: typeof import('./src/components/yvan-print-designer-left.vue')['default']
     YvanPrintDesignerLeft: typeof import('./src/components/yvan-print-designer-left.vue')['default']
-    YvanPrintDesignerLeftComponent: typeof import('./src/components/yvan-print-designer-left-component.vue')['default']
-    YvanPrintDesignerLeftStart: typeof import('./src/components/yvan-print-designer-left-start.vue')['default']
+    YvanPrintDesignerLeftElement: typeof import('./src/components/yvan-print-designer-left-element.vue')['default']
     YvanPrintDesignerLeftStructure: typeof import('./src/components/yvan-print-designer-left-structure.vue')['default']
     YvanPrintDesignerMain: typeof import('./src/components/yvan-print-designer-main.vue')['default']
-    YvanPrintDesignerRight: typeof import('./src/components/yvan-print-designer-right.vue')['default']
+    YvanPrintDesignerProps: typeof import('./src/components/yvan-print-designer-props.vue')['default']
+    YvanPrintDesignerRight: typeof import('./src/components/yvan-print-designer-props.vue')['default']
     YvanPrintHeader: typeof import('./src/components/yvan-ui/yvan-print-header.vue')['default']
     YvanPrintMain: typeof import('./src/components/yvan-ui/yvan-print-main.vue')['default']
     YvanPrintPageFormat: typeof import('./src/components/yvan-print-page-format.vue')['default']
     YvanPrintToolbar: typeof import('./src/components/yvan-ui/yvan-print-toolbar.vue')['default']
+    YvanRect: typeof import('./src/components/PageComponents/YvanRect.vue')['default']
+    YvanRectProps: typeof import('./src/components/PageComponents/YvanRectProps.vue')['default']
+    YvanRichText: typeof import('./src/components/PageComponents/YvanRichText.vue')['default']
+    YvanRichTextProps: typeof import('./src/components/PageComponents/YvanRichTextProps.vue')['default']
+    YvanSimpleTable: typeof import('./src/components/PageComponents/RoyTable/YvanSimpleTable.vue')['default']
+    YvanSimpleText: typeof import('./src/components/PageComponents/YvanSimpleText.vue')['default']
+    YvanSimpleTextProps: typeof import('./src/components/PageComponents/YvanSimpleTextProps.vue')['default']
   }
 }

+ 1 - 2
index.html

@@ -2,9 +2,8 @@
 <html lang="en">
 <head>
     <meta charset="UTF-8"/>
-    <link rel="icon" type="image/svg+xml" href="/vite.svg"/>
+    <link rel="icon" type="image/svg+xml" href="/favicon.ico"/>
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-<!--    <link rel="stylesheet" href="./src/assets/iconfont/iconfont.css">-->
     <link rel="stylesheet" href="./src/assets/font-awesome/css/font-awesome.min.css">
     <title>Yvan打印系统</title>
 </head>

+ 26 - 0
package-lock.json

@@ -8,6 +8,7 @@
       "name": "yvan-print",
       "version": "0.0.0",
       "dependencies": {
+        "@ant-design/icons-vue": "^6.1.0",
         "@element-plus/icons-vue": "^2.1.0",
         "@wangeditor/editor": "^5.1.22",
         "big.js": "^6.2.1",
@@ -33,6 +34,31 @@
         "vue-tsc": "^1.4.2"
       }
     },
+    "node_modules/@ant-design/colors": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz",
+      "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==",
+      "dependencies": {
+        "@ctrl/tinycolor": "^3.4.0"
+      }
+    },
+    "node_modules/@ant-design/icons-svg": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/@ant-design/icons-svg/-/icons-svg-4.3.0.tgz",
+      "integrity": "sha512-WOgvdH/1Wl8Z7VXigRbCa5djO14zxrNTzvrAQzhWiBQtEKT0uTc8K1ltjKZ8U1gPn/wXhMA8/jE39SJl0WNxSg=="
+    },
+    "node_modules/@ant-design/icons-vue": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/@ant-design/icons-vue/-/icons-vue-6.1.0.tgz",
+      "integrity": "sha512-EX6bYm56V+ZrKN7+3MT/ubDkvJ5rK/O2t380WFRflDcVFgsvl3NLH7Wxeau6R8DbrO5jWR6DSTC3B6gYFp77AA==",
+      "dependencies": {
+        "@ant-design/colors": "^6.0.0",
+        "@ant-design/icons-svg": "^4.2.1"
+      },
+      "peerDependencies": {
+        "vue": ">=3.0.3"
+      }
+    },
     "node_modules/@antfu/utils": {
       "version": "0.7.4",
       "resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.4.tgz",

+ 1 - 0
package.json

@@ -10,6 +10,7 @@
     "preview": "vite preview"
   },
   "dependencies": {
+    "@ant-design/icons-vue": "^6.1.0",
     "@element-plus/icons-vue": "^2.1.0",
     "@wangeditor/editor": "^5.1.22",
     "big.js": "^6.2.1",

BIN
public/favicon.ico


File diff suppressed because it is too large
+ 0 - 1
public/vite.svg


+ 1 - 2
src/App.vue

@@ -1,11 +1,10 @@
 <template>
   <div class="yvan-print">
-    <yvan-print-designer ></yvan-print-designer>
+    <yvan-print-designer />
   </div>
 </template>
 
 <script setup lang="ts">
-
 import YvanPrintDesigner from "@/components/yvan-print-designer.vue";
 </script>
 

+ 2 - 2
src/assets/style/main.less

@@ -31,8 +31,8 @@
     }
   }
 
-  .roy-binding-value {
-    background: var(--roy-color-info-light-8);
+  .yvan-binding-value {
+    background: var(--yvan-color-info-light-8);
     padding: 3px;
     border-radius: 3px;
     border: 1px solid var(--roy-color-info);

+ 2 - 2
src/components/PageComponents/RoyGroup.vue

@@ -18,8 +18,8 @@
 
 <script>
 import commonMixin from '@/mixin/commonMixin'
-import RoyText from '@/components/PageComponents/RoyText'
-import RoyRect from '@/components/PageComponents/RoyRect'
+import RoyText from '@/components/PageComponents/YvanRichText.vue'
+import RoyRect from '@/components/PageComponents/YvanRect.vue'
 
 /**
  * roy-group

+ 0 - 56
src/components/PageComponents/RoyStar.vue

@@ -1,56 +0,0 @@
-<template>
-  <div class="RoyStar">
-    <StyledStar v-bind="style">
-      <span :class="style.icon" class="iconfont roy-star-icon"></span>
-    </StyledStar>
-  </div>
-</template>
-
-<script>
-import commonMixin from '@/mixin/commonMixin'
-import { StyledStar } from '@/components/PageComponents/style'
-
-/**
- * 五角星
- */
-export default {
-  name: 'RoyStar',
-  mixins: [commonMixin],
-  components: {
-    StyledStar
-  },
-  props: {
-    element: {
-      type: Object,
-      default: () => {}
-    },
-    propValue: {
-      type: String,
-      default: ''
-    }
-  },
-  computed: {
-    style() {
-      return this.element.style || {}
-    }
-  },
-  data() {
-    return {}
-  },
-  methods: {
-    initMounted() {}
-  },
-  created() {},
-  mounted() {
-    this.initMounted()
-  },
-  watch: {}
-}
-</script>
-
-<style lang="less">
-.RoyStar {
-  width: 100%;
-  height: 100%;
-}
-</style>

+ 1 - 1
src/components/PageComponents/RoyTable/RoyComplexTable.vue

@@ -109,7 +109,7 @@
 <script>
 import commonMixin from '@/mixin/commonMixin'
 import RoyTextInTable from './RoyTextInTable'
-import RoySimpleTable from './RoySimpleTable'
+import RoySimpleTable from './YvanSimpleTable.vue'
 import ResizeObserver from '@/components/PageComponents/RoyTable/ResizeObserver'
 import TableDataSetting from '@/components/PageComponents/RoyTable/TableDataSetting'
 import { StyledComplexTable } from '@/components/PageComponents/style'

+ 3 - 7
src/components/PageComponents/RoyTable/RoySimpleTextInTable.vue

@@ -1,7 +1,3 @@
-<!--
-* @description RoySimpleTextInTable
-* @filename RoySimpleText.vue
-!-->
 <template>
   <div
     class="RoySimpleText"
@@ -28,7 +24,7 @@
       @mousedown="handleMouseDown"
       @paste="clearStyle"
     >
-      <div class="roy-simple-text-inner" v-html="propValue"></div>
+      <div class="yvan-simple-text-inner" v-html="propValue"></div>
     </StyledSimpleText>
   </div>
 </template>
@@ -146,12 +142,12 @@ export default {
           // this.$emit('update:propValue', `[绑定:${bindingDataSource.title}]`)
           this.$store.commit('printTemplateModule/updateDataValue', {
             data: this.element,
-            value: `<span class="roy-binding-value">[绑定:${bindingDataSource.title}]</span>`,
+            value: `<span class="yvan-binding-value">[绑定:${bindingDataSource.title}]</span>`,
             key: 'propValue'
           })
           this.$emit(
             'componentUpdated',
-            `<span class="roy-binding-value">[绑定:${bindingDataSource.title}]</span>`
+            `<span class="yvan-binding-value">[绑定:${bindingDataSource.title}]</span>`
           )
           this.canEdit = false
         }

+ 2 - 2
src/components/PageComponents/RoyTable/RoySimpleTable.vue

@@ -4,7 +4,7 @@
       <ContextItem
         v-for="item in contextMenu"
         :key="item.code"
-        :class="`roy-context--${item.status}`"
+        :class="`yvan-context--${item.status}`"
         @click="item.event"
       >
         <i :class="item.icon"></i>
@@ -80,7 +80,7 @@ const defaultTableCell = {
   icon: 'ri-text',
   code: 'text',
   name: '文本',
-  component: 'RoySimpleTextIn',
+  component: 'YvanSimpleTextIn',
   propValue: '',
   width: 100,
   height: 30,

+ 60 - 0
src/components/PageComponents/YvanBarcode.vue

@@ -0,0 +1,60 @@
+<template>
+  <div class="yvan-barcode">
+    <StyledImage v-bind="style">
+      <img :alt="element.title || 'RoyImage'" :src="element.src" />
+    </StyledImage>
+  </div>
+</template>
+
+<script>
+import commonMixin from '@/mixin/commonMixin'
+import { StyledImage } from '@/components/PageComponents/style'
+import YvanBarcodeProps from "@/components/PageComponents/YvanBarcodeProps.vue";
+
+export default {
+  name: 'YvanBarcode',
+  mixins: [commonMixin],
+  components: {
+    StyledImage,
+    YvanBarcodeProps
+  },
+  props: {
+    element: {
+      type: Object,
+      default: () => {}
+    },
+    propValue: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    }
+  },
+  computed: {
+    style() {
+      return this.element.style || {}
+    }
+  },
+  data() {
+    return {}
+  },
+  methods: {
+    initMounted() {}
+  },
+  install(Vue) {
+    Vue.component(this.name, this)
+    Vue.component(YvanBarcodeProps.name, YvanBarcodeProps)
+  },
+  mounted() {
+    this.initMounted()
+  },
+  watch: {}
+}
+</script>
+
+<style lang="less">
+.yvan-barcode {
+  height: 100%;
+  padding: 0;
+}
+</style>

+ 51 - 0
src/components/PageComponents/YvanBarcodeProps.vue

@@ -0,0 +1,51 @@
+<template>
+  <section class="yvan-barcode-props">
+    <el-form ref="form" label-position="top">
+      <el-form-item label="标题">
+        <el-input />
+      </el-form-item>
+      <el-form-item label="图片地址">
+        <el-input />
+      </el-form-item>
+      <el-form-item label="上传图片">
+        <el-input />
+      </el-form-item>
+      <el-form-item label="边框类型">
+        <el-select placeholder="请选择粗细">
+          <el-option label="font.name" value="font.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="边框颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="旋转角度(°)">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+    </el-form>
+  </section>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'YvanBarcodeProps',
+  data() {
+    return {}
+  }
+}
+</script>
+
+<style lang="less">
+.yvan-barcode-props {
+
+  .el-input-number {
+    width: 100%;
+  }
+
+  .el-select {
+    width: 100%;
+  }
+}
+</style>

+ 10 - 8
src/components/PageComponents/RoyCircle.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="RoyCircle">
+  <div class="yvan-circle">
     <StyledCircle v-bind="style" />
   </div>
 </template>
@@ -7,15 +7,14 @@
 <script>
 import commonMixin from '@/mixin/commonMixin'
 import { StyledCircle } from '@/components/PageComponents/style'
+import YvanCircleProps from "@/components/PageComponents/YvanCircleProps.vue";
 
-/**
- * 矩形组件
- */
 export default {
-  name: 'RoyCircle',
+  name: 'YvanCircle',
   mixins: [commonMixin],
   components: {
-    StyledCircle
+    StyledCircle,
+    YvanCircleProps
   },
   props: {
     element: {
@@ -38,7 +37,10 @@ export default {
   methods: {
     initMounted() {}
   },
-  created() {},
+  install(Vue) {
+    Vue.component(this.name, this)
+    Vue.component(YvanCircleProps.name, YvanCircleProps)
+  },
   mounted() {
     this.initMounted()
   },
@@ -47,7 +49,7 @@ export default {
 </script>
 
 <style lang="less">
-.RoyCircle {
+.yvan-circle {
   width: 100%;
   height: 100%;
 }

+ 55 - 0
src/components/PageComponents/YvanCircleProps.vue

@@ -0,0 +1,55 @@
+<template>
+  <section class="yvan-circle-props">
+    <el-form ref="form" label-position="top">
+      <el-form-item label="宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="高度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="背景颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框类型">
+        <el-select placeholder="请选择行高">
+          <el-option v-for="borderStyle in borderStyleList" :label="borderStyle.label" :value="borderStyle.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="边框颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="旋转角度(°)">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+    </el-form>
+  </section>
+</template>
+
+<script lang="ts">
+import {borderStyleList} from "@/components/config/globalConfig";
+
+export default {
+  name: 'YvanCircleProps',
+  data() {
+    return {
+      borderStyleList
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.yvan-circle-props {
+
+  .el-input-number {
+    width: 100%;
+  }
+
+  .el-select {
+    width: 100%;
+  }
+}
+</style>

+ 10 - 8
src/components/PageComponents/RoyImage.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="RoyImage">
+  <div class="yvan-image">
     <StyledImage v-bind="style">
       <img :alt="element.title || 'RoyImage'" :src="element.src" />
     </StyledImage>
@@ -9,15 +9,14 @@
 <script>
 import commonMixin from '@/mixin/commonMixin'
 import { StyledImage } from '@/components/PageComponents/style'
+import YvanImageProps from "@/components/PageComponents/YvanImageProps.vue";
 
-/**
- * 图片组件
- */
 export default {
-  name: 'RoyImage',
+  name: 'YvanImage',
   mixins: [commonMixin],
   components: {
-    StyledImage
+    StyledImage,
+    YvanImageProps
   },
   props: {
     element: {
@@ -42,7 +41,10 @@ export default {
   methods: {
     initMounted() {}
   },
-  created() {},
+  install(Vue) {
+    Vue.component(this.name, this)
+    Vue.component(YvanImageProps.name, YvanImageProps)
+  },
   mounted() {
     this.initMounted()
   },
@@ -51,7 +53,7 @@ export default {
 </script>
 
 <style lang="less">
-.RoyImage {
+.yvan-image {
   height: 100%;
   padding: 0;
 }

+ 51 - 0
src/components/PageComponents/YvanImageProps.vue

@@ -0,0 +1,51 @@
+<template>
+  <section class="yvan-image-props">
+    <el-form ref="form" label-position="top">
+      <el-form-item label="标题">
+        <el-input/>
+      </el-form-item>
+      <el-form-item label="图片地址">
+        <el-input/>
+      </el-form-item>
+      <el-form-item label="上传图片">
+        <el-input/>
+      </el-form-item>
+      <el-form-item label="边框类型">
+        <el-select placeholder="请选择粗细">
+          <el-option label="font.name" value="font.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="边框颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="旋转角度(°)">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+    </el-form>
+  </section>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'YvanImageProps',
+  data() {
+    return {}
+  }
+}
+</script>
+
+<style lang="less">
+.yvan-image-props {
+
+  .el-input-number {
+    width: 100%;
+  }
+
+  .el-select {
+    width: 100%;
+  }
+}
+</style>

+ 10 - 8
src/components/PageComponents/RoyLine.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="yvan-print-line">
+  <div class="yvan-line">
     <StyledLine v-bind="style" />
   </div>
 </template>
@@ -7,15 +7,14 @@
 <script>
 import commonMixin from '@/mixin/commonMixin'
 import { StyledLine } from '@/components/PageComponents/style'
+import YvanLineProps from '@/components/PageComponents/YvanLineProps.vue'
 
-/**
- * 矩形组件
- */
 export default {
-  name: 'RoyLine',
+  name: 'YvanLine',
   mixins: [commonMixin],
   components: {
-    StyledLine
+    StyledLine,
+    YvanLineProps
   },
   props: {
     element: {
@@ -38,7 +37,10 @@ export default {
   methods: {
     initMounted() {}
   },
-  created() {},
+  install(Vue) {
+    Vue.component(this.name, this)
+    Vue.component(YvanLineProps.name, YvanLineProps)
+  },
   mounted() {
     this.initMounted()
   },
@@ -47,7 +49,7 @@ export default {
 </script>
 
 <style lang="less">
-.yvan-print-line {
+.yvan-line {
   height: 100%;
   width: 100%;
 }

+ 44 - 0
src/components/PageComponents/YvanLineProps.vue

@@ -0,0 +1,44 @@
+<template>
+  <section class="yvan-line-props">
+    <el-form ref="form" label-position="top">
+      <el-form-item label="宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="粗细">
+        <el-select placeholder="请选择粗细">
+          <el-option label="font.name" value="font.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="旋转角度(°)">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+    </el-form>
+  </section>
+</template>
+
+<script lang="ts">
+
+export default {
+  name: 'YvanLineProps',
+  data() {
+    return {}
+  }
+}
+
+</script>
+
+<style lang="less">
+.yvan-line-props {
+
+  .el-input-number {
+    width: 100%;
+  }
+
+  .el-select {
+    width: 100%;
+  }
+}
+</style>

+ 27 - 0
src/components/PageComponents/YvanLinePropsTemplate.vue

@@ -0,0 +1,27 @@
+<template>
+  <section class="yvan-line">
+    <el-form  ref="form" label-position="top">
+
+      <el-form-item label="旋转角度(°)">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+    </el-form>
+  </section>
+</template>
+
+<script setup>
+
+</script>
+
+<style lang="less">
+.yvan-line {
+
+  .el-input-number {
+    width: 100%;
+  }
+
+  .el-select {
+    width: 100%;
+  }
+}
+</style>

+ 14 - 11
src/components/PageComponents/RoyRect.vue

@@ -1,18 +1,16 @@
 <template>
-  <div class="RoyRect">
-    <StyledRect v-bind="style" />
+  <div class="yvan-rect">
+    <StyledRect v-bind="style"/>
   </div>
 </template>
 
 <script>
 import commonMixin from '@/mixin/commonMixin'
-import { StyledRect } from '@/components/PageComponents/style'
+import {StyledRect} from '@/components/PageComponents/style'
+import YvanRectProps from "@/components/PageComponents/YvanRectProps.vue";
 
-/**
- * 矩形组件
- */
 export default {
-  name: 'RoyRect',
+  name: 'YvanRect',
   mixins: [commonMixin],
   components: {
     StyledRect
@@ -20,7 +18,8 @@ export default {
   props: {
     element: {
       type: Object,
-      default: () => {}
+      default: () => {
+      }
     },
     propValue: {
       type: String,
@@ -36,9 +35,13 @@ export default {
     return {}
   },
   methods: {
-    initMounted() {}
+    initMounted() {
+    }
+  },
+  install(Vue) {
+    Vue.component(this.name, this)
+    Vue.component(YvanRectProps.name, YvanRectProps)
   },
-  created() {},
   mounted() {
     this.initMounted()
   },
@@ -47,7 +50,7 @@ export default {
 </script>
 
 <style lang="less">
-.RoyRect {
+.yvan-rect {
   width: 100%;
   height: 100%;
 }

+ 55 - 0
src/components/PageComponents/YvanRectProps.vue

@@ -0,0 +1,55 @@
+<template>
+  <section class="yvan-rect-props">
+    <el-form ref="form" label-position="top">
+      <el-form-item label="宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="高度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="背景颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框类型">
+        <el-select placeholder="请选择行高">
+          <el-option v-for="borderStyle in borderStyleList" :label="borderStyle.label" :value="borderStyle.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="边框颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="旋转角度(°)">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+    </el-form>
+  </section>
+</template>
+
+<script lang="ts">
+import {borderStyleList} from "@/components/config/globalConfig";
+
+export default {
+  name: 'YvanRectProps',
+  data() {
+    return {
+      borderStyleList
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.yvan-rect-props {
+
+  .el-input-number {
+    width: 100%;
+  }
+
+  .el-select {
+    width: 100%;
+  }
+}
+</style>

+ 11 - 4
src/components/PageComponents/RoyText.vue

@@ -23,8 +23,9 @@
 <!--        />-->
 <!--      </div>-->
 <!--    </RoyModal>-->
+
     <StyledText v-bind="style">
-      <div class="roy-text-inner" v-html="propValue ?? 1234"></div>
+      <div class="yvan-text-inner" v-html="propValue"></div>
     </StyledText>
   </div>
 </template>
@@ -38,9 +39,10 @@ import WangToolbar from '@/components/PageComponents/WangEditorVue/WangToolbar.v
 import WangEditor from '@/components/PageComponents/WangEditorVue/WangEditor.vue';
 import {toolBarConfig, editorConfig, mode} from '@/components/config/editorConfig';
 import commonMixin from '@/mixin/commonMixin';
+import YvanRichTextProps from "@/components/PageComponents/YvanRichTextProps.vue";
 
 export default {
-  name: 'RoyText',
+  name: 'YvanRichText',
   mixins: [commonMixin],
   props: {
     element: {
@@ -57,7 +59,8 @@ export default {
     WangEditor,
     WangToolbar,
     StyledText,
-    RoyModal
+    RoyModal,
+    YvanRichTextProps
   },
   computed: {
     ...mapState(globalStore, {
@@ -82,7 +85,7 @@ export default {
       this.wangEditor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
     },
     onBlur() {
-      this.$store.commit('printTemplateModule/setPropValue', {
+      globalStore().setPropValue({
         id: this.element.id,
         propValue: this.html
       })
@@ -97,6 +100,10 @@ export default {
       this.onBlur()
     }
   },
+  install(Vue) {
+    Vue.component(this.name, this)
+    Vue.component(YvanRichTextProps.name, YvanRichTextProps)
+  },
   created() {
   },
   watch: {},

+ 53 - 0
src/components/PageComponents/YvanRichTextProps.vue

@@ -0,0 +1,53 @@
+<template>
+  <section class="yvan-rich-text-props">
+    <el-form ref="form" label-position="top">
+      <el-form-item label="宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="高度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="背景颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框类型">
+        <el-select placeholder="请选择边框类型">
+          <el-option label="font.name" value="font.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="边框颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="旋转角度(°)">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+    </el-form>
+  </section>
+</template>
+
+<script lang="ts">
+
+export default {
+  name: 'YvanRichTextProps',
+  data() {
+    return {}
+  }
+}
+
+</script>
+
+<style lang="less">
+.yvan-rich-text-props {
+
+  .el-input-number {
+    width: 100%;
+  }
+
+  .el-select {
+    width: 100%;
+  }
+}
+</style>

+ 33 - 29
src/components/PageComponents/RoySimpleText.vue

@@ -1,19 +1,19 @@
 <template>
   <div
-    class="RoySimpleText"
-    style="width: 100%; height: 100%"
-    @click="setEdit"
-    @contextmenu="setEdit"
-    @dragenter="handleDragEnter"
-    @dragleave="handleDragLeave"
-    @drop="handleDrop"
+      class="yvan-simple-text"
+      style="width: 100%; height: 100%"
+      @click="setEdit"
+      @contextmenu="setEdit"
+      @dragenter="handleDragEnter"
+      @dragleave="handleDragLeave"
+      @drop="handleDrop"
   >
     <StyledSimpleText
         ref="editArea"
         :class="{
-        'can-edit': canEdit,
-        'is-drag-over': dragOver
-      }"
+          'can-edit': canEdit,
+          'is-drag-over': dragOver
+        }"
         :contenteditable="canEdit"
         class="edit-area"
         tabindex="0"
@@ -23,31 +23,30 @@
         @mousedown="handleMouseDown"
         @paste="clearStyle"
     >
-      <div class="roy-simple-text-inner" v-html="propValue"></div>
+      <div class="yvan-simple-text-inner" v-html="propValue"></div>
     </StyledSimpleText>
   </div>
 </template>
 
 <script>
-import { mapState } from 'pinia'
+import {mapState} from 'pinia';
 import {globalStore} from "@/store";
-import { StyledSimpleText } from '@/components/PageComponents/style'
-import commonMixin from '@/mixin/commonMixin'
-import toast from '@/utils/toast'
+import commonMixin from '@/mixin/commonMixin';
+import {StyledSimpleText} from '@/components/PageComponents/style';
+import YvanSimpleTextProps from "@/components/PageComponents/YvanSimpleTextProps.vue";
 
-/**
- *
- */
 export default {
-  name: 'RoySimpleText',
+  name: 'YvanSimpleText',
   mixins: [commonMixin],
   components: {
-    StyledSimpleText
+    StyledSimpleText,
+    YvanSimpleTextProps
   },
   props: {
     element: {
       type: Object,
-      default: () => {}
+      default: () => {
+      }
     },
     propValue: {
       type: String,
@@ -77,7 +76,8 @@ export default {
     }
   },
   methods: {
-    initMounted() {},
+    initMounted() {
+    },
     setEdit() {
       if (this.canEdit) {
         return
@@ -111,18 +111,18 @@ export default {
       if (index) {
         let bindingDataSource = this.dataSource[index]
         if (bindingDataSource) {
-          this.$store.commit('printTemplateModule/setBindValue', {
+          globalStore().setBindValue({
             id: this.element.id,
             bindValue: bindingDataSource
           })
-          this.$store.commit('printTemplateModule/setPropValue', {
+          globalStore().setPropValue({
             id: this.element.id,
-            propValue: `<span class="roy-binding-value">[绑定:${bindingDataSource.title}]</span>`
+            propValue: `<span class="yvan-binding-value">[绑定:${bindingDataSource.title}]</span>`
           })
           this.canEdit = false
         }
       } else {
-        toast('拖拽元素非数据源元素,此次拖拽无效', 'info')
+        System.toast('拖拽元素非数据源元素,此次拖拽无效', 'info')
       }
     },
     handleBlur() {
@@ -148,10 +148,14 @@ export default {
     },
     handleDragLeave() {
       this.dragOver = false
-    }
+    },
+  },
+  install(Vue) {
+    Vue.component(this.name, this)
+    Vue.component(YvanSimpleTextProps.name, YvanSimpleTextProps)
   },
   created() {
-    console.log(" RoySimpleText >>> ", this)
+
   },
   mounted() {
     this.initMounted()
@@ -175,7 +179,7 @@ export default {
 </script>
 
 <style lang="less">
-.RoySimpleText {
+.yvan-simple-text {
   .edit-area {
     width: 100%;
     height: 100%;

+ 128 - 0
src/components/PageComponents/YvanSimpleTextProps.vue

@@ -0,0 +1,128 @@
+<template>
+  <section class="yvan-simple-text-props">
+    <el-form ref="form" label-position="top">
+      <el-form-item label="宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="高度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="字体">
+        <el-select placeholder="请选择字体">
+          <el-option v-for="font in fontList" :label="font.name" :value="font.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="字体颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="字体大小(pt)">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="行高">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="排列">
+        <el-radio-group size="small">
+          <el-radio-button>
+            <component is="align-left-outlined"/>
+          </el-radio-button>
+          <el-radio-button>
+            <component is="align-center-outlined"/>
+          </el-radio-button>
+          <el-radio-button>
+            <component is="align-right-outlined"/>
+          </el-radio-button>
+          <el-radio-button>
+            <component is="vertical-align-top-outlined"/>
+          </el-radio-button>
+          <el-radio-button>
+            <component is="vertical-align-middle-outlined"/>
+          </el-radio-button>
+          <el-radio-button>
+            <component is="vertical-align-bottom-outlined"/>
+          </el-radio-button>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="文字样式">
+        <el-radio-group size="small">
+          <el-radio-button>
+            <i class="fa fa-bold"/>
+          </el-radio-button>
+          <el-radio-button>
+            <i class="fa fa-italic"/>
+          </el-radio-button>
+          <el-radio-button>
+            <i class="fa fa-underline"/>
+          </el-radio-button>
+          <el-radio-button>
+            <i class="fa fa-strikethrough"/>
+          </el-radio-button>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="背景颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框样式">
+        <el-checkbox-group size="small">
+          <el-checkbox-button label="全">
+            <component is="border-outer-outlined"/>
+          </el-checkbox-button>
+          <el-checkbox-button label="上">
+            <component is="border-top-outlined"/>
+          </el-checkbox-button>
+          <el-checkbox-button label="右">
+            <component is="border-right-outlined"/>
+          </el-checkbox-button>
+          <el-checkbox-button label="下">
+            <component is="border-bottom-outlined"/>
+          </el-checkbox-button>
+          <el-checkbox-button label="左">
+            <component is="border-left-outlined"/>
+          </el-checkbox-button>
+        </el-checkbox-group>
+      </el-form-item>
+      <el-form-item label="边框类型">
+        <el-select placeholder="请选择行高">
+          <el-option v-for="borderStyle in borderStyleList" :label="borderStyle.label" :value="borderStyle.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="边框颜色">
+        <el-color-picker show-alpha/>
+      </el-form-item>
+      <el-form-item label="边框宽度">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="旋转角度(°)">
+        <el-input-number controls-position="right"/>
+      </el-form-item>
+    </el-form>
+  </section>
+</template>
+
+<script lang="ts">
+import {fontList, borderStyleList} from "@/components/config/globalConfig";
+
+export default {
+  name: 'YvanSimpleTextProps',
+  data() {
+    return {
+      fontList,
+      borderStyleList
+    }
+  }
+}
+
+</script>
+
+<style lang="less">
+.yvan-simple-text-props {
+
+  .el-input-number {
+    width: 100%;
+  }
+
+  .el-select {
+    width: 100%;
+  }
+}
+</style>

+ 17 - 0
src/components/PageComponents/index.js

@@ -0,0 +1,17 @@
+import YvanLine from "@/components/PageComponents/YvanLine.vue";
+import YvanRect from "@/components/PageComponents/YvanRect.vue";
+import YvanImage from "@/components/PageComponents/YvanImage.vue";
+import YvanCircle from "@/components/PageComponents/YvanCircle.vue";
+import YvanBarcode from "@/components/PageComponents/YvanBarcode.vue";
+import YvanRichText from "@/components/PageComponents/YvanRichText.vue";
+import YvanSimpleText from "@/components/PageComponents/YvanSimpleText.vue";
+
+export const install = (Vue) => {
+    YvanLine.install(Vue)
+    YvanRect.install(Vue)
+    YvanImage.install(Vue)
+    YvanCircle.install(Vue)
+    YvanBarcode.install(Vue)
+    YvanRichText.install(Vue)
+    YvanSimpleText.install(Vue)
+}

+ 1 - 1
src/components/PageComponents/style.js

@@ -180,7 +180,7 @@ export const StyledSimpleText = styled('div', textProps)`
   border: ${(props) => `${props.borderWidth}px ${props.borderType} ${props.borderColor}`};
   z-index: ${(props) => props.zIndex};
 
-  .roy-simple-text-inner {
+  .yvan-simple-text-inner {
     height: 100%;
     display: flex;
     text-align: left;

+ 1 - 81
src/components/PageToc.vue

@@ -26,9 +26,9 @@
 
 <script lang="js">
 import {mapState} from 'pinia'
+import {globalStore} from "@/store";
 import commonMixin from '@/mixin/commonMixin'
 import YvanPrintMain from "@/components/yvan-ui/yvan-print-main.vue";
-import {globalStore} from "@/store";
 
 /**
  * 页面大纲
@@ -95,85 +95,5 @@ export default {
 </script>
 
 <style lang="less" scoped>
-.roy-page-toc {
-  height: 100%;
-  padding: 6px;
-
-  .roy-page-toc__empty {
-    font-size: 10px;
-    height: 100%;
-    width: 100%;
-    display: flex;
-    flex-flow: row wrap;
-
-    i {
-      font-size: 28px;
-      width: 100%;
-      align-self: end;
-      text-align: center;
-    }
-
-    div {
-      text-align: center;
-    }
-  }
-
-  .roy-page-toc__list {
-    height: 30px;
-    cursor: grab;
-    text-align: center;
-    color: var(--roy-text-color-primary);
-    display: flex;
-    align-items: center;
-    font-size: 12px;
-    padding: 0 10px;
-    position: relative;
-    user-select: none;
-
-    .roy-page-toc__label {
-      text-align: left;
-      white-space: nowrap;
-      text-overflow: ellipsis;
-      width: 50%;
-      overflow: hidden;
-    }
-
-    i {
-      font-size: 12px;
-    }
 
-    &.activated {
-      color: var(--roy-color-primary);
-      background: var(--roy-color-primary-light-7);
-    }
-
-    &:active {
-      cursor: grabbing;
-    }
-
-    &:hover {
-      background-color: rgba(200, 200, 200, 0.2);
-      color: var(--roy-text-color-primary);
-
-      .roy-page-toc__buttons {
-        display: block;
-      }
-    }
-  }
-
-  .roy-page-toc__buttons {
-    position: absolute;
-    right: 10px;
-    display: none;
-
-    span {
-      cursor: pointer;
-      padding: 5px;
-
-      &:hover {
-        background: var(--roy-menu-item-hover-fill);
-      }
-    }
-  }
-}
 </style>

+ 28 - 25
src/components/config/componentList.ts

@@ -29,10 +29,10 @@ export const layoutComponentList = [
  */
 export const basicComponentList = [
     {
-        icon: 'fa file-text-o',
+        icon: 'fa fa-file-text-o',
         code: 'text',
         name: '文本',
-        component: 'RoySimpleText',
+        component: 'YvanSimpleText',
         propValue: '单击编辑文本',
         style: {
             color: '#000000',
@@ -60,10 +60,10 @@ export const basicComponentList = [
         groupStyle: {}
     },
     {
-        icon: 'ri-t-box-line',
+        icon: 'fa fa-text-height',
         code: 'long-text',
         name: '长文本',
-        component: 'RoyText',
+        component: 'YvanRichText',
         propValue:
             '<p><span style="font-size: 16pt;">双击</span><span style="color: rgb(255, 255, 255); background-color: #009688; font-size: 16pt; font-family: 仿宋;">编辑</span><span style="font-size: 16pt;">文本</span></p>',
         style: {
@@ -80,7 +80,7 @@ export const basicComponentList = [
         icon: 'ri-table-2',
         code: 'table',
         name: '单元格',
-        component: 'RoySimpleTable',
+        component: 'YvanSimpleTable',
         propValue: {},
         style: {
             width: 'auto',
@@ -94,10 +94,10 @@ export const basicComponentList = [
         groupStyle: {}
     },
     {
-        icon: 'ri-table-line',
+        icon: 'fa fa-table',
         code: 'complex-table',
         name: '复杂表格',
-        component: 'RoyComplexTable',
+        component: 'YvanComplexTable',
         propValue: {},
         showPrefix: true,
         showHead: true,
@@ -117,10 +117,10 @@ export const basicComponentList = [
         groupStyle: {}
     },
     {
-        icon: 'ri-subtract-line',
+        icon: 'fa fa-minus',
         code: 'line',
         name: '直线',
-        component: 'RoyLine',
+        component: 'YvanLine',
         propValue: '',
         style: {
             width: 200,
@@ -131,10 +131,10 @@ export const basicComponentList = [
         groupStyle: {}
     },
     {
-        icon: 'ri-checkbox-blank-line',
+        icon: 'fa fa-square-o',
         code: 'rectangle',
         name: '矩形',
-        component: 'RoyRect',
+        component: 'YvanRect',
         propValue: '',
         style: {
             borderRadius: 'inherit',
@@ -149,10 +149,10 @@ export const basicComponentList = [
         groupStyle: {}
     },
     {
-        icon: 'ri-checkbox-blank-circle-line',
+        icon: 'fa fa-circle-thin',
         code: 'circle',
         name: '圆形',
-        component: 'RoyCircle',
+        component: 'YvanCircle',
         propValue: '',
         style: {
             borderWidth: 1,
@@ -166,25 +166,29 @@ export const basicComponentList = [
         groupStyle: {}
     },
     {
-        icon: 'ri-star-line',
-        code: 'star',
-        name: '五角星',
-        component: 'RoyStar',
-        propValue: '',
+        icon: 'fa fa-image',
+        code: 'image',
+        name: '图片',
+        component: 'YvanImage',
+        src: '',
+        title: '默认图片',
         style: {
+            borderRadius: 'inherit',
+            borderWidth: 0,
+            borderColor: '#212121',
+            borderType: 'none',
             width: 200,
             height: 200,
-            background: '#FF0000',
-            icon: 'icon-shiwujiaoxing',
+            background: null,
             rotate: 0
         },
         groupStyle: {}
     },
     {
-        icon: 'ri-image-2-line',
-        code: 'image',
-        name: '图片',
-        component: 'RoyImage',
+        icon: 'fa fa-barcode',
+        code: 'barcode',
+        name: '条码',
+        component: 'YvanBarcode',
         src: '',
         title: '默认图片',
         style: {
@@ -245,6 +249,5 @@ export const getComponentMap = function () {
             componentMap.set(component.code, component)
         }
     }
-    console.log(" >>> ", componentMap)
     return componentMap
 }

+ 15 - 0
src/components/config/globalConfig.ts

@@ -0,0 +1,15 @@
+/** 字体 */
+export const fontList = [
+    {code: 'black_body', name: '黑体'},
+    {code: 'STFangSong', name: '华文仿宋'},
+    {code: 'Microsoft_YaHei', name: '微软雅黑'},
+]
+
+export const borderStyleList = [
+    {code: 'none', name: '无', label: '无'},
+    {code: 'solid', name: '实线', label: '实线'},
+    {code: 'dotted', name: '点状', label: '点状'},
+    {code: 'dashed', name: '虚线', label: '虚线'},
+    {code: 'double', name: '双线', label: '双线'},
+]
+

+ 0 - 47
src/components/config/menuConfig.ts

@@ -1,47 +0,0 @@
-import {markRaw} from "vue";
-// import PageComponent from '@/components/PageComponent.vue';
-import PageToc from '@/components/PageToc.vue';
-import PagePalette from '@/components/PagePalette.vue';
-import DataSource from '@/components/DataSource.vue';
-import GlobalSetting from '@/components/GlobalSetting.vue';
-
-export default {
-    menuList: [
-        {
-            title: '组件',
-            code: 'component',
-            icon: 'fa fa-cube',
-            activeIcon: 'fa fa-cube',
-            isActive: true,
-            // relativeComponent: markRaw(PageComponent)
-        },
-        {
-            title: '结构',
-            code: 'toc',
-            icon: 'fa fa-reorder',
-            activeIcon: 'fa fa-reorder',
-            relativeComponent: markRaw(PageToc)
-        },
-        {
-            title: '属性',
-            code: 'palette',
-            icon: 'fa fa-bullseye',
-            activeIcon: 'fa fa-bullseye',
-            relativeComponent: markRaw(PagePalette)
-        },
-        {
-            title: '数据源',
-            code: 'datasource',
-            icon: 'fa fa-database',
-            activeIcon: 'fa fa-database',
-            relativeComponent: markRaw(DataSource)
-        },
-        {
-            title: '全局',
-            code: 'setting',
-            icon: 'fa fa-gear',
-            activeIcon: 'fa fa-gear',
-            relativeComponent: markRaw(GlobalSetting)
-        }
-    ]
-}

+ 2 - 2
src/components/config/toolbarConfig.ts

@@ -35,9 +35,9 @@ export default [
         name: '页面设置',
         icon: 'fa fa-gear',
         event: () => {
-            System.showDialog(YvanPrintPageFormat, {title: "页面设置", width: 40}).then((res) => {
+            window['System'].showDialog(YvanPrintPageFormat, {title: "页面设置", width: 40}).then((res: any) => {
                 console.log(" >>> then", res)
-            }).catch((res) => {
+            }).catch((res: any) => {
                 console.log(" >>> catch", res)
             }).finally(() => {
                 console.log(" >>> finally")

+ 1 - 1
src/components/sketch-ruler/sketchRuler.vue

@@ -194,7 +194,7 @@ export default {
     }
   },
   mounted() {
-    console.log("this.props", this.$props)
+
   }
 }
 </script>

+ 41 - 31
src/components/yvan-context/components/Context.vue

@@ -5,8 +5,10 @@
 </template>
 
 <script>
+import eventBus from "@/utils/eventBus";
+
 export default {
-  name: 'RoyContext',
+  name: 'yvan-print-context',
 
   provide() {
     return {
@@ -42,18 +44,20 @@ export default {
   },
   computed: {
     clickOutsideHandler() {
-      return this.visible ? this.hide : () => {}
+      return this.visible ? this.hide : () => {
+      }
     },
     isClick() {
       return this.eventType === 'click'
     },
     contextmenuCls() {
-      return ['roy-context', `roy-context--${this.theme}`]
+      return ['yvan-print-context', `yvan-print-context--${this.theme}`]
     }
   },
 
   watch: {
     visible(value) {
+      console.log("watch visible >>>> ", value)
       if (value) {
         this.$emit('show', this)
 
@@ -66,12 +70,18 @@ export default {
     }
   },
   mounted() {
+    console.log('Context menu >>> ', this.$props)
+
     document.body.appendChild(this.$el)
 
+    eventBus.on("showContextMenu", (position) => {
+      this.show(position)
+    })
+
     if (window.$$VContextmenu) {
       window.$$VContextmenu[this.$contextmenuId] = this
     } else {
-      window.$$VContextmenu = { [this.$contextmenuId]: this }
+      window.$$VContextmenu = {[this.$contextmenuId]: this}
     }
   },
   beforeDestroy() {
@@ -136,8 +146,8 @@ export default {
     },
     handleBodyClick(event) {
       const notOutside =
-        this.$el.contains(event.target) ||
-        (this.isClick && this.references.some((ref) => ref.el.contains(event.target)))
+          this.$el.contains(event.target) ||
+          (this.isClick && this.references.some((ref) => ref.el.contains(event.target)))
 
       if (!notOutside) {
         this.visible = false
@@ -156,7 +166,7 @@ export default {
           left: `${position.left}px`
         }
       }
-
+      console.log("position >>>", position, this.style)
       this.visible = true
     },
     hide() {
@@ -172,7 +182,7 @@ export default {
 </script>
 
 <style>
-.roy-context {
+.yvan-print-context {
   position: absolute;
   padding: 5px 0;
   margin: 0;
@@ -188,7 +198,7 @@ export default {
   -webkit-tap-highlight-color: transparent;
 }
 
-.roy-context .roy-context-item {
+.yvan-print-context .yvan-print-context-item {
   padding: 5px 14px;
   line-height: 1;
   color: #333;
@@ -197,102 +207,102 @@ export default {
   cursor: pointer;
 }
 
-.roy-context .roy-context-item.roy-context-item--hover {
+.yvan-print-context .yvan-print-context-item.yvan-print-context-item--hover {
   color: #fff;
 }
 
-.roy-context .roy-context-item.roy-context-item--disabled {
+.yvan-print-context .yvan-print-context-item.yvan-print-context-item--disabled {
   color: #ccc;
   cursor: not-allowed;
 }
 
-.roy-context .roy-context-divider {
+.yvan-print-context .yvan-print-context-divider {
   height: 0;
   margin: 5px 0;
   border-bottom: 1px solid #e8e8e8;
 }
 
-.roy-context .roy-context-group__menus {
+.yvan-print-context .yvan-print-context-group__menus {
   padding: 0 5px;
   margin: 0;
   list-style: none;
 }
 
-.roy-context .roy-context-group__menus .roy-context-item {
+.yvan-print-context .yvan-print-context-group__menus .yvan-print-context-item {
   display: inline-block;
   padding: 5px 9px;
 }
 
-.roy-context .roy-context-submenu {
+.yvan-print-context .yvan-print-context-submenu {
   position: relative;
 }
 
-.roy-context .roy-context-submenu > .roy-context {
+.yvan-print-context .yvan-print-context-submenu > .yvan-print-context {
   position: absolute;
 }
 
-.roy-context .roy-context-submenu > .roy-context.left {
+.yvan-print-context .yvan-print-context-submenu > .yvan-print-context.left {
   left: 0;
   transform: translateX(-100%);
 }
 
-.roy-context .roy-context-submenu > .roy-context.right {
+.yvan-print-context .yvan-print-context-submenu > .yvan-print-context.right {
   right: 0;
   transform: translateX(100%);
 }
 
-.roy-context .roy-context-submenu > .roy-context.top {
+.yvan-print-context .yvan-print-context-submenu > .yvan-print-context.top {
   top: -6px;
 }
 
-.roy-context .roy-context-submenu > .roy-context.bottom {
+.yvan-print-context .yvan-print-context-submenu > .yvan-print-context.bottom {
   bottom: -6px;
 }
 
-.roy-context .roy-context-submenu .roy-context-submenu__title {
+.yvan-print-context .yvan-print-context-submenu .yvan-print-context-submenu__title {
   margin-right: 10px;
 }
 
-.roy-context .roy-context-submenu .roy-context-submenu__icon {
+.yvan-print-context .yvan-print-context-submenu .yvan-print-context-submenu__icon {
   position: absolute;
   right: 5px;
 }
 
-.roy-context .roy-context-submenu .roy-context-submenu__icon::before {
+.yvan-print-context .yvan-print-context-submenu .yvan-print-context-submenu__icon::before {
   content: '\e622';
 }
 
-.roy-context--default .roy-context-item--hover {
+.yvan-print-context--default .yvan-print-context-item--hover {
   background-color: #4579e1;
 }
 
-.roy-context--bright .roy-context-item--hover {
+.yvan-print-context--bright .yvan-print-context-item--hover {
   background-color: #ef5350;
 }
 
-.roy-context--dark .roy-context-item--hover {
+.yvan-print-context--dark .yvan-print-context-item--hover {
   background-color: #2d3035;
 }
 
-.roy-context--dark {
+.yvan-print-context--dark {
   background: #222222;
   box-shadow: 2px 2px 8px 0 rgba(0, 0, 0, 0.2);
   border: 1px solid #111111;
 }
 
-.roy-context--dark .roy-context-item {
+.yvan-print-context--dark .yvan-print-context-item {
   color: #ccc;
 }
 
-.roy-context-item i {
+.yvan-print-context-item i {
   padding: 0 10px 0 0;
 }
 
-.roy-context--danger {
+.yvan-print-context--danger {
   color: #f54536 !important;
 }
 
-.roy-context--danger:hover {
+.yvan-print-context--danger:hover {
   background: #f54536;
   color: #fff !important;
 }

+ 4 - 4
src/components/yvan-context/components/ContextItem.vue

@@ -1,5 +1,5 @@
 <template>
-  <li v-if="divider" class="roy-context-divider"></li>
+  <li v-if="divider" class="yvan-print-context-divider"></li>
 
   <li
     v-else
@@ -35,9 +35,9 @@ export default {
   computed: {
     classname() {
       return {
-        'roy-context-item': !this.divider,
-        'roy-context-item--hover': this.hover,
-        'roy-context-item--disabled': this.disabled
+        'yvan-print-context-item': !this.divider,
+        'yvan-print-context-item--hover': this.hover,
+        'yvan-print-context-item--disabled': this.disabled
       }
     }
   },

+ 1 - 0
src/components/yvan-context/directive.js

@@ -2,6 +2,7 @@
 export default {
   // 之所以用 inserted 而不是 bind,是需要确保 contentmenu mounted 后才进行 addRef 操作
   inserted(el, binding, vnode) {
+    console.log('directive >>> ', el, binding, vnode)
     const node = vnode.context.$refs[binding.arg] || vnode.context.$refs[binding.value]
     const contextmenu = Object.prototype.toString.call(node) === '[object Array]' ? node[0] : node
     contextmenu.addRef({ el, vnode })

+ 14 - 14
src/components/yvan-editor/ComponentAdjuster.vue

@@ -2,30 +2,30 @@
   <div
       ref="adjuster"
       :style="adjusterStyle"
-      class="roy-component-adjuster"
+      class="yvan-print-component-adjuster"
       @click="selectCurComponent"
       @mousedown="handleMouseDownOnShape"
   >
     <span
         v-show="isActive && showRotate"
-        class="fa fa-rotate-left roy-component-adjuster__rotate"
+        class="fa fa-rotate-left yvan-print-component-adjuster__rotate"
         @mousedown="handleRotate"
     ></span>
-    <span v-show="element.isLock" class="ri-lock-fill roy-component-adjuster__lock"></span>
+    <span v-show="element.isLock" class="fa fa-lock yvan-print-component-adjuster__lock"></span>
     <span
         v-show="element.bindValue"
-        class="ri-link-unlink-m roy-component-adjuster__bind"
+        class="ri-link-unlink-m yvan-print-component-adjuster__bind"
         @click="unlinkElement"
     ></span>
     <span
         :class="element.icon"
-        class="roy-component-adjuster__move"
+        class="yvan-print-component-adjuster__move"
         @mousedown="handleMouseMoveItem"
     ></span>
     <div
         v-for="item in isActive ? pointList : []"
         :key="item"
-        :class="`roy-component-adjuster__shape-point--${item}`"
+        :class="`yvan-print-component-adjuster__shape-point--${item}`"
         :style="getPointStyle(item)"
         @mousedown="handleMouseDownOnPoint(item, $event)"
     ></div>
@@ -435,7 +435,7 @@ export default {
 </script>
 
 <style lang="less">
-.roy-component-adjuster {
+.yvan-print-component-adjuster {
   margin: 0;
   padding: 0;
   position: absolute;
@@ -445,12 +445,12 @@ export default {
     border: 0.5px dotted var(--yvan-text-color-secondary);
   }
 
-  .roy-component-adjuster__rotate {
+  .yvan-print-component-adjuster__rotate {
     position: absolute;
     top: -28px;
     left: 50%;
     transform: translateX(-60%);
-    cursor: grab;
+    cursor: pointer;
     color: var(--yvan-text-color-regular);
     font-size: 10px;
     font-weight: 400;
@@ -469,20 +469,20 @@ export default {
     }
   }
 
-  .roy-component-adjuster__lock {
+  .yvan-print-component-adjuster__lock {
     position: absolute;
     top: -15px;
     right: 0;
     z-index: 9;
   }
 
-  .roy-component-adjuster__move {
+  .yvan-print-component-adjuster__move {
     position: absolute;
     top: 0;
     left: -25px;
     z-index: 9;
     padding: 2px;
-    font-size: 10px;
+    font-size: 15px;
     border-radius: 2px;
     font-weight: 100;
     cursor: move;
@@ -499,7 +499,7 @@ export default {
     }
   }
 
-  .roy-component-adjuster__bind {
+  .yvan-print-component-adjuster__bind {
     position: absolute;
     top: 20px;
     left: -25px;
@@ -512,7 +512,7 @@ export default {
     color: #999;
   }
 
-  [class^='roy-component-adjuster__shape-point--'] {
+  [class^='yvan-print-component-adjuster__shape-point--'] {
     position: absolute;
     border: 1px solid var(--yvan-color-primary);
     box-shadow: 0 0 2px #bbb;

+ 35 - 52
src/components/yvan-editor/Editor.vue

@@ -54,12 +54,8 @@
           <!-- 标线 -->
           <EditorLine/>
           <!-- 上下边距线 -->
-          <div
-              :style="`top: ${pageConfig?.pageMarginTop * realScale}px`"
-              class="yvan-print-margin-top-line"/>
-          <div
-              :style="`bottom: ${pageConfig?.pageMarginBottom * realScale}px`"
-              class="yvan-print-margin-bottom-line"/>
+          <div :style="`top: ${pageConfig?.pageMarginTop * realScale}px`" class="yvan-print-margin-top-line"/>
+          <div :style="`bottom: ${pageConfig?.pageMarginBottom * realScale}px`" class="yvan-print-margin-bottom-line"/>
         </div>
       </div>
     </div>
@@ -88,10 +84,10 @@ import {Context, ContextItem, directive} from '@/components/yvan-context'
 import ComponentAdjuster from '@/components/yvan-editor/ComponentAdjuster.vue'
 import {getComponentRotatedStyle, getShapeStyle} from '@/utils/style-util.js'
 import Big from 'big.js'
-import RoyText from '@/components/PageComponents/RoyText.vue'
-import RoySimpleText from '@/components/PageComponents/RoySimpleText.vue'
+// import RoyText from '@/components/PageComponents/YvanRichText.vue'
+// import YvanSimpleText from '@/components/PageComponents/YvanSimpleText.vue'
 // import RoyRect from '@/components/PageComponents/RoyRect'
-import RoyLine from '@/components/PageComponents/RoyLine.vue'
+// import RoyLine from '@/components/PageComponents/YvanLine.vue'
 // import RoyImage from '@/components/PageComponents/RoyImage'
 // import RoyStar from '@/components/PageComponents/RoyStar'
 // import RoyCircle from '@/components/PageComponents/RoyCircle'
@@ -103,6 +99,7 @@ import commonMixin from '@/mixin/commonMixin'
 import {$, isPreventDrop} from '@/utils/html-util.js'
 import EditorLine from '@/components/yvan-editor/EditorLine.vue'
 import EditorCoordinate from '@/components/yvan-editor/EditorCoordinate.vue'
+import eventBus from "@/utils/eventBus.js";
 
 const {MIN_SCALE, MAX_SCALE} = CONSTANT
 
@@ -119,11 +116,11 @@ export default {
     Context,
     ContextItem,
     ComponentAdjuster,
-    RoyText,
-    RoySimpleText,
+    // RoyText,
+    // YvanSimpleText,
     // RoyGroup,
     // RoyRect,
-    RoyLine,
+    // RoyLine,
     // RoyCircle,
     // RoyStar,
     // RoyImage,
@@ -195,89 +192,73 @@ export default {
       if (!this.curComponent) {
         return [
           {
-            code: 'setting',
-            icon: 'ri-list-settings-line',
-            label: '属性',
-            status: 'default',
-            event: () => {
-              // this.$store.commit('printTemplateModule/setGlobalCount')
-            }
-          },
-          {
             code: 'paste',
-            icon: 'ri-clipboard-line',
+            icon: 'fa fa-paste',
             label: '粘贴',
             status: 'default',
             event: () => {
-              // this.$store.commit('printTemplateModule/paste', true)
-              // this.$store.commit('printTemplateModule/recordSnapshot')
+              globalStore().paste(true)
+              globalStore().recordSnapshot()
             }
           }
         ]
       }
       if (this.curComponent.isLock) {
+        const curComponent = this.curComponent
         return [
           {
             code: 'unlock',
-            icon: 'ri-lock-unlock-line',
+            icon: 'fa fa-unlock',
             label: '解锁',
             status: 'default',
             event: () => {
-              // this.$store.commit('printTemplateModule/unlock')
+              globalStore().unlock({curComponent})
             }
           }
         ]
       }
+      const curComponent = this.curComponent
       return [
         {
-          code: 'setting',
-          icon: 'ri-list-settings-line',
-          label: '属性',
-          status: 'default',
-          event: () => {
-            // this.$store.commit('printTemplateModule/setPaletteCount')
-          }
-        },
-        {
           code: 'copy',
-          icon: 'ri-file-copy-line',
+          icon: 'fa fa-copy',
           label: '复制',
           status: 'default',
           event: () => {
-            // this.$store.commit('printTemplateModule/copy')
+            globalStore().copy()
           }
         },
         {
           code: 'cut',
-          icon: 'ri-scissors-cut-line',
+          icon: 'fa fa-cut',
           label: '剪切',
           status: 'default',
           event: () => {
-            // this.$store.commit('printTemplateModule/cut')
+            globalStore().cut()
           }
         },
         {
           code: 'del',
-          icon: 'ri-delete-bin-line',
+          icon: 'fa fa-trash',
           label: '删除',
           status: 'danger',
           event: () => {
-            // this.$store.commit('printTemplateModule/deleteComponent')
-            // this.$store.commit('printTemplateModule/recordSnapshot')
+            globalStore().deleteComponent(globalStore().curComponentIndex)
+            globalStore().recordSnapshot()
           }
         },
         {
           code: 'lock',
-          icon: 'ri-lock-line',
+          icon: 'fa fa-lock',
           label: '锁定',
           status: 'default',
           event: () => {
-            // this.$store.commit('printTemplateModule/lock')
+            globalStore().lock({curComponent})
           }
         },
         {
           code: 'top',
-          icon: 'ri-align-top',
+          icon: 'fa fa-angle-double-up',
           label: '置顶',
           status: 'default',
           event: () => {
@@ -287,7 +268,7 @@ export default {
         },
         {
           code: 'bottom',
-          icon: 'ri-align-bottom',
+          icon: 'fa fa-angle-double-down',
           label: '置底',
           status: 'default',
           event: () => {
@@ -297,7 +278,7 @@ export default {
         },
         {
           code: 'up',
-          icon: 'ri-arrow-up-line',
+          icon: 'fa fa-arrow-circle-up',
           label: '上移',
           status: 'default',
           event: () => {
@@ -307,7 +288,7 @@ export default {
         },
         {
           code: 'down',
-          icon: 'ri-arrow-down-line',
+          icon: 'fa fa-arrow-circle-down',
           label: '下移',
           status: 'default',
           event: () => {
@@ -351,6 +332,7 @@ export default {
     ...mapActions(ruleStore, ['setReDrawRuler', 'setScale']),
     getShapeStyle,
     handleMouseDown(e) {
+      console.log("editor >> handleMouseDown >>> ", e)
       // 如果没有选中组件 在画布上点击时需要调用 e.preventDefault() 防止触发 drop 事件
       if (!this.curComponent || isPreventDrop(this.curComponent.component)) {
         e.preventDefault()
@@ -400,9 +382,11 @@ export default {
     handleContextMenu(e) {
       e.stopPropagation()
       e.preventDefault()
-      let top = e.offsetY
-      let left = e.offsetX
-      globalStore().showContextMenu(globalStore, {top, left})
+      let top = e.clientY
+      let left = e.clientX
+      console.log("handleContextMenu >>> ", top, left, e)
+      // globalStore().showContextMenu( {top, left})
+      eventBus.emit("showContextMenu", {top, left})
     },
     hideArea() {
       this.isShowArea = 0
@@ -544,7 +528,6 @@ export default {
     }
   },
   mounted() {
-    console.log("mounted >>> editor")
     this.rulerWidth = this.$el.offsetWidth
     this.rulerHeight = this.$el.offsetHeight
     this.$refs.screensRef.scrollLeft = this.$refs.containerRef.getBoundingClientRect().width / 2 - this.rectWidth

+ 11 - 11
src/components/yvan-print-designer-left-component.vue

@@ -1,23 +1,23 @@
 <template>
-  <section :style="asideStyle" class="yvan-print-designer-left-component__main">
-    <div class="yvan-print-designer-left-component__title">
+  <section :style="asideStyle" class="yvan-print-designer-left-element__main">
+    <div class="yvan-print-designer-left-element__title">
       <i class="fa fa-cubes vsm--icon"></i>
       <span>组件列表</span>
     </div>
-    <div class="yvan-print-designer-left-component__content">
+    <div class="yvan-print-designer-left-element__content">
       <el-collapse v-model="collapseOptions.activeName">
         <el-collapse-item
             v-for="componentType in componentTypeList"
             :title="componentType.title"
             :name="componentType.name">
-          <div class="yvan-print-designer-left-component__collapse_item">
+          <div class="yvan-print-designer-left-element__collapse_item">
             <el-space wrap @dragstart="handleDragStart">
               <div
                   v-for="component in componentType.componentList"
                   :key="component.code"
                   :data-code="component.code"
                   draggable="true">
-                <el-button :icon="renderIcon(component.icon)"> {{ component.name }}</el-button>
+                <el-button> {{ component.name }}</el-button>
               </div>
             </el-space>
           </div>
@@ -34,7 +34,7 @@ import commonMixin from '@/mixin/commonMixin'
 import {componentTypeList} from "@/components/config/componentList";
 
 export default {
-  name: 'yvan-print-designer-left-component',
+  name: 'yvan-print-designer-left-element',
   mixins: [commonMixin],
   data() {
     return {
@@ -76,10 +76,10 @@ export default {
 </script>
 
 <style lang="less" scoped>
-.yvan-print-designer-left-component__main {
+.yvan-print-designer-left-element__main {
   height: 100%;
 
-  .yvan-print-designer-left-component__title {
+  .yvan-print-designer-left-element__title {
     width: 100%;
     height: 45px;
     text-align: left;
@@ -93,13 +93,13 @@ export default {
     }
   }
 
-  .yvan-print-designer-left-component__content {
+  .yvan-print-designer-left-element__content {
     padding: 0 5px;
     height: calc(100% - 50px);
-    overflow: auto;
+    overflow-y: auto;
     background: var(--yvan-bg-color-overlay);
 
-    .yvan-print-designer-left-component__collapse_item {
+    .yvan-print-designer-left-element__collapse_item {
       margin: 0 10px;
     }
   }

+ 155 - 9
src/components/yvan-print-designer-left-structure.vue

@@ -5,17 +5,44 @@
       <span>页面结构</span>
     </div>
     <div class="yvan-print-designer-left-structure__content">
-
+      <yvan-print-main class="yvan-page-toc">
+        <div v-if="componentData.length">
+          <div
+              v-for="(item, index) in componentData"
+              :key="index"
+              :class="{ activated: transformIndex(index) === curComponentIndex }"
+              class="yvan-page-toc__list"
+              @click="onClick(transformIndex(index))"
+          >
+            <i :class="getComponent(index).icon" style="padding-right: 5px"></i>
+            <span class="yvan-page-toc__label">{{ getComponent(index).label }}</span>
+            <div class="yvan-page-toc__buttons">
+              <span class="fa fa-arrow-up" @click="upComponent(transformIndex(index))"></span>
+              <span class="fa fa-arrow-down" @click="downComponent(transformIndex(index))"></span>
+              <span class="fa fa-trash" @click="deleteComponent(transformIndex(index))"></span>
+            </div>
+          </div>
+        </div>
+        <div v-else class="yvan-page-structure__empty animate__animated animate__headShake">
+          <component is="exclamation-circle-outlined" class="yvan-page-structure__empty_icon"/>
+          <div>当前没有组件,请通过拖拽添加组件</div>
+        </div>
+      </yvan-print-main>
     </div>
   </section>
 </template>
 
 <script>
+import {mapState} from "pinia";
+import {globalStore} from "@/store";
 import commonMixin from '@/mixin/commonMixin'
+import YvanPrintMain from "@/components/yvan-ui/yvan-print-main.vue";
 
 export default {
   name: 'yvan-print-designer-left-structure',
-  components: {},
+  components: {
+    YvanPrintMain
+  },
   mixins: [commonMixin],
   data() {
     return {
@@ -30,16 +57,54 @@ export default {
     }
   },
   computed: {
-    // ...mapState({
-    //   paletteCount: (state) => state.printTemplateModule.paletteCount,
-    //   globalCount: (state) => state.printTemplateModule.globalCount,
-    //   isNightMode: (state) => state.printTemplateModule.nightMode.isNightMode
-    // }),
+    ...mapState(globalStore, {
+      componentData: (state) => state.componentData,
+      curComponentIndex: (state) => state.curComponentIndex,
+      curComponent: (state) => state.curComponent
+    }),
     asideStyle() {
       return this.showRight ? 'width: 300px' : 'width: 65px'
     }
   },
-  methods: {},
+  methods: {
+    getComponent(index) {
+      return this.componentData[this.componentData.length - 1 - index]
+    },
+
+    transformIndex(index) {
+      return this.componentData.length - 1 - index
+    },
+    onClick(index) {
+      this.setCurComponent(index)
+    },
+    deleteComponent() {
+      setTimeout(() => {
+        globalStore().deleteComponent();
+        globalStore().recordSnapshot();
+      })
+    },
+
+    upComponent() {
+      setTimeout(() => {
+        globalStore().upComponent();
+        globalStore().recordSnapshot();
+      })
+    },
+
+    downComponent() {
+      setTimeout(() => {
+        globalStore().downComponent();
+        globalStore().recordSnapshot();
+      })
+    },
+
+    setCurComponent(index) {
+      globalStore().setCurComponent({
+        component: this.componentData[index],
+        index
+      })
+    }
+  },
   mounted() {
   },
   watch: {}
@@ -66,9 +131,90 @@ export default {
 
   .yvan-print-designer-left-structure__content {
     padding: 0 5px;
-    height: calc(100% - 45px);
+    height: calc(100% - 40px);
     overflow: auto;
     background: var(--yvan-bg-color-overlay);
+
+
+    .yvan-page-toc {
+      height: 100%;
+      padding: 6px;
+
+      .yvan-page-structure__empty {
+        width: 100%;
+        height: 100%;
+        font-size: 10px;
+        line-height: 25px;
+
+        .yvan-page-structure__empty_icon {
+          font-size: 28px;
+          color: var(--yvan-color-warning);
+        }
+
+        div {
+          text-align: center;
+        }
+      }
+
+      .yvan-page-toc__list {
+        height: 30px;
+        cursor: grab;
+        text-align: center;
+        color: var(--roy-text-color-primary);
+        display: flex;
+        align-items: center;
+        font-size: 12px;
+        padding: 0 10px;
+        position: relative;
+        user-select: none;
+
+        .yvan-page-toc__label {
+          text-align: left;
+          white-space: nowrap;
+          text-overflow: ellipsis;
+          width: 50%;
+          overflow: hidden;
+        }
+
+        i {
+          font-size: 12px;
+        }
+
+        &.activated {
+          color: var(--yvan-color-primary);
+          background: var(--yvan-color-primary-light-7);
+        }
+
+        &:active {
+          cursor: grabbing;
+        }
+
+        &:hover {
+          background-color: rgba(200, 200, 200, 0.2);
+          color: var(--yvan-text-color-primary);
+
+          .yvan-page-toc__buttons {
+            display: block;
+          }
+        }
+      }
+
+      .yvan-page-toc__buttons {
+        position: absolute;
+        right: 10px;
+        display: none;
+
+        span {
+          cursor: pointer;
+          padding: 5px;
+
+          &:hover {
+            background: var(--yvan-menu-item-hover-fill);
+          }
+        }
+      }
+    }
+
   }
 }
 </style>

+ 5 - 5
src/components/yvan-print-designer-left.vue

@@ -1,6 +1,6 @@
 <template>
-  <div class="yvan-print-designer-left-component">
-    <yvan-print-designer-left-component/>
+  <div class="yvan-print-designer-left-element">
+    <yvan-print-designer-left-element/>
   </div>
   <div class="yvan-print-designer-left-structure">
     <yvan-print-designer-left-structure/>
@@ -8,13 +8,13 @@
 </template>
 
 <script>
-import YvanPrintDesignerLeftComponent from "@/components/yvan-print-designer-left-component.vue";
+import YvanPrintDesignerLeftElement from "@/components/yvan-print-designer-left-element.vue";
 import YvanPrintDesignerLeftStructure from "@/components/yvan-print-designer-left-structure.vue";
 
 export default {
   name: 'yvan-print-designer-left',
   components: {
-    YvanPrintDesignerLeftComponent,
+    YvanPrintDesignerLeftElement,
     YvanPrintDesignerLeftStructure
   },
   data() {
@@ -37,7 +37,7 @@ export default {
 </script>
 
 <style lang="less" scoped>
-.yvan-print-designer-left-component {
+.yvan-print-designer-left-element {
   height: calc(50% - 10px);
   width: 100%;
 }

+ 2 - 9
src/components/yvan-print-designer-main.vue

@@ -24,15 +24,12 @@ import YvanPrintToolbar from "@/components/yvan-ui/yvan-print-toolbar.vue";
 import YvanPrintDesignerEditor from "@/components/yvan-editor/Editor.vue";
 import { getComponentMap } from '@/components/config/componentList';
 
-/**
- * 主操作视图
- */
 export default {
   name: 'yvan-print-designer-main',
   mixins: [commonMixin],
   components: {
-    YvanPrintDesignerEditor,
-    YvanPrintToolbar
+    YvanPrintToolbar,
+    YvanPrintDesignerEditor
   },
   props: {
     showRight: {
@@ -87,10 +84,6 @@ export default {
           component: null,
           index: null
         })
-      //   this.$store.commit('printTemplateModule/setCurComponent', {
-      //     component: null,
-      //     index: null
-      //   })
       }
     }
   },

+ 93 - 0
src/components/yvan-print-designer-props.vue

@@ -0,0 +1,93 @@
+<template>
+  <section :style="asideStyle" class="yvan-print-designer-props__main">
+    <div class="yvan-print-designer-props__title">
+      <i class="fa fa-reorder vsm--icon"></i>
+      <span>样式属性</span>
+    </div>
+    <div class="yvan-print-designer-props__content">
+      <component v-if="activeComponentName" :is="activeComponentName" class=""/>
+      <div v-else class="yvan-print-designer-props__empty">
+        <component is="exclamation-circle-outlined" class="yvan-print-designer-props__empty_icon"/>
+        <div>请先选定组件,再进行属性设置</div>
+      </div>
+    </div>
+  </section>
+</template>
+
+<script>
+import {mapState} from 'pinia'
+import {globalStore} from "@/store";
+import commonMixin from '@/mixin/commonMixin'
+
+export default {
+  name: 'yvan-print-designer-props',
+  components: {},
+  mixins: [commonMixin],
+  data() {
+    return {
+      isNightMode: false,
+    }
+  },
+  props: {
+    showRight: {
+      type: Boolean,
+      default: true
+    }
+  },
+  computed: {
+    ...mapState(globalStore, {
+      activeComponentName: (state) => {
+        console.log("activeComponentName => ", state.curComponent?.component)
+        if (state.curComponent?.component) {
+          return state.curComponent?.component + 'Props'
+        }
+        return state.curComponent;
+      }
+    }),
+    asideStyle() {
+      return this.showRight ? 'width: 300px' : 'width: 65px'
+    }
+  },
+  methods: {},
+}
+</script>
+
+<style lang="less" scoped>
+.yvan-print-designer-props__main {
+  width: 100%;
+  height: 100%;
+  background: var(--yvan-bg-color-overlay);
+
+  .yvan-print-designer-props__title {
+    width: 100%;
+    height: 45px;
+    text-align: left;
+    line-height: 45px;
+    background: var(--yvan-menu-bar-background);
+    color: #fff;
+    align-items: center;
+
+    i {
+      margin: 0 5px 0 10px;
+    }
+  }
+
+  .yvan-print-designer-props__content {
+    margin: 10px;
+    height: calc(100% - 55px);
+    overflow-y: auto;
+
+    .yvan-print-designer-props__empty {
+      width: 100%;
+      height: 100%;
+      font-size: 12px;
+      line-height: 25px;
+
+      .yvan-print-designer-props__empty_icon {
+        font-size: 25px;
+        color: var(--yvan-color-warning)
+      }
+    }
+  }
+}
+</style>

+ 0 - 160
src/components/yvan-print-designer-right.vue

@@ -1,160 +0,0 @@
-<template>
-  <section :style="asideStyle" class="yvan-print-designer-right__main">
-    <div class="yvan-print-designer-right__title">
-      <i class="fa fa-reorder vsm--icon"></i>
-      <span>组件属性</span>
-    </div>
-    <div class="yvan-print-designer-right__content">
-<!--      <yvan-print-sidebar-menu-->
-<!--          ref="sideMenu"-->
-<!--          :collapsed="true"-->
-<!--          :menu="menuList"-->
-<!--          :theme="isNightMode ? '' : 'white-theme'"-->
-<!--          width="150px"-->
-<!--          @item-click="onMenuSelect"-->
-<!--      />-->
-      <!--      <keep-alive>-->
-      <!--        <component-->
-      <!--            :is="curActiveComponent"-->
-      <!--            v-show="showRight"-->
-      <!--            :key="curActiveComponentCode"-->
-      <!--            class="yvan-print-designer-aside__right_panel"-->
-      <!--        />-->
-      <!--      </keep-alive>-->
-    </div>
-  </section>
-</template>
-
-<script>
-import commonMixin from '@/mixin/commonMixin'
-import menuConfig from "@/components/config/menuConfig";
-import YvanPrintSidebarMenu from "@/components/yvan-ui/yvan-sidebar-menu/SidebarMenu.vue";
-
-export default {
-  name: 'yvan-print-designer-aside',
-  components: {YvanPrintSidebarMenu},
-  mixins: [commonMixin],
-  data() {
-    return {
-      isNightMode: false,
-      menuList: menuConfig.menuList,
-      curActiveComponent: null,
-      curActiveComponentCode: ''
-    }
-  },
-  props: {
-    showRight: {
-      type: Boolean,
-      default: true
-    }
-  },
-  computed: {
-    // ...mapState({
-    //   paletteCount: (state) => state.printTemplateModule.paletteCount,
-    //   globalCount: (state) => state.printTemplateModule.globalCount,
-    //   isNightMode: (state) => state.printTemplateModule.nightMode.isNightMode
-    // }),
-    asideStyle() {
-      return this.showRight ? 'width: 300px' : 'width: 65px'
-    }
-  },
-  methods: {
-    onMenuSelect(e, item) {
-      this.curActiveComponent = item.relativeComponent
-      this.curActiveComponentCode = item.code
-      this.menuList.forEach((mItem) => {
-        if (item.code === mItem.code) {
-          mItem.isActive = true
-          return
-        }
-        mItem.isActive = false
-      })
-    },
-    clickPaletteMenu() {
-      this.$refs.sideMenu.$refs.menuItems.forEach((item) => {
-        if (item.item.code === 'palette' && this.curActiveComponentCode !== 'palette') {
-          this.onMenuSelect(null, item.item)
-        }
-      })
-    },
-    clickGlobalMenu() {
-      this.$refs.sideMenu.$refs.menuItems.forEach((item) => {
-        if (item.item.code === 'setting' && this.curActiveComponentCode !== 'setting') {
-          this.onMenuSelect(null, item.item)
-        }
-      })
-    }
-  },
-  mounted() {
-    const currentMenu = this.menuList[0]
-    this.curActiveComponent = currentMenu?.relativeComponent
-    this.curActiveComponentCode = currentMenu?.code
-  },
-  watch: {
-    paletteCount() {
-      this.clickPaletteMenu()
-    },
-    globalCount() {
-      this.clickGlobalMenu()
-    }
-  }
-}
-</script>
-
-<style lang="less" scoped>
-.yvan-print-designer-right__main {
-  height: 100%;
-  width: 100%;
-  background: var(--yvan-bg-color-overlay);
-
-  .yvan-print-designer-right__title {
-    width: 100%;
-    height: 45px;
-    text-align: left;
-    line-height: 45px;
-    background: var(--yvan-menu-bar-background);
-    color: #fff;
-    align-items: center;
-
-    i {
-      margin: 0 5px 0 10px;
-    }
-  }
-
-
-  .yvan-print-designer-right__menu {
-    height: 100%;
-    z-index: 1;
-
-    .yvan-print-designer-aside__menu__icon {
-      display: grid;
-      top: -7px;
-      position: relative;
-
-      i {
-        padding: 0;
-        margin: 0;
-        font-size: 20px;
-      }
-
-      span {
-        line-height: 14px;
-        visibility: visible;
-        height: auto;
-        width: auto;
-        font-size: 8px;
-        top: -14px;
-        position: relative;
-      }
-    }
-  }
-
-  .yvan-print-designer-aside__right_panel {
-    width: calc(100% - 64px);
-    background: var(--yvan-bg-color-overlay);
-    position: absolute;
-    right: 0;
-    top: 0;
-  }
-}
-</style>

+ 5 - 5
src/components/yvan-print-designer.vue

@@ -43,8 +43,8 @@
           </template>
         </yvan-print-designer-main>
       </yvan-print-main>
-      <yvan-print-aside class="yvan-print-designer-right" width="auto">
-        <yvan-print-designer-right :show-right.sync="defaultExpendAside"/>
+      <yvan-print-aside class="yvan-print-designer-props" width="auto">
+        <yvan-print-designer-props :show-right.sync="defaultExpendAside"/>
       </yvan-print-aside>
     </yvan-print-container>
   </yvan-print-container>
@@ -59,7 +59,7 @@ import YvanPrintAside from "@/components/yvan-ui/yvan-print-aside.vue";
 import YvanPrintMain from "@/components/yvan-ui/yvan-print-main.vue";
 import YvanPrintDesignerLeft from "@/components/yvan-print-designer-left.vue";
 import YvanPrintDesignerMain from "@/components/yvan-print-designer-main.vue";
-import YvanPrintDesignerRight from "@/components/yvan-print-designer-right.vue";
+import YvanPrintDesignerProps from "@/components/yvan-print-designer-props.vue";
 
 /**
  * 主页
@@ -69,7 +69,7 @@ export default {
   components: {
     YvanPrintDesignerLeft,
     YvanPrintDesignerMain,
-    YvanPrintDesignerRight,
+    YvanPrintDesignerProps,
     YvanPrintMain,
     YvanPrintAside,
     YvanPrintHeader,
@@ -253,7 +253,7 @@ export default {
     padding: 0;
   }
 
-  .yvan-print-designer-right {
+  .yvan-print-designer-props {
     margin: 5px;
     height: calc(100% - 10px);
   }

+ 3 - 2
src/components/yvan-print-page-format.vue

@@ -47,7 +47,7 @@
 
 <script setup lang="ts">
 import {pageSizeList, pageDirectionList} from '@/components/config/pageFormatConfig'
-import {reactive, ref} from "vue";
+import {reactive} from "vue";
 
 const defaultPageSize = pageSizeList[0]
 const defaultPageDirection = pageDirectionList[0]
@@ -67,7 +67,7 @@ const pageFormat = reactive<PageFormat>({
 })
 
 interface PageFormat {
-  pageSize,
+  pageSize: any,
   pageDirection: string,
   width: number,
   height: number,
@@ -103,6 +103,7 @@ interface Margins {
   .yvan-print-page-format__content_display {
     background: #ffffff;
     position: absolute;
+    top: 75px;
     right: 125px;
     width: 168px;
     height: 237.6px;

+ 2 - 2
src/components/yvan-ui/yvan-print-dialog/index.ts

@@ -5,13 +5,13 @@ export default (options) => {
     return new Promise((resolve, reject) => {
         // 创建一个空的div
         const mountNode = document.createElement("div");
-        const handleConfirm = (res) => {
+        const handleConfirm = (res: any) => {
             // 调用完毕后应该清空节点
             render(null, mountNode)
             mountNode.remove();
             resolve(res)
         }
-        const handleClose = (res) => {
+        const handleClose = (res: any) => {
             render(null, mountNode);
             mountNode.remove();
             reject(res)

+ 2 - 2
src/components/yvan-ui/yvan-print-toast/index.ts

@@ -1,9 +1,9 @@
 import {createVNode, render} from "vue";
 import toast from "@/components/yvan-ui/yvan-print-toast/toast.vue";
 
-let mountNode = null;
+let mountNode: any = null;
 
-export default (options) => {
+export default (options: any) => {
     const duration = options.duration | 3000;
     //确保只存在一个弹框,如果前一个弹窗还在,就移除
     if (mountNode) {

+ 11 - 2
src/main.ts

@@ -5,11 +5,20 @@ import '@/style.css'
 import '@/assets/style/main.less'
 import '@/assets/style/variable.css'
 import 'element-plus/theme-chalk/index.css'
+import * as Icons from '@ant-design/icons-vue'
 import System from "@/utils/system";
 import App from '@/App.vue'
+import {install} from "@/components/PageComponents"
 
-const Pinia = createPinia()
+const pinia = createPinia()
+
+const app = createApp(App)
+for (const i in Icons) {
+    app.component(i, Icons[i])
+}
 
 window['System'] = System;
 
-createApp(App).use(Pinia).use(ElementPlus, {}).mount('#app')
+app.use({install})
+
+app.use(pinia).use(ElementPlus, {}).mount('#app')

+ 33 - 33
src/store/copy.ts

@@ -9,30 +9,30 @@ export default {
     menuLeft: 0
   },
   actions: {
-    copy(state) {
-      if (!state.curComponent) {
-        // toast('请选择组件')
+    copy() {
+      if (!this.curComponent) {
+        System.toast('请选择组件')
         return
       }
 
       // 如果有剪切的数据,需要先还原
-      restorePreCutData(state)
-      copyData(state)
+      restorePreCutData()
+      copyData()
 
-      state.isCut = false
+      this.isCut = false
     },
 
-    paste(state, isMouse) {
-      if (!state.copyData) {
+    paste(isMouse) {
+      if (!this.copyData) {
         // toast('请选择组件')
         return
       }
 
-      const data = state.copyData.data
+      const data = this.copyData.data
 
       if (isMouse) {
-        data.style.top = state.menuTop
-        data.style.left = state.menuLeft
+        data.style.top = this.menuTop
+        data.style.left = this.menuLeft
       } else {
         data.style.top += 10
         data.style.left += 10
@@ -43,48 +43,48 @@ export default {
       // store.commit('printTemplateModule/addComponent', {
       //   component: deepCopy(data)
       // })
-      if (state.isCut) {
-        state.copyData = null
+      if (this.isCut) {
+        this.copyData = null
       }
     },
 
-    cut(state) {
-      if (!state.curComponent) {
-        // toast('请选择组件')
+    cut() {
+      if (!this.curComponent) {
+        System.toast('请选择组件')
         return
       }
 
       // 如果重复剪切,需要恢复上一次剪切的数据
-      restorePreCutData(state)
-      copyData(state)
+      restorePreCutData()
+      copyData()
 
-      // store.commit('printTemplateModule/deleteComponent')
-      state.isCut = true
+      this.deleteComponent()
+      this.isCut = true
     },
 
-    showContextMenu(state, { top, left }) {
-      state.menuTop = top
-      state.menuLeft = left
+    showContextMenu({ top, left }) {
+      this.menuTop = top
+      this.menuLeft = left
     }
   }
 }
 
 // 恢复上一次剪切的数据
-function restorePreCutData(state) {
-  if (state.isCut && state.copyData) {
-    const data = deepCopy(state.copyData.data)
-    const index = state.copyData.index
+function restorePreCutData() {
+  if (this.isCut && this.copyData) {
+    const data = deepCopy(this.copyData.data)
+    const index = this.copyData.index
     // store.commit('addComponent', { component: data, index })
-    if (state.curComponentIndex >= index) {
+    if (this.curComponentIndex >= index) {
       // 如果当前组件索引大于等于插入索引,需要加一,因为当前组件往后移了一位
-      state.curComponentIndex++
+      this.curComponentIndex++
     }
   }
 }
 
-function copyData(state) {
-  state.copyData = {
-    data: deepCopy(state.curComponent),
-    index: state.curComponentIndex
+function copyData() {
+  this.copyData = {
+    data: deepCopy(this.curComponent),
+    index: this.curComponentIndex
   }
 }

+ 8 - 8
src/store/global.ts

@@ -181,8 +181,8 @@ export const globalStore = defineStore('global', {
             }
         },
 
-        setShapeSingleStyle({curComponent}, {key, value}) {
-            curComponent.style[key] = value
+        setShapeSingleStyle({key, value}) {
+            this.curComponent.style[key] = value
         },
 
         setComponentData(state, componentData = []) {
@@ -197,18 +197,18 @@ export const globalStore = defineStore('global', {
             }
         },
 
-        deleteComponent(state, index) {
+        deleteComponent(index) {
             if (index === undefined) {
-                index = state.curComponentIndex
+                index = this.curComponentIndex
             }
 
-            if (index === state.curComponentIndex) {
-                state.curComponentIndex = null
-                state.curComponent = null
+            if (index === this.curComponentIndex) {
+                this.curComponentIndex = null
+                this.curComponent = null
             }
 
             if (/\d/.test(index)) {
-                state.componentData.splice(index, 1)
+                this.componentData.splice(index, 1)
             }
         },
     },

+ 12 - 12
src/store/layer.ts

@@ -8,47 +8,47 @@ const swap = (arr, i, j) => {
 
 export default {
     actions: {
-        upComponent(state) {
-            const {componentData, curComponentIndex} = state
+        upComponent() {
+            const {componentData, curComponentIndex} = this
             // 上移图层 index,表示元素在数组中越往后
             if (curComponentIndex < componentData.length - 1) {
                 swap(componentData, curComponentIndex, curComponentIndex + 1)
-                state.curComponentIndex = curComponentIndex + 1
+                this.curComponentIndex = curComponentIndex + 1
             } else {
                 toast('已经到顶了')
             }
         },
 
-        downComponent(state) {
-            const {componentData, curComponentIndex} = state
+        downComponent() {
+            const {componentData, curComponentIndex} = this
             // 下移图层 index,表示元素在数组中越往前
             if (curComponentIndex > 0) {
                 swap(componentData, curComponentIndex, curComponentIndex - 1)
-                state.curComponentIndex = curComponentIndex - 1
+                this.curComponentIndex = curComponentIndex - 1
             } else {
                 toast('已经到底了')
             }
         },
 
-        topComponent(state) {
-            const {componentData, curComponentIndex, curComponent} = state
+        topComponent() {
+            const {componentData, curComponentIndex, curComponent} = this
             // 置顶
             if (curComponentIndex < componentData.length - 1) {
                 componentData.splice(curComponentIndex, 1)
                 componentData.push(curComponent)
-                state.curComponentIndex = componentData.length - 1
+                this.curComponentIndex = componentData.length - 1
             } else {
                 toast('已经到顶了')
             }
         },
 
-        bottomComponent(state) {
-            const {componentData, curComponentIndex, curComponent} = state
+        bottomComponent() {
+            const {componentData, curComponentIndex, curComponent} = this
             // 置底
             if (curComponentIndex > 0) {
                 componentData.splice(curComponentIndex, 1)
                 componentData.unshift(curComponent)
-                state.curComponentIndex = 0
+                this.curComponentIndex = 0
             } else {
                 toast('已经到底了')
             }

+ 2 - 2
src/store/ruler-things.ts

@@ -8,8 +8,8 @@ const {MIN_SCALE, MAX_SCALE} = CONSTANT
 export const ruleStore = defineStore('ruleThings', {
     state: () => ({
         scale: 5,
-        rectWidth: 100,
-        rectHeight: 200,
+        rectWidth: 210,
+        rectHeight: 297,
         needReDrawRuler: 0,
         showRuler: true
     }),

+ 18 - 0
src/style.css

@@ -35,6 +35,22 @@ html, body {
   text-align: center;
 }
 
+::-webkit-scrollbar {
+  width: 6px;
+  height: 8px;
+  background-color: #ebeef5;
+}
+::-webkit-scrollbar-thumb {
+  box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
+  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
+  background-color: #ccc;
+}
+::-webkit-scrollbar-track{
+  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+  border-radius: 3px;
+  background: rgba(255, 255, 255, 1);
+}
+
 @media (prefers-color-scheme: light) {
   :root {
     color: #213547;
@@ -47,3 +63,5 @@ html, body {
     background-color: #f9f9f9;
   }
 }
+
+

+ 0 - 1
src/utils/system.ts

@@ -27,7 +27,6 @@ export default class System {
         if(!iconName){
             return
         }
-        iconName = iconName.substring("fa ".length);
         return () => h(ElIcon, null, {default: () => h(FaIcon[iconName])});
     }
 }