Преглед изворни кода

feat: 添加看板组件库

liaojiaxing пре 1 година
родитељ
комит
0dde7a2b9f
40 измењених фајлова са 784 додато и 2633 уклоњено
  1. 10 0
      README.md
  2. 1 0
      package.json
  3. 518 1
      pnpm-lock.yaml
  4. 0 6
      src/components/Charts/Bar/BasicBar/index.ts
  5. 0 17
      src/components/Charts/Bar/BasicBar/src/BasicBar.vue
  6. 0 51
      src/components/Charts/Bar/BasicBar/src/Config.vue
  7. 0 120
      src/components/Charts/Bar/BasicBar/src/props.ts
  8. 0 798
      src/components/Charts/Bar/BasicBar/src/styleFormData.ts
  9. 0 53
      src/components/Charts/Charts.vue
  10. 0 161
      src/components/Charts/DataConfig.vue
  11. 0 6
      src/components/Charts/Line/BasicLine/index.ts
  12. 0 17
      src/components/Charts/Line/BasicLine/src/BasicLine.vue
  13. 0 39
      src/components/Charts/Line/BasicLine/src/Config.vue
  14. 0 115
      src/components/Charts/Line/BasicLine/src/props.ts
  15. 0 161
      src/components/Charts/StyleConfig.vue
  16. 0 102
      src/components/Charts/hooks/useChartOptions.ts
  17. 0 7
      src/components/CusForm/index.ts
  18. 0 122
      src/components/CusForm/src/BackgroundSelect.vue
  19. 0 74
      src/components/CusForm/src/ColorScheme.vue
  20. 0 66
      src/components/CusForm/src/ColorSelect.vue
  21. 0 85
      src/components/CusForm/src/CusFormItem.vue
  22. 0 27
      src/components/CusForm/src/CusSlider.vue
  23. 0 86
      src/components/CusForm/src/FontStyle.vue
  24. 0 37
      src/components/CusForm/src/Position.vue
  25. 0 92
      src/components/CusForm/src/index.vue
  26. 0 52
      src/components/CusForm/src/type.ts
  27. 0 6
      src/components/Text/Title/index.ts
  28. 0 54
      src/components/Text/Title/src/Config.vue
  29. 0 32
      src/components/Text/Title/src/index.vue
  30. 0 54
      src/components/Text/Title/src/props.ts
  31. 0 9
      src/components/index.ts
  32. 0 102
      src/hooks/useEcharts.ts
  33. 1 1
      src/mock/index.ts
  34. 5 5
      src/store/modules/project.ts
  35. 0 62
      src/utils/echarts.ts
  36. 3 3
      src/views/designer/component/ComponentWrapper.vue
  37. 239 5
      src/views/designer/component/Configurator.vue
  38. 2 2
      src/views/designer/component/PageConfig.vue
  39. 3 3
      src/views/view/component/RenderComponent.vue
  40. 2 0
      vite.config.ts

+ 10 - 0
README.md

@@ -5,6 +5,16 @@
 安装:pnpm install
 运行:pnpm dev
 
+1、运行前需要先拷贝组件库项目: shalu-dashboard-ui
+2、需要添加本地link
+```
+cd shalu-dashboard-ui
+pnpm link ./
+pnpm link --global
+cd shalu-dashboard-designer
+pnpm link --global shalu-dashboard-ui
+```
+
 
 ### 图表组件开发思路
 - 图表的option参数归一,提供统一的配置,便于后期做主题配置

+ 1 - 0
package.json

@@ -38,6 +38,7 @@
   "devDependencies": {
     "@types/node": "^20.14.2",
     "@vitejs/plugin-vue": "^5.0.4",
+    "@vitejs/plugin-vue-jsx": "^4.0.0",
     "typescript": "^5.2.2",
     "vite": "^5.2.0",
     "vite-plugin-mock": "^3.0.2",

+ 518 - 1
pnpm-lock.yaml

@@ -88,6 +88,9 @@ devDependencies:
   '@vitejs/plugin-vue':
     specifier: ^5.0.4
     version: 5.0.5(vite@5.2.13)(vue@3.4.27)
+  '@vitejs/plugin-vue-jsx':
+    specifier: ^4.0.0
+    version: 4.0.0(vite@5.2.13)(vue@3.4.27)
   typescript:
     specifier: ^5.2.2
     version: 5.4.5
@@ -103,6 +106,14 @@ devDependencies:
 
 packages:
 
+  /@ampproject/remapping@2.3.0:
+    resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
+    engines: {node: '>=6.0.0'}
+    dependencies:
+      '@jridgewell/gen-mapping': 0.3.5
+      '@jridgewell/trace-mapping': 0.3.25
+    dev: true
+
   /@ant-design/colors@6.0.0:
     resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==}
     dependencies:
@@ -123,6 +134,208 @@ packages:
       vue: 3.4.27(typescript@5.4.5)
     dev: false
 
+  /@babel/code-frame@7.24.7:
+    resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/highlight': 7.24.7
+      picocolors: 1.0.1
+    dev: true
+
+  /@babel/compat-data@7.24.7:
+    resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /@babel/core@7.24.7:
+    resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@ampproject/remapping': 2.3.0
+      '@babel/code-frame': 7.24.7
+      '@babel/generator': 7.24.7
+      '@babel/helper-compilation-targets': 7.24.7
+      '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7)
+      '@babel/helpers': 7.24.7
+      '@babel/parser': 7.24.7
+      '@babel/template': 7.24.7
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+      convert-source-map: 2.0.0
+      debug: 4.3.5
+      gensync: 1.0.0-beta.2
+      json5: 2.2.3
+      semver: 6.3.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/generator@7.24.7:
+    resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.24.7
+      '@jridgewell/gen-mapping': 0.3.5
+      '@jridgewell/trace-mapping': 0.3.25
+      jsesc: 2.5.2
+    dev: true
+
+  /@babel/helper-annotate-as-pure@7.24.7:
+    resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.24.7
+    dev: true
+
+  /@babel/helper-compilation-targets@7.24.7:
+    resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/compat-data': 7.24.7
+      '@babel/helper-validator-option': 7.24.7
+      browserslist: 4.23.1
+      lru-cache: 5.1.1
+      semver: 6.3.1
+    dev: true
+
+  /@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.7):
+    resolution: {integrity: sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.7
+      '@babel/helper-annotate-as-pure': 7.24.7
+      '@babel/helper-environment-visitor': 7.24.7
+      '@babel/helper-function-name': 7.24.7
+      '@babel/helper-member-expression-to-functions': 7.24.7
+      '@babel/helper-optimise-call-expression': 7.24.7
+      '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7)
+      '@babel/helper-skip-transparent-expression-wrappers': 7.24.7
+      '@babel/helper-split-export-declaration': 7.24.7
+      semver: 6.3.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-environment-visitor@7.24.7:
+    resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.24.7
+    dev: true
+
+  /@babel/helper-function-name@7.24.7:
+    resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/template': 7.24.7
+      '@babel/types': 7.24.7
+    dev: true
+
+  /@babel/helper-hoist-variables@7.24.7:
+    resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.24.7
+    dev: true
+
+  /@babel/helper-member-expression-to-functions@7.24.7:
+    resolution: {integrity: sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-module-imports@7.22.15:
+    resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.24.7
+    dev: true
+
+  /@babel/helper-module-imports@7.24.7:
+    resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7):
+    resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.7
+      '@babel/helper-environment-visitor': 7.24.7
+      '@babel/helper-module-imports': 7.24.7
+      '@babel/helper-simple-access': 7.24.7
+      '@babel/helper-split-export-declaration': 7.24.7
+      '@babel/helper-validator-identifier': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-optimise-call-expression@7.24.7:
+    resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.24.7
+    dev: true
+
+  /@babel/helper-plugin-utils@7.24.7:
+    resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /@babel/helper-replace-supers@7.24.7(@babel/core@7.24.7):
+    resolution: {integrity: sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.24.7
+      '@babel/helper-environment-visitor': 7.24.7
+      '@babel/helper-member-expression-to-functions': 7.24.7
+      '@babel/helper-optimise-call-expression': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-simple-access@7.24.7:
+    resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-skip-transparent-expression-wrappers@7.24.7:
+    resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-split-export-declaration@7.24.7:
+    resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.24.7
+    dev: true
+
   /@babel/helper-string-parser@7.24.7:
     resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==}
     engines: {node: '>=6.9.0'}
@@ -131,6 +344,29 @@ packages:
     resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
     engines: {node: '>=6.9.0'}
 
+  /@babel/helper-validator-option@7.24.7:
+    resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /@babel/helpers@7.24.7:
+    resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/template': 7.24.7
+      '@babel/types': 7.24.7
+    dev: true
+
+  /@babel/highlight@7.24.7:
+    resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/helper-validator-identifier': 7.24.7
+      chalk: 2.4.2
+      js-tokens: 4.0.0
+      picocolors: 1.0.1
+    dev: true
+
   /@babel/parser@7.24.7:
     resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==}
     engines: {node: '>=6.0.0'}
@@ -138,6 +374,41 @@ packages:
     dependencies:
       '@babel/types': 7.24.7
 
+  /@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.7):
+    resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.7
+      '@babel/helper-plugin-utils': 7.24.7
+    dev: true
+
+  /@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.24.7):
+    resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.7
+      '@babel/helper-plugin-utils': 7.24.7
+    dev: true
+
+  /@babel/plugin-transform-typescript@7.24.7(@babel/core@7.24.7):
+    resolution: {integrity: sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.24.7
+      '@babel/helper-annotate-as-pure': 7.24.7
+      '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7)
+      '@babel/helper-plugin-utils': 7.24.7
+      '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.7)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/runtime@7.24.7:
     resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==}
     engines: {node: '>=6.9.0'}
@@ -145,6 +416,33 @@ packages:
       regenerator-runtime: 0.14.1
     dev: false
 
+  /@babel/template@7.24.7:
+    resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/code-frame': 7.24.7
+      '@babel/parser': 7.24.7
+      '@babel/types': 7.24.7
+    dev: true
+
+  /@babel/traverse@7.24.7:
+    resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/code-frame': 7.24.7
+      '@babel/generator': 7.24.7
+      '@babel/helper-environment-visitor': 7.24.7
+      '@babel/helper-function-name': 7.24.7
+      '@babel/helper-hoist-variables': 7.24.7
+      '@babel/helper-split-export-declaration': 7.24.7
+      '@babel/parser': 7.24.7
+      '@babel/types': 7.24.7
+      debug: 4.3.5
+      globals: 11.12.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/types@7.24.7:
     resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==}
     engines: {node: '>=6.9.0'}
@@ -488,9 +786,35 @@ packages:
     resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==}
     dev: false
 
+  /@jridgewell/gen-mapping@0.3.5:
+    resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
+    engines: {node: '>=6.0.0'}
+    dependencies:
+      '@jridgewell/set-array': 1.2.1
+      '@jridgewell/sourcemap-codec': 1.4.15
+      '@jridgewell/trace-mapping': 0.3.25
+    dev: true
+
+  /@jridgewell/resolve-uri@3.1.2:
+    resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+    engines: {node: '>=6.0.0'}
+    dev: true
+
+  /@jridgewell/set-array@1.2.1:
+    resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+    engines: {node: '>=6.0.0'}
+    dev: true
+
   /@jridgewell/sourcemap-codec@1.4.15:
     resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
 
+  /@jridgewell/trace-mapping@0.3.25:
+    resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+    dependencies:
+      '@jridgewell/resolve-uri': 3.1.2
+      '@jridgewell/sourcemap-codec': 1.4.15
+    dev: true
+
   /@lezer/common@1.2.1:
     resolution: {integrity: sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==}
     dev: false
@@ -737,6 +1061,22 @@ packages:
     resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
     dev: false
 
