Przeglądaj źródła

image、barcode、qrcode element props

zhoucg 1 rok temu
rodzic
commit
b96481d51f

+ 0 - 1
auto-imports.d.ts

@@ -1,7 +1,6 @@
 /* eslint-disable */
 /* prettier-ignore */
 // @ts-nocheck
-// noinspection JSUnusedGlobalSymbols
 // Generated by unplugin-auto-import
 export {}
 declare global {

+ 4 - 0
components.d.ts

@@ -42,6 +42,7 @@ declare module 'vue' {
     ElRow: typeof import('element-plus/es')['ElRow']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSpace: typeof import('element-plus/es')['ElSpace']
+    ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTabPane: typeof import('element-plus/es')['ElTabPane']
     ElTabs: typeof import('element-plus/es')['ElTabs']
     ElUpload: typeof import('element-plus/es')['ElUpload']
@@ -85,6 +86,7 @@ declare module 'vue' {
     YvanLineProps: typeof import('./src/components/elements/YvanLineProps.vue')['default']
     YvanLinePropsTemplate: typeof import('./src/components/elements/YvanLinePropsTemplate.vue')['default']
     YvanPrintAside: typeof import('./src/components/yvan-ui/YvanPrintAside.vue')['default']
+    YvanPrintBarcode: typeof import('./src/components/yvan-ui/YvanPrintBarcode.vue')['default']
     YvanPrintContainer: typeof import('./src/components/yvan-ui/YvanPrintContainer.vue')['default']
     YvanPrintDataSource: typeof import('./src/components/YvanPrintDataSource.vue')['default']
     YvanPrintDesigner: typeof import('./src/components/YvanPrintDesigner.vue')['default']
@@ -101,6 +103,8 @@ declare module 'vue' {
     YvanPrintPageFormat: typeof import('./src/components/YvanPrintPageFormat.vue')['default']
     YvanPrintTextEditor: typeof import('./src/components/yvan-ui/YvanPrintTextEditor.vue')['default']
     YvanPrintToolbar: typeof import('./src/components/yvan-ui/YvanPrintToolbar.vue')['default']
+    YvanQrcode: typeof import('./src/components/elements/YvanQrcode.vue')['default']
+    YvanQrcodeProps: typeof import('./src/components/elements/YvanQrcodeProps.vue')['default']
     YvanRect: typeof import('./src/components/elements/YvanRect.vue')['default']
     YvanRectProps: typeof import('./src/components/elements/YvanRectProps.vue')['default']
     YvanRichText: typeof import('./src/components/elements/YvanRichText.vue')['default']

+ 86 - 0
package-lock.json

@@ -11,11 +11,15 @@
         "@ant-design/icons-vue": "^6.1.0",
         "@element-plus/icons-vue": "^2.1.0",
         "@wangeditor/editor": "^5.1.22",
+        "@wangeditor/editor-for-vue": "^5.1.12",
         "big.js": "^6.2.1",
         "element-plus": "^2.3.7",
+        "jsbarcode": "^3.11.5",
         "mitt": "^3.0.0",
         "nanoid": "^4.0.2",
         "pinia": "^2.1.4",
+        "qrcode.vue": "^3.4.1",
+        "qrcodejs2": "^0.0.2",
         "vue": "^3.2.47",
         "vue3-styled-components": "^1.2.1",
         "vuedraggable": "^2.24.3",
@@ -1024,6 +1028,15 @@
         "snabbdom": "^3.1.0"
       }
     },
+    "node_modules/@wangeditor/editor-for-vue": {
+      "version": "5.1.12",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/editor-for-vue/-/editor-for-vue-5.1.12.tgz",
+      "integrity": "sha512-0Ds3D8I+xnpNWezAeO7HmPRgTfUxHLMd9JKcIw+QzvSmhC5xUHbpCcLU+KLmeBKTR/zffnS5GQo6qi3GhTMJWQ==",
+      "peerDependencies": {
+        "@wangeditor/editor": ">=5.1.0",
+        "vue": "^3.0.5"
+      }
+    },
     "node_modules/@wangeditor/editor/node_modules/@wangeditor/basic-modules": {
       "version": "1.1.7",
       "resolved": "https://registry.npmmirror.com/@wangeditor/basic-modules/-/basic-modules-1.1.7.tgz",
@@ -2186,6 +2199,66 @@
       "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
       "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
     },
+    "node_modules/jsbarcode": {
+      "version": "3.11.5",
+      "resolved": "https://registry.npmmirror.com/jsbarcode/-/jsbarcode-3.11.5.tgz",
+      "integrity": "sha512-zv3KsH51zD00I/LrFzFSM6dst7rDn0vIMzaiZFL7qusTjPZiPtxg3zxetp0RR7obmjTw4f6NyGgbdkBCgZUIrA==",
+      "bin": {
+        "auto.js": "bin/barcodes/CODE128/auto.js",
+        "Barcode.js": "bin/barcodes/Barcode.js",
+        "barcodes": "bin/barcodes",
+        "canvas.js": "bin/renderers/canvas.js",
+        "checksums.js": "bin/barcodes/MSI/checksums.js",
+        "codabar": "bin/barcodes/codabar",
+        "CODE128": "bin/barcodes/CODE128",
+        "CODE128_AUTO.js": "bin/barcodes/CODE128/CODE128_AUTO.js",
+        "CODE128.js": "bin/barcodes/CODE128/CODE128.js",
+        "CODE128A.js": "bin/barcodes/CODE128/CODE128A.js",
+        "CODE128B.js": "bin/barcodes/CODE128/CODE128B.js",
+        "CODE128C.js": "bin/barcodes/CODE128/CODE128C.js",
+        "CODE39": "bin/barcodes/CODE39",
+        "constants.js": "bin/barcodes/ITF/constants.js",
+        "defaults.js": "bin/options/defaults.js",
+        "EAN_UPC": "bin/barcodes/EAN_UPC",
+        "EAN.js": "bin/barcodes/EAN_UPC/EAN.js",
+        "EAN13.js": "bin/barcodes/EAN_UPC/EAN13.js",
+        "EAN2.js": "bin/barcodes/EAN_UPC/EAN2.js",
+        "EAN5.js": "bin/barcodes/EAN_UPC/EAN5.js",
+        "EAN8.js": "bin/barcodes/EAN_UPC/EAN8.js",
+        "encoder.js": "bin/barcodes/EAN_UPC/encoder.js",
+        "ErrorHandler.js": "bin/exceptions/ErrorHandler.js",
+        "exceptions": "bin/exceptions",
+        "exceptions.js": "bin/exceptions/exceptions.js",
+        "fixOptions.js": "bin/help/fixOptions.js",
+        "GenericBarcode": "bin/barcodes/GenericBarcode",
+        "getOptionsFromElement.js": "bin/help/getOptionsFromElement.js",
+        "getRenderProperties.js": "bin/help/getRenderProperties.js",
+        "help": "bin/help",
+        "index.js": "bin/renderers/index.js",
+        "index.tmp.js": "bin/barcodes/index.tmp.js",
+        "ITF": "bin/barcodes/ITF",
+        "ITF.js": "bin/barcodes/ITF/ITF.js",
+        "ITF14.js": "bin/barcodes/ITF/ITF14.js",
+        "JsBarcode.js": "bin/JsBarcode.js",
+        "linearizeEncodings.js": "bin/help/linearizeEncodings.js",
+        "merge.js": "bin/help/merge.js",
+        "MSI": "bin/barcodes/MSI",
+        "MSI.js": "bin/barcodes/MSI/MSI.js",
+        "MSI10.js": "bin/barcodes/MSI/MSI10.js",
+        "MSI1010.js": "bin/barcodes/MSI/MSI1010.js",
+        "MSI11.js": "bin/barcodes/MSI/MSI11.js",
+        "MSI1110.js": "bin/barcodes/MSI/MSI1110.js",
+        "object.js": "bin/renderers/object.js",
+        "options": "bin/options",
+        "optionsFromStrings.js": "bin/help/optionsFromStrings.js",
+        "pharmacode": "bin/barcodes/pharmacode",
+        "renderers": "bin/renderers",
+        "shared.js": "bin/renderers/shared.js",
+        "svg.js": "bin/renderers/svg.js",
+        "UPC.js": "bin/barcodes/EAN_UPC/UPC.js",
+        "UPCE.js": "bin/barcodes/EAN_UPC/UPCE.js"
+      }
+    },
     "node_modules/json-parse-even-better-errors": {
       "version": "2.3.1",
       "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
@@ -2763,6 +2836,19 @@
         "node": ">=6"
       }
     },
+    "node_modules/qrcode.vue": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmmirror.com/qrcode.vue/-/qrcode.vue-3.4.1.tgz",
+      "integrity": "sha512-wq/zHsifH4FJ1GXQi8/wNxD1KfQkckIpjK1KPTc/qwYU5/Bkd4me0w4xZSg6EXk6xLBkVDE0zxVagewv5EMAVA==",
+      "peerDependencies": {
+        "vue": "^3.0.0"
+      }
+    },
+    "node_modules/qrcodejs2": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmmirror.com/qrcodejs2/-/qrcodejs2-0.0.2.tgz",
+      "integrity": "sha512-+Y4HA+cb6qUzdgvI3KML8GYpMFwB24dFwzMkS/yXq6hwtUGNUnZQdUnksrV1XGMc2mid5ROw5SAuY9XhI3ValA=="
+    },
     "node_modules/queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",