+  /@vitejs/plugin-vue-jsx@4.0.0(vite@5.2.13)(vue@3.4.27):
+    resolution: {integrity: sha512-A+6wL2AdQhDsLsDnY+2v4rRDI1HLJGIMc97a8FURO9tqKsH5QvjWrzsa5DH3NlZsM742W2wODl2fF+bfcTWtXw==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    peerDependencies:
+      vite: ^5.0.0
+      vue: ^3.0.0
+    dependencies:
+      '@babel/core': 7.24.7
+      '@babel/plugin-transform-typescript': 7.24.7(@babel/core@7.24.7)
+      '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.24.7)
+      vite: 5.2.13(@types/node@20.14.2)(less@4.2.0)
+      vue: 3.4.27(typescript@5.4.5)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@vitejs/plugin-vue@5.0.5(vite@5.2.13)(vue@3.4.27):
     resolution: {integrity: sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==}
     engines: {node: ^18.0.0 || >=20.0.0}
@@ -768,6 +1108,47 @@ packages:
       vscode-uri: 3.0.8
     dev: true
 
+  /@vue/babel-helper-vue-transform-on@1.2.2:
+    resolution: {integrity: sha512-nOttamHUR3YzdEqdM/XXDyCSdxMA9VizUKoroLX6yTyRtggzQMHXcmwh8a7ZErcJttIBIc9s68a1B8GZ+Dmvsw==}
+    dev: true
+
+  /@vue/babel-plugin-jsx@1.2.2(@babel/core@7.24.7):
+    resolution: {integrity: sha512-nYTkZUVTu4nhP199UoORePsql0l+wj7v/oyQjtThUVhJl1U+6qHuoVhIvR3bf7eVKjbCK+Cs2AWd7mi9Mpz9rA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    peerDependenciesMeta:
+      '@babel/core':
+        optional: true
+    dependencies:
+      '@babel/core': 7.24.7
+      '@babel/helper-module-imports': 7.22.15
+      '@babel/helper-plugin-utils': 7.24.7
+      '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.7)
+      '@babel/template': 7.24.7
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+      '@vue/babel-helper-vue-transform-on': 1.2.2
+      '@vue/babel-plugin-resolve-type': 1.2.2(@babel/core@7.24.7)
+      camelcase: 6.3.0
+      html-tags: 3.3.1
+      svg-tags: 1.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@vue/babel-plugin-resolve-type@1.2.2(@babel/core@7.24.7):
+    resolution: {integrity: sha512-EntyroPwNg5IPVdUJupqs0CFzuf6lUrVvCspmv2J1FITLeGnUCuoGNNk78dgCusxEiYj6RMkTJflGSxk5aIC4A==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/code-frame': 7.24.7
+      '@babel/core': 7.24.7
+      '@babel/helper-module-imports': 7.22.15
+      '@babel/helper-plugin-utils': 7.24.7
+      '@babel/parser': 7.24.7
+      '@vue/compiler-sfc': 3.4.27
+    dev: true
+
   /@vue/compiler-core@3.4.27:
     resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==}
     dependencies:
@@ -950,6 +1331,13 @@ packages:
     hasBin: true
     dev: false
 
+  /ansi-styles@3.2.1:
+    resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+    engines: {node: '>=4'}
+    dependencies:
+      color-convert: 1.9.3
+    dev: true
+
   /ant-design-vue@4.2.3(vue@3.4.27):
     resolution: {integrity: sha512-kqGyWvZtFlSInFP93Ow6wS8LzEsxxUgpI+ZY5jQQkuX8WAcqdwXCA7IcHMpECW6JB89DZMo2Bw85jUg2SjlgQA==}
     engines: {node: '>=12.22.0'}
@@ -1036,6 +1424,17 @@ packages:
     dependencies:
       fill-range: 7.1.1
 
+  /browserslist@4.23.1:
+    resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==}
+    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+    hasBin: true
+    dependencies:
+      caniuse-lite: 1.0.30001639
+      electron-to-chromium: 1.4.816
+      node-releases: 2.0.14
+      update-browserslist-db: 1.0.16(browserslist@4.23.1)
+    dev: true
+
   /bundle-require@4.2.1(esbuild@0.20.2):
     resolution: {integrity: sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -1057,6 +1456,24 @@ packages:
       set-function-length: 1.2.2
     dev: false
 
+  /camelcase@6.3.0:
+    resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /caniuse-lite@1.0.30001639:
+    resolution: {integrity: sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==}
+    dev: true
+
+  /chalk@2.4.2:
+    resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      ansi-styles: 3.2.1
+      escape-string-regexp: 1.0.5
+      supports-color: 5.5.0
+    dev: true
+
   /chokidar@3.6.0:
     resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
     engines: {node: '>= 8.10.0'}
@@ -1085,6 +1502,16 @@ packages:
       - '@lezer/common'
     dev: false
 
+  /color-convert@1.9.3:
+    resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+    dependencies:
+      color-name: 1.1.3
+    dev: true
+
+  /color-name@1.1.3:
+    resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+    dev: true
+
   /combined-stream@1.0.8:
     resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
     engines: {node: '>= 0.8'}
@@ -1131,6 +1558,10 @@ packages:
       - supports-color
     dev: true
 
+  /convert-source-map@2.0.0:
+    resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+    dev: true
+
   /copy-anything@2.0.6:
     resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
     dependencies:
@@ -1227,6 +1658,10 @@ packages:
     resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
     dev: true
 
+  /electron-to-chromium@1.4.816:
+    resolution: {integrity: sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==}
+    dev: true
+
   /element-plus@2.7.6(vue@3.4.27):
     resolution: {integrity: sha512-36sw1K23hYjgeooR10U6CiCaCp2wvOqwoFurADZVlekeQ9v5U1FhJCFGEXO6i/kZBBMwsE1c9fxjLs9LENw2Rg==}
     peerDependencies:
@@ -1316,9 +1751,19 @@ packages:
       '@esbuild/win32-x64': 0.20.2
     dev: true
 
+  /escalade@3.1.2:
+    resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
+    engines: {node: '>=6'}
+    dev: true
+
   /escape-html@1.0.3:
     resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
 
+  /escape-string-regexp@1.0.5:
+    resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+    engines: {node: '>=0.8.0'}
+    dev: true
+
   /estree-walker@2.0.2:
     resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
 
@@ -1399,6 +1844,11 @@ packages:
     resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
     dev: false
 
+  /gensync@1.0.0-beta.2:
+    resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
   /get-intrinsic@1.2.4:
     resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
     engines: {node: '>= 0.4'}
@@ -1428,6 +1878,11 @@ packages:
       path-is-absolute: 1.0.1
     dev: false
 
+  /globals@11.12.0:
+    resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+    engines: {node: '>=4'}
+    dev: true
+
   /gopd@1.0.1:
     resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
     dependencies:
@@ -1439,6 +1894,11 @@ packages:
     requiresBuild: true
     optional: true
 
+  /has-flag@3.0.0:
+    resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+    engines: {node: '>=4'}
+    dev: true
+
   /has-property-descriptors@1.0.2:
     resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
     dependencies:
@@ -1467,6 +1927,11 @@ packages:
     hasBin: true
     dev: true
 
+  /html-tags@3.3.1:
+    resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==}
+    engines: {node: '>=8'}
+    dev: true
+
   /iconv-lite@0.6.3:
     resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
     engines: {node: '>=0.10.0'}
@@ -1544,7 +2009,18 @@ packages:
 
   /js-tokens@4.0.0:
     resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
-    dev: false
+
+  /jsesc@2.5.2:
+    resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
+    engines: {node: '>=4'}
+    hasBin: true
+    dev: true
+
+  /json5@2.2.3:
+    resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+    engines: {node: '>=6'}
+    hasBin: true
+    dev: true
 
   /less-loader@12.2.0(less@4.2.0):
     resolution: {integrity: sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==}
@@ -1618,6 +2094,12 @@ packages:
       yallist: 2.1.2
     dev: false
 
+  /lru-cache@5.1.1:
+    resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+    dependencies:
+      yallist: 3.1.1
+    dev: true
+
   /magic-string@0.30.10:
     resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
     dependencies:
@@ -1718,6 +2200,10 @@ packages:
       sax: 1.4.1
     optional: true
 
+  /node-releases@2.0.14:
+    resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
+    dev: true
+
   /nopt@5.0.0:
     resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
     engines: {node: '>=6'}
@@ -1928,6 +2414,11 @@ packages:
     hasBin: true
     requiresBuild: true
 
+  /semver@6.3.1:
+    resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+    hasBin: true
+    dev: true
+
   /semver@7.6.2:
     resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
     engines: {node: '>=10'}
@@ -2001,6 +2492,17 @@ packages:
     resolution: {integrity: sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==}
     dev: false
 
+  /supports-color@5.5.0:
+    resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
+    engines: {node: '>=4'}
+    dependencies:
+      has-flag: 3.0.0
+    dev: true
+
+  /svg-tags@1.0.0:
+    resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
+    dev: true
+
   /throttle-debounce@5.0.0:
     resolution: {integrity: sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==}
     engines: {node: '>=12.22'}
@@ -2059,6 +2561,17 @@ packages:
       webpack-virtual-modules: 0.6.2
     dev: false
 
+  /update-browserslist-db@1.0.16(browserslist@4.23.1):
+    resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==}
+    hasBin: true
+    peerDependencies:
+      browserslist: '>= 4.21.0'
+    dependencies:
+      browserslist: 4.23.1
+      escalade: 3.1.2
+      picocolors: 1.0.1
+    dev: true
+
   /utils-merge@1.0.1:
     resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
     engines: {node: '>= 0.4.0'}
@@ -2260,6 +2773,10 @@ packages:
     resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
     dev: false
 
+  /yallist@3.1.1:
+    resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+    dev: true
+
   /zrender@5.5.0:
     resolution: {integrity: sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==}
     dependencies:

+ 0 - 6
src/components/Charts/Bar/BasicBar/index.ts

@@ -1,6 +0,0 @@
-import BasicBar from './src/BasicBar.vue';
-import Config from './src/Config.vue';
-
-export default BasicBar;
-export { Config };
-export { defaultPropsValue, basicBarProps } from './src/props';

+ 0 - 17
src/components/Charts/Bar/BasicBar/src/BasicBar.vue

@@ -1,17 +0,0 @@
-<template>
-  <Charts :width="width" :height="height" :echarts-options="options" :loading="loading"></Charts>
-</template>
-
-<script setup lang="ts">
-import { defineProps } from "vue";
-import Charts from '@/components/Charts/Charts.vue';
-import { basicBarProps } from "./props";
-import { useChartOptions } from "@/components/Charts/hooks/useChartOptions";
-
-const props = defineProps(basicBarProps);
-
-const { options, loading } = useChartOptions(props);
-
-</script>
-
-<style scoped></style>

+ 0 - 51
src/components/Charts/Bar/BasicBar/src/Config.vue

@@ -1,51 +0,0 @@
-<template>
-  <div class="chart-config">
-    <div class="config-tab">
-      <Tabs v-model:activeKey="activeTab" size="small" centered>
-        <TabPane key="1">
-          <template #tab>
-            <DatabaseOutlined />
-            <span>数据设置</span>
-          </template>
-        </TabPane>
-        <TabPane key="2">
-          <template #tab>
-            <SkinOutlined />
-            <span>样式设置</span>
-          </template>
-        </TabPane>
-      </Tabs>
-    </div>
-
-    <DataConfig v-if="activeTab === '1'" :dataSource="dataSource" @change="handleChange"/>
-    <CusForm v-if="activeTab === '2'" :columns="formItems"/>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref, defineProps, defineEmits } from 'vue';
-import { Tabs, TabPane } from 'ant-design-vue';
-import { DatabaseOutlined, SkinOutlined } from '@ant-design/icons-vue';
-import DataConfig from '@/components/Charts/DataConfig.vue';
-import { CusForm } from '@/components/CusForm';
-import { basicBarProps } from './props';
-import { formItems } from './styleFormData';
-
-const props = defineProps(basicBarProps);
-const activeTab = ref('1');
-const emit = defineEmits(['change']);
-
-const handleChange = (data: any) => {
-  emit('change', {
-    ...props,
-    dataSource: data,
-  });
-}
-</script>
-
-<style lang="less" scoped>
-.config-tab {
-  text-align: center;
-  margin-bottom: 12px;
-}
-</style>

+ 0 - 120
src/components/Charts/Bar/BasicBar/src/props.ts

@@ -1,120 +0,0 @@
-import { type PropType } from "vue";
-import { EChartsOption } from "echarts";
-import { getNormalizedChart } from "@/utils/common";
-import { dataSource } from "@/utils/common";
-import { DataSourceType } from "@/enum";
-
-export const basicBarProps = {
-  width: {
-    type: Number as PropType<number>,
-    default: 400,
-  },
-  height: {
-    type: Number as PropType<number>,
-    default: 260,
-  },
-  dataSource,
-  // 标题
-  title: {
-    type: Object as PropType<EChartsOption["title"]>,
-  },
-  // 图例
-  legend: {
-    type: Object as PropType<EChartsOption["legend"]>,
-  },
-  // 背景
-  backgroundColor: {
-    type: String as PropType<string>,
-  },
-  // 边框
-  grid: {
-    type: Object as PropType<EChartsOption["grid"]>,
-  },
-  // 提示框
-  tooltip: {
-    type: Object as PropType<EChartsOption["tooltip"]>,
-  },
-  // x轴数据
-  xAxis: {
-    type: Object as PropType<EChartsOption["xAxis"]>,
-  },
-  // y轴数据
-  yAxis: {
-    type: Object as PropType<EChartsOption["yAxis"]>,
-  },
-  // 折线
-  series: {
-    type: Array as PropType<EChartsOption["series"]>,
-  },
-  // 数据集
-  dataset: {
-    type: Object as PropType<EChartsOption["dataset"]>,
-  },
-  // color
-  color: {
-    type: Object as PropType<EChartsOption["color"]>
-  }
-};
-
-const chartOptions = getNormalizedChart({
-  title: {
-    text: "柱状图标题",
-  },
-  xAxis: {
-    data: ['轴标签A', '轴标签B', '轴标签C', '轴标签D']
-  },
-})
-
-export const defaultPropsValue: EChartsOption = {
-  // 组件容器默认属性
-  container: {
-    props: {
-      width: 400,
-      height: 260,
-    },
-  },
-  // 图表默认属性
-  props: {
-    // 数据源
-    dataSource: {
-      sourceType: DataSourceType.STATIC,
-      data: {
-        xData: ['轴标签A', '轴标签B', '轴标签C', '轴标签D'],
-        series: [
-          {
-            type: 'bar',
-            name: '系列1',
-            data: [89.3, 92.1, 94.4, 85.4]
-          },
-          {
-            type: 'bar',
-            name: '系列2',
-            data: [95.8, 89.4, 91.2, 76.9]
-          },
-        ]
-      },
-      url: location.origin + "/mock/api/get/example/bar",
-      method: "POST",
-      params: {},
-      headers: {},
-      refreshTime: 0,
-      dataProcess: `
-        (res) => {
-          // 取出列表
-          const data = res.data;
-          // x轴数据
-          const xData = data.map((item) => item.name); 
-          // 系列数据
-          const series = [
-            { type: 'bar', name: '价格', data: data.map(item => item.price) },
-            { type: 'bar', name: '总量', data: data.map(item => item.count) },
-          ];
-
-          // 返回图表数据
-          return { xData, series };
-        }
-      `
-    },
-    ...chartOptions
-  },
-};

+ 0 - 798
src/components/Charts/Bar/BasicBar/src/styleFormData.ts