+ 2 - 0
package.json

@@ -16,9 +16,11 @@
     "@wangeditor/editor-for-vue": "^5.1.12",
     "big.js": "^6.2.1",
     "element-plus": "^2.3.7",
+    "jsbarcode": "^3.11.5",
     "mitt": "^3.0.0",
     "nanoid": "^4.0.2",
     "pinia": "^2.1.4",
+    "qrcode.vue": "^3.4.1",
     "vue": "^3.2.47",
     "vue3-styled-components": "^1.2.1",
     "vuedraggable": "^2.24.3",

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

@@ -1,13 +1,8 @@
-/**
- * 纸张大小
- */
+/** 纸张大小 */
 export const pageSizeList = [
     {name: "A4", width: 210, height: 297}
 ]
-
-/**
- * 纸张方向
- */
+/** 纸张方向 */
 export const pageDirectionList = [
     {label: "垂直方向", value: "vertical"},
     {label: "水平方向", value: "horizontal"},
@@ -18,7 +13,7 @@ export const fontList = [
     {code: 'STFangSong', name: '华文仿宋'},
     {code: 'Microsoft_YaHei', name: '微软雅黑'},
 ]
-
+/** 边框类型 */
 export const borderTypeList = [
     {code: 'none', name: '无', label: '无'},
     {code: 'solid', name: '实线', label: '实线'},
@@ -26,6 +21,19 @@ export const borderTypeList = [
     {code: 'dashed', name: '虚线', label: '虚线'},
     // {code: 'double', name: '双线', label: '双线'},
 ]
+/** 条码类型 */
+export const barcodeTypList = [
+    {code: 'CODABAR', name: 'Codabar'},
+    {code: 'CODE128', name: 'Code128'},
+    {code: 'CODE128A', name: 'Code128A'},
+    {code: 'CODE128B', name: 'Code128B'},
+    {code: 'CODE128C', name: 'Code128C'},
+    {code: 'CODE39', name: 'Code39'},
+    {code: 'EAN8', name: 'EAN8'},
+    {code: 'EAN13', name: 'EAN13'},
+    {code: 'EAN8', name: 'EAN8'},
+    {code: 'UPC', name: 'UPC'},
+]
 
 export const commonStyle = {
     rotate: 0,
@@ -198,18 +206,42 @@ export const elementList = [
     {
         icon: 'fa fa-barcode',
         code: 'barcode',
-        name: '条码',
+        name: '条码',
         component: 'YvanBarcode',
-        src: '',
-        title: '默认图片',
+        config: {
+            textValue: '1234567890',
+            format: 'CODE128',
+            displayValue: true,
+            textAlign: 'center',
+            fontSize: 20
+        },
         style: {
-            borderRadius: 'inherit',
+            borderType: 'none',
             borderWidth: 0,
             borderColor: '#212121',
-            borderType: 'none',
+            borderRadius: 0,
             width: 200,
-            height: 200,
-            background: null,
+            height: 145,
+            background: '#fff',
+            rotate: 0
+        },
+        groupStyle: {}
+    },
+    {
+        icon: 'fa fa-qrcode',
+        code: 'qrcode',
+        name: '二维码',
+        component: 'YvanQrcode',
+        config: {
+            textValue: '1234567890',
+        },
+        style: {
+            borderType: 'none',
+            borderWidth: 0,
+            borderColor: '#212121',
+            borderRadius: 0,
+            size: 100,
+            background: '#fff',
             rotate: 0
         },
         groupStyle: {}

+ 11 - 8
src/components/elements/YvanBarcode.vue

@@ -1,27 +1,30 @@
 <template>
   <div class="yvan-barcode">
-    <StyledImage v-bind="style">
-      <img :alt="element.title || 'RoyImage'" :src="element.src" />
-    </StyledImage>
+    <StyledBarcode v-bind="style">
+      <yvan-print-barcode :config="element.config" />
+    </StyledBarcode>
   </div>
 </template>
 
 <script>
 import commonMixin from '@/mixin/commonMixin'
-import { StyledImage } from '@/components/elements/style'
+import {StyledBarcode} from '@/components/elements/style'
+import YvanPrintBarcode from "@/components/yvan-ui/YvanPrintBarcode.vue";
 import YvanBarcodeProps from "@/components/elements/YvanBarcodeProps.vue";
 
 export default {
   name: 'YvanBarcode',
   mixins: [commonMixin],
   components: {
-    StyledImage,
+    StyledBarcode,
+    YvanPrintBarcode,
     YvanBarcodeProps
   },
   props: {
     element: {
       type: Object,
-      default: () => {}
+      default: () => {
+      }
     },
     propValue: {
       type: Object,
@@ -39,7 +42,8 @@ export default {
     return {}
   },
   methods: {
-    initMounted() {}
+    initMounted() {
+    }
   },
   install(Vue) {
     Vue.component(this.name, this)
@@ -48,7 +52,6 @@ export default {
   mounted() {
     this.initMounted()
   },
-  watch: {}
 }
 </script>
 

+ 56 - 12
src/components/elements/YvanBarcodeProps.vue

@@ -1,38 +1,82 @@
 <template>
   <section class="yvan-barcode-props">
     <el-form ref="form" label-position="top">
-      <el-form-item label="标题">
-        <el-input />
+      <el-form-item label="文本值">
+        <el-input v-model="activeComponent.config.textValue" placeholder="请输入标题"/>
       </el-form-item>
-      <el-form-item label="图片地址">
-        <el-input />
+      <el-form-item label="条码类型">
+        <el-select v-model="activeComponent.config.format" placeholder="请选择边框类型" filterable>
+          <el-option v-for="barcodeType in barcodeTypList" :label="barcodeType.name" :value="barcodeType.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="是否显示文字">
+        <el-switch v-model="activeComponent.config.displayValue" inline-prompt active-text="是" inactive-text="否"/>
+      </el-form-item>
+      <el-form-item label="文字水平布局">
+        <el-radio-group v-model="activeComponent.config.textAlign" size="small">
+          <el-radio-button label="left">
+            <component is="align-left-outlined"/>
+          </el-radio-button>
+          <el-radio-button label="center">
+            <component is="align-center-outlined"/>
+          </el-radio-button>
+          <el-radio-button label="right">
+            <component is="align-right-outlined"/>
+          </el-radio-button>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="文字尺寸">
+        <el-input-number v-model="activeComponent.config.fontSize" :min="0" controls-position="right"/>
       </el-form-item>
-      <el-form-item label="上传图片">
-        <el-input />
+      <el-form-item label="宽度">
+        <el-input-number v-model="activeComponent.style.width" :min="0" controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="高度">
+        <el-input-number v-model="activeComponent.style.height" :min="0" controls-position="right"/>
       </el-form-item>
       <el-form-item label="边框类型">
-        <el-select placeholder="请选择粗细">
-          <el-option label="font.name" value="font.code"/>
+        <el-select v-model="activeComponent.style.borderType" placeholder="请选择边框类型" filterable>
+          <el-option v-for="borderType in borderTypeList" :label="borderType.label" :value="borderType.code"/>
         </el-select>
       </el-form-item>
       <el-form-item label="边框颜色">
-        <el-color-picker show-alpha/>
+        <el-color-picker v-model="activeComponent.style.borderColor"/>
       </el-form-item>
       <el-form-item label="边框宽度">
-        <el-input-number controls-position="right"/>
+        <el-input-number v-model="activeComponent.style.borderWidth" :min="0" controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="边框圆角">
+        <el-input-number v-model="activeComponent.style.borderRadius" :min="0" controls-position="right"/>
       </el-form-item>
       <el-form-item label="旋转角度(°)">
-        <el-input-number controls-position="right"/>
+        <el-input-number v-model="activeComponent.style.rotate" controls-position="right"/>
       </el-form-item>
     </el-form>
   </section>
 </template>
 
 <script lang="ts">
+import {mapState} from "pinia";
+import {globalStore} from "@/store";
+import {barcodeTypList, borderTypeList} from "@/components/config/globalConfig";
+
 export default {
   name: 'YvanBarcodeProps',
   data() {
-    return {}
+    return {
+      barcodeTypList,
+      borderTypeList
+    }
+  },
+  computed: {
+    ...mapState(globalStore, {
+      activeComponent: (state) => {
+        return state.curComponent
+      }
+    }),
+  },
+  methods: {
+
   }
 }
 </script>

+ 4 - 5
src/components/elements/YvanImageProps.vue

@@ -17,7 +17,7 @@
         <el-upload
             class="file-upload"
             action="/wms_api/print/com/galaxis/wms/print/CommonManager@uploadFile"
-            accept=".png,"
+            accept="image/*"
             :limit="1"
             :before-upload="handleBeforeFileUpload"
             :on-success="handleFileUploadSuccess"
@@ -33,12 +33,12 @@
       <el-form-item label="边框颜色">
         <el-color-picker v-model="activeComponent.style.borderColor"/>
       </el-form-item>
-      <el-form-item label="边框圆角">
-        <el-input-number v-model="activeComponent.style.borderRadius" :min="0" controls-position="right"/>
-      </el-form-item>
       <el-form-item label="边框宽度">
         <el-input-number v-model="activeComponent.style.borderWidth" :min="0" controls-position="right"/>
       </el-form-item>
+      <el-form-item label="边框圆角">
+        <el-input-number v-model="activeComponent.style.borderRadius" :min="0" controls-position="right"/>
+      </el-form-item>
       <el-form-item label="旋转角度(°)">
         <el-input-number v-model="activeComponent.style.rotate" controls-position="right"/>
       </el-form-item>
@@ -61,7 +61,6 @@ export default {
   computed: {
     ...mapState(globalStore, {
       activeComponent: (state) => {
-        console.log("activeComponent => ", state.curComponent)
         return state.curComponent
       }
     }),

+ 65 - 0
src/components/elements/YvanQrcode.vue

@@ -0,0 +1,65 @@
+<template>
+  <div class="yvan-qrcode">
+    <StyledQrcode v-bind="style">
+      <qrcode-vue :value="element.config.textValue" :size="element.style.size" level="H"/>
+    </StyledQrcode>
+  </div>
+</template>
+
+<script>
+import QrcodeVue from 'qrcode.vue';
+import commonMixin from '@/mixin/commonMixin';
+import {StyledQrcode} from '@/components/elements/style';
+import YvanQrcodeProps from "@/components/elements/YvanQrcodeProps.vue";
+
+export default {
+  name: 'YvanQrcode',
+  mixins: [commonMixin],
+  components: {
+    QrcodeVue,
+    StyledQrcode,
+    YvanQrcodeProps
+  },
+  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(YvanQrcodeProps.name, YvanQrcodeProps)
+  },
+  mounted() {
+    this.initMounted()
+  },
+  watch: {}
+}
+</script>
+
+<style lang="less">
+.yvan-qrcode {
+  height: 100%;
+  padding: 0;
+}
+</style>

+ 64 - 0
src/components/elements/YvanQrcodeProps.vue

@@ -0,0 +1,64 @@
+<template>
+  <section class="yvan-barcode-props">
+    <el-form ref="form" label-position="top">
+      <el-form-item label="文本值">
+        <el-input v-model="activeComponent.config.textValue" placeholder="请输入标题"/>
+      </el-form-item>
+      <el-form-item label="尺寸">
+        <el-input-number v-model="activeComponent.style.size" :min="0" controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="边框类型">
+        <el-select v-model="activeComponent.style.borderType" placeholder="请选择边框类型" filterable>
+          <el-option v-for="borderType in borderTypeList" :label="borderType.label" :value="borderType.code"/>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="边框颜色">
+        <el-color-picker v-model="activeComponent.style.borderColor"/>
+      </el-form-item>
+      <el-form-item label="边框宽度">
+        <el-input-number v-model="activeComponent.style.borderWidth" :min="0" controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="边框圆角">
+        <el-input-number v-model="activeComponent.style.borderRadius" :min="0" controls-position="right"/>
+      </el-form-item>
+      <el-form-item label="旋转角度(°)">
+        <el-input-number v-model="activeComponent.style.rotate" controls-position="right"/>
+      </el-form-item>
+    </el-form>
+  </section>
+</template>
+
+<script lang="ts">
+import {mapState} from "pinia";
+import {globalStore} from "@/store";
+import {borderTypeList} from "@/components/config/globalConfig";
+
+export default {
+  name: 'YvanQrcodeProps',
+  data() {
+    return {
+      borderTypeList
+    }
+  },
+  computed: {
+    ...mapState(globalStore, {
+      activeComponent: (state) => {
+        return state.curComponent
+      }
+    }),
+  },
+}
+</script>
+
+<style lang="less">
+.yvan-qrcode-props {
+
+  .el-input-number {
+    width: 100%;
+  }
+
+  .el-select {
+    width: 100%;
+  }
+}
+</style>

+ 2 - 0
src/components/elements/index.js

@@ -2,6 +2,7 @@ import YvanLine from "@/components/elements/YvanLine.vue";
 import YvanRect from "@/components/elements/YvanRect.vue";
 import YvanImage from "@/components/elements/YvanImage.vue";
 import YvanCircle from "@/components/elements/YvanCircle.vue";
+import YvanQrcode from "@/components/elements/YvanQrcode.vue";
 import YvanBarcode from "@/components/elements/YvanBarcode.vue";
 import YvanRichText from "@/components/elements/YvanRichText.vue";
 import YvanSimpleText from "@/components/elements/YvanSimpleText.vue";
@@ -13,6 +14,7 @@ export const install = (Vue) => {
     YvanRect.install(Vue)
     YvanImage.install(Vue)
     YvanCircle.install(Vue)
+    YvanQrcode.install(Vue)
     YvanBarcode.install(Vue)
     YvanRichText.install(Vue)
     YvanSimpleText.install(Vue)

+ 48 - 4
src/components/elements/style.js

@@ -9,6 +9,10 @@ const commonProps = {
         type: [Number, String],
         default: 10
     },
+    size: {
+        type: [Number, String],
+        default: 100
+    },
     color: {
         type: String,
         default: '#212121'
@@ -22,8 +26,8 @@ const commonProps = {
         default: 'none'
     },
     borderRadius: {
-        type: String,
-        default: 'inherit'
+        type: Number,
+        default: 0
     },
     padding: {
         type: String,
@@ -46,8 +50,8 @@ const commonProps = {
         default: 'default'
     },
     lineHeight: {
-        type: String,
-        default: '1'
+        type: Number,
+        default: 1
     },
     letterSpacing: {
         type: String,
@@ -95,6 +99,10 @@ const textProps = Object.assign({}, commonProps, {})
 
 const imageProps = Object.assign({}, commonProps, {})
 
+const barcodeProps = Object.assign({}, commonProps, {})
+
+const qrcodeProps = Object.assign({}, commonProps, {})
+
 const lineProps = Object.assign({}, commonProps, {})
 
 const starProps = Object.assign({}, commonProps, {})
@@ -257,6 +265,42 @@ export const StyledImage = styled('div', imageProps)`
   }
 `
 
+export const StyledBarcode = styled('div', barcodeProps)`
+  width: 100%;
+  height: 100%;
+  
+  svg {
+    z-index: ${(props) => props.zIndex};
+    border-radius: ${(props) => isNaN(props.borderRadius) ? props.borderRadius : `${props.borderRadius}px`};
+    border: ${(props) => {
+      const {borderWidth, borderType, borderColor} = props
+      if (borderType === 'none') {
+        return borderType
+      } else {
+        return `${borderWidth}px ${borderType} ${borderColor}`
+      }
+    }};
+  }
+`
+
+export const StyledQrcode = styled('div', qrcodeProps)`
+  width: 100%;
+  height: 100%;
+
+  canvas {
+    z-index: ${(props) => props.zIndex};
+    border-radius: ${(props) => isNaN(props.borderRadius) ? props.borderRadius : `${props.borderRadius}px`};
+    border: ${(props) => {
+      const {borderWidth, borderType, borderColor} = props
+      if (borderType === 'none') {
+        return borderType
+      } else {
+        return `${borderWidth}px ${borderType} ${borderColor}`
+      }
+    }};
+  }
+`
+
 export const StyledCircle = styled('div', circleProps)`
   width: 100%;
   height: 100%;

+ 41 - 0
src/components/yvan-ui/YvanPrintBarcode.vue

@@ -0,0 +1,41 @@
+<template>
+  <svg id="barcode"/>
+</template>
+
+<script>
+import JsBarcode from 'jsbarcode';
+
+export default {
+  name: "YvanPrintBarcode",
+  props: {
+    config: {
+      type: Object,
+    }
+  },
+  data() {
+    return {}
+  },
+  mounted() {
+    this.createBarcode(this.config)
+  },
+  methods: {
+    createBarcode(config) {
+      JsBarcode("#barcode", config.textValue, {
+        ...config
+      });
+    }
+  },
+  watch: {
+    config: {
+      handler(newConfig) {
+        this.createBarcode(newConfig)
+      },
+      deep: true
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+
+</style>