@@ -1,798 +0,0 @@
-import { IFormItem } from "@/components/CusForm";
-
-export const formItems: IFormItem[] = [
-  {
-    label: "标题",
-    prop: "title",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showTitle",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [{ label: "标题可见", value: true }],
-        },
-        defaultValue: []
-      },
-      {
-        label: "文本",
-        prop: "titleText",
-        type: "input",
-        defaultValue: "图表标题"
-      },
-      {
-        label: "位置",
-        prop: "titlePosition",
-        type: "position",
-        defaultValue: "center"
-      },
-      {
-        label: "样式",
-        prop: "titleStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 18,
-          bold: true,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "填充",
-        prop: "titleBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "透明度",
-        prop: "titleOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "圆角",
-        prop: "titleBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-    ],
-  },
-  {
-    label: "图例",
-    prop: "legend",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showLegend",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [{ label: "图例可见", value: true }],
-        },
-        defaultValue: [true]
-      },
-      {
-        label: "位置",
-        prop: "legendPosition",
-        type: "position",
-        fieldProps: {
-          type: "round",
-        },
-        defaultValue: "top"
-      },
-      {
-        label: "样式",
-        prop: "legendStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "legendBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "legendBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "legendBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "背景",
-        prop: "legendBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "背景透明度",
-        prop: "legendBackgroudOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "背景圆角",
-        prop: "legendBackgroundRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "阴影",
-        prop: "legendShadow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "开启", value: true },
-            { label: "关闭", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-    ],
-  },
-  {
-    label: "标签",
-    prop: "label",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showLabel",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [{ label: "标签可见", value: true }],
-        },
-        defaultValue: false
-      },
-      {
-        label: "文本",
-        prop: "labelValueType",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [
-            { label: "分类名", value: 'category' },
-            { label: "系列名", value: 'serie' },
-            { label: "数值", value: 'value' },
-            { label: "百分比", value: 'percent' },
-          ]
-        },
-        defaultValue: ['value']
-      },
-      {
-        label: "格式化",
-        prop: "labelFormatter",
-        type: "input",
-        tip: "支持字符串模板和回调函数",
-        defaultValue: "{value}"
-      },
-      {
-        label: "颜色",
-        prop: "labelColor",
-        type: "colorSelect",
-        defaultValue: "#000"
-      },
-      {
-        label: "样式",
-        prop: "labelStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "布局",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "位置",
-        prop: "labelPosition",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "内部", value: "inside" },
-            { label: "外部", value: "outside" },
-            { label: "中间", value: "center" },
-          ],
-        },
-        defaultValue: "outside"
-      },
-      {
-        label: "文本方向",
-        prop: "labelDirection",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "水平", value: "horizontal" },
-            { label: "垂直", value: "vertical" },
-          ],
-        },
-        defaultValue: "horizontal"
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "labelBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "labelBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "labelBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-    ],
-  },
-  {
-    label: "系列",
-    prop: "serie",
-    type: "group",
-    children: [
-      {
-        label: "配色",
-        prop: "colorScheme",
-        type: "colorScheme",
-        defaultValue: "custom"
-      },
-      {
-        label: "样式",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "固定柱宽",
-        prop: "serieBarFixedWidth",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "是", value: true },
-            { label: "否", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-      {
-        label: "系列间隔",
-        prop: "serieGap",
-        type: "slider",
-        defaultValue: 20
-      },
-      {
-        label: "分类间隔",
-        prop: "categoryGap",
-        type: "slider",
-        defaultValue: 20
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "serieBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "serieBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "serieBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-    ]
-  },
-  {
-    label: "X 轴",
-    prop: "xAxis",
-    type: "group",
-    children: [
-      {
-        label: "类型",
-        prop: "xAxisType",
-        type: "select",
-        fieldProps: {
-          options: [
-            { label: "类目坐标轴", value: "category" },
-            { label: "数值坐标轴", value: "value" },
-            { label: "时间坐标轴", value: "time" },
-          ],
-        },
-        defaultValue: "category"
-      },
-      {
-        label: "轴标题",
-        prop: "xAliasShowTitle",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-      {
-        label: "标题内容",
-        prop: "xAliasTitle",
-        type: "input",
-        defaultValue: "X 轴标题"
-      },
-      {
-        label: "标题位置",
-        prop: "xAliasPosition",
-        type: "position",
-        defaultValue: "center"
-      },
-      {
-        label: "标题样式",
-        prop: "xAliasStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "轴线",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "xAliasLineWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 1
-      },
-      {
-        label: "颜色",
-        prop: "xAliasLineColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "刻度",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "显示刻度",
-        prop: "xAliasTickShow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: true
-      },
-      {
-        label: "刻度长度",
-        prop: "xAliasTickLength",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 5
-      },
-      {
-        label: "刻度颜色",
-        prop: "xAliasTickColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "标签",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "颜色",
-        prop: "xAliasLabelColor",
-        type: "colorSelect",
-        defaultValue: "#000"
-      },
-      {
-        label: "样式",
-        prop: "xAliasLabelStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-    ]
-  },
-  {
-    label: "Y 轴",
-    prop: "yAxis",
-    type: "group",
-    children: [
-      {
-        label: "轴标题",
-        prop: "yAliasShowTitle",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-      {
-        label: "标题内容",
-        prop: "yAliasTitle",
-        type: "input",
-        defaultValue: "Y 轴标题"
-      },
-      {
-        label: "标题位置",
-        prop: "yAliasPosition",
-        type: "position",
-        defaultValue: "center"
-      },
-      {
-        label: "标题样式",
-        prop: "yAliasStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "轴线",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "yAliasLineWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 1
-      },
-      {
-        label: "颜色",
-        prop: "yAliasLineColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "刻度",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "显示刻度",
-        prop: "yAliasTickShow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: true
-      },
-      {
-        label: "刻度长度",
-        prop: "yAliasTickLength",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 5
-      },
-      {
-        label: "刻度颜色",
-        prop: "yAliasTickColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "标签",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "颜色",
-        prop: "yAliasLabelColor",
-        type: "colorSelect",
-        defaultValue: "#000"
-      },
-      {
-        label: "样式",
-        prop: "yAliasLabelStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-    ]
-  },
-  {
-    label: "提示",
-    prop: "tooltip",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showTooltip",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [
-            { label: "提示可见", value: true },
-          ],
-        },
-        defaultValue: [true]
-      },
-      {
-        label: "文本",
-        prop: "tooltipValueType",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [
-            { label: "分类名", value: 'category' },
-            { label: "系列名", value: 'serie' },
-            { label: "数值", value: 'value' },
-            { label: "百分比", value: 'percent' },
-          ]
-        },
-        defaultValue: ['value']
-      },
-      {
-        label: "格式化",
-        prop: "tooltipFormatter",
-        type: "input",
-        tip: "支持字符串模板和回调函数",
-        defaultValue: "{value}"
-      },
-      {
-        label: "样式",
-        prop: "tooltipStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "tooltipBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 1
-      },
-      {
-        label: "颜色",
-        prop: "tooltipBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "tooltipBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "填充",
-        prop: "tooltipBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "背景透明度",
-        prop: "tooltipBackgroudOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "阴影",
-        prop: "tooltipShadow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "开启", value: true },
-            { label: "关闭", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-    ]
-  },
-  {
-    label: "背景",
-    prop: "background",
-    type: "group",
-    children: [
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "backgroundBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "backgroundBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "backgroundBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "填充",
-        prop: "backgroundBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "背景透明度",
-        prop: "backgroundBackgroudOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "阴影",
-        prop: "backgroundShadow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "开启", value: true },
-            { label: "关闭", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-    ]
-  }
-];

+ 0 - 53
src/components/Charts/Charts.vue

@@ -1,53 +0,0 @@
-<!-- charts基础组件 -->
-<template>
-  <Spin :spinning="loading" :indicator="indicator">
-    <div ref="chartRef" :style="{width: width + 'px', height: height + 'px'}"></div>
-  </Spin>
-</template>
-
-<script setup lang="ts">
-import { ref, Ref, defineProps, watch, nextTick, h } from "vue";
-import { Spin } from "ant-design-vue";
-import { LoadingOutlined } from "@ant-design/icons-vue";
-import { useEcharts } from "@/hooks/useEcharts";
-import type { EChartsOption } from "echarts";
-import { throttle } from "lodash";
-
-const props = defineProps<{
-  echartsOptions: EChartsOption;
-  width: number;
-  height: number;
-  loading?: boolean;
-}>();
-const chartRef: Ref<null | HTMLDivElement> = ref(null);
-const { setOptions, resize } = useEcharts(chartRef as Ref<HTMLDivElement>);
-
-const indicator = h(LoadingOutlined, {
-  style: {
-    fontSize: "24px",
-  },
-});
-
-watch(
-  () => [props.width, props.height],
-  throttle(async () => {
-    resize();
-  }, 200)
-);
-
-watch(
-  () => props,
-  async () => {
-    await nextTick();
-    const { echartsOptions } = props;
-
-    setOptions(echartsOptions);
-  },
-  {
-    immediate: true,
-    deep: true,
-  }
-);
-</script>
-
-<style scoped></style>

+ 0 - 161
src/components/Charts/DataConfig.vue

@@ -1,161 +0,0 @@
-<template>
-  <Form
-    size="small"
-    layout="horizontal"
-    :model="formModel"
-    :label-col="{ span: 8 }"
-    :wrapper-col="{ span: 16 }"
-  >
-    <Form.Item label="类型" name="sourceType">
-      <Select v-model:value="formModel.sourceType">
-        <SelectOption :value="DataSourceType.STATIC">静态数据</SelectOption>
-        <SelectOption :value="DataSourceType.API">动态数据</SelectOption>
-      </Select>
-    </Form.Item>
-    <!-- 静态数据 -->
-    <template v-if="formModel.sourceType === DataSourceType.STATIC">
-      <Form.Item label="数据" name="data">
-        <Button type="default" size="small" @click="handleEditData('data')"
-          >编辑</Button
-        >
-      </Form.Item>
-    </template>
-    <!-- 接口 -->
-    <template v-else-if="formModel.sourceType === DataSourceType.API">
-      <Form.Item label="接口地址" name="url">
-        <Input.TextArea
-          :auto-size="{ minRows: 5 }"
-          placeholder="请输入接口地址"
-          v-model:value="formModel.url"
-        ></Input.TextArea>
-      </Form.Item>
-      <Form.Item label="请求方式" name="method">
-        <RadioGroup v-model:value="formModel.method">
-          <Radio value="GET">GET</Radio>
-          <Radio value="POST">POST</Radio>
-        </RadioGroup>
-      </Form.Item>
-      <Form.Item label="刷新时间" name="refreshTime">
-        <InputNumber
-          v-model:value="formModel.refreshTime"
-          :step="1"
-          style="width: 100%"
-          @change="handleRefreshTimeChange"
-        >
-          <template #addonAfter>
-            <span class="text-gray-500">秒</span>
-          </template>
-        </InputNumber>
-      </Form.Item>
-      <Form.Item label="请求参数" name="params">
-        <Button type="default" size="small" @click="handleEditData('params')"
-          >编辑</Button
-        >
-      </Form.Item>
-      <Form.Item label="请求头" name="headers">
-        <Button type="default" size="small" @click="handleEditData('headers')"
-          >编辑</Button
-        >
-      </Form.Item>
-      <Form.Item label="数据处理" name="dataProcess">
-        <Button
-          type="default"
-          size="small"
-          @click="handleEditData('dataProcess')"
-          >编辑</Button
-        >
-      </Form.Item>
-    </template>
-  </Form>
-  <CodeEditorModal ref="codeEditorRef" title="编辑数据" @ok="handleCodeSave" />
-</template>
-
-<script setup lang="ts">
-import type { DataSource } from "#/echart";
-import type { Ref } from "vue";
-import { ref, defineProps, watch, defineEmits } from "vue";
-import {
-  Form,
-  Input,
-  Button,
-  InputNumber,
-  Select,
-  SelectOption,
-  RadioGroup,
-  Radio
-} from "ant-design-vue";
-import { DataSourceType } from "@/enum";
-import {
-  CodeEditorModal,
-  type CodeEditorModalInstance,
-} from "@/components/CodeEditor";
-
-/**
- * 通用数据data约定内容结构
- * {
- *  xData: ['x轴标签A', 'x轴标签B', 'x轴标签C', 'x轴标签D'],
- *  yData: ['y轴数据A', 'y轴数据B', 'y轴数据C', 'y轴数据D'],
- *  // 根据不同类型的图表配置不同的series
- *  series: [
- *    {
- *      name: '系列A',
- *      data: [10, 20, 30, 40]
- *    },
- *    {
- *      name: '系列B',
- *      data: [10, 20, 30, 40]
- *    }
- *  ]
- * }
- */
-const emit = defineEmits(["change"]);
-const props = defineProps<{
-  dataSource: DataSource;
-}>();
-const formModel = ref({
-  sourceType: DataSourceType.STATIC,
-  // 静态数据相关
-  data: "",
-  // 接口相关
-  url: '',
-  method: "",
-  params: {},
-  headers: {},
-  refreshTime: 0,
-  // 数据处理
-  dataProcess: "",
-});
-
-const handleRefreshTimeChange = (val: unknown) => {
-  formModel.value.refreshTime = val === 0 || val as number >= 60 ? val as number : 60;
-};
-
-/* =====================编辑代码======================= */
-let pathKey: "data" | "params" | "headers" | "dataProcess";
-const codeEditorRef = ref<Ref<CodeEditorModalInstance> | null>(null);
-const handleEditData = (key: "data" | "params" | "headers" | "dataProcess") => {
-  pathKey = key;
-  codeEditorRef.value?.open(JSON.stringify(formModel.value[key]));
-};
-const handleCodeSave = (code: string) => {
-  formModel.value[pathKey] = JSON.parse(code);
-};
-
-watch(
-  () => props.dataSource,
-  (val) => {
-    Object.assign(formModel.value, val || {});
-  },
-  { immediate: true }
-);
-
-watch(
-  () => formModel.value,
-  (val) => {
-    emit("change", val);
-  },
-  { deep: true }
-);
-</script>
-
-<style scoped></style>

+ 0 - 6
src/components/Charts/Line/BasicLine/index.ts

@@ -1,6 +0,0 @@
-import BasicLine from './src/BasicLine.vue';
-import Config from './src/Config.vue';
-
-export default BasicLine;
-export { Config };
-export { defaultPropsValue, basicLineProps } from './src/props';

+ 0 - 17
src/components/Charts/Line/BasicLine/src/BasicLine.vue

@@ -1,17 +0,0 @@
-<template>
-  <Charts :width="width" :height="height" :echarts-options="options" :loading="loading"></Charts>
-</template>
-
-<script setup lang="ts">
-import { defineProps } from "vue";
-import Charts from '@/components/Charts/Charts.vue';
-import { basicLineProps } from "./props";
-import { useChartOptions } from "@/components/Charts/hooks/useChartOptions";
-
-const props = defineProps(basicLineProps);
-
-const { options, loading } = useChartOptions(props);
-
-</script>
-
-<style scoped></style>

+ 0 - 39
src/components/Charts/Line/BasicLine/src/Config.vue

@@ -1,39 +0,0 @@
-<template>
-  <div class="chart-config">
-    <div class="config-tab">
-      <ElRadioGroup v-model="activeTab" size="small">
-        <ElRadioButton value="1">数据</ElRadioButton>
-        <ElRadioButton value="2">样式</ElRadioButton>
-      </ElRadioGroup>
-    </div>
-
-    <DataConfig v-if="activeTab === '1'" :dataSource="dataSource" @change="handleChange"/>
-    <StyleConfig v-if="activeTab === '2'" @change="handleChange"/>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref, defineProps, defineEmits } from 'vue';
-import { ElRadioGroup, ElRadioButton } from 'element-plus';
-import DataConfig from '@/components/Charts/DataConfig.vue';
-import StyleConfig from '@/components/Charts/StyleConfig.vue';
-import { basicLineProps } from './props';
-
-const props = defineProps(basicLineProps);
-const activeTab = ref('1');
-const emit = defineEmits(['change']);
-
-const handleChange = (data: any) => {
-  emit('change', {
-    ...props,
-    dataSource: data,
-  });
-}
-</script>
-
-<style lang="less" scoped>
-.config-tab {
-  text-align: center;
-  margin-bottom: 12px;
-}
-</style>

+ 0 - 115
src/components/Charts/Line/BasicLine/src/props.ts

@@ -1,115 +0,0 @@
-import { type PropType } from "vue";
-import { EChartsOption } from "echarts";
-import { getNormalizedChart } from "@/utils/common";
-import { dataSource } from "@/utils/common";
-import { DataSourceType } from "@/enum";
-
-export const basicLineProps = {
-  width: {
-    type: Number as PropType<number>,
-    default: 400,
-  },
-  height: {
-    type: Number as PropType<number>,
-    default: 260,
-  },
-  dataSource,
-  // 标题
-  title: {
-    type: Object as PropType<EChartsOption["title"]>,
-  },
-  // 图例
-  legend: {
-    type: Object as PropType<EChartsOption["legend"]>,
-  },
-  // 背景
-  backgroundColor: {
-    type: String as PropType<string>,
-  },
-  // 边框
-  grid: {
-    type: Object as PropType<EChartsOption["grid"]>,
-  },
-  // 提示框
-  tooltip: {
-    type: Object as PropType<EChartsOption["tooltip"]>,
-  },
-  // x轴数据
-  xAxis: {
-    type: Object as PropType<EChartsOption["xAxis"]>,
-  },
-  // y轴数据
-  yAxis: {
-    type: Object as PropType<EChartsOption["yAxis"]>,
-  },
-  // 折线
-  series: {
-    type: Array as PropType<EChartsOption["series"]>,
-  },
-  // 数据集
-  dataset: {
-    type: Object as PropType<EChartsOption["dataset"]>,
-  },
-};
-
-const chartOptions = getNormalizedChart({
-  title: {
-    text: "折线图标题",
-  },
-  xAxis: {
-    data: ['轴标签A', '轴标签B', '轴标签C', '轴标签D']
-  },
-});
-
-export const defaultPropsValue: EChartsOption = {
-  container: {
-    props: {
-      width: 400,
-      height: 260,
-    },
-  },
-  props: {
-    // 数据源
-    dataSource: {
-      sourceType: DataSourceType.STATIC,
-      data: {
-        xData: ['轴标签A', '轴标签B', '轴标签C', '轴标签D'],
-        series: [
-          {
-            type: 'line',
-            name: '系列1',
-            data: [89.3, 92.1, 94.4, 85.4]
-          },
-          {
-            type: 'line',
-            name: '系列2',
-            data: [95.8, 89.4, 91.2, 76.9]
-          },
-        ]
-      },
-      url: location.origin + "/mock/api/get/example/line",
-      method: "POST",
-      params: {},
-      headers: {},
-      refreshTime: 0,
-      dataProcess: `
-        (res) => {
-          // 取出列表
-          const data = res.data;
-          // x轴数据
-          const xData = data.map((item) => item.name); 
-          // 系列数据
-          const series = [
-            { type: 'line', name: '苹果', data: data.map(item => item.apple) },
-            { type: 'line', name: 'VIVO', data: data.map(item => item.vivo) },
-            { type: 'line', name: '小米', data: data.map(item => item.mi) },
-          ];
-
-          // 返回图表数据
-          return { xData, series };
-        }
-      `
-    },
-    ...chartOptions
-  },
-};

+ 0 - 161
src/components/Charts/StyleConfig.vue

@@ -1,161 +0,0 @@
-<template>
-  <Form size="small" :label-col="{span: 8}" :colon="false">
-    <Collapse :bordered="false">
-      <CollapsePanel header="标题">
-        <Form.Item name="title" label=" ">
-          <Checkbox v-model:checked="formModel.title.visible">标题可见</Checkbox>
-        </Form.Item>
-        <Form.Item label="内容" name="subTitle">
-          <Input v-model:value="formModel.title.content"/>
-        </Form.Item>
-        <Form.Item label="位置" name="subTitle">
-          <RadioGroup v-model:value="formModel.title.position">
-            <RadioButton value="left"><AlignLeftOutlined/></RadioButton>
-            <RadioButton value="center"><AlignCenterOutlined/></RadioButton>
-            <RadioButton value="right"><AlignRightOutlined/></RadioButton>
-          </RadioGroup>
-        </Form.Item>
-        <Form.Item label="颜色" name="subTitle">
-          <ColorSelect v-model:value="formModel.title.color" />
-        </Form.Item>
-        <Form.Item label="样式" name="subTitle">
-          <FontStyle
-            v-model:value="formModel.title.fontSize"
-            v-model:bold="formModel.title.bold"
-            v-model:italic="formModel.title.italic"
-            v-model:underline="formModel.title.underline"
-          />
-        </Form.Item>
-      </CollapsePanel>
-
-      <CollapsePanel header="图例">
-        <Form.Item name="title" label=" ">
-          <Checkbox v-model:checked="formModel.legend.visible">图例可见</Checkbox>
-        </Form.Item>
-        <Form.Item label="位置" name="subTitle">
-          <RadioGroup v-model:value="formModel.legend.position">
-            <RadioButton value="left"><AlignLeftOutlined/></RadioButton>
-            <RadioButton value="center"><AlignCenterOutlined/></RadioButton>
-            <RadioButton value="right"><AlignRightOutlined/></RadioButton>
-          </RadioGroup>
-        </Form.Item>
-        <Form.Item label="颜色" name="subTitle">
-          <ColorSelect v-model:value="formModel.legend.color" />
-        </Form.Item>
-        <Form.Item label="样式" name="subTitle">
-          <FontStyle
-            v-model:value="formModel.legend.fontSize"
-            v-model:bold="formModel.legend.bold"
-            v-model:italic="formModel.legend.italic"
-            v-model:underline="formModel.legend.underline"
-          />
-        </Form.Item>
-      </CollapsePanel>
-
-      <CollapsePanel header="标签">
-        
-      </CollapsePanel>
-
-      <CollapsePanel header="系列">
-        <Form.Item label="配色" name="subTitle">
-          <ColorScheme v-model:value="formModel.series.colors" />
-        </Form.Item>
-        <Form.Item label="固定柱宽" name="subTitle">
-          <RadioGroup>
-            <RadioButton value="left">是</RadioButton>
-            <RadioButton value="center">否</RadioButton>
-          </RadioGroup>
-          <InputNumber/>
-        </Form.Item>
-      </CollapsePanel>
-
-      <CollapsePanel header="坐标轴">
-      
-      </CollapsePanel>
-
-      <CollapsePanel header="数据表">
-
-      </CollapsePanel>
-
-      <CollapsePanel header="背景">
-
-      </CollapsePanel>
-
-      <CollapsePanel header="提示">
-      
-      </CollapsePanel>
-    </Collapse>
-  </Form>
-</template>
-
-<script setup lang="ts">
-import { ref } from "vue";
-import {
-  Collapse,
-  CollapsePanel,
-  Form,
-  Checkbox,
-  Input,
-  InputNumber,
-  Select,
-  RadioGroup,
-  RadioButton,
-} from "ant-design-vue";
-import { AlignCenterOutlined, AlignRightOutlined, AlignLeftOutlined } from "@ant-design/icons-vue";
-import ColorSelect from "@/components/CusForm/src/ColorSelect.vue";
-import FontStyle from "@/components/CusForm/src/FontStyle.vue";
-import ColorScheme from "@/components/CusForm/src/ColorScheme.vue";
-
-const formModel = ref({
-  // 标题
-  title: {
-    visible: true,
-    content: "",
-    position: "center",
-    color: "#FFFFFFFF",
-    fontSize: 18,
-    bold: false,
-    italic: false,
-    underline: false,
-  },
-  // 图例
-  legend: {
-    visible: true,
-    position: "center",
-    color: "#FFFFFFFF",
-    fontSize: 12,
-    bold: false,
-    italic: false,
-    underline: false,
-  },
-  // 标签
-  label: {
-    visible: true,
-    position: "center",
-    color: "#FFFFFFFF",
-    fontSize: 12,
-    bold: false,
-    italic: false,
-    underline: false,
-  },
-  // 系列
-  series: {
-    barWidth: 20,
-    // 配色方案
-    colors: [],
-    fontSize: 12,
-    bold: false,
-    italic: false,
-    underline: false,
-  },
-});
-</script>
-
-<style lang="less" scoped>
-:deep(.ant-collapse-content-box) {
-  background: #fff;
-  .ant-form-item:last-child {
-    margin-bottom: 0;
-  }
-}
-</style>

+ 0 - 102
src/components/Charts/hooks/useChartOptions.ts

@@ -1,102 +0,0 @@
-import type { EChartsOption } from "echarts";
-import { computed, watch, ref } from "vue";
-import { omit, defaultsDeep } from "lodash";
-import { useRequest } from "vue-hooks-plus";
-import { DataSourceType } from "@/enum";
-import { cllJsCode } from "@/utils/calljs";
-import { message } from "ant-design-vue";
-
-export const useChartOptions = (chartProps: Record<string, any>) => {
-  const dataSource = chartProps.dataSource || {};
-  const xAxis = ref<EChartsOption["xAxis"]>({ data: dataSource?.data?.xData });
-  const yAxis = ref<EChartsOption["yAxis"]>({ data: dataSource?.data?.yData });
-  const series = ref<EChartsOption["series"]>(dataSource?.data?.series);
-
-  const server = computed(() => {
-    return async () =>
-      await fetch(chartProps.dataSource.url, {
-        method: chartProps.dataSource.method,
-      })
-      .then((res) => res.json());
-  });
-
-  // 请求数据
-  const { run, refresh, cancel, data, loading } = useRequest(server.value, {
-    defaultParams: chartProps.dataSource.params,
-    manual: true,
-    pollingInterval: (chartProps.dataSource?.refreshTime || 0) * 1000, // 刷新时间
-    onError: (error) => {
-      console.error(error);
-      message.error(chartProps.dataSource.url + "请求失败");
-    }
-  });
-
-  /* 初始请求 */
-  if (chartProps.dataSource.sourceType === DataSourceType.API) {
-    run();
-  }
-
-  watch(
-    () => data.value,
-    async (val) => {
-      if (val && chartProps.dataSource.sourceType === DataSourceType.API) {
-        let res = val;
-        if(chartProps.dataSource.dataProcess) {
-          res = await cllJsCode(chartProps.dataSource.dataProcess, JSON.stringify(val));
-        }
-    
-        xAxis.value = res.xAxis || { data: res.xData };
-        yAxis.value = res.yAxis || { data: res.yData };
-        series.value = res.series;
-      }
-    },
-    {
-      deep: true,
-    }
-  );
-
-  watch(
-    () => [
-      chartProps.dataSource.sourceType,
-      chartProps.dataSource.method
-    ],
-    () => {
-      if (chartProps.dataSource.sourceType === DataSourceType.API) {
-        refresh();
-      } else {
-        cancel();
-        const dataSource = chartProps.dataSource || {};
-        xAxis.value = { data: dataSource?.data?.xData };
-        yAxis.value = { data: dataSource?.data?.yData };
-        series.value = dataSource?.data?.series;
-      }
-    },
-    {
-      deep: true,
-    }
-  );
-
-  const options = computed((): EChartsOption => {
-    const opt = omit(chartProps, [
-      "width",
-      "height",
-      "dataSource",
-    ]) as EChartsOption;
-
-    const result = defaultsDeep(
-      {
-        xAxis: xAxis.value,
-        yAxis: yAxis.value,
-        series: series.value,
-      },
-      opt
-    );
-
-    return result;
-  });
-
-  return {
-    options,
-    loading,
-  };
-};

+ 0 - 7
src/components/CusForm/index.ts

@@ -1,7 +0,0 @@
-import CusForm from './src/index.vue';
-import type { IFormItem } from './src/type';
-
-export {
-  CusForm,
-  IFormItem
-}

+ 0 - 122
src/components/CusForm/src/BackgroundSelect.vue

@@ -1,122 +0,0 @@
-<template>
-  <Select v-model:value="backgroundObj.type" style="width: 100%" :options="getOptions" @change="handleChangeColor"/>
-  <template v-if="backgroundObj.type === 'color'">
-    <div class="color-box">
-      <ElColorPicker v-model="backgroundObj.color" color-format="hex" show-alpha size="small"/>
-      <ElInput v-model="backgroundObj.color" size="small"></ElInput>
-    </div>
-  </template>
-  <template v-else-if="backgroundObj.type === 'image'">
-    <div class="img-preview">
-      <div class="img-empty">未选择</div>
-      <Image :src="backgroundObj.image" />
-      <div class="img-tip">选择素材</div>
-    </div>
-    <ElRadioGroup v-model="backgroundObj.fillType">
-      <ElRadioButton value="cover">填充</ElRadioButton>
-      <ElRadioButton value="contain">适应</ElRadioButton>
-      <ElRadioButton value="stretch">拉伸</ElRadioButton>
-    </ElRadioGroup>
-  </template>
-</template>
-
-<script setup lang="ts">
-import { defineEmits, defineProps, withDefaults, ref, watch, computed } from "vue";
-import { Select, Image } from "ant-design-vue";
-import { ElColorPicker, ElRadioGroup, ElRadioButton, ElInput } from "element-plus";
-
-interface Prop {
-  background: {
-    type: "none" | "color" | "image";
-    color?: string;
-    image?: string;
-    fillType?: "cover" | "contain" | "stretch" | "";
-  };
-  filterOptions?: string[];
-}
-const props = withDefaults(defineProps<Prop>(), {
-  background: () => ({
-    type: "none",
-    color: "",
-    image: "",
-    fillType: ""
-  })
-});
-
-const emit = defineEmits(["update:background"]);
-
-const backgroundObj = ref(props.background);
-
-const options = [
-  { label: "无", value: "none" },
-  { label: "颜色", value: "color" },
-  { label: "图片", value: "image" },
-];
-
-const getOptions = computed(() => {
-  if(!props.filterOptions) {
-    return options;
-  }
-  return options.filter((item) => !props.filterOptions?.includes(item.value));
-});
-
-watch(
-  () => backgroundObj.value,
-  () => {
-    emit("update:background", backgroundObj.value);
-  }, {
-    deep: true,
-    immediate: true
-  }
-)
-
-const handleChangeColor = (type: any) => {
-  if(type === 'color' && !backgroundObj.value.color) {
-    backgroundObj.value.color = '#0B074BFF';
-  }
-};
-</script>
-
-<style lang="less" scoped>
-.color-box {
-  display: flex;
-  align-items: center;
-  margin: 12px 0;
-  margin-bottom: 0;
-  :deep(.el-color-picker) {
-    margin-right: 8px;
-  }
-}
-
-.img-preview {
-  margin: 12px 0;
-  border: solid 1px #eee;
-  height: 120px;
-  position: relative;
-  .img-empty {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    height: 100%;
-    color: #999;
-  }
-  .img-tip {
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    left: 0;
-    top: 0;
-    background: rgba(0, 0, 0, .6);
-    color: #fff;
-    font-size: 12px;
-    opacity: 0;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    cursor: pointer;
-    &:hover {
-      opacity: 1;
-    }
-  }
-}
-</style>

+ 0 - 74
src/components/CusForm/src/ColorScheme.vue

@@ -1,74 +0,0 @@
-<template>
-  <div>
-    <Select v-model:value="colorType" size="small" style="width: 100%" @change="changeColorType">
-      <SelectOption
-        v-for="item in colorPreset"
-        :key="item.name"
-        :value="item.color.join(',')"
-      >
-        <span
-          class="color-block"
-          v-for="color in item.color.slice(0, 5)"
-          :key="color"
-          :style="{background: color}"
-        ></span>
-        {{ item.name }}</SelectOption
-      >
-
-      <SelectOption value="custom">自定义组合</SelectOption>
-      <!-- <SelectOption value="gradient">自定义渐变色</SelectOption> -->
-    </Select>
-    <div class="color-list">
-      <span
-        class="color-block"
-        v-for="(color, index) in value"
-        :key="index"
-        :style="{background: color}"
-      ></span>
-      <span class="color-block cus-btn"><PlusOutlined /></span>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from "vue";
-import { Select, SelectOption } from "ant-design-vue";
-import { PlusOutlined } from "@ant-design/icons-vue";
-import { colorPreset } from "@/config/colorDefaultConfig";
-
-const value = ref<string[]>(colorPreset[0].color);
-const colorType = ref<string>(colorPreset[0].color.join(","));
-
-const changeColorType = (val: string) => {
-  if (val === "custom") {
-    value.value = [];
-  } else {
-    value.value = val.split(",");
-  }
-};
-</script>
-
-<style lang="less" scoped>
-.color-block {
-  display: inline-block;
-  width: 10px;
-  height: 10px;
-  margin-right: 4px;
-}
-.color-list {
-  margin-top: 12px;
-  display: flex;
-  flex-wrap: wrap;
-  .color-block {
-    margin-right: 0;
-    width: 16px;
-    height: 16px;
-  }
-  .cus-btn {
-    cursor: pointer;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-  }
-}
-</style>

+ 0 - 66
src/components/CusForm/src/ColorSelect.vue

@@ -1,66 +0,0 @@
-<template>
-  <ElRadioGroup v-model="colorType" size="small" style="width: 100%">
-    <ElRadioButton value="pure">单色</ElRadioButton>
-    <ElRadioButton value="gradient">渐变色</ElRadioButton>
-  </ElRadioGroup>
-  <template v-if="colorType === 'pure'">
-    <div class="color-box">
-      <ElColorPicker v-model="color" color-format="hex" show-alpha size="small"/>
-      <ElInput v-model="color" size="small"></ElInput>
-    </div>
-  </template>
-  <template v-else-if="colorType === 'gradient'">
-    <div class="gradient-box" :style="{ background: color }">
-      <ElColorPicker v-model="gradientColor[0]" color-format="hex" show-alpha size="small"/>
-      <ElColorPicker v-model="gradientColor[1]" color-format="hex" show-alpha size="small"/>
-    </div>
-  </template>
-</template>
-
-<script setup lang="ts">
-import { ElRadioGroup, ElRadioButton, ElColorPicker, ElInput, } from 'element-plus';
-import { defineEmits, defineProps, ref, watch } from 'vue';
-
-const emit = defineEmits(["update:value"]);
-const props = defineProps<{
-  value: string;
-}>();
-const colorType = ref(props.value?.length <= 9 || !props.value ? 'pure' : 'gradient');
-const color = ref(props.value);
-// 'linear-gradient(90deg,#9CEC5BFF,#0764F0FF)'
-const gradientColor = ref(props.value?.length >= 9 ? props.value.slice(22).replace(')', '').split(',') : ['#4ba9ff', '#fff']);
-
-watch(
-  () => [colorType.value, color.value, gradientColor.value],
-  () => {
-    if (colorType.value === 'pure') {
-      color.value = color.value.length > 9 ? '#FFFFFFFF' : color.value;
-    } else {
-      color.value = `linear-gradient(90deg, ${gradientColor.value.join(',')})`
-    }
-    emit('update:value', color.value);
-  },
-  {
-    deep: true
-  }
-);
-</script>
-
-<style lang="less" scoped>
-.color-box {
-  display: flex;
-  align-items: center;
-  margin-top: 12px;
-  :deep(.el-color-picker) {
-    margin-right: 8px;
-  }
-}
-.gradient-box {
-  padding: 2px;
-  margin-top: 12px;
-  border: solid 1px #eee;
-  width: 100%;
-  display: flex;
-  justify-content: space-between;
-}
-</style>

+ 0 - 85
src/components/CusForm/src/CusFormItem.vue

@@ -1,85 +0,0 @@
-<template>
-  <FormItem :label="item.type !== 'divider' ? item.label : ''" :name="item.prop" :rules="item.rules">
-    <template v-if="item.type === 'divider'">
-      <Divider style="margin: 0">{{ item.label }}</Divider>
-    </template>
-    <template v-else-if="item.type === 'input'">
-      <Input v-model:value="model" v-bind="item?.fieldProps"/>
-    </template>
-    <template v-else-if="item.type === 'select'">
-      <Select v-model:value="model" v-bind="item?.fieldProps"></Select>
-    </template>
-    <template v-else-if="item.type === 'inputNumber'">
-      <InputNumber v-model:value="model"  v-bind="item?.fieldProps" style="width: 100%"/>
-    </template>
-    <template v-else-if="item.type === 'image'">
-      <Image v-model:value="model"  v-bind="item?.fieldProps"/>
-    </template>
-    <template v-else-if="item.type === 'checkboxGroup'">
-      <CheckboxGroup v-model:value="model" v-bind="item?.fieldProps">
-      </CheckboxGroup>
-    </template>
-    <template v-else-if="item.type === 'backgroundSelect'">
-      <BackgroundSelect v-model:background="model"  v-bind="item?.fieldProps"/>
-    </template>
-    <template v-else-if="item.type === 'colorSelect'">
-      <ColorSelect v-model:value="model"  v-bind="item?.fieldProps"/>
-    </template>
-    <template v-else-if="item.type === 'radioGroup'">
-      <RadioGroup v-model:value="model" size="small" v-bind="item?.fieldProps">
-      </RadioGroup>
-    </template>
-    <template v-else-if="item.type === 'position'">
-      <Position v-model:value="model"  v-bind="item?.fieldProps"/>
-    </template>
-    <template v-else-if="item.type === 'fontStyle'">
-      <FontStyle v-model:value="model"  v-bind="item?.fieldProps"/>
-    </template>
-    <template v-else-if="item.type === 'slider'">
-      <FormItemRest>
-        <CusSlider v-model:value="model"  v-bind="item?.fieldProps"/>
-      </FormItemRest>
-    </template>
-    <!-- 提示 -->
-    <template v-if="item.tip">
-      <Tooltip :title="item.tip">
-        <InfoCircleOutlined style="color: #666"/>
-      </Tooltip>
-    </template>
-  </FormItem>
-</template>
-
-<script setup lang="ts">
-import { IFormItem } from "./type";
-import { defineProps, defineModel } from "vue";
-import {
-  FormItem,
-  FormItemRest,
-  Input,
-  Select,
-  InputNumber,
-  CheckboxGroup,
-  Image,
-  Divider,
-  RadioGroup,
-  Tooltip
-} from "ant-design-vue";
-import { InfoCircleOutlined } from "@ant-design/icons-vue";
-
-import BackgroundSelect from "./BackgroundSelect.vue";
-import ColorSelect from "./ColorSelect.vue";
-import Position from "./Position.vue";
-import FontStyle from "./FontStyle.vue";
-import CusSlider from "./CusSlider.vue";
-
-defineProps<{item: IFormItem}>();
-const model = defineModel<any>();
-
-</script>
-
-<style lang="less" scoped>
-:deep(.ant-divider-inner-text ){
-  font-size: 12px;
-  color: #666;
-}
-</style>

+ 0 - 27
src/components/CusForm/src/CusSlider.vue

@@ -1,27 +0,0 @@
-<template>
-  <div class="cus-slider">
-    <Slider :value="value" @change="(val) => $emit('update:value', val)" :tip-formatter="(val) => `${val}%`"/>
-    <InputNumber :value="value" addon-after="%"/>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { defineProps, defineEmits } from "vue";
-import { Slider, InputNumber } from "ant-design-vue";
-
-defineProps<{ value: number }>();
-defineEmits(["update:value"]);
-</script>
-
-<style lang="less" scoped>
-.cus-slider {
-  display: flex;
-  align-items: center;
-  .ant-slider {
-    flex: 1;
-  }
-  .ant-input-number-group-wrapper {
-    flex: 15%;
-  }
-}
-</style>

+ 0 - 86
src/components/CusForm/src/FontStyle.vue

@@ -1,86 +0,0 @@
-<template>
-  <div class="font-style">
-    <span class="cus-btn" :class="{ 'active-btn': bold }"
-      ><BoldOutlined @click="handleBold"
-    /></span>
-    <span class="cus-btn" :class="{ 'active-btn': italic }"
-      ><ItalicOutlined @click="handleItalic"
-    /></span>
-    <span class="cus-btn" :class="{ 'active-btn': underline }"
-      ><UnderlineOutlined @click="handleUnderline"
-    /></span>
-    <InputNumber
-      size="small"
-      :value="size"
-      :min="12"
-      :step="1"
-      :precision="0"
-      style="width: 80px"
-      @change="handleChange"
-    >
-      <template #addonAfter>px</template>
-    </InputNumber>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { defineProps, defineEmits, ref } from "vue";
-import {
-  BoldOutlined,
-  ItalicOutlined,
-  UnderlineOutlined,
-} from "@ant-design/icons-vue";
-import { InputNumber } from "ant-design-vue";
-
-const props = defineProps<{
-  value: {
-    size: number;
-    bold: boolean;
-    italic: boolean;
-    underline: boolean;
-  };
-}>();
-
-const emit = defineEmits(["update:value"]);
-
-const bold = ref(props.value?.bold);
-const italic = ref(props.value?.italic);
-const underline = ref(props.value?.underline);
-const size = ref(props.value?.size);
-
-const handleUpdate = () => {
-  emit("update:value", {
-    size: size.value,
-    bold: bold.value,
-    italic: italic.value,
-    underline: underline.value,
-  });
-};
-
-const handleBold = () => {
-  bold.value = !bold.value;
-  handleUpdate();
-};
-const handleItalic = () => {
-  italic.value = !italic.value;
-  handleUpdate();
-};
-const handleUnderline = () => {
-  underline.value = !underline.value;
-  handleUpdate();
-};
-const handleChange = (val: number) => {
-  size.value = val;
-  handleUpdate();
-};
-</script>
-
-<style lang="less" scoped>
-.font-style {
-  display: flex;
-  justify-content: space-between;
-}
-.active-btn {
-  color: @primary-color;
-}
-</style>

+ 0 - 37
src/components/CusForm/src/Position.vue

@@ -1,37 +0,0 @@
-<template>
-  <div class="position">
-    <RadioGroup v-if="type === 'line'" :value="value" @change="(e) => $emit('update:value', e.target.value)">
-      <RadioButton value="left"><AlignLeftOutlined/></RadioButton>
-      <RadioButton value="center"><AlignCenterOutlined/></RadioButton>
-      <RadioButton value="right"><AlignRightOutlined/></RadioButton>
-    </RadioGroup>
-
-    <RadioGroup v-else-if="type === 'round'" :value="value" @change="(e) => $emit('update:value', e.target.value)">
-      <RadioButton value="top"><BorderTopOutlined/></RadioButton>
-      <RadioButton value="bottom"><BorderBottomOutlined/></RadioButton>
-      <RadioButton value="left"><BorderLeftOutlined/></RadioButton>
-      <RadioButton value="right"><BorderRightOutlined/></RadioButton>
-      <!-- <RadioButton value="right-top"><AlignRightOutlined/></RadioButton> -->
-    </RadioGroup>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { defineProps, defineEmits, withDefaults } from 'vue';
-import { RadioGroup, RadioButton } from 'ant-design-vue';
-import { AlignCenterOutlined, AlignRightOutlined, AlignLeftOutlined, BorderBottomOutlined, BorderTopOutlined, BorderLeftOutlined, BorderRightOutlined } from '@ant-design/icons-vue';
-
-withDefaults(defineProps<{value: string, type?: 'round' | 'line'}>(), { type: 'line'});
-defineEmits(['update:value']);
-</script>
-
-<style lang="less" scoped>
-:deep(.ant-radio-group) {
-  width: 100%;
-  display: flex;
-}
-:deep(.ant-radio-button-wrapper) {
-  flex: 1;
-  text-align: center;
-}
-</style>

+ 0 - 92
src/components/CusForm/src/index.vue

@@ -1,92 +0,0 @@
-<template>
-  <Form
-    :model="formModel"
-    :colon="false"
-    :label-col="{ span: 8 }"
-    ref="formRef"
-    layout="horizontal"
-    size="small"
-  >
-    <template v-for="item in formItems" :key="item.prop">
-      <!-- 分组 -->
-      <Collapse v-if="item.type === 'group'">
-        <CollapsePanel :key="item.prop" :header="item.label">
-          <CusFormItem v-for="child in item.children" :key="child.prop" :item="child" v-model="formModel[child.prop]" />
-        </CollapsePanel>
-      </Collapse>
-      <!-- 单个表单项 -->
-      <CusFormItem v-else :item="item" v-model="formModel[item.prop]" />
-    </template>
-  </Form>
-</template>
-
-<script setup lang="ts">
-import type { IFormItem } from "./type";
-import type { FormInstance } from "ant-design-vue";
-import {
-  ref,
-  defineProps,
-  defineExpose,
-  computed,
-  watch,
-  defineEmits,
-} from "vue";
-import {
-  Form,
-  Collapse,
-  CollapsePanel
-} from "ant-design-vue";
-import CusFormItem from "./CusFormItem.vue";
-
-const props = defineProps<{
-  columns: IFormItem[];
-  formModel?: Record<string, any>;
-}>();
-
-const emit = defineEmits(["change"]);
-
-const formModel = ref<Record<string, any>>({});
-const formRef = ref<FormInstance>();
-
-const formItems = computed(() => {
-  return props.columns.map((item) => {
-    return {
-      ...item,
-      rules: item.rules || [],
-    };
-  });
-});
-
-watch(
-  () => formItems.value,
-  (val) => {
-    val &&
-      props.columns?.forEach((item) => {
-        // 设置表单初始值
-        if (item.type === "group") {
-          const children = item.children || [];
-          children.forEach((child) => {
-            if(item.type === 'divider') return;
-            formModel.value[child.prop] = child?.defaultValue;
-          });
-        } else {
-          if(item.type === 'divider') return;
-          formModel.value[item.prop] = item?.defaultValue;
-        }
-      });
-  },
-  { immediate: true }
-);
-
-watch(
-  () => formModel.value,
-  (val) => {
-    emit("change", val);
-  },
-  { deep: true }
-);
-
-defineExpose(formRef.value);
-</script>
-
-<style lang="less" scoped></style>

+ 0 - 52
src/components/CusForm/src/type.ts

@@ -1,52 +0,0 @@
-import { VNode } from "vue";
-
-export interface IFormItem {
-  label: string;
-  icon?: string;
-  prop: string;
-  type:
-    // 内置类型--分组
-    | "group"
-    | "input"
-    | "select"
-    | "inputNumber"
-    | "image"
-    | "checkboxGroup"
-    | "radioGroup"
-    // 背景选择
-    | "backgroundSelect"
-    // 边框选择
-    | "boderSelect"
-    // 边框圆角选择
-    | "boderRadiusSelect"
-    // 阴影选择
-    | "shodowSelect"
-    // 内边距选择
-    | "paddingSelect"
-    // 旋转选择
-    | "rotateSelect"
-    // 透明度选择
-    | "opacitySelect"
-    // 颜色选择
-    | "colorSelect"
-    // 配色方案
-    | "colorScheme"
-    // 字体样式
-    | "fontStyle"
-    // 位置
-    | "position"
-    // 滑块
-    | "slider"
-    // 分割线
-    | "divider"
-  rules?: any[];
-  defaultValue?: any;
-  // 分组表单项
-  children?: IFormItem[];
-  // 组件属性
-  fieldProps?: any;
-  // 自定义渲染
-  render?: (form: any) => VNode;
-  // 提示内容
-  tip?: string;
-}

+ 0 - 6
src/components/Text/Title/index.ts

@@ -1,6 +0,0 @@
-import Title from './src/index.vue';
-import Config from './src/Config.vue';
-
-export default Title;
-export { Config };
-export { defaultPropsValue, titleProps } from './src/props';

+ 0 - 54
src/components/Text/Title/src/Config.vue

@@ -1,54 +0,0 @@
-<!-- 组件自定义配置部分 -->
-<template>
-  <CusForm :columns="columns" v-bind="$attrs" @change="handleChange">
-  </CusForm>
-</template>
-
-<script setup lang="ts">
-import { defineProps, defineEmits, computed } from 'vue';
-import { CusForm, type IFormItem } from '@/components/CusForm';
-import { titleProps } from './props';
-
-const props = defineProps(titleProps);
-const emit = defineEmits(["change"]);
-
-const columns = computed((): IFormItem[] => [
-  {
-    label: '内容',
-    prop: 'text',
-    type: 'input',
-    defaultValue: props.text,
-  },
-  {
-    label: '字体',
-    prop: 'fontSize',
-    type: 'inputnumber',
-    defaultValue: props.fontSize,
-  },
-  {
-    label: '颜色',
-    prop: 'color',
-    type: 'colorSelect',
-    defaultValue: props.color,
-  },
-  {
-    label: '对齐',
-    prop: 'textAlign',
-    type: 'radioGroup',
-    defaultValue: props.textAlign,
-    options: [
-      { label: '左对齐', value: 'left' },
-      { label: '居中', value: 'center' },
-      { label: '右对齐', value: 'right'}
-    ]
-  }
-]);
-
-const handleChange = (val: Record<string, any>) => {
-  emit('change', val);
-};
-</script>
-
-<style lang="scss" scoped>
-
-</style>

+ 0 - 32
src/components/Text/Title/src/index.vue

@@ -1,32 +0,0 @@
-<template>
-  <div class="cus-title" :style="style">
-    {{ text }}
-  </div>
-</template>
-
-<script setup lang="ts">
-import { defineProps, computed } from 'vue';
-import { titleProps } from './props';
-import { transformStyle } from '@/utils/style';
-
-const props = defineProps(titleProps);
-const style = computed(() => {
-  const style = transformStyle(props);
-  const obj: Record<string, string> = {};
-  if(style.color.length > 9) {
-    obj.backgroundImage = style.color;
-    obj.webkitBackgroundClip = 'text';
-    obj.webkitTextFillColor = 'transparent';
-  }
-  return {
-    ...obj,
-    ...style,
-    width: '100%',
-    height: '100%',
-    lineHeight: props.height + 'px'
-  }
-});
-</script>
-
-<style lang="less" scoped>
-</style>

+ 0 - 54
src/components/Text/Title/src/props.ts

@@ -1,54 +0,0 @@
-import { PropType } from 'vue';
-
-export const titleProps = {
-  text: {
-    type: String,
-    required: true
-  },
-  width: {
-    type: Number,
-  },
-  height: {
-    type: Number,
-  },
-  fontSize: {
-    type: Number,
-  },
-  fontWeight: {
-    type: [Number, String],
-  },
-  color: {
-    type: String,
-  },
-  backgroundColor: {
-    type: String,
-  },
-  textAlign: {
-    type: String,
-  },
-  direction: {
-    type: String as PropType<'horizontal' | 'vertical'>,
-  }
-}
-
-export const defaultPropsValue = {
-  container: {
-    style: {
-      background: {
-        type: 'none'
-      }
-    },
-    props: {
-      width: 300,
-      height: 80,
-    }
-  },
-  props: {
-    text: '标题内容',
-    fontSize: 24,
-    color: '#fff',
-    fontWeight: 'bold',
-    textAlign: 'left',
-    direction: 'horizontal'
-  }
-}

+ 0 - 9
src/components/index.ts

@@ -1,9 +0,0 @@
-// 暴露大屏组件资源
-const componentAll = {
-  Title: () => import("@/components/Text/Title"),
-  BasicLine: () => import("@/components/Charts/Line/BasicLine"),
-  BasicBar: () => import("@/components/Charts/Bar/BasicBar"),
-};
-
-export default componentAll;
-export type ComponentType = keyof typeof componentAll;

+ 0 - 102
src/hooks/useEcharts.ts

@@ -1,102 +0,0 @@
-import type { Ref } from "vue";
-import type { EChartsOption } from 'echarts';
-import echarts from "@/utils/echarts";
-// import * as echarts from 'echarts';
-import { unref, nextTick, watch, computed, ref } from "vue";
-import { tryOnUnmounted, useDebounceFn, useEventListener } from '@vueuse/core';
-
-export function useEcharts(
-  elRef: Ref<HTMLElement>,
-  theme: 'default' | 'dark' | 'light' = 'default',
-) {
-  let chartInstance: echarts.ECharts | null = null;
-  let resizeFn: Fn = resize;
-  const cacheOptions = ref({});
-
-  let removeResizeFn: Fn = () => {};
-
-  const getOptions = computed(() => {
-    return cacheOptions.value;
-  })
-
-  resizeFn = useDebounceFn(resize, 200);
-
-  function resize() {
-    chartInstance?.resize({
-      animation: {
-        duration: 300,
-        easing: 'quadraticIn',
-      },
-    });
-  }
-
-  function initCharts( t = theme) {
-    const el = unref(elRef);
-    if (!el || !unref(el)) {
-      return;
-    }
-
-    chartInstance = echarts.init(el, t);
-    const removeEvent = useEventListener(window, 'resize', resizeFn);
-
-    removeResizeFn = removeEvent;
-  }
-
-  function setOptions(options: EChartsOption, clear = true) {
-    cacheOptions.value = options;
-    return new Promise((resolve) => {
-      if (unref(elRef)?.offsetHeight === 0) {
-        setTimeout(() => {
-          setOptions(unref(getOptions));
-          resolve(null);
-        }, 30);
-      }
-      nextTick(() => {
-        setTimeout(() => {
-          if (!chartInstance) {
-            initCharts('default');
-
-            if (!chartInstance) return;
-          }
-          clear && chartInstance?.clear();
-
-          chartInstance?.setOption(unref(getOptions));
-          resolve(null);
-        }, 30);
-      });
-    });
-  }
-
-  watch(
-    () => theme,
-    (theme) => {
-      if (chartInstance) {
-        chartInstance.dispose();
-        initCharts(theme as 'default');
-        setOptions(cacheOptions.value);
-      }
-    },
-  );
-
-
-  tryOnUnmounted(() => {
-    if (!chartInstance) return;
-    removeResizeFn();
-    chartInstance.dispose();
-    chartInstance = null;
-  });
-
-  function getInstance(): echarts.ECharts | null {
-    if (!chartInstance) {
-      initCharts('default');
-    }
-    return chartInstance;
-  }
-
-  return {
-    setOptions,
-    resize,
-    echarts,
-    getInstance
-  }
-}

+ 1 - 1
src/mock/index.ts

@@ -5,7 +5,7 @@ export default [
   {
     url: '/mock/api/get/resource/image-list',
     method: 'get',
-    response: ({ query }) => {
+    response: ({ }) => {
       return {
         code: 0,
         data: {

+ 5 - 5
src/store/modules/project.ts

@@ -1,7 +1,6 @@
 import type { ProjectInfo, Page, ReferLine } from "#/project";
-import type { ComponentType } from "@/components";
 import { defineStore } from "pinia";
-import componentAll from "@/components";
+import { asyncComponentAll } from "shalu-dashboard-ui";
 import { ScreenFillEnum } from "@/enum/screenFillEnum";
 import { update, defaultsDeep } from "lodash";
 import { getNormalizedContainer } from "@/utils/common";
@@ -12,7 +11,7 @@ type ProjectState = {
   addCompData: {
     key: number;
     name: string;
-    componentType: ComponentType;
+    componentType: string;
     container: {
       style: Record<string, any>;
       props: Record<string, any>;
@@ -116,9 +115,10 @@ export const useProjectStore = defineStore({
       if (!element) return;
 
       const elements = this.projectInfo.pages[this.activePageIndex].elements;
-      // 获取每个自定义组件暴露出来的属性
+      // 获取每个自定义组件暴露出来的默认属性
       const { defaultPropsValue } =
-        (await componentAll[element.componentType as ComponentType]?.()) || {};
+        (await asyncComponentAll[element.componentType]?.()) || {};
+
       const { width = 400, height = 260 } = defaultPropsValue?.container?.props  || {};
       const { props: containerProps = {}, style = {} } = defaultPropsValue?.container || {};
 

+ 0 - 62
src/utils/echarts.ts

@@ -1,62 +0,0 @@
-import * as echarts from 'echarts/core';
-
-import {
-  BarChart,
-  LineChart,
-  PieChart,
-  MapChart,
-  PictorialBarChart,
-  RadarChart,
-  ScatterChart,
-} from 'echarts/charts';
-
-import {
-  TitleComponent,
-  TooltipComponent,
-  GridComponent,
-  PolarComponent,
-  AriaComponent,
-  ParallelComponent,
-  LegendComponent,
-  RadarComponent,
-  ToolboxComponent,
-  DataZoomComponent,
-  VisualMapComponent,
-  TimelineComponent,
-  CalendarComponent,
-  GraphicComponent,
-  DatasetComponent,
-  // 内置数据转换器组件 (filter, sort)
-  TransformComponent
-} from 'echarts/components';
-
-import { CanvasRenderer } from 'echarts/renderers';
-
-echarts.use([
-  LegendComponent,
-  TitleComponent,
-  TooltipComponent,
-  GridComponent,
-  PolarComponent,
-  AriaComponent,
-  ParallelComponent,
-  BarChart,
-  LineChart,
-  PieChart,
-  MapChart,
-  RadarChart,
-  CanvasRenderer,
-  PictorialBarChart,
-  RadarComponent,
-  ToolboxComponent,
-  DataZoomComponent,
-  VisualMapComponent,
-  TimelineComponent,
-  CalendarComponent,
-  GraphicComponent,
-  ScatterChart,
-  DatasetComponent,
-  TransformComponent
-]);
-
-export default echarts;

+ 3 - 3
src/views/designer/component/ComponentWrapper.vue

@@ -34,19 +34,19 @@
 <script setup lang="ts">
 import type { CustomElement } from "#/project";
 import { defineProps, defineAsyncComponent, computed, ref } from "vue";
-import componentAll from "@/components";
 import { transformStyle } from "@/utils/style";
-
 import { useStageStore } from "@/store/modules/stage";
 import { useProjectStore } from "@/store/modules/project";
 import { useDraggable } from "@vueuse/core";
 import { UseDraggable } from "@vueuse/components";
+import { asyncComponentAll } from 'shalu-dashboard-ui';
 
 const { componentData } = defineProps<{ componentData: CustomElement }>();
 // 动态引入组件
 const component = defineAsyncComponent(
-  componentAll[componentData.componentType]
+  asyncComponentAll[componentData.componentType]
 );
+
 const componentWrapperRef = ref<HTMLElement | null>(null);
 const stageStore = useStageStore();
 const projectStore = useProjectStore();

+ 239 - 5
src/views/designer/component/Configurator.vue

@@ -27,29 +27,263 @@
         <div class="config-content">动画处理</div>
       </TabPane>
       <TabPane key="4" tab="组件">
-        <div class="config-content">样式属性</div>
+        <div class="config-content">
+          <CusForm :columns="formItems"/>
+        </div>
       </TabPane>
     </Tabs>
   </div>
 </template>
 
 <script setup lang="ts">
-import { shallowRef, watch } from "vue";
+import { computed, shallowRef, watch, } from "vue";
 import { Tabs, TabPane } from "ant-design-vue";
 import { useProjectStore } from "@/store/modules/project";
 import PageConfig from "./PageConfig.vue";
-import componentAll from "@/components";
+import { asyncComponentAll, CusForm } from 'shalu-dashboard-ui';
+import type { IFormItem } from 'shalu-dashboard-ui';
 
 const projectStore = useProjectStore();
 const configComponent = shallowRef<null | string>(null);
 const currentElementProps = shallowRef<any>({});
 
+const formItems = computed((): IFormItem[] => {
+  const element = projectStore.currentSelectedElements[0];
+  return [
+  {
+    label: "组件样式",
+    prop: "style",
+    type: "group",
+    children: [
+      {
+        label: "边框背景",
+        prop: "bakcground",
+        type: "backgroundSelect",
+        defaultValue: element?.container?.style?.background ?? {
+          type: 'none',
+          color: "",
+          image: "",
+          fillType: "cover",
+        }
+      },
+      {
+        label: "不透明度",
+        prop: "opacity",
+        type: "slider",
+        defaultValue: element?.container?.style?.opacity ?? 1
+      },
+      {
+        label: "边框线",
+        prop: "borderStyle",
+        type: "select",
+        fieldProps: {
+          options: [
+            { label: "无", value: "none" },
+            { label: "实线", value: "solid" },
+            { label: "虚线", value: "dashed" },
+            { label: "点线", value: "dotted" }
+          ]
+        },
+        defaultValue: element?.container?.style?.borderStyle || "none"
+      },
+      {
+        label: "边框颜色",
+        prop: "borderColor",
+        type: "colorSelect",
+        defaultValue: element?.container?.style?.borderColor ?? "#EEEEEEFF"
+      },
+      {
+        label: "边框宽度",
+        prop: "borderWidth",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.style?.borderWidth ?? 1
+      },
+      {
+        label: "圆角",
+        prop: "borderRadius",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.style?.borderRadius ?? 0
+      },
+      {
+        label: "毛玻璃",
+        prop: "backdropFilter",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [
+            { label: "开启", value: "blur(10px)" }
+          ]
+        },
+        defaultValue: element?.container?.style?.backdropFilter ? ["blur(10px)"] : []
+      },
+      {
+        label: "阴影",
+        prop: "boxShadow",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [
+            { label: "开启", value: "0 0 10px rgba(0,0,0,0.1)" }
+          ]
+        },
+        defaultValue: element?.container?.style?.boxShadow ? ["0 0 10px rgba(0,0,0,0.1)"] : []
+      },
+      {
+        label: "倒影",
+        prop: "webkitBoxReflect",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [
+            { label: "开启", value: "below 2px linear-gradient(transparent, rgba(0,0,0,0.5))" }
+          ]
+        },
+        defaultValue: element?.container?.style?.webkitBoxReflect ? ["below 2px linear-gradient(transparent, rgba(0,0,0,0.5))"] : []
+      }
+    ]
+  },
+  {
+    label: "组件属性",
+    prop: "props",
+    type: "group",
+    children: [
+      {
+        label: "名称",
+        prop: "name",
+        type: "input",
+        defaultValue: element?.name ?? ""
+      },
+      {
+        label: "宽度",
+        prop: "width",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.props?.width ?? 400
+      },
+      {
+        label: "高度",
+        prop: "height",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.props?.height ?? 260
+      },
+      {
+        label: "距离左侧",
+        prop: "x",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.props?.x ?? 0
+      },
+      {
+        label: "距离顶部",
+        prop: "y",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.props?.y ?? 0
+      },
+      {
+        label: "顶边距",
+        prop: "paddingTop",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.props?.paddingTop ?? 0
+      },
+      {
+        label: "右边距",
+        prop: "paddingRight",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.props?.paddingRight ?? 0
+      },
+      {
+        label: "底边距",
+        prop: "paddingBottom",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.props?.paddingBottom ?? 0
+      },
+      {
+        label: "左边距",
+        prop: "paddingLeft",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "px"
+        },
+        defaultValue: element?.container?.props?.paddingLeft ?? 0
+      },
+      {
+        label: "X轴旋转",
+        prop: "xRotate",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "deg"
+        },
+        defaultValue: element?.container?.props?.xRotate ?? 0
+      },
+      {
+        label: "Y轴旋转",
+        prop: "yRotate",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "deg"
+        },
+        defaultValue: element?.container?.props?.yRotate ?? 0
+      },
+      {
+        label: "Z轴旋转",
+        prop: "zRotate",
+        type: "inputNumber",
+        fieldProps: {
+          min: 0,
+          addonAfter: "deg"
+        },
+        defaultValue: element?.container?.props?.zRotate ?? 0
+      },
+      {
+        label: "不透明度",
+        prop: "opacity",
+        type: "slider",
+        defaultValue: element?.container?.props?.opacity ?? 100
+      }
+    ]
+  }
+]});
+
 watch(
   () => projectStore.currentSelectedElements,
   async (val) => {
     if (val.length === 1) {
-      const { Config } = await componentAll[
-        val[0].componentType as keyof typeof componentAll
+      const { Config } = await asyncComponentAll[
+        val[0].componentType as keyof typeof asyncComponentAll
       ]?.();
       configComponent.value = Config;
       currentElementProps.value = val[0].props;

+ 2 - 2
src/views/designer/component/PageConfig.vue

@@ -3,11 +3,11 @@
 </template>
 
 <script setup lang="ts">
-import { CusForm, IFormItem } from '@/components/CusForm';
+import { CusForm } from 'shalu-dashboard-ui';
 import { useProjectStore } from '@/store/modules/project';
 
 const projectStore = useProjectStore();
-const formItems: IFormItem[] = [
+const formItems = [
   {
     label: '页面背景',
     prop: 'background',

+ 3 - 3
src/views/view/component/RenderComponent.vue

@@ -6,13 +6,13 @@
 
 <script setup lang="ts">
 import type { CustomElement } from '#/project';
-import { defineProps, ref, onMounted, defineAsyncComponent } from 'vue';
-import componentAll from '@/components';
+import { defineProps, ref, defineAsyncComponent } from 'vue';
+import { asyncComponentAll } from 'shalu-dashboard-ui';
 
 const props = defineProps<{
   element: CustomElement;
 }>();
-const component = defineAsyncComponent(componentAll[props.element.componentType]);
+const component = defineAsyncComponent(asyncComponentAll[props.element.componentType]);
 const containerStyle = ref({
   width: `${props.element.container.props.width}px`,
   height: `${props.element.container.props.height}px`,

+ 2 - 0
vite.config.ts

@@ -3,6 +3,7 @@ import vue from "@vitejs/plugin-vue";
 import path from "path";
 import ElementPlus from "unplugin-element-plus/vite";
 import { viteMockServe } from "vite-plugin-mock";
+import vueJsx from '@vitejs/plugin-vue-jsx';
 
 // https://vitejs.dev/config/
 export default defineConfig({
@@ -14,6 +15,7 @@ export default defineConfig({
       enable: true,
       watchFiles: true
     }),
+    vueJsx(),
   ],
   resolve: {
     alias: {