Browse Source

Merge branch 'dev' of https://gitee.com/wangbosheng/yudao-ui-admin-vue3 into dev

Chika 1 year ago
parent
commit
8456c671e8
100 changed files with 665 additions and 2071 deletions
  1. 0 3
      .env
  2. 15 0
      .env.front
  3. 31 0
      .env.stage
  4. 1 1
      .env.test
  5. 1 1
      .gitignore
  6. 16 0
      .vscode/launch.json
  7. 11 1
      .vscode/settings.json
  8. 2 2
      README.md
  9. 5 4
      build/vite/index.ts
  10. 17 5
      build/vite/optimize.ts
  11. 7 8
      package.json
  12. 3 1
      src/App.vue
  13. 5 5
      src/api/mall/product/category.ts
  14. 39 0
      src/api/mall/product/management/spu.ts
  15. 79 0
      src/api/mall/product/management/type/skuType.ts
  16. 25 0
      src/api/mall/product/management/type/spuType.ts
  17. 2 2
      src/api/mall/product/property.ts
  18. 1 1
      src/api/mp/account/index.ts
  19. 2 2
      src/api/pay/merchant/index.ts
  20. 5 0
      src/api/pay/order/index.ts
  21. 8 14
      src/api/system/notify/template/index.ts
  22. 1 1
      src/components/Backtop/src/Backtop.vue
  23. 2 2
      src/components/ConfigGlobal/src/ConfigGlobal.vue
  24. 6 4
      src/components/ContentDetailWrap/src/ContentDetailWrap.vue
  25. 2 2
      src/components/ContentWrap/src/ContentWrap.vue
  26. 1 1
      src/components/CountTo/src/CountTo.vue
  27. 55 47
      src/components/Crontab/src/Crontab.vue
  28. 26 23
      src/components/Cropper/src/CopperModal.vue
  29. 2 2
      src/components/Cropper/src/Cropper.vue
  30. 10 4
      src/components/Cropper/src/CropperAvatar.vue
  31. 5 5
      src/components/Descriptions/src/Descriptions.vue
  32. 7 7
      src/components/Dialog/src/Dialog.vue
  33. 1 1
      src/components/Echart/src/Echart.vue
  34. 5 4
      src/components/Editor/src/Editor.vue
  35. 2 2
      src/components/Error/src/Error.vue
  36. 4 4
      src/components/Form/src/helper.ts
  37. 1 1
      src/components/Form/src/types.ts
  38. 3 3
      src/components/IFrame/src/IFrame.vue
  39. 2 2
      src/components/Icon/src/Icon.vue
  40. 12 12
      src/components/Icon/src/IconSelect.vue
  41. 1 1
      src/components/ImageViewer/src/ImageViewer.vue
  42. 3 3
      src/components/Infotip/src/Infotip.vue
  43. 4 4
      src/components/InputPassword/src/InputPassword.vue
  44. 5 5
      src/components/Pagination/index.vue
  45. 4 5
      src/components/Qrcode/src/Qrcode.vue
  46. 12 12
      src/components/Search/src/Search.vue
  47. 3 2
      src/components/Sticky/src/Sticky.vue
  48. 2 1
      src/components/Tooltip/src/Tooltip.vue
  49. 23 13
      src/components/Verifition/src/Verify.vue
  50. 7 7
      src/components/Verifition/src/Verify/VerifyPoints.vue
  51. 11 11
      src/components/Verifition/src/Verify/VerifySlide.vue
  52. 4 3
      src/components/XButton/src/XButton.vue
  53. 4 3
      src/components/XButton/src/XTextButton.vue
  54. 0 3
      src/components/XModal/index.ts
  55. 0 44
      src/components/XModal/src/XModal.vue
  56. 0 3
      src/components/XTable/index.ts
  57. 0 442
      src/components/XTable/src/XTable.vue
  58. 0 81
      src/components/XTable/src/style/dark.scss
  59. 0 6
      src/components/XTable/src/style/index.scss
  60. 0 16
      src/components/XTable/src/style/light.scss
  61. 0 26
      src/components/XTable/src/type.ts
  62. 14 11
      src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue
  63. 6 32
      src/components/bpmnProcessDesigner/package/index.ts
  64. 6 3
      src/components/bpmnProcessDesigner/package/penal/form/ElementForm.vue
  65. 0 19
      src/components/index.ts
  66. 2 0
      src/hooks/web/useCrudSchemas.ts
  67. 0 354
      src/hooks/web/useVxeCrudSchemas.ts
  68. 0 264
      src/hooks/web/useVxeGrid.ts
  69. 0 39
      src/hooks/web/useXTable.ts
  70. 6 5
      src/layout/components/AppView.vue
  71. 3 3
      src/layout/components/Collapse/src/Collapse.vue
  72. 6 5
      src/layout/components/ContextMenu/src/ContextMenu.vue
  73. 1 1
      src/layout/components/Footer/src/Footer.vue
  74. 4 4
      src/layout/components/LocaleDropdown/src/LocaleDropdown.vue
  75. 3 3
      src/layout/components/Logo/src/Logo.vue
  76. 13 6
      src/layout/components/Message/src/Message.vue
  77. 3 3
      src/layout/components/Screenfull/src/Screenfull.vue
  78. 8 8
      src/layout/components/Setting/src/Setting.vue
  79. 3 3
      src/layout/components/Setting/src/components/ColorRadioPicker.vue
  80. 1 1
      src/layout/components/Setting/src/components/InterfaceDisplay.vue
  81. 1 1
      src/layout/components/Setting/src/components/LayoutRadioPicker.vue
  82. 2 2
      src/layout/components/SizeDropdown/src/SizeDropdown.vue
  83. 21 18
      src/layout/components/TagsView/src/TagsView.vue
  84. 5 5
      src/layout/components/ThemeSwitch/src/ThemeSwitch.vue
  85. 1 1
      src/layout/components/UserInfo/src/UserInfo.vue
  86. 3 1
      src/layout/components/useRenderLayout.tsx
  87. 0 32
      src/main.ts
  88. 1 5
      src/plugins/formCreate/index.ts
  89. 0 223
      src/plugins/vxeTable/index.ts
  90. 0 20
      src/plugins/vxeTable/renderer/dataPicker.tsx
  91. 0 23
      src/plugins/vxeTable/renderer/dataTimeRangePicker.tsx
  92. 0 12
      src/plugins/vxeTable/renderer/dict.tsx
  93. 0 10
      src/plugins/vxeTable/renderer/html.tsx
  94. 0 20
      src/plugins/vxeTable/renderer/img.tsx
  95. 0 7
      src/plugins/vxeTable/renderer/index.tsx
  96. 0 15
      src/plugins/vxeTable/renderer/link.tsx
  97. 0 35
      src/plugins/vxeTable/renderer/preview.tsx
  98. 41 6
      src/router/modules/remaining.ts
  99. 6 1
      src/styles/index.scss
  100. 0 2
      src/styles/variables.scss

+ 0 - 3
.env

@@ -13,8 +13,5 @@ VITE_APP_TENANT_ENABLE=true
 # 验证码的开关
 VITE_APP_CAPTCHA_ENABLE=true
 
-# 验证码的开关
-VITE_APP_CAPTCHA_ENABLE=true
-
 # 百度统计
 VITE_APP_BAIDU_CODE = a1ff8825baa73c3a78eb96aa40325abc

+ 15 - 0
.env.front

@@ -17,3 +17,18 @@ VITE_API_URL=/admin-api
 
 # 打包路径
 VITE_BASE_PATH=/
+
+# 项目本地运行端口号, 与.vscode/launch.json配合
+VITE_PORT=80
+
+# 是否删除debugger
+VITE_DROP_DEBUGGER=false
+
+# 是否删除console.log
+VITE_DROP_CONSOLE=false
+
+# 是否sourcemap
+VITE_SOURCEMAP=true
+
+# 验证码的开关
+VITE_APP_CAPTCHA_ENABLE=false

+ 31 - 0
.env.stage

@@ -0,0 +1,31 @@
+# 生产环境
+NODE_ENV=production
+
+VITE_DEV=false
+
+# 请求路径
+VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
+
+# 上传路径
+VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload'
+
+# 接口前缀
+VITE_API_BASEPATH=
+
+# 接口地址
+VITE_API_URL=/admin-api
+
+# 是否删除debugger
+VITE_DROP_DEBUGGER=true
+
+# 是否删除console.log
+VITE_DROP_CONSOLE=true
+
+# 是否sourcemap
+VITE_SOURCEMAP=false
+
+# 打包路径
+VITE_BASE_PATH='http://static-vue3.yudao.iocoder.cn/'
+
+# 输出路径
+VITE_OUT_DIR=dist-stage

+ 1 - 1
.env.test

@@ -25,7 +25,7 @@ VITE_DROP_CONSOLE=false
 VITE_SOURCEMAP=true
 
 # 打包路径
-VITE_BASE_PATH=/dist-test/
+VITE_BASE_PATH=/
 
 # 输出路径
 VITE_OUT_DIR=dist-test

+ 1 - 1
.gitignore

@@ -6,6 +6,6 @@ dist-ssr
 /dist*
 *-lock.*
 pnpm-debug
-
+auto-*.d.ts
 .idea
 .history

+ 16 - 0
.vscode/launch.json

@@ -0,0 +1,16 @@
+{
+  // Use IntelliSense to learn about possible attributes.
+  // Hover to view descriptions of existing attributes.
+  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "type": "msedge",
+      "request": "launch",
+      "name": "Launch Edge against localhost",
+      "url": "http://localhost",
+      "webRoot": "${workspaceFolder}/src",
+      "sourceMaps": true
+    }
+  ]
+}

+ 11 - 1
.vscode/settings.json

@@ -40,5 +40,15 @@
   "i18n-ally.displayLanguage": "zh-CN",
   "i18n-ally.enabledFrameworks": ["vue", "react"],
   "god.tsconfig": "./tsconfig.json",
-  "vue-i18n.i18nPaths": "src/locales"
+  "vue-i18n.i18nPaths": "src/locales",
+  "explorer.fileNesting.enabled": true,
+  "explorer.fileNesting.expand": false,
+  "explorer.fileNesting.patterns": {
+    "*.ts": "$(capture).test.ts, $(capture).test.tsx",
+    "*.tsx": "$(capture).test.ts, $(capture).test.tsx",
+    "*.env": "$(capture).env.*",
+    "CHANGELOG.md": "CHANGELOG*",
+    "package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,README*,.npmrc,.browserslistrc,vite.config.*,windi.*,tailwind.*,tsconfig.*,postcss*",
+    ".eslintrc.js": ".eslintignore,.eslintrc-*,.prettierignore,.stylelintignore,.commitlintrc.js,.prettierrc.js,.stylelint*,stylelint*,prettier.*,.editorconfig"
+  }
 }

+ 2 - 2
README.md

@@ -10,7 +10,8 @@
 ## 🐶 新手必读
 
 * nodejs > 16.0.0 && pnpm > 7.30.0
-* 演示地址:<http://dashboard.yudao.iocoder.cn>
+* 演示地址【Vue3 + element-plus】:<http://dashboard-vue3.yudao.iocoder.cn>
+* 演示地址【Vue2 + element-ui】:<http://dashboard.yudao.iocoder.cn>
 * 启动文档:<https://doc.iocoder.cn/quick-start/>
 * 视频教程:<https://doc.iocoder.cn/video/>
 
@@ -42,7 +43,6 @@
 | [TypeScript](https://www.typescriptlang.org/docs/)                   | JavaScript 的超集   | 4.9.5  |
 | [pinia](https://pinia.vuejs.org/)                                    | Vue 存储库 替代 vuex5 | 2.0.33 |
 | [vueuse](https://vueuse.org/)                                        | 常用工具集            | 9.13.0 |
-| [vxe-table](https://vxetable.cn/)                                    | Vue 最强表单         | 4.3.10  |
 | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化              | 9.2.2  |
 | [vue-router](https://router.vuejs.org/)                              | Vue 路由           | 4.1.6  |
 | [windicss](https://cn.windicss.org/)                                 | 下一代工具优先的 CSS 框架  | 3.5.6  |

+ 5 - 4
build/vite/index.ts

@@ -13,16 +13,18 @@ import Components from 'unplugin-vue-components/vite'
 import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
 import viteCompression from 'vite-plugin-compression'
 import topLevelAwait from 'vite-plugin-top-level-await'
-import vueSetupExtend from 'vite-plugin-vue-setup-extend'
+import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus'
 import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
 import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
 
 export function createVitePlugins() {
   const root = process.cwd()
+
   // 路径查找
   function pathResolve(dir: string) {
     return resolve(root, '.', dir)
   }
+
   return [
     Vue(),
     VueJsx(),
@@ -45,8 +47,6 @@ export function createVitePlugins() {
         {
           '@/hooks/web/useI18n': ['useI18n'],
           '@/hooks/web/useMessage': ['useMessage'],
-          '@/hooks/web/useXTable': ['useXTable'],
-          '@/hooks/web/useVxeCrudSchemas': ['useVxeCrudSchemas'],
           '@/hooks/web/useTable': ['useTable'],
           '@/hooks/web/useCrudSchemas': ['useCrudSchemas'],
           '@/utils/formRules': ['required'],
@@ -98,7 +98,8 @@ export function createVitePlugins() {
       deleteOriginFile: false //压缩后是否删除源文件
     }),
     ViteEjsPlugin(),
-    topLevelAwait({ // https://juejin.cn/post/7152191742513512485
+    topLevelAwait({
+      // https://juejin.cn/post/7152191742513512485
       // The export name of top-level await promise for each chunk module
       promiseExportName: '__tla',
       // The function to generate import names of top-level await promise in each chunk module

+ 17 - 5
build/vite/optimize.ts

@@ -18,10 +18,6 @@ const include = [
   'lodash-es',
   'nprogress',
   'animate.css',
-  'vxe-table',
-  'vxe-table/es/style',
-  'vxe-table/lib/locale/lang/zh-CN',
-  'vxe-table/lib/locale/lang/en-US',
   'web-storage-cache',
   '@iconify/iconify',
   '@vueuse/core',
@@ -68,6 +64,7 @@ const include = [
   'element-plus/es/components/dropdown-menu/style/index',
   'element-plus/es/components/dropdown-item/style/index',
   'element-plus/es/components/skeleton/style/index',
+
   'element-plus/es/components/skeleton/style/css',
   'element-plus/es/components/backtop/style/css',
   'element-plus/es/components/menu/style/css',
@@ -79,7 +76,22 @@ const include = [
   'element-plus/es/components/dropdown-item/style/css',
   'element-plus/es/components/badge/style/css',
   'element-plus/es/components/breadcrumb/style/css',
-  'element-plus/es/components/breadcrumb-item/style/css'
+  'element-plus/es/components/breadcrumb-item/style/css',
+  'element-plus/es/components/image/style/css',
+  'element-plus/es/components/tag/style/css',
+  'element-plus/es/components/dialog/style/css',
+  'element-plus/es/components/form/style/css',
+  'element-plus/es/components/form-item/style/css',
+  'element-plus/es/components/card/style/css',
+  'element-plus/es/components/tooltip/style/css',
+  'element-plus/es/components/radio-group/style/css',
+  'element-plus/es/components/radio/style/css',
+  'element-plus/es/components/input-number/style/css',
+  'element-plus/es/components/tree-select/style/css',
+  'element-plus/es/components/drawer/style/css',
+  'element-plus/es/components/image-viewer/style/css',
+  'element-plus/es/components/upload/style/css',
+  'element-plus/es/components/switch/style/css'
 ]
 
 const exclude = ['@iconify/json']

+ 7 - 8
package.json

@@ -1,6 +1,6 @@
 {
   "name": "yudao-ui-admin-vue3",
-  "version": "1.7.1-snapshot.1961",
+  "version": "1.7.2-snapshot",
   "description": "基于vue3、vite4、element-plus、typesScript",
   "author": "xingyu",
   "private": false,
@@ -11,6 +11,7 @@
     "ts:check": "vue-tsc --noEmit",
     "build:pro": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode pro",
     "build:dev": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode dev",
+    "build:stage": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode stage",
     "build:test": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode test",
     "build:static": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode static",
     "build:front": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode front",
@@ -32,13 +33,12 @@
     "@form-create/element-ui": "^3.1.17",
     "@iconify/iconify": "^3.1.0",
     "@videojs-player/vue": "^1.0.0",
-    "@vueup/vue-quill": "^1.1.1",
     "@vueuse/core": "^9.13.0",
     "@wangeditor/editor": "^5.1.23",
     "@wangeditor/editor-for-vue": "^5.1.10",
     "@zxcvbn-ts/core": "^2.2.1",
     "animate.css": "^4.1.1",
-    "axios": "^1.3.4",
+    "axios": "^1.3.5",
     "benz-amr-recorder": "^1.1.5",
     "bpmn-js-token-simulation": "^0.10.0",
     "camunda-bpmn-moddle": "^7.0.1",
@@ -48,16 +48,16 @@
     "diagram-js": "^11.6.0",
     "echarts": "^5.4.1",
     "echarts-wordcloud": "^2.1.0",
-    "element-plus": "2.3.1",
+    "element-plus": "2.3.3",
     "fast-xml-parser": "^4.1.3",
     "highlight.js": "^11.7.0",
-    "intro.js": "^6.0.0",
+    "intro.js": "^7.0.1",
     "jsencrypt": "^3.3.2",
     "lodash-es": "^4.17.21",
     "min-dash": "^4.0.0",
     "mitt": "^3.0.0",
     "nprogress": "^0.2.0",
-    "pinia": "^2.0.33",
+    "pinia": "^2.0.34",
     "qrcode": "^1.5.1",
     "qs": "^6.11.1",
     "steady-xml": "^0.1.0",
@@ -68,7 +68,6 @@
     "vue-router": "^4.1.6",
     "vue-types": "^5.0.2",
     "vuedraggable": "^4.1.0",
-    "vxe-table": "^4.3.11",
     "web-storage-cache": "^1.1.1",
     "xe-utils": "^3.5.7",
     "xml-js": "^1.6.11"
@@ -126,7 +125,7 @@
     "vite-plugin-purge-icons": "^0.9.2",
     "vite-plugin-svg-icons": "^2.0.1",
     "vite-plugin-top-level-await": "^1.3.0",
-    "vite-plugin-vue-setup-extend": "^0.4.0",
+    "vite-plugin-vue-setup-extend-plus": "^0.1.0",
     "vite-plugin-windicss": "^1.8.10",
     "vue-tsc": "^1.2.0",
     "windicss": "^3.5.6"

+ 3 - 1
src/App.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="APP" setup>
 import { isDark } from '@/utils/is'
 import { useAppStore } from '@/store/modules/app'
 import { useDesign } from '@/hooks/web/useDesign'
@@ -32,6 +32,7 @@ $prefix-cls: #{$namespace}-app;
   width: 100%;
   height: 100%;
 }
+
 html,
 body {
   padding: 0 !important;
@@ -43,6 +44,7 @@ body {
     @extend .size;
   }
 }
+
 .#{$prefix-cls}-grey-mode {
   filter: grayscale(100%);
 }

+ 5 - 5
src/api/mall/product/category.ts

@@ -17,17 +17,17 @@ export interface CategoryVO {
    */
   name: string
   /**
-   * 分类图
+   * 移动端分类图
    */
   picUrl: string
   /**
-   * 分类排序
+   * PC 端分类图
    */
-  sort?: number
+  bigPicUrl?: string
   /**
-   * 分类描述
+   * 分类排序
    */
-  description?: string
+  sort: number
   /**
    * 开启状态
    */

+ 39 - 0
src/api/mall/product/management/spu.ts

@@ -0,0 +1,39 @@
+import request from '@/config/axios'
+import type { SpuType } from './type/spuType' // TODO  @puhui999: type 和 api 一起放,简单一点哈~
+
+// TODO @puhui999:中英文之间有空格
+
+// 获得spu列表 TODO @puhui999:这个是 getSpuPage 哈
+export const getSpuList = (params: PageParam) => {
+  return request.get({ url: '/product/spu/page', params })
+}
+
+// 获得spu列表tabsCount
+export const getTabsCount = () => {
+  return request.get({ url: '/product/spu/tabsCount' })
+}
+
+// 创建商品spu
+export const createSpu = (data: SpuType) => {
+  return request.post({ url: '/product/spu/create', data })
+}
+
+// 更新商品spu
+export const updateSpu = (data: SpuType) => {
+  return request.put({ url: '/product/spu/update', data })
+}
+
+// 更新商品spu status
+export const updateStatus = (data: { id: number; status: number }) => {
+  return request.put({ url: '/product/spu/updateStatus', data })
+}
+
+// 获得商品 spu
+export const getSpu = (id: number) => {
+  return request.get({ url: `/product/spu/get-detail?id=${id}` })
+}
+
+// 删除商品Spu
+export const deleteSpu = (id: number) => {
+  return request.delete({ url: `/product/spu/delete?id=${id}` })
+}

+ 79 - 0
src/api/mall/product/management/type/skuType.ts

@@ -0,0 +1,79 @@
+export interface Property {
+  /**
+   * 属性编号
+   *
+   * 关联 {@link ProductPropertyDO#getId()}
+   */
+  propertyId?: number
+  /**
+   * 属性值编号
+   *
+   * 关联 {@link ProductPropertyValueDO#getId()}
+   */
+  valueId?: number
+  /**
+   * 属性值名称
+   */
+  valueName?: string
+}
+
+export interface SkuType {
+  /**
+   * 商品 SKU 编号,自增
+   */
+  id?: number
+  /**
+   * SPU 编号
+   */
+  spuId?: number
+  /**
+   * 属性数组,JSON 格式
+   */
+  properties?: Property[]
+  /**
+   * 商品价格,单位:分
+   */
+  price?: number
+  /**
+   * 市场价,单位:分
+   */
+  marketPrice?: number
+  /**
+   * 成本价,单位:分
+   */
+  costPrice?: number
+  /**
+   * 商品条码
+   */
+  barCode?: string
+  /**
+   * 图片地址
+   */
+  picUrl?: string
+  /**
+   * 库存
+   */
+  stock?: number
+  /**
+   * 商品重量,单位:kg 千克
+   */
+  weight?: number
+  /**
+   * 商品体积,单位:m^3 平米
+   */
+  volume?: number
+
+  /**
+   * 一级分销的佣金,单位:分
+   */
+  subCommissionFirstPrice?: number
+  /**
+   * 二级分销的佣金,单位:分
+   */
+  subCommissionSecondPrice?: number
+
+  /**
+   * 商品销量
+   */
+  salesCount?: number
+}

+ 25 - 0
src/api/mall/product/management/type/spuType.ts

@@ -0,0 +1,25 @@
+import { SkuType } from './skuType'
+
+export interface SpuType {
+  id?: number
+  name?: string // 商品名称
+  categoryId?: number | null // 商品分类
+  keyword?: string // 关键字
+  unit?: number | null // 单位
+  picUrl?: string // 商品封面图
+  sliderPicUrls?: string[] // 商品轮播图
+  introduction?: string // 商品简介
+  deliveryTemplateId?: number // 运费模版
+  specType?: boolean // 商品规格
+  subCommissionType?: boolean // 分销类型
+  skus: SkuType[] // sku数组
+  description?: string // 商品详情
+  sort?: string // 商品排序
+  giveIntegral?: number // 赠送积分
+  virtualSalesCount?: number // 虚拟销量
+  recommendHot?: boolean // 是否热卖
+  recommendBenefit?: boolean // 是否优惠
+  recommendBest?: boolean // 是否精品
+  recommendNew?: boolean // 是否新品
+  recommendGood?: boolean // 是否优品
+}

+ 2 - 2
src/api/mall/product/property.ts

@@ -71,8 +71,8 @@ export const getPropertyList = (params: any) => {
 }
 
 // 获得属性项列表
-export const getPropertyListAndValue = (params: any) => {
-  return request.get({ url: '/product/property/get-value-list', params })
+export const getPropertyListAndValue = (data: any) => {
+  return request.post({ url: '/product/property/get-value-list', data })
 }
 
 // ------------------------ 属性值 -------------------

+ 1 - 1
src/api/mp/account/index.ts

@@ -1,7 +1,7 @@
 import request from '@/config/axios'
 
 export interface AccountVO {
-  id?: number
+  id: number
   name: string
 }
 

+ 2 - 2
src/api/pay/merchant/index.ts

@@ -39,9 +39,9 @@ export const getMerchant = (id: number) => {
 }
 
 // 根据商户名称搜索商户列表
-export const getMerchantListByName = (name: string) => {
+export const getMerchantListByName = (name?: string) => {
   return request.get({
-    url: '/pay/merchant/list-by-name?id=',
+    url: '/pay/merchant/list-by-name',
     params: {
       name: name
     }

+ 5 - 0
src/api/pay/order/index.ts

@@ -88,6 +88,11 @@ export const getOrder = async (id: number) => {
   return await request.get({ url: '/pay/order/get?id=' + id })
 }
 
+// 获得支付订单的明细
+export const getOrderDetail = async (id: number) => {
+  return await request.get({ url: '/pay/order/get-detail?id=' + id })
+}
+
 // 新增支付订单
 export const createOrder = async (data: OrderVO) => {
   return await request.post({ url: '/pay/order/create', data })

+ 8 - 14
src/api/system/notify/template/index.ts

@@ -1,8 +1,9 @@
 import request from '@/config/axios'
 
 export interface NotifyTemplateVO {
-  id: number
+  id?: number
   name: string
+  nickname: string
   code: string
   content: string
   type: number
@@ -11,36 +12,29 @@ export interface NotifyTemplateVO {
   remark: string
 }
 
-export interface NotifyTemplatePageReqVO extends PageParam {
-  name?: string
-  code?: string
-  status?: number
-  createTime?: Date[]
-}
-
 export interface NotifySendReqVO {
-  userId: number
+  userId: number | null
   templateCode: string
   templateParams: Map<String, Object>
 }
 
 // 查询站内信模板列表
-export const getNotifyTemplatePageApi = async (params: NotifyTemplatePageReqVO) => {
+export const getNotifyTemplatePage = async (params: PageParam) => {
   return await request.get({ url: '/system/notify-template/page', params })
 }
 
 // 查询站内信模板详情
-export const getNotifyTemplateApi = async (id: number) => {
+export const getNotifyTemplate = async (id: number) => {
   return await request.get({ url: '/system/notify-template/get?id=' + id })
 }
 
 // 新增站内信模板
-export const createNotifyTemplateApi = async (data: NotifyTemplateVO) => {
+export const createNotifyTemplate = async (data: NotifyTemplateVO) => {
   return await request.post({ url: '/system/notify-template/create', data })
 }
 
 // 修改站内信模板
-export const updateNotifyTemplateApi = async (data: NotifyTemplateVO) => {
+export const updateNotifyTemplate = async (data: NotifyTemplateVO) => {
   return await request.put({ url: '/system/notify-template/update', data })
 }
 
@@ -50,6 +44,6 @@ export const deleteNotifyTemplateApi = async (id: number) => {
 }
 
 // 发送站内信
-export const sendNotifyApi = (data: NotifySendReqVO) => {
+export const sendNotify = (data: NotifySendReqVO) => {
   return request.post({ url: '/system/notify-template/send-notify', data })
 }

+ 1 - 1
src/components/Backtop/src/Backtop.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="BackTop" setup>
 import { ElBacktop } from 'element-plus'
 import { useDesign } from '@/hooks/web/useDesign'
 

+ 2 - 2
src/components/ConfigGlobal/src/ConfigGlobal.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="ConfigGlobal" setup>
 import { propTypes } from '@/utils/propTypes'
 import { useLocaleStore } from '@/store/modules/locale'
 import { useAppStore } from '@/store/modules/app'
@@ -51,9 +51,9 @@ const currentLocale = computed(() => localeStore.currentLocale)
 
 <template>
   <ElConfigProvider
-    :namespace="variables.elNamespace"
     :locale="currentLocale.elLocale"
     :message="{ max: 1 }"
+    :namespace="variables.elNamespace"
     :size="size"
   >
     <slot></slot>

+ 6 - 4
src/components/ContentDetailWrap/src/ContentDetailWrap.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="ContentDetailWrap" setup>
 import { propTypes } from '@/utils/propTypes'
 import { useDesign } from '@/hooks/web/useDesign'
 
@@ -21,7 +21,7 @@ onMounted(() => {
 </script>
 
 <template>
-  <div :class="[`${prefixCls}-container`]" ref="contentDetailWrap">
+  <div ref="contentDetailWrap" :class="[`${prefixCls}-container`]">
     <Sticky :offset="offset">
       <div
         :class="[
@@ -31,7 +31,7 @@ onMounted(() => {
       >
         <div :class="[`${prefixCls}-header__back`, 'flex pl-10px pr-10px ']">
           <ElButton @click="emit('back')">
-            <Icon icon="ep:arrow-left" class="mr-5px" />
+            <Icon class="mr-5px" icon="ep:arrow-left" />
             {{ t('common.back') }}
           </ElButton>
         </div>
@@ -47,7 +47,9 @@ onMounted(() => {
     </Sticky>
     <div style="padding: var(--app-content-padding)">
       <ElCard :class="[`${prefixCls}-body`, 'mb-20px']" shadow="never">
-        <div> <slot></slot> </div>
+        <div>
+          <slot></slot>
+        </div>
       </ElCard>
     </div>
   </div>

+ 2 - 2
src/components/ContentWrap/src/ContentWrap.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="ContentWrap" setup>
 import { propTypes } from '@/utils/propTypes'
 import { useDesign } from '@/hooks/web/useDesign'
 
@@ -21,7 +21,7 @@ defineProps({
           <template #content>
             <div class="max-w-200px">{{ message }}</div>
           </template>
-          <Icon class="ml-5px" icon="ep:question-filled" :size="14" />
+          <Icon :size="14" class="ml-5px" icon="ep:question-filled" />
         </ElTooltip>
       </div>
     </template>

+ 1 - 1
src/components/CountTo/src/CountTo.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="CountTo" setup>
 import { PropType } from 'vue'
 import { isNumber } from '@/utils/is'
 import { propTypes } from '@/utils/propTypes'

+ 55 - 47
src/components/Crontab/src/Crontab.vue

@@ -1,10 +1,12 @@
-<script setup lang="ts">
+<script lang="ts" name="Crontab" setup>
 import { ElMessage } from 'element-plus'
 import { PropType } from 'vue'
+
 interface shortcutsType {
   text: string
   value: string
 }
+
 const props = defineProps({
   modelValue: {
     type: String,
@@ -501,7 +503,7 @@ const submit = () => {
 }
 </script>
 <template>
-  <el-input v-model="defaultValue" v-bind="$attrs" class="input-with-select">
+  <el-input v-model="defaultValue" class="input-with-select" v-bind="$attrs">
     <template #append>
       <el-select v-model="select" placeholder="生成器" style="width: 115px">
         <el-option label="每分钟" value="0 * * * * ?" />
@@ -522,11 +524,11 @@ const submit = () => {
   </el-input>
 
   <el-dialog
-    title="cron规则生成器"
     v-model="dialogVisible"
     :width="580"
-    destroy-on-close
     append-to-body
+    destroy-on-close
+    title="cron规则生成器"
   >
     <div class="sc-cron">
       <el-tabs>
@@ -546,38 +548,38 @@ const submit = () => {
                 <el-radio-button label="3">指定</el-radio-button>
               </el-radio-group>
             </el-form-item>
-            <el-form-item label="范围" v-if="cronValue.second.type == '1'">
+            <el-form-item v-if="cronValue.second.type == '1'" label="范围">
               <el-input-number
                 v-model="cronValue.second.range.start"
-                :min="0"
                 :max="59"
+                :min="0"
                 controls-position="right"
               />
               <span style="padding: 0 15px">-</span>
               <el-input-number
                 v-model="cronValue.second.range.end"
-                :min="0"
                 :max="59"
+                :min="0"
                 controls-position="right"
               />
             </el-form-item>
-            <el-form-item label="间隔" v-if="cronValue.second.type == '2'">
+            <el-form-item v-if="cronValue.second.type == '2'" label="间隔">
               <el-input-number
                 v-model="cronValue.second.loop.start"
-                :min="0"
                 :max="59"
+                :min="0"
                 controls-position="right"
               />
               秒开始,每
               <el-input-number
                 v-model="cronValue.second.loop.end"
-                :min="0"
                 :max="59"
+                :min="0"
                 controls-position="right"
               />
               秒执行一次
             </el-form-item>
-            <el-form-item label="指定" v-if="cronValue.second.type == '3'">
+            <el-form-item v-if="cronValue.second.type == '3'" label="指定">
               <el-select v-model="cronValue.second.appoint" multiple style="width: 100%">
                 <el-option
                   v-for="(item, index) in data.second"
@@ -605,38 +607,38 @@ const submit = () => {
                 <el-radio-button label="3">指定</el-radio-button>
               </el-radio-group>
             </el-form-item>
-            <el-form-item label="范围" v-if="cronValue.minute.type == '1'">
+            <el-form-item v-if="cronValue.minute.type == '1'" label="范围">
               <el-input-number
                 v-model="cronValue.minute.range.start"
-                :min="0"
                 :max="59"
+                :min="0"
                 controls-position="right"
               />
               <span style="padding: 0 15px">-</span>
               <el-input-number
                 v-model="cronValue.minute.range.end"
-                :min="0"
                 :max="59"
+                :min="0"
                 controls-position="right"
               />
             </el-form-item>
-            <el-form-item label="间隔" v-if="cronValue.minute.type == '2'">
+            <el-form-item v-if="cronValue.minute.type == '2'" label="间隔">
               <el-input-number
                 v-model="cronValue.minute.loop.start"
-                :min="0"
                 :max="59"
+                :min="0"
                 controls-position="right"
               />
               分钟开始,每
               <el-input-number
                 v-model="cronValue.minute.loop.end"
-                :min="0"
                 :max="59"
+                :min="0"
                 controls-position="right"
               />
               分钟执行一次
             </el-form-item>
-            <el-form-item label="指定" v-if="cronValue.minute.type == '3'">
+            <el-form-item v-if="cronValue.minute.type == '3'" label="指定">
               <el-select v-model="cronValue.minute.appoint" multiple style="width: 100%">
                 <el-option
                   v-for="(item, index) in data.minute"
@@ -664,38 +666,38 @@ const submit = () => {
                 <el-radio-button label="3">指定</el-radio-button>
               </el-radio-group>
             </el-form-item>
-            <el-form-item label="范围" v-if="cronValue.hour.type == '1'">
+            <el-form-item v-if="cronValue.hour.type == '1'" label="范围">
               <el-input-number
                 v-model="cronValue.hour.range.start"
-                :min="0"
                 :max="23"
+                :min="0"
                 controls-position="right"
               />
               <span style="padding: 0 15px">-</span>
               <el-input-number
                 v-model="cronValue.hour.range.end"
-                :min="0"
                 :max="23"
+                :min="0"
                 controls-position="right"
               />
             </el-form-item>
-            <el-form-item label="间隔" v-if="cronValue.hour.type == '2'">
+            <el-form-item v-if="cronValue.hour.type == '2'" label="间隔">
               <el-input-number
                 v-model="cronValue.hour.loop.start"
-                :min="0"
                 :max="23"
+                :min="0"
                 controls-position="right"
               />
               小时开始,每
               <el-input-number
                 v-model="cronValue.hour.loop.end"
-                :min="0"
                 :max="23"
+                :min="0"
                 controls-position="right"
               />
               小时执行一次
             </el-form-item>
-            <el-form-item label="指定" v-if="cronValue.hour.type == '3'">
+            <el-form-item v-if="cronValue.hour.type == '3'" label="指定">
               <el-select v-model="cronValue.hour.appoint" multiple style="width: 100%">
                 <el-option
                   v-for="(item, index) in data.hour"
@@ -725,38 +727,38 @@ const submit = () => {
                 <el-radio-button label="5">不指定</el-radio-button>
               </el-radio-group>
             </el-form-item>
-            <el-form-item label="范围" v-if="cronValue.day.type == '1'">
+            <el-form-item v-if="cronValue.day.type == '1'" label="范围">
               <el-input-number
                 v-model="cronValue.day.range.start"
-                :min="1"
                 :max="31"
+                :min="1"
                 controls-position="right"
               />
               <span style="padding: 0 15px">-</span>
               <el-input-number
                 v-model="cronValue.day.range.end"
-                :min="1"
                 :max="31"
+                :min="1"
                 controls-position="right"
               />
             </el-form-item>
-            <el-form-item label="间隔" v-if="cronValue.day.type == '2'">
+            <el-form-item v-if="cronValue.day.type == '2'" label="间隔">
               <el-input-number
                 v-model="cronValue.day.loop.start"
-                :min="1"
                 :max="31"
+                :min="1"
                 controls-position="right"
               />
               号开始,每
               <el-input-number
                 v-model="cronValue.day.loop.end"
-                :min="1"
                 :max="31"
+                :min="1"
                 controls-position="right"
               />
               天执行一次
             </el-form-item>
-            <el-form-item label="指定" v-if="cronValue.day.type == '3'">
+            <el-form-item v-if="cronValue.day.type == '3'" label="指定">
               <el-select v-model="cronValue.day.appoint" multiple style="width: 100%">
                 <el-option
                   v-for="(item, index) in data.day"
@@ -784,38 +786,38 @@ const submit = () => {
                 <el-radio-button label="3">指定</el-radio-button>
               </el-radio-group>
             </el-form-item>
-            <el-form-item label="范围" v-if="cronValue.month.type == '1'">
+            <el-form-item v-if="cronValue.month.type == '1'" label="范围">
               <el-input-number
                 v-model="cronValue.month.range.start"
-                :min="1"
                 :max="12"
+                :min="1"
                 controls-position="right"
               />
               <span style="padding: 0 15px">-</span>
               <el-input-number
                 v-model="cronValue.month.range.end"
-                :min="1"
                 :max="12"
+                :min="1"
                 controls-position="right"
               />
             </el-form-item>
-            <el-form-item label="间隔" v-if="cronValue.month.type == '2'">
+            <el-form-item v-if="cronValue.month.type == '2'" label="间隔">
               <el-input-number
                 v-model="cronValue.month.loop.start"
-                :min="1"
                 :max="12"
+                :min="1"
                 controls-position="right"
               />
               月开始,每
               <el-input-number
                 v-model="cronValue.month.loop.end"
-                :min="1"
                 :max="12"
+                :min="1"
                 controls-position="right"
               />
               月执行一次
             </el-form-item>
-            <el-form-item label="指定" v-if="cronValue.month.type == '3'">
+            <el-form-item v-if="cronValue.month.type == '3'" label="指定">
               <el-select v-model="cronValue.month.appoint" multiple style="width: 100%">
                 <el-option
                   v-for="(item, index) in data.month"
@@ -846,7 +848,7 @@ const submit = () => {
                   <el-radio-button label="5">不指定</el-radio-button>
                 </el-radio-group>
               </el-form-item>
-              <el-form-item label="范围" v-if="cronValue.week.type == '1'">
+              <el-form-item v-if="cronValue.week.type == '1'" label="范围">
                 <el-select v-model="cronValue.week.range.start">
                   <el-option
                     v-for="(item, index) in data.week"
@@ -865,12 +867,12 @@ const submit = () => {
                   />
                 </el-select>
               </el-form-item>
-              <el-form-item label="间隔" v-if="cronValue.week.type == '2'">
+              <el-form-item v-if="cronValue.week.type == '2'" label="间隔">
                 <el-input-number
                   v-model="cronValue.week.loop.start"
-                  :min="1"
                   :max="4"
+                  :min="1"
                   controls-position="right"
                 />
                 周的星期
@@ -884,7 +886,7 @@ const submit = () => {
                 </el-select>
                 执行一次
               </el-form-item>
-              <el-form-item label="指定" v-if="cronValue.week.type == '3'">
+              <el-form-item v-if="cronValue.week.type == '3'" label="指定">
                 <el-select v-model="cronValue.week.appoint" multiple style="width: 100%">
                   <el-option
                     v-for="(item, index) in data.week"
@@ -894,7 +896,7 @@ const submit = () => {
                   />
                 </el-select>
               </el-form-item>
-              <el-form-item label="最后一周" v-if="cronValue.week.type == '4'">
+              <el-form-item v-if="cronValue.week.type == '4'" label="最后一周">
                 <el-select v-model="cronValue.week.last">
                   <el-option
                     v-for="(item, index) in data.week"
@@ -924,12 +926,12 @@ const submit = () => {
                 <el-radio-button label="3">指定</el-radio-button>
               </el-radio-group>
             </el-form-item>
-            <el-form-item label="范围" v-if="cronValue.year.type == '1'">
+            <el-form-item v-if="cronValue.year.type == '1'" label="范围">
               <el-input-number v-model="cronValue.year.range.start" controls-position="right" />
               <span style="padding: 0 15px">-</span>
               <el-input-number v-model="cronValue.year.range.end" controls-position="right" />
             </el-form-item>
-            <el-form-item label="间隔" v-if="cronValue.year.type == '2'">
+            <el-form-item v-if="cronValue.year.type == '2'" label="间隔">
               <el-input-number v-model="cronValue.year.loop.start" controls-position="right" />
               年开始,每
               <el-input-number
@@ -939,7 +941,7 @@ const submit = () => {
               />
               年执行一次
             </el-form-item>
-            <el-form-item label="指定" v-if="cronValue.year.type == '3'">
+            <el-form-item v-if="cronValue.year.type == '3'" label="指定">
               <el-select v-model="cronValue.year.appoint" multiple style="width: 100%">
                 <el-option
                   v-for="(item, index) in data.year"
@@ -968,16 +970,19 @@ const submit = () => {
   padding: 0 7px;
   vertical-align: bottom;
 }
+
 .sc-cron-num {
   text-align: center;
   margin-bottom: 15px;
   width: 100%;
 }
+
 .sc-cron-num h2 {
   font-size: 12px;
   margin-bottom: 15px;
   font-weight: normal;
 }
+
 .sc-cron-num h4 {
   display: block;
   height: 32px;
@@ -988,13 +993,16 @@ const submit = () => {
   background: var(--el-color-primary-light-9);
   border-radius: 4px;
 }
+
 .sc-cron:deep(.el-tabs__item.is-active) .sc-cron-num h4 {
   background: var(--el-color-primary);
   color: #fff;
 }
+
 [data-theme='dark'] .sc-cron-num h4 {
   background: var(--el-color-white);
 }
+
 .input-with-select .el-input-group__prepend {
   background-color: var(--el-fill-color-blank);
 }

+ 26 - 23
src/components/Cropper/src/CopperModal.vue

@@ -2,26 +2,26 @@
   <div>
     <Dialog
       v-model="dialogVisible"
+      :canFullscreen="false"
       :title="t('cropper.modalTitle')"
-      width="800px"
       maxHeight="380px"
-      :canFullscreen="false"
+      width="800px"
     >
       <div :class="prefixCls">
         <div :class="`${prefixCls}-left`">
           <div :class="`${prefixCls}-cropper`">
             <CropperImage
               v-if="src"
+              :circled="circled"
               :src="src"
               height="300px"
-              :circled="circled"
               @cropend="handleCropend"
               @ready="handleReady"
             />
           </div>
 
           <div :class="`${prefixCls}-toolbar`">
-            <el-upload :fileList="[]" accept="image/*" :beforeUpload="handleBeforeUpload">
+            <el-upload :beforeUpload="handleBeforeUpload" :fileList="[]" accept="image/*">
               <el-tooltip :content="t('cropper.selectImage')" placement="bottom">
                 <XButton preIcon="ant-design:upload-outlined" type="primary" />
               </el-tooltip>
@@ -29,64 +29,64 @@
             <el-space>
               <el-tooltip :content="t('cropper.btn_reset')" placement="bottom">
                 <XButton
-                  type="primary"
+                  :disabled="!src"
                   preIcon="ant-design:reload-outlined"
                   size="small"
-                  :disabled="!src"
+                  type="primary"
                   @click="handlerToolbar('reset')"
                 />
               </el-tooltip>
               <el-tooltip :content="t('cropper.btn_rotate_left')" placement="bottom">
                 <XButton
-                  type="primary"
+                  :disabled="!src"
                   preIcon="ant-design:rotate-left-outlined"
                   size="small"
-                  :disabled="!src"
+                  type="primary"
                   @click="handlerToolbar('rotate', -45)"
                 />
               </el-tooltip>
               <el-tooltip :content="t('cropper.btn_rotate_right')" placement="bottom">
                 <XButton
-                  type="primary"
+                  :disabled="!src"
                   preIcon="ant-design:rotate-right-outlined"
                   size="small"
-                  :disabled="!src"
+                  type="primary"
                   @click="handlerToolbar('rotate', 45)"
                 />
               </el-tooltip>
               <el-tooltip :content="t('cropper.btn_scale_x')" placement="bottom">
                 <XButton
-                  type="primary"
+                  :disabled="!src"
                   preIcon="vaadin:arrows-long-h"
                   size="small"
-                  :disabled="!src"
+                  type="primary"
                   @click="handlerToolbar('scaleX')"
                 />
               </el-tooltip>
               <el-tooltip :content="t('cropper.btn_scale_y')" placement="bottom">
                 <XButton
-                  type="primary"
+                  :disabled="!src"
                   preIcon="vaadin:arrows-long-v"
                   size="small"
-                  :disabled="!src"
+                  type="primary"
                   @click="handlerToolbar('scaleY')"
                 />
               </el-tooltip>
               <el-tooltip :content="t('cropper.btn_zoom_in')" placement="bottom">
                 <XButton
-                  type="primary"
+                  :disabled="!src"
                   preIcon="ant-design:zoom-in-outlined"
                   size="small"
-                  :disabled="!src"
+                  type="primary"
                   @click="handlerToolbar('zoom', 0.1)"
                 />
               </el-tooltip>
               <el-tooltip :content="t('cropper.btn_zoom_out')" placement="bottom">
                 <XButton
-                  type="primary"
+                  :disabled="!src"
                   preIcon="ant-design:zoom-out-outlined"
                   size="small"
-                  :disabled="!src"
+                  type="primary"
                   @click="handlerToolbar('zoom', -0.1)"
                 />
               </el-tooltip>
@@ -95,14 +95,14 @@
         </div>
         <div :class="`${prefixCls}-right`">
           <div :class="`${prefixCls}-preview`">
-            <img :src="previewSource" v-if="previewSource" :alt="t('cropper.preview')" />
+            <img v-if="previewSource" :alt="t('cropper.preview')" :src="previewSource" />
           </div>
           <template v-if="previewSource">
             <div :class="`${prefixCls}-group`">
               <el-avatar :src="previewSource" size="large" />
-              <el-avatar :src="previewSource" :size="48" />
-              <el-avatar :src="previewSource" :size="64" />
-              <el-avatar :src="previewSource" :size="80" />
+              <el-avatar :size="48" :src="previewSource" />
+              <el-avatar :size="64" :src="previewSource" />
+              <el-avatar :size="80" :src="previewSource" />
             </div>
           </template>
         </div>
@@ -113,7 +113,7 @@
     </Dialog>
   </div>
 </template>
-<script setup lang="ts">
+<script lang="ts" name="CopperModal" setup>
 import { useDesign } from '@/hooks/web/useDesign'
 import { dataURLtoBlob } from '@/utils/filt'
 import { useI18n } from 'vue-i18n'
@@ -173,12 +173,15 @@ async function handleOk() {
   const blob = dataURLtoBlob(previewSource.value)
   emit('uploadSuccess', { source: previewSource.value, data: blob, filename: filename })
 }
+
 function openModal() {
   dialogVisible.value = true
 }
+
 function closeModal() {
   dialogVisible.value = false
 }
+
 defineExpose({ openModal, closeModal })
 </script>
 <style lang="scss">

+ 2 - 2
src/components/Cropper/src/Cropper.vue

@@ -3,14 +3,14 @@
     <img
       v-show="isReady"
       ref="imgElRef"
-      :src="src"
       :alt="alt"
       :crossorigin="crossorigin"
+      :src="src"
       :style="getImageStyle"
     />
   </div>
 </template>
-<script setup lang="ts">
+<script lang="ts" name="Cropper" setup>
 import { CSSProperties, PropType } from 'vue'
 import Cropper from 'cropperjs'
 import 'cropperjs/dist/cropper.css'

+ 10 - 4
src/components/Cropper/src/CropperAvatar.vue

@@ -1,17 +1,17 @@
 <template>
   <div class="user-info-head" @click="open()">
-    <img :src="sourceValue" v-if="sourceValue" class="img-circle img-lg" alt="avatar" />
-    <el-button :class="`${prefixCls}-upload-btn`" @click="open()" v-if="showBtn">
+    <img v-if="sourceValue" :src="sourceValue" alt="avatar" class="img-circle img-lg" />
+    <el-button v-if="showBtn" :class="`${prefixCls}-upload-btn`" @click="open()">
       {{ btnText ? btnText : t('cropper.selectImage') }}
     </el-button>
     <CopperModal
       ref="cropperModelRef"
-      @upload-success="handleUploadSuccess"
       :srcValue="sourceValue"
+      @upload-success="handleUploadSuccess"
     />
   </div>
 </template>
-<script setup lang="ts">
+<script lang="ts" name="CropperAvatar" setup>
 import { useDesign } from '@/hooks/web/useDesign'
 
 import { propTypes } from '@/utils/propTypes'
@@ -54,9 +54,11 @@ function handleUploadSuccess({ source, data, filename }) {
 function open() {
   cropperModelRef.value.openModal()
 }
+
 function close() {
   cropperModelRef.value.closeModal()
 }
+
 defineExpose({
   open,
   close
@@ -104,17 +106,21 @@ $prefix-cls: #{$namespace}--cropper-avatar;
     margin: 10px auto;
   }
 }
+
 .user-info-head {
   position: relative;
   display: inline-block;
 }
+
 .img-circle {
   border-radius: 50%;
 }
+
 .img-lg {
   width: 120px;
   height: 120px;
 }
+
 .user-info-head:hover:after {
   content: '+';
   position: absolute;

+ 5 - 5
src/components/Descriptions/src/Descriptions.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="Descriptions" setup>
 import { PropType } from 'vue'
 import dayjs from 'dayjs'
 import { useDesign } from '@/hooks/web/useDesign'
@@ -84,7 +84,7 @@ const toggleClick = () => {
         <div class="flex items-center">
           {{ title }}
           <ElTooltip v-if="message" :content="message" placement="right">
-            <Icon icon="ep:warning" class="ml-5px" />
+            <Icon class="ml-5px" icon="ep:warning" />
           </ElTooltip>
         </div>
       </div>
@@ -95,8 +95,8 @@ const toggleClick = () => {
       <div v-show="show" :class="[`${prefixCls}-content`, 'p-10px']">
         <ElDescriptions
           :column="props.columns"
-          border
           :direction="mobile ? 'vertical' : 'horizontal'"
+          border
           v-bind="getBindValue"
         >
           <template v-if="slots['extra']" #extra>
@@ -114,8 +114,8 @@ const toggleClick = () => {
                 :row="{
                   label: item.label
                 }"
-                >{{ item.label }}</slot
-              >
+                >{{ item.label }}
+              </slot>
             </template>
 
             <template #default>

+ 7 - 7
src/components/Dialog/src/Dialog.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="Dialog" setup>
 import { propTypes } from '@/utils/propTypes'
 import { isNumber } from '@/utils/is'
 
@@ -59,13 +59,13 @@ const dialogStyle = computed(() => {
 
 <template>
   <ElDialog
-    v-bind="getBindValue"
+    :close-on-click-modal="true"
     :fullscreen="isFullscreen"
+    :width="width"
     destroy-on-close
-    lock-scroll
     draggable
-    :width="width"
-    :close-on-click-modal="true"
+    lock-scroll
+    v-bind="getBindValue"
   >
     <template #header>
       <div class="flex justify-between">
@@ -74,8 +74,8 @@ const dialogStyle = computed(() => {
         </slot>
         <Icon
           v-if="fullscreen"
-          class="mr-22px cursor-pointer is-hover mt-2px z-10"
           :icon="isFullscreen ? 'zmdi:fullscreen-exit' : 'zmdi:fullscreen'"
+          class="mr-22px cursor-pointer is-hover mt-2px z-10"
           color="var(--el-color-info)"
           @click="toggleFull"
         />
@@ -83,7 +83,7 @@ const dialogStyle = computed(() => {
     </template>
 
     <!-- 情况一:如果 scroll 为 true,说明开启滚动条 -->
-    <ElScrollbar :style="dialogStyle" v-if="scroll">
+    <ElScrollbar v-if="scroll" :style="dialogStyle">
       <slot></slot>
     </ElScrollbar>
     <!-- 情况二:如果 scroll 为 false,说明关闭滚动条滚动条 -->

+ 1 - 1
src/components/Echart/src/Echart.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="EChart" setup>
 import type { EChartsOption } from 'echarts'
 import echarts from '@/plugins/echarts'
 import { debounce } from 'lodash-es'

+ 5 - 4
src/components/Editor/src/Editor.vue

@@ -1,7 +1,7 @@
-<script setup lang="ts">
+<script lang="ts" name="Editor" setup>
 import { PropType } from 'vue'
 import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
-import { IDomEditor, IEditorConfig, i18nChangeLanguage } from '@wangeditor/editor'
+import { i18nChangeLanguage, IDomEditor, IEditorConfig } from '@wangeditor/editor'
 import { propTypes } from '@/utils/propTypes'
 import { isNumber } from '@/utils/is'
 import { ElMessage } from 'element-plus'
@@ -20,7 +20,7 @@ const props = defineProps({
   editorId: propTypes.string.def('wangeEditor-1'),
   height: propTypes.oneOfType([Number, String]).def('500px'),
   editorConfig: {
-    type: Object as PropType<IEditorConfig>,
+    type: Object as PropType<Partial<IEditorConfig>>,
     default: () => undefined
   },
   readonly: propTypes.bool.def(false),
@@ -147,6 +147,7 @@ const editorConfig = computed((): IEditorConfig => {
     props.editorConfig || {}
   )
 })
+
 const editorStyle = computed(() => {
   return {
     height: isNumber(props.height) ? `${props.height}px` : props.height
@@ -188,8 +189,8 @@ defineExpose({
     <!-- 编辑器 -->
     <Editor
       v-model="valueHtml"
-      :editorId="editorId"
       :defaultConfig="editorConfig"
+      :editorId="editorId"
       :style="editorStyle"
       @on-change="handleChange"
       @on-created="handleCreated"

+ 2 - 2
src/components/Error/src/Error.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="Error" setup>
 import pageError from '@/assets/svgs/404.svg'
 import networkError from '@/assets/svgs/500.svg'
 import noPermission from '@/assets/svgs/403.svg'
@@ -46,7 +46,7 @@ const btnClick = () => {
 <template>
   <div class="flex justify-center">
     <div class="text-center">
-      <img width="350" :src="errorMap[type].url" alt="" />
+      <img :src="errorMap[type].url" alt="" width="350" />
       <div class="text-14px text-[var(--el-color-info)]">{{ errorMap[type].message }}</div>
       <div class="mt-20px">
         <ElButton type="primary" @click="btnClick">{{ errorMap[type].buttonText }}</ElButton>

+ 4 - 4
src/components/Form/src/helper.ts

@@ -1,6 +1,6 @@
 import type { Slots } from 'vue'
 import { getSlot } from '@/utils/tsxHelper'
-import { PlaceholderMoel } from './types'
+import { PlaceholderModel } from './types'
 import { FormSchema } from '@/types/form'
 import { ColProps } from '@/types/components'
 
@@ -10,7 +10,7 @@ import { ColProps } from '@/types/components'
  * @returns 返回提示信息对象
  * @description 用于自动设置placeholder
  */
-export const setTextPlaceholder = (schema: FormSchema): PlaceholderMoel => {
+export const setTextPlaceholder = (schema: FormSchema): PlaceholderModel => {
   const { t } = useI18n()
   const textMap = ['Input', 'Autocomplete', 'InputNumber', 'InputPassword']
   const selectMap = ['Select', 'SelectV2', 'TimePicker', 'DatePicker', 'TimeSelect', 'TimeSelect']
@@ -108,8 +108,8 @@ export const setItemComponentSlots = (
 /**
  *
  * @param schema Form表单结构化数组
- * @param formModel FormMoel
- * @returns FormMoel
+ * @param formModel FormModel
+ * @returns FormModel
  * @description 生成对应的formModel
  */
 export const initModel = (schema: FormSchema[], formModel: Recordable) => {

+ 1 - 1
src/components/Form/src/types.ts

@@ -1,6 +1,6 @@
 import { FormSchema } from '@/types/form'
 
-export interface PlaceholderMoel {
+export interface PlaceholderModel {
   placeholder?: string
   startPlaceholder?: string
   endPlaceholder?: string

+ 3 - 3
src/components/IFrame/src/IFrame.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="IFrame" setup>
 import { propTypes } from '@/utils/propTypes'
 
 const props = defineProps({
@@ -20,11 +20,11 @@ onMounted(() => {
 <template>
   <div v-loading="loading" :style="'height:' + height">
     <iframe
+      ref="frameRef"
       :src="props.src"
-      style="width: 100%; height: 100%"
       frameborder="no"
       scrolling="auto"
-      ref="frameRef"
+      style="width: 100%; height: 100%"
     ></iframe>
   </div>
 </template>

+ 2 - 2
src/components/Icon/src/Icon.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="Icon" setup>
 import { propTypes } from '@/utils/propTypes'
 import Iconify from '@purge-icons/generated'
 import { useDesign } from '@/hooks/web/useDesign'
@@ -72,7 +72,7 @@ watch(
 
 <template>
   <ElIcon :class="prefixCls" :color="color" :size="size">
-    <svg v-if="isLocal" aria-hidden="true" :class="getSvgClass">
+    <svg v-if="isLocal" :class="getSvgClass" aria-hidden="true">
       <use :xlink:href="symbolId" />
     </svg>
 

+ 12 - 12
src/components/Icon/src/IconSelect.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="IconSelect" setup>
 import { CSSProperties } from 'vue'
 import { cloneDeep } from 'lodash-es'
 import { IconJson } from '@/components/Icon/src/data'
@@ -95,7 +95,7 @@ watch(
     return props.modelValue
   },
   () => {
-    if (props.modelValue) {
+    if (props.modelValue && props.modelValue.indexOf(':') >= 0) {
       currentActiveType.value = props.modelValue.substring(0, props.modelValue.indexOf(':') + 1)
       icon.value = props.modelValue.substring(props.modelValue.indexOf(':') + 1)
     }
@@ -116,13 +116,13 @@ watch(
     <ElInput v-model="inputValue" @click="visible = !visible">
       <template #append>
         <ElPopover
-          :width="350"
-          trigger="click"
-          popper-class="pure-popper"
           :popper-options="{
             placement: 'auto'
           }"
           :visible="visible"
+          :width="350"
+          popper-class="pure-popper"
+          trigger="click"
         >
           <template #reference>
             <div
@@ -133,7 +133,7 @@ watch(
             </div>
           </template>
 
-          <ElInput class="p-2" v-model="filterValue" placeholder="搜索图标" clearable />
+          <ElInput v-model="filterValue" class="p-2" clearable placeholder="搜索图标" />
           <ElDivider border-style="dashed" />
 
           <ElTabs v-model="currentActiveType" @tab-click="handleClick">
@@ -143,15 +143,15 @@ watch(
               :label="pane.label"
               :name="pane.name"
             >
-              <ElDivider class="tab-divider" border-style="dashed" />
+              <ElDivider border-style="dashed" class="tab-divider" />
               <ElScrollbar height="220px">
                 <ul class="flex flex-wrap px-2 ml-2">
                   <li
                     v-for="(item, key) in pageList"
                     :key="key"
+                    :style="iconItemStyle(item)"
                     :title="item"
                     class="icon-item p-2 w-1/10 cursor-pointer mr-2 mt-1 flex justify-center items-center border border-solid"
-                    :style="iconItemStyle(item)"
                     @click="onChangeIcon(item)"
                   >
                     <Icon :icon="currentActiveType + item" />
@@ -163,13 +163,13 @@ watch(
           <ElDivider border-style="dashed" />
 
           <ElPagination
-            small
-            :total="iconCount"
-            :page-size="pageSize"
             :current-page="currentPage"
+            :page-size="pageSize"
+            :total="iconCount"
             background
-            layout="prev, pager, next"
             class="flex items-center justify-center h-10"
+            layout="prev, pager, next"
+            small
             @current-change="onCurrentChange"
           />
         </ElPopover>

+ 1 - 1
src/components/ImageViewer/src/ImageViewer.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="ImageViewer" setup>
 import { PropType } from 'vue'
 import { propTypes } from '@/utils/propTypes'
 

+ 3 - 3
src/components/Infotip/src/Infotip.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="InfoTip" setup>
 import { PropType } from 'vue'
 import { useDesign } from '@/hooks/web/useDesign'
 import { propTypes } from '@/utils/propTypes'
@@ -34,14 +34,14 @@ const keyClick = (key: string) => {
     ]"
   >
     <div v-if="title" :class="[`${prefixCls}__header`, 'flex items-center']">
-      <Icon icon="ep:warning-filled" :size="22" color="var(--el-color-primary)" />
+      <Icon :size="22" color="var(--el-color-primary)" icon="ep:warning-filled" />
       <span :class="[`${prefixCls}__title`, 'pl-5px text-16px font-bold']">{{ title }}</span>
     </div>
     <div :class="`${prefixCls}__content`">
       <p v-for="(item, $index) in schema" :key="$index" class="text-14px mt-15px">
         <Highlight
-          :keys="typeof item === 'string' ? [] : item.keys"
           :color="highlightColor"
+          :keys="typeof item === 'string' ? [] : item.keys"
           @click="keyClick"
         >
           {{ showIndex ? `${$index + 1}、` : '' }}{{ typeof item === 'string' ? item : item.label }}

+ 4 - 4
src/components/InputPassword/src/InputPassword.vue

@@ -1,8 +1,8 @@
-<script setup lang="ts">
+<script lang="ts" name="InputPassword" setup>
 import { propTypes } from '@/utils/propTypes'
 import { useConfigGlobal } from '@/hooks/web/useConfigGlobal'
-import { zxcvbn } from '@zxcvbn-ts/core'
 import type { ZxcvbnResult } from '@zxcvbn-ts/core'
+import { zxcvbn } from '@zxcvbn-ts/core'
 import { useDesign } from '@/hooks/web/useDesign'
 
 const { getPrefixCls } = useDesign()
@@ -57,9 +57,9 @@ const getIconName = computed(() => (unref(textType) === 'password' ? 'ep:hide' :
 
 <template>
   <div :class="[prefixCls, `${prefixCls}--${configGlobal?.size}`]">
-    <ElInput v-bind="$attrs" v-model="valueRef" :type="textType">
+    <ElInput v-model="valueRef" :type="textType" v-bind="$attrs">
       <template #suffix>
-        <Icon class="el-input__icon cursor-pointer" :icon="getIconName" @click="changeTextType" />
+        <Icon :icon="getIconName" class="el-input__icon cursor-pointer" @click="changeTextType" />
       </template>
     </ElInput>
     <div

+ 5 - 5
src/components/Pagination/index.vue

@@ -2,19 +2,19 @@
 <template>
   <el-pagination
     v-show="total > 0"
-    class="float-right mt-15px mb-15px"
-    :background="true"
-    layout="total, sizes, prev, pager, next, jumper"
-    :page-sizes="[10, 20, 30, 50, 100]"
     v-model:current-page="currentPage"
     v-model:page-size="pageSize"
+    :background="true"
+    :page-sizes="[10, 20, 30, 50, 100]"
     :pager-count="pagerCount"
     :total="total"
+    class="float-right mt-15px mb-15px"
+    layout="total, sizes, prev, pager, next, jumper"
     @size-change="handleSizeChange"
     @current-change="handleCurrentChange"
   />
 </template>
-<script setup>
+<script name="Pagination" setup>
 import { computed } from 'vue'
 
 const props = defineProps({

+ 4 - 5
src/components/Qrcode/src/Qrcode.vue

@@ -1,7 +1,6 @@
-<script setup lang="ts">
-import { PropType, nextTick, ref, watch, computed, unref } from 'vue'
-import QRCode from 'qrcode'
-import { QRCodeRenderersOptions } from 'qrcode'
+<script lang="ts" name="Qrcode" setup>
+import { computed, nextTick, PropType, ref, unref, watch } from 'vue'
+import QRCode, { QRCodeRenderersOptions } from 'qrcode'
 import { cloneDeep } from 'lodash-es'
 import { propTypes } from '@/utils/propTypes'
 import { useDesign } from '@/hooks/web/useDesign'
@@ -230,7 +229,7 @@ const disabledClick = () => {
       @click="disabledClick"
     >
       <div class="absolute top-[50%] left-[50%] font-bold">
-        <Icon icon="ep:refresh-right" :size="30" color="var(--el-color-primary)" />
+        <Icon :size="30" color="var(--el-color-primary)" icon="ep:refresh-right" />
         <div>{{ disabledText }}</div>
       </div>
     </div>

+ 12 - 12
src/components/Search/src/Search.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="Search" setup>
 import { PropType } from 'vue'
 import { propTypes } from '@/utils/propTypes'
 
@@ -100,25 +100,25 @@ const setVisible = () => {
 <template>
   <!-- update by 芋艿:class="-mb-15px" 用于降低和 ContentWrap 组件的底部距离,避免空隙过大 -->
   <Form
-    :is-custom="false"
-    :label-width="labelWidth"
-    hide-required-asterisk
     :inline="inline"
     :is-col="isCol"
+    :is-custom="false"
+    :label-width="labelWidth"
     :schema="newSchema"
-    @register="register"
     class="-mb-15px"
+    hide-required-asterisk
+    @register="register"
   >
     <template #action>
       <div v-if="layout === 'inline'">
         <!-- update by 芋艿:去除搜索的 type="primary",颜色变淡一点 -->
         <ElButton v-if="showSearch" @click="search">
-          <Icon icon="ep:search" class="mr-5px" />
+          <Icon class="mr-5px" icon="ep:search" />
           {{ t('common.query') }}
         </ElButton>
         <!-- update by 芋艿:将 icon="ep:refresh-right" 修改成 icon="ep:refresh",和 ruoyi-vue 搜索保持一致  -->
         <ElButton v-if="showReset" @click="reset">
-          <Icon icon="ep:refresh" class="mr-5px" />
+          <Icon class="mr-5px" icon="ep:refresh" />
           {{ t('common.reset') }}
         </ElButton>
         <ElButton v-if="expand" text @click="setVisible">
@@ -129,19 +129,19 @@ const setVisible = () => {
         <slot name="actionMore"></slot>
       </div>
     </template>
-    <template #[name] v-for="name in Object.keys($slots)" :key="name"
-      ><slot :name="name"></slot
-    ></template>
+    <template v-for="name in Object.keys($slots)" :key="name" #[name]>
+      <slot :name="name"></slot>
+    </template>
   </Form>
 
   <template v-if="layout === 'bottom'">
     <div :style="bottonButtonStyle">
       <ElButton v-if="showSearch" type="primary" @click="search">
-        <Icon icon="ep:search" class="mr-5px" />
+        <Icon class="mr-5px" icon="ep:search" />
         {{ t('common.query') }}
       </ElButton>
       <ElButton v-if="showReset" @click="reset">
-        <Icon icon="ep:refresh-right" class="mr-5px" />
+        <Icon class="mr-5px" icon="ep:refresh-right" />
         {{ t('common.reset') }}
       </ElButton>
       <ElButton v-if="expand" text @click="setVisible">

+ 3 - 2
src/components/Sticky/src/Sticky.vue

@@ -1,7 +1,8 @@
-<script setup lang="ts">
+<script lang="ts" name="Sticky" setup>
 import { propTypes } from '@/utils/propTypes'
 import { isClient, useEventListener, useWindowSize } from '@vueuse/core'
 import type { CSSProperties } from 'vue'
+
 const props = defineProps({
   // 距离顶部或者底部的距离(单位px)
   offset: propTypes.number.def(0),
@@ -120,7 +121,7 @@ const reset = () => {
 }
 </script>
 <template>
-  <div :style="{ height: height, zIndex: zIndex }" ref="refSticky">
+  <div ref="refSticky" :style="{ height: height, zIndex: zIndex }">
     <div
       :class="className"
       :style="{

+ 2 - 1
src/components/Tooltip/src/Tooltip.vue

@@ -1,5 +1,6 @@
-<script setup lang="ts">
+<script lang="ts" name="Tooltip" setup>
 import { propTypes } from '@/utils/propTypes'
+
 defineProps({
   titel: propTypes.string.def(''),
   message: propTypes.string.def(''),

+ 23 - 13
src/components/Verifition/src/Verify.vue

@@ -1,42 +1,42 @@
 <template>
-  <div :class="mode == 'pop' ? 'mask' : ''" v-show="showBox">
+  <div v-show="showBox" :class="mode == 'pop' ? 'mask' : ''">
     <div
       :class="mode == 'pop' ? 'verifybox' : ''"
       :style="{ 'max-width': parseInt(imgSize.width) + 20 + 'px' }"
     >
-      <div class="verifybox-top" v-if="mode == 'pop'">
+      <div v-if="mode == 'pop'" class="verifybox-top">
         {{ t('captcha.verification') }}
         <span class="verifybox-close" @click="closeBox">
           <i class="iconfont icon-close"></i>
         </span>
       </div>
-      <div class="verifybox-bottom" :style="{ padding: mode == 'pop' ? '10px' : '0' }">
+      <div :style="{ padding: mode == 'pop' ? '10px' : '0' }" class="verifybox-bottom">
         <!-- 验证码容器 -->
         <component
-          v-if="componentType"
           :is="componentType"
+          v-if="componentType"
+          ref="instance"
+          :arith="arith"
+          :barSize="barSize"
+          :blockSize="blockSize"
           :captchaType="captchaType"
-          :type="verifyType"
+          :explain="explain"
           :figure="figure"
-          :arith="arith"
+          :imgSize="imgSize"
           :mode="mode"
+          :type="verifyType"
           :vSpace="vSpace"
-          :explain="explain"
-          :imgSize="imgSize"
-          :blockSize="blockSize"
-          :barSize="barSize"
-          ref="instance"
         />
       </div>
     </div>
   </div>
 </template>
-<script type="text/babel">
+<script name="Verify" type="text/babel">
 /**
  * Verify 验证码组件
  * @description 分发验证码使用
  * */
-import { VerifySlide, VerifyPoints } from './Verify'
+import { VerifyPoints, VerifySlide } from './Verify'
 import { computed, ref, toRefs, watchEffect } from 'vue'
 
 export default {
@@ -155,6 +155,7 @@ export default {
   border-radius: 5px;
   transform: translate(-50%, -50%);
 }
+
 .verifybox-top {
   padding: 0 15px;
   height: 40px;
@@ -165,10 +166,12 @@ export default {
   border-bottom: 1px solid #e4e7eb;
   box-sizing: border-box;
 }
+
 .verifybox-bottom {
   padding: 10px;
   box-sizing: border-box;
 }
+
 .verifybox-close {
   position: absolute;
   top: 13px;
@@ -178,6 +181,7 @@ export default {
   text-align: center;
   cursor: pointer;
 }
+
 .mask {
   position: fixed;
   top: 0;
@@ -189,6 +193,7 @@ export default {
   /* display: none; */
   transition: all 0.5s;
 }
+
 .verify-tips {
   text-indent: 10px;
   position: absolute;
@@ -199,22 +204,27 @@ export default {
   line-height: 30px;
   color: #fff;
 }
+
 .suc-bg {
   background-color: rgba(92, 184, 92, 0.5);
   filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7f5CB85C, endcolorstr=#7f5CB85C);
 }
+
 .err-bg {
   background-color: rgba(217, 83, 79, 0.5);
   filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7fD9534F, endcolorstr=#7fD9534F);
 }
+
 .tips-enter,
 .tips-leave-to {
   bottom: -30px;
 }
+
 .tips-enter-active,
 .tips-leave-active {
   transition: bottom 0.5s;
 }
+
 /* ---------------------------- */
 /*常规验证码*/
 .verify-code {

+ 7 - 7
src/components/Verifition/src/Verify/VerifyPoints.vue

@@ -2,20 +2,20 @@
   <div style="position: relative">
     <div class="verify-img-out">
       <div
-        class="verify-img-panel"
         :style="{
           width: setSize.imgWidth,
           height: setSize.imgHeight,
           'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
           'margin-bottom': vSpace + 'px'
         }"
+        class="verify-img-panel"
       >
-        <div class="verify-refresh" style="z-index: 3" @click="refresh" v-show="showRefresh">
+        <div v-show="showRefresh" class="verify-refresh" style="z-index: 3" @click="refresh">
           <i class="iconfont icon-refresh"></i>
         </div>
         <img
-          :src="'data:image/png;base64,' + pointBackImgBase"
           ref="canvas"
+          :src="'data:image/png;base64,' + pointBackImgBase"
           alt=""
           style="width: 100%; height: 100%; display: block"
           @click="bindingClick ? canvasClick($event) : undefined"
@@ -24,7 +24,6 @@
         <div
           v-for="(tempPoint, index) in tempPoints"
           :key="index"
-          class="point-area"
           :style="{
             'background-color': '#1abd6c',
             color: '#fff',
@@ -38,6 +37,7 @@
             top: parseInt(tempPoint.y - 10) + 'px',
             left: parseInt(tempPoint.x - 10) + 'px'
           }"
+          class="point-area"
         >
           {{ index + 1 }}
         </div>
@@ -45,19 +45,19 @@
     </div>
     <!-- 'height': this.barSize.height, -->
     <div
-      class="verify-bar-area"
       :style="{
         width: setSize.imgWidth,
         color: barAreaColor,
         'border-color': barAreaBorderColor,
         'line-height': barSize.height
       }"
+      class="verify-bar-area"
     >
       <span class="verify-msg">{{ text }}</span>
     </div>
   </div>
 </template>
-<script type="text/babel" setup>
+<script name="VerifyPoints" setup type="text/babel">
 /**
  * VerifyPoints
  * @description 点选
@@ -65,7 +65,7 @@
 import { resetSize } from './../utils/util'
 import { aesEncrypt } from './../utils/ase'
 import { getCode, reqCheck } from '@/api/login'
-import { onMounted, reactive, ref, nextTick, toRefs, getCurrentInstance } from 'vue'
+import { getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs } from 'vue'
 
 const props = defineProps({
   //弹出式pop,固定fixed

+ 11 - 11
src/components/Verifition/src/Verify/VerifySlide.vue

@@ -2,20 +2,20 @@
   <div style="position: relative">
     <div
       v-if="type === '2'"
-      class="verify-img-out"
       :style="{ height: parseInt(setSize.imgHeight) + vSpace + 'px' }"
+      class="verify-img-out"
     >
-      <div class="verify-img-panel" :style="{ width: setSize.imgWidth, height: setSize.imgHeight }">
+      <div :style="{ width: setSize.imgWidth, height: setSize.imgHeight }" class="verify-img-panel">
         <img
           :src="'data:image/png;base64,' + backImgBase"
           alt=""
           style="width: 100%; height: 100%; display: block"
         />
-        <div class="verify-refresh" @click="refresh" v-show="showRefresh">
+        <div v-show="showRefresh" class="verify-refresh" @click="refresh">
           <i class="iconfont icon-refresh"></i>
         </div>
         <transition name="tips">
-          <span class="verify-tips" v-if="tipWords" :class="passFlag ? 'suc-bg' : 'err-bg'">
+          <span v-if="tipWords" :class="passFlag ? 'suc-bg' : 'err-bg'" class="verify-tips">
             {{ tipWords }}
           </span>
         </transition>
@@ -23,24 +23,21 @@
     </div>
     <!-- 公共部分 -->
     <div
-      class="verify-bar-area"
       :style="{ width: setSize.imgWidth, height: barSize.height, 'line-height': barSize.height }"
+      class="verify-bar-area"
     >
       <span class="verify-msg" v-text="text"></span>
       <div
-        class="verify-left-bar"
         :style="{
           width: leftBarWidth !== undefined ? leftBarWidth : barSize.height,
           height: barSize.height,
           'border-color': leftBarBorderColor,
           transaction: transitionWidth
         }"
+        class="verify-left-bar"
       >
         <span class="verify-msg" v-text="finishText"></span>
         <div
-          class="verify-move-block"
-          @touchstart="start"
-          @mousedown="start"
           :style="{
             width: barSize.height,
             height: barSize.height,
@@ -48,17 +45,20 @@
             left: moveBlockLeft,
             transition: transitionLeft
           }"
+          class="verify-move-block"
+          @mousedown="start"
+          @touchstart="start"
         >
           <i :class="['verify-icon iconfont', iconClass]" :style="{ color: iconColor }"></i>
           <div
             v-if="type === '2'"
-            class="verify-sub-block"
             :style="{
               width: Math.floor((parseInt(setSize.imgWidth) * 47) / 310) + 'px',
               height: setSize.imgHeight,
               top: '-' + (parseInt(setSize.imgHeight) + vSpace) + 'px',
               'background-size': setSize.imgWidth + ' ' + setSize.imgHeight
             }"
+            class="verify-sub-block"
           >
             <img
               :src="'data:image/png;base64,' + blockBackImgBase"
@@ -71,7 +71,7 @@
     </div>
   </div>
 </template>
-<script type="text/babel" setup>
+<script name="VerifySlide" setup type="text/babel">
 /**
  * VerifySlide
  * @description 滑块

+ 4 - 3
src/components/XButton/src/XButton.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="XButton" setup>
 import { PropType } from 'vue'
 import { propTypes } from '@/utils/propTypes'
 
@@ -30,9 +30,9 @@ const getBindValue = computed(() => {
 
 <template>
   <el-button v-bind="getBindValue" @click="onClick">
-    <Icon :icon="preIcon" v-if="preIcon" class="mr-1px" />
+    <Icon v-if="preIcon" :icon="preIcon" class="mr-1px" />
     {{ title ? title : '' }}
-    <Icon :icon="postIcon" v-if="postIcon" class="mr-1px" />
+    <Icon v-if="postIcon" :icon="postIcon" class="mr-1px" />
   </el-button>
 </template>
 <style lang="scss" scoped>
@@ -40,6 +40,7 @@ const getBindValue = computed(() => {
   margin-left: 0;
   padding: 8px 4px;
 }
+
 :deep(.el-button.is-link) {
   margin-left: 0;
   padding: 8px 4px;

+ 4 - 3
src/components/XButton/src/XTextButton.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="XTextButton" setup>
 import { propTypes } from '@/utils/propTypes'
 import { PropType } from 'vue'
 
@@ -29,9 +29,9 @@ const getBindValue = computed(() => {
 
 <template>
   <el-button link v-bind="getBindValue" @click="onClick">
-    <Icon :icon="preIcon" v-if="preIcon" class="mr-1px" />
+    <Icon v-if="preIcon" :icon="preIcon" class="mr-1px" />
     {{ title ? title : '' }}
-    <Icon :icon="postIcon" v-if="postIcon" class="mr-1px" />
+    <Icon v-if="postIcon" :icon="postIcon" class="mr-1px" />
   </el-button>
 </template>
 <style lang="scss" scoped>
@@ -39,6 +39,7 @@ const getBindValue = computed(() => {
   margin-left: 0;
   padding: 8px 4px;
 }
+
 :deep(.el-button.is-link) {
   margin-left: 0;
   padding: 8px 4px;

+ 0 - 3
src/components/XModal/index.ts

@@ -1,3 +0,0 @@
-import XModal from './src/XModal.vue'
-
-export { XModal }

+ 0 - 44
src/components/XModal/src/XModal.vue

@@ -1,44 +0,0 @@
-<script setup lang="ts">
-import { propTypes } from '@/utils/propTypes'
-const slots = useSlots()
-
-const props = defineProps({
-  id: propTypes.string.def('model_1'),
-  modelValue: propTypes.bool.def(false),
-  fullscreen: propTypes.bool.def(false),
-  loading: propTypes.bool.def(false),
-  title: propTypes.string.def('弹窗'),
-  width: propTypes.string.def('40%'),
-  height: propTypes.string,
-  minWidth: propTypes.string.def('460'),
-  minHeight: propTypes.string.def('320'),
-  showFooter: propTypes.bool.def(true),
-  maskClosable: propTypes.bool.def(false),
-  escClosable: propTypes.bool.def(false)
-})
-
-const getBindValue = computed(() => {
-  const attrs = useAttrs()
-  const obj = { ...attrs, ...props }
-  return obj
-})
-</script>
-
-<template>
-  <vxe-modal v-bind="getBindValue" destroy-on-close show-zoom resize transfer>
-    <template v-if="slots.header" #header>
-      <slot name="header"></slot>
-    </template>
-    <ElScrollbar>
-      <template v-if="slots.default" #default>
-        <slot name="default"></slot>
-      </template>
-    </ElScrollbar>
-    <template v-if="slots.corner" #corner>
-      <slot name="corner"></slot>
-    </template>
-    <template v-if="slots.footer" #footer>
-      <slot name="footer"></slot>
-    </template>
-  </vxe-modal>
-</template>

+ 0 - 3
src/components/XTable/index.ts

@@ -1,3 +0,0 @@
-import XTable from './src/XTable.vue'
-
-export { XTable }

+ 0 - 442
src/components/XTable/src/XTable.vue

@@ -1,442 +0,0 @@
-<template>
-  <VxeGrid v-bind="getProps" ref="xGrid" :class="`${prefixCls}`" class="xtable-scrollbar">
-    <template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
-      <slot :name="item" v-bind="data || {}"></slot>
-    </template>
-  </VxeGrid>
-</template>
-<script setup lang="ts" name="XTable">
-import { PropType } from 'vue'
-import { SizeType, VxeGridInstance } from 'vxe-table'
-import { useAppStore } from '@/store/modules/app'
-import { useDesign } from '@/hooks/web/useDesign'
-import { XTableProps } from './type'
-import { isBoolean, isFunction } from '@/utils/is'
-import styleCss from './style/dark.scss?inline'
-import download from '@/utils/download'
-
-const { t } = useI18n()
-const message = useMessage() // 消息弹窗
-
-const appStore = useAppStore()
-
-const { getPrefixCls } = useDesign()
-const prefixCls = getPrefixCls('x-vxe-table')
-
-const attrs = useAttrs()
-const emit = defineEmits(['register'])
-const removeStyles = () => {
-  const filename = 'cssTheme'
-  //移除引入的文件名
-  const targetelement = 'style'
-  const targetattr = 'id'
-  const allsuspects = document.getElementsByTagName(targetelement)
-  for (let i = allsuspects.length; i >= 0; i--) {
-    if (
-      allsuspects[i] &&
-      allsuspects[i].getAttribute(targetattr) != null &&
-      allsuspects[i].getAttribute(targetattr)?.indexOf(filename) != -1
-    ) {
-      console.log(allsuspects[i], 'node')
-      allsuspects[i].parentNode?.removeChild(allsuspects[i])
-    }
-  }
-}
-const reImport = () => {
-  const head = document.getElementsByTagName('head')[0]
-  const style = document.createElement('style')
-  style.innerText = styleCss
-  style.id = 'cssTheme'
-  head.appendChild(style)
-}
-watch(
-  () => appStore.getIsDark,
-  () => {
-    if (appStore.getIsDark) {
-      reImport()
-    }
-    if (!appStore.getIsDark) {
-      removeStyles()
-    }
-  },
-  { immediate: true }
-)
-
-const currentSize = computed(() => {
-  let resSize: SizeType = 'small'
-  const appsize = appStore.getCurrentSize
-  switch (appsize) {
-    case 'large':
-      resSize = 'medium'
-      break
-    case 'default':
-      resSize = 'small'
-      break
-    case 'small':
-      resSize = 'mini'
-      break
-  }
-  return resSize
-})
-
-const props = defineProps({
-  options: {
-    type: Object as PropType<XTableProps>,
-    default: () => {}
-  }
-})
-const innerProps = ref<Partial<XTableProps>>()
-
-const getProps = computed(() => {
-  const options = innerProps.value || props.options
-  options.size = currentSize as any
-  options.height = 700
-  getOptionInitConfig(options)
-  getColumnsConfig(options)
-  getProxyConfig(options)
-  getPageConfig(options)
-  getToolBarConfig(options)
-  // console.log(options);
-  return {
-    ...options,
-    ...attrs
-  }
-})
-
-const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
-
-let proxyForm = false
-
-const getOptionInitConfig = (options: XTableProps) => {
-  options.size = currentSize as any
-  options.rowConfig = {
-    isCurrent: true, // 当鼠标点击行时,是否要高亮当前行
-    isHover: true // 当鼠标移到行时,是否要高亮当前行
-  }
-}
-
-// columns
-const getColumnsConfig = (options: XTableProps) => {
-  const { allSchemas } = options
-  if (!allSchemas) return
-  if (allSchemas.printSchema) {
-    options.printConfig = {
-      columns: allSchemas.printSchema
-    }
-  }
-  if (allSchemas.formSchema) {
-    proxyForm = true
-    options.formConfig = {
-      enabled: true,
-      titleWidth: 110,
-      titleAlign: 'right',
-      items: allSchemas.searchSchema
-    }
-  }
-  if (allSchemas.tableSchema) {
-    options.columns = allSchemas.tableSchema
-  }
-}
-
-// 动态请求
-const getProxyConfig = (options: XTableProps) => {
-  const { getListApi, proxyConfig, data, isList } = options
-  if (proxyConfig || data) return
-  if (getListApi && isFunction(getListApi)) {
-    if (!isList) {
-      options.proxyConfig = {
-        seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
-        form: proxyForm, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
-        props: { result: 'list', total: 'total' },
-        ajax: {
-          query: async ({ page, form }) => {
-            let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
-            if (options.params) {
-              queryParams = Object.assign(queryParams, options.params)
-            }
-            if (!options?.treeConfig) {
-              queryParams.pageSize = page.pageSize
-              queryParams.pageNo = page.currentPage
-            }
-            return new Promise(async (resolve) => {
-              resolve(await getListApi(queryParams))
-            })
-          },
-          delete: ({ body }) => {
-            return new Promise(async (resolve) => {
-              if (options.deleteApi) {
-                resolve(await options.deleteApi(JSON.stringify(body)))
-              } else {
-                Promise.reject('未设置deleteApi')
-              }
-            })
-          },
-          queryAll: ({ form }) => {
-            const queryParams = Object.assign({}, JSON.parse(JSON.stringify(form)))
-            return new Promise(async (resolve) => {
-              if (options.getAllListApi) {
-                resolve(await options.getAllListApi(queryParams))
-              } else {
-                resolve(await getListApi(queryParams))
-              }
-            })
-          }
-        }
-      }
-    } else {
-      options.proxyConfig = {
-        seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
-        form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
-        props: { result: 'data' },
-        ajax: {
-          query: ({ form }) => {
-            let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
-            if (options?.params) {
-              queryParams = Object.assign(queryParams, options.params)
-            }
-            return new Promise(async (resolve) => {
-              resolve(await getListApi(queryParams))
-            })
-          }
-        }
-      }
-    }
-  }
-  if (options.exportListApi) {
-    options.exportConfig = {
-      filename: options?.exportName,
-      // 默认选中类型
-      type: 'csv',
-      // 自定义数据量列表
-      modes: options?.getAllListApi ? ['current', 'all'] : ['current'],
-      columns: options?.allSchemas?.printSchema
-    }
-  }
-}
-
-// 分页
-const getPageConfig = (options: XTableProps) => {
-  const { pagination, pagerConfig, treeConfig, isList } = options
-  if (isList) return
-  if (treeConfig) {
-    options.treeConfig = options.treeConfig
-    return
-  }
-  if (pagerConfig) return
-  if (pagination) {
-    if (isBoolean(pagination)) {
-      options.pagerConfig = {
-        border: false, // 带边框
-        background: false, // 带背景颜色
-        perfect: false, // 配套的样式
-        pageSize: 10, // 每页大小
-        pagerCount: 7, // 显示页码按钮的数量
-        autoHidden: false, // 当只有一页时自动隐藏
-        pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表
-        layouts: [
-          'PrevJump',
-          'PrevPage',
-          'JumpNumber',
-          'NextPage',
-          'NextJump',
-          'Sizes',
-          'FullJump',
-          'Total'
-        ]
-      }
-      return
-    }
-    options.pagerConfig = pagination
-  } else {
-    if (pagination != false) {
-      options.pagerConfig = {
-        border: false, // 带边框
-        background: false, // 带背景颜色
-        perfect: false, // 配套的样式
-        pageSize: 10, // 每页大小
-        pagerCount: 7, // 显示页码按钮的数量
-        autoHidden: false, // 当只有一页时自动隐藏
-        pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表
-        layouts: [
-          'Sizes',
-          'PrevJump',
-          'PrevPage',
-          'Number',
-          'NextPage',
-          'NextJump',
-          'FullJump',
-          'Total'
-        ]
-      }
-    }
-  }
-}
-
-// tool bar
-const getToolBarConfig = (options: XTableProps) => {
-  const { toolBar, toolbarConfig, topActionSlots } = options
-  if (toolbarConfig) return
-  if (toolBar) {
-    if (!isBoolean(toolBar)) {
-      console.info(2)
-      options.toolbarConfig = toolBar
-      return
-    }
-  } else if (topActionSlots != false) {
-    options.toolbarConfig = {
-      slots: { buttons: 'toolbar_buttons' }
-    }
-  } else {
-    options.toolbarConfig = {
-      enabled: true
-    }
-  }
-}
-
-// 刷新列表
-const reload = () => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
-  }
-  g.commitProxy('query')
-}
-
-// 删除
-const deleteData = async (id: string | number) => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
-  }
-  const options = innerProps.value || props.options
-  if (!options.deleteApi) {
-    console.error('未传入delListApi')
-    return
-  }
-  return new Promise(async () => {
-    message.delConfirm().then(async () => {
-      await (options?.deleteApi && options?.deleteApi(id))
-      message.success(t('common.delSuccess'))
-      // 刷新列表
-      reload()
-    })
-  })
-}
-
-// 批量删除
-const deleteBatch = async () => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
-  }
-  const rows = g.getCheckboxRecords() || g.getRadioRecord()
-  let ids: any[] = []
-  if (rows.length == 0) {
-    message.error('请选择数据')
-    return
-  } else {
-    rows.forEach((row) => {
-      ids.push(row.id)
-    })
-  }
-  const options = innerProps.value || props.options
-  if (options.deleteListApi) {
-    return new Promise(async () => {
-      message.delConfirm().then(async () => {
-        await (options?.deleteListApi && options?.deleteListApi(ids))
-        message.success(t('common.delSuccess'))
-        // 刷新列表
-        reload()
-      })
-    })
-  } else if (options.deleteApi) {
-    return new Promise(async () => {
-      message.delConfirm().then(async () => {
-        ids.forEach(async (id) => {
-          await (options?.deleteApi && options?.deleteApi(id))
-        })
-        message.success(t('common.delSuccess'))
-        // 刷新列表
-        reload()
-      })
-    })
-  } else {
-    console.error('未传入delListApi')
-    return
-  }
-}
-
-// 导出
-const exportList = async (fileName?: string) => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
-  }
-  const options = innerProps.value || props.options
-  if (!options?.exportListApi) {
-    console.error('未传入exportListApi')
-    return
-  }
-  const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form)))
-  message.exportConfirm().then(async () => {
-    const res = await (options?.exportListApi && options?.exportListApi(queryParams))
-    download.excel(res as unknown as Blob, fileName ? fileName : 'excel.xls')
-  })
-}
-
-// 获取查询参数
-const getSearchData = () => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
-  }
-  const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form)))
-  return queryParams
-}
-
-// 获取当前列
-const getCurrentColumn = () => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
-  }
-  return g.getCurrentColumn()
-}
-
-// 获取当前选中列,redio
-const getRadioRecord = () => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
-  }
-  return g.getRadioRecord(false)
-}
-
-// 获取当前选中列,checkbox
-const getCheckboxRecords = () => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
-  }
-  return g.getCheckboxRecords(false)
-}
-const setProps = (prop: Partial<XTableProps>) => {
-  innerProps.value = { ...unref(innerProps), ...prop }
-}
-
-defineExpose({ reload, Ref: xGrid, getSearchData, deleteData, exportList })
-emit('register', {
-  reload,
-  getSearchData,
-  setProps,
-  deleteData,
-  deleteBatch,
-  exportList,
-  getCurrentColumn,
-  getRadioRecord,
-  getCheckboxRecords
-})
-</script>
-<style lang="scss">
-@import './style/index.scss';
-</style>

+ 0 - 81
src/components/XTable/src/style/dark.scss

@@ -1,81 +0,0 @@
-// 修改样式变量
-//@import 'vxe-table/styles/variable.scss';
-
-/*font*/
-$vxe-font-color: #e5e7eb;
-// $vxe-font-size: 14px !default;
-// $vxe-font-size-medium: 16px !default;
-// $vxe-font-size-small: 14px !default;
-// $vxe-font-size-mini: 12px !default;
-
-/*color*/
-$vxe-primary-color: #409eff !default;
-$vxe-success-color: #67c23a !default;
-$vxe-info-color: #909399 !default;
-$vxe-warning-color: #e6a23c !default;
-$vxe-danger-color: #f56c6c !default;
-$vxe-disabled-color: #bfbfbf !default;
-$vxe-primary-disabled-color: #c0c4cc !default;
-
-/*loading*/
-$vxe-loading-color: $vxe-primary-color !default;
-$vxe-loading-background-color: #1d1e1f !default;
-$vxe-loading-z-index: 999 !default;
-
-/*icon*/
-$vxe-icon-font-family: Verdana, Arial, Tahoma !default;
-$vxe-icon-background-color: #e5e7eb !default;
-
-/*toolbar*/
-$vxe-toolbar-background-color: #1d1e1f !default;
-$vxe-toolbar-button-border: #dcdfe6 !default;
-$vxe-toolbar-custom-active-background-color: #d9dadb !default;
-$vxe-toolbar-panel-background-color: #e5e7eb !default;
-
-$vxe-table-font-color: #e5e7eb;
-$vxe-table-header-background-color: #1d1e1f;
-$vxe-table-body-background-color: #141414;
-$vxe-table-row-striped-background-color: #1d1d1d;
-$vxe-table-row-hover-background-color: #1d1e1f;
-$vxe-table-row-hover-striped-background-color: #1e1e1e;
-$vxe-table-footer-background-color: #1d1e1f;
-$vxe-table-row-current-background-color: #302d2d;
-$vxe-table-column-current-background-color: #302d2d;
-$vxe-table-column-hover-background-color: #302d2d;
-$vxe-table-row-hover-current-background-color: #302d2d;
-$vxe-table-row-checkbox-checked-background-color: #3e3c37 !default;
-$vxe-table-row-hover-checkbox-checked-background-color: #615a4a !default;
-$vxe-table-menu-background-color: #1d1e1f;
-$vxe-table-border-width: 1px !default;
-$vxe-table-border-color: #4c4d4f !default;
-$vxe-table-fixed-left-scrolling-box-shadow: 8px 0px 10px -5px rgba(0, 0, 0, 0.12) !default;
-$vxe-table-fixed-right-scrolling-box-shadow: -8px 0px 10px -5px rgba(0, 0, 0, 0.12) !default;
-
-$vxe-form-background-color: #141414;
-
-/*pager*/
-$vxe-pager-background-color: #1d1e1f !default;
-$vxe-pager-perfect-background-color: #262727 !default;
-$vxe-pager-perfect-button-background-color: #a7a3a3 !default;
-
-$vxe-input-background-color: #141414;
-$vxe-input-border-color: #4c4d4f !default;
-
-$vxe-select-option-hover-background-color: #262626 !default;
-$vxe-select-panel-background-color: #141414 !default;
-$vxe-select-empty-color: #262626 !default;
-$vxe-optgroup-title-color: #909399 !default;
-
-/*button*/
-$vxe-button-default-background-color: #262626;
-$vxe-button-dropdown-panel-background-color: #141414;
-
-/*modal*/
-$vxe-modal-header-background-color: #141414;
-$vxe-modal-body-background-color: #141414;
-$vxe-modal-border-color: #3b3b3b;
-
-/*pulldown*/
-$vxe-pulldown-panel-background-color: #262626 !default;
-
-@import 'vxe-table/styles/index.scss';

+ 0 - 6
src/components/XTable/src/style/index.scss

@@ -1,6 +0,0 @@
-// @import 'vxe-table/styles/variable.scss';
-// @import 'vxe-table/styles/modules.scss';
-// @import './theme/light.scss';
-i {
-  border-color: initial;
-}

+ 0 - 16
src/components/XTable/src/style/light.scss

@@ -1,16 +0,0 @@
-// 修改样式变量
-// /*font*/
-// $vxe-font-size: 12px !default;
-// $vxe-font-size-medium: 16px !default;
-// $vxe-font-size-small: 14px !default;
-// $vxe-font-size-mini: 12px !default;
-/*color*/
-$vxe-primary-color: #409eff !default;
-$vxe-success-color: #67c23a !default;
-$vxe-info-color: #909399 !default;
-$vxe-warning-color: #e6a23c !default;
-$vxe-danger-color: #f56c6c !default;
-$vxe-disabled-color: #bfbfbf !default;
-$vxe-primary-disabled-color: #c0c4cc !default;
-
-@import 'vxe-table/styles/index.scss';

+ 0 - 26
src/components/XTable/src/type.ts

@@ -1,26 +0,0 @@
-import { CrudSchema } from '@/hooks/web/useCrudSchemas'
-import type { VxeGridProps, VxeGridPropTypes, VxeTablePropTypes } from 'vxe-table'
-
-export type XTableProps<D = any> = VxeGridProps<D> & {
-  allSchemas?: CrudSchema
-  height?: number // 高度 默认730
-  topActionSlots?: boolean // 是否开启表格内顶部操作栏插槽
-  treeConfig?: VxeTablePropTypes.TreeConfig // 树形表单配置
-  isList?: boolean // 是否不带分页的list
-  getListApi?: Function // 获取列表接口
-  getAllListApi?: Function // 获取全部数据接口 用于 vxe 导出
-  deleteApi?: Function // 删除接口
-  deleteListApi?: Function // 批量删除接口
-  exportListApi?: Function // 导出接口
-  exportName?: string // 导出文件夹名称
-  params?: any // 其他查询参数
-  pagination?: boolean | VxeGridPropTypes.PagerConfig // 分页配置参数
-  toolBar?: boolean | VxeGridPropTypes.ToolbarConfig // 右侧工具栏配置参数
-}
-export type XColumns = VxeGridPropTypes.Columns
-
-export type VxeTableColumn = {
-  field: string
-  title?: string
-  children?: VxeTableColumn[]
-} & Recordable

+ 14 - 11
src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue

@@ -188,7 +188,13 @@
       <!-- <div id="js-properties-panel" class="panel"></div> -->
       <!-- <div class="my-process-designer__canvas" ref="bpmn-canvas"></div> -->
     </div>
-    <XModal title="预览" width="80%" height="90%" v-model="previewModelVisible" destroy-on-close>
+    <Dialog
+      title="预览"
+      v-model="previewModelVisible"
+      width="80%"
+      :scroll="true"
+      max-height="600px"
+    >
       <!-- append-to-body -->
       <div v-highlight>
         <code class="hljs">
@@ -196,10 +202,7 @@
           {{ previewResult }}
         </code>
       </div>
-      <!-- <pre>
-        <code class="hljs" v-html="highlightedCode(previewType, previewResult)"></code>
-      </pre> -->
-    </XModal>
+    </Dialog>
   </div>
 </template>
 
@@ -231,7 +234,7 @@ import activitiModdleExtension from './plugins/extension-moddle/activiti'
 import flowableModdleExtension from './plugins/extension-moddle/flowable'
 // 引入json转换与高亮
 // import xml2js from 'xml-js'
-import xml2js from 'fast-xml-parser'
+// import xml2js from 'fast-xml-parser'
 import { XmlNode, XmlNodeType, parseXmlString } from 'steady-xml'
 // 代码高亮插件
 // import hljs from 'highlight.js/lib/highlight'
@@ -626,7 +629,7 @@ const elementsAlign = (align) => {
 const previewProcessXML = () => {
   console.log(bpmnModeler.saveXML, 'bpmnModeler')
   bpmnModeler.saveXML({ format: true }).then(({ xml }) => {
-    console.log(xml, 'xml111111')
+    // console.log(xml, 'xml111111')
     previewResult.value = xml
     previewType.value = 'xml'
     previewModelVisible.value = true
@@ -634,7 +637,7 @@ const previewProcessXML = () => {
 }
 const previewProcessJson = () => {
   bpmnModeler.saveXML({ format: true }).then(({ xml }) => {
-    console.log(xml, 'xml')
+    // console.log(xml, 'xml')
 
     // const rootNode = parseXmlString(xml)
     // console.log(rootNode, 'rootNoderootNode')
@@ -644,9 +647,9 @@ const previewProcessJson = () => {
     // console.log(JSON.stringify(rootNodes.parent.toJsObject()), 'rootNodes.toJSON()')
     // console.log(JSON.stringify(rootNodes.parent.toJSON()), 'rootNodes.toJSON()')
 
-    const parser = new xml2js.XMLParser()
-    let jObj = parser.parse(xml)
-    console.log(jObj, 'jObjjObjjObjjObjjObj')
+    // const parser = new xml2js.XMLParser()
+    // let jObj = parser.parse(xml)
+    // console.log(jObj, 'jObjjObjjObjjObjjObj')
     // const builder = new xml2js.XMLBuilder(xml)
     // const xmlContent = builder
     // console.log(xmlContent, 'xmlContent')

+ 6 - 32
src/components/bpmnProcessDesigner/package/index.ts

@@ -1,37 +1,11 @@
-import { App } from 'vue'
 import MyProcessDesigner from './designer'
 import MyProcessPenal from './penal'
 import MyProcessViewer from './designer/index2'
 
-const components = [MyProcessDesigner, MyProcessPenal, MyProcessViewer]
+import './theme/index.scss'
+import 'bpmn-js/dist/assets/diagram-js.css'
+import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
+import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
+import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
 
-// const install = function (Vue) {
-//   components.forEach(component => {
-//     Vue.component(component.name, component)
-//   })
-// }
-
-// if (typeof window !== "undefined" && window.Vue) {
-//   install(window.Vue)
-// }
-//   components.forEach(component => {
-//     Vue.component(component.name, component)
-//   })
-const componentss = {
-  install: (Vue: App): void => {
-    components.forEach((component) => {
-      Vue.component(component.name, component)
-    })
-  }
-}
-// let version = "0.0.1"
-export const MyPD = (app) => {
-  // export default {
-  // app.use(version)
-  // app.use(install)
-  // app.use(MyProcessDesigner)
-  // app.use(MyProcessPenal)
-  // app.use(MyProcessViewer)
-  // app.use(components)
-  app.use(componentss)
-}
+export { MyProcessDesigner, MyProcessPenal, MyProcessViewer }

+ 6 - 3
src/components/bpmnProcessDesigner/package/penal/form/ElementForm.vue

@@ -111,7 +111,8 @@
               >
               <el-divider direction="vertical" />
               <el-button
-                type="text"
+                type="primary"
+                link
                 style="color: #ff4d4f"
                 @click="removeFieldOptionItem(scope, scope.$index, 'enum')"
                 >移除</el-button
@@ -143,7 +144,8 @@
             >
             <el-divider direction="vertical" />
             <el-button
-              type="text"
+              type="primary"
+              link
               style="color: #ff4d4f"
               @click="removeFieldOptionItem(scope, scope.$index, 'constraint')"
               >移除</el-button
@@ -174,7 +176,8 @@
             >
             <el-divider direction="vertical" />
             <el-button
-              type="text"
+              type="primary"
+              link
               style="color: #ff4d4f"
               @click="removeFieldOptionItem(scope, scope.$index, 'property')"
               >移除</el-button

+ 0 - 19
src/components/index.ts

@@ -1,25 +1,6 @@
 import type { App } from 'vue'
 import { Icon } from './Icon'
-import { Form } from '@/components/Form'
-import { Table } from '@/components/Table'
-import { Search } from '@/components/Search'
-import { XModal } from '@/components/XModal'
-import { XTable } from '@/components/XTable'
-import { XButton, XTextButton } from '@/components/XButton'
-import { DictTag } from '@/components/DictTag'
-import { ContentWrap } from '@/components/ContentWrap'
-import { Descriptions } from '@/components/Descriptions'
 
 export const setupGlobCom = (app: App<Element>): void => {
   app.component('Icon', Icon)
-  app.component('Form', Form)
-  app.component('Table', Table)
-  app.component('Search', Search)
-  app.component('XModal', XModal)
-  app.component('XTable', XTable)
-  app.component('XButton', XButton)
-  app.component('XTextButton', XTextButton)
-  app.component('DictTag', DictTag)
-  app.component('ContentWrap', ContentWrap)
-  app.component('Descriptions', Descriptions)
 }

+ 2 - 0
src/hooks/web/useCrudSchemas.ts

@@ -29,6 +29,8 @@ type CrudSearchParams = {
   show?: boolean
   // 接口
   api?: () => Promise<any>
+  // 搜索字段
+  field?: string
 } & Omit<FormSchema, 'field'>
 
 type CrudTableParams = {

+ 0 - 354
src/hooks/web/useVxeCrudSchemas.ts

@@ -1,354 +0,0 @@
-import {
-  FormItemRenderOptions,
-  VxeColumnPropTypes,
-  VxeFormItemProps,
-  VxeGridPropTypes,
-  VxeTableDefines
-} from 'vxe-table'
-import { eachTree } from 'xe-utils'
-
-import { getBoolDictOptions, getDictOptions, getIntDictOptions } from '@/utils/dict'
-import { FormSchema } from '@/types/form'
-import { VxeTableColumn } from '@/types/table'
-import { ComponentOptions } from '@/types/components'
-import { DescriptionsSchema } from '@/types/descriptions'
-
-export type VxeCrudSchema = {
-  primaryKey?: string // 主键ID
-  primaryTitle?: string // 主键标题 默认为序号
-  primaryType?: VxeColumnPropTypes.Type | 'id' // 还支持 "id" | "seq" | "radio" | "checkbox" | "expand" | "html" | null
-  firstColumn?: VxeColumnPropTypes.Type // 第一列显示类型
-  action?: boolean // 是否开启表格内右侧操作栏插槽
-  actionTitle?: string // 操作栏标题 默认为操作
-  actionWidth?: string // 操作栏插槽宽度,一般2个字带图标 text 类型按钮 50-70
-  columns: VxeCrudColumns[]
-  searchSpan?: number
-}
-type VxeCrudColumns = Omit<VxeTableColumn, 'children'> & {
-  field: string // 字段名
-  title?: string // 标题名
-  formatter?: VxeColumnPropTypes.Formatter // vxe formatter格式化
-  isSearch?: boolean // 是否在查询显示
-  search?: CrudSearchParams // 查询的详细配置
-  isTable?: boolean // 是否在列表显示
-  table?: CrudTableParams // 列表的详细配置
-  isForm?: boolean // 是否在表单显示
-  form?: CrudFormParams // 表单的详细配置
-  isDetail?: boolean // 是否在详情显示
-  detail?: CrudDescriptionsParams // 详情的详细配置
-  print?: CrudPrintParams // vxe 打印的字段
-  children?: VxeCrudColumns[] // 子级
-  dictType?: string // 字典类型
-  dictClass?: 'string' | 'number' | 'boolean' // 字典数据类型 string | number | boolean
-}
-
-type CrudSearchParams = {
-  // 是否显示在查询项
-  show?: boolean
-} & Omit<VxeFormItemProps, 'field'>
-
-type CrudTableParams = {
-  // 是否显示表头
-  show?: boolean
-} & Omit<VxeTableDefines.ColumnOptions, 'field'>
-
-type CrudFormParams = {
-  // 是否显示表单项
-  show?: boolean
-} & Omit<FormSchema, 'field'>
-
-type CrudDescriptionsParams = {
-  // 是否显示表单项
-  show?: boolean
-} & Omit<DescriptionsSchema, 'field'>
-
-type CrudPrintParams = {
-  // 是否显示打印项
-  show?: boolean
-} & Omit<VxeTableDefines.ColumnInfo[], 'field'>
-
-export type VxeAllSchemas = {
-  searchSchema: VxeFormItemProps[]
-  tableSchema: VxeGridPropTypes.Columns
-  formSchema: FormSchema[]
-  detailSchema: DescriptionsSchema[]
-  printSchema: VxeTableDefines.ColumnInfo[]
-}
-
-// 过滤所有结构
-export const useVxeCrudSchemas = (
-  crudSchema: VxeCrudSchema
-): {
-  allSchemas: VxeAllSchemas
-} => {
-  // 所有结构数据
-  const allSchemas = reactive<VxeAllSchemas>({
-    searchSchema: [],
-    tableSchema: [],
-    formSchema: [],
-    detailSchema: [],
-    printSchema: []
-  })
-
-  const searchSchema = filterSearchSchema(crudSchema)
-  allSchemas.searchSchema = searchSchema || []
-
-  const tableSchema = filterTableSchema(crudSchema)
-  allSchemas.tableSchema = tableSchema || []
-
-  const formSchema = filterFormSchema(crudSchema)
-  allSchemas.formSchema = formSchema
-
-  const detailSchema = filterDescriptionsSchema(crudSchema)
-  allSchemas.detailSchema = detailSchema
-
-  const printSchema = filterPrintSchema(crudSchema)
-  allSchemas.printSchema = printSchema
-
-  return {
-    allSchemas
-  }
-}
-
-// 过滤 Search 结构
-const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] => {
-  const { t } = useI18n()
-  const span = crudSchema.searchSpan ? crudSchema.searchSpan : 6
-  const spanLength = 24 / span
-  const searchSchema: VxeFormItemProps[] = []
-  eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
-    // 判断是否显示
-    if (schemaItem?.isSearch || schemaItem.search?.show) {
-      let itemRenderName = schemaItem?.search?.itemRender?.name || '$input'
-      const options: any[] = []
-      let itemRender: FormItemRenderOptions = {}
-
-      if (schemaItem.dictType) {
-        const allOptions = { label: '全部', value: '' }
-        options.push(allOptions)
-        getDictOptions(schemaItem.dictType).forEach((dict) => {
-          options.push(dict)
-        })
-        itemRender.options = options
-        if (!schemaItem?.search?.itemRender?.name) itemRenderName = '$select'
-        itemRender = {
-          name: itemRenderName,
-          options: options,
-          props: { placeholder: t('common.selectText') }
-        }
-      } else {
-        if (schemaItem.search?.itemRender) {
-          itemRender = schemaItem.search.itemRender
-        } else {
-          itemRender = {
-            name: itemRenderName,
-            props:
-              itemRenderName == '$input'
-                ? { placeholder: t('common.inputText') }
-                : { placeholder: t('common.selectText') }
-          }
-        }
-      }
-      const searchSchemaItem = {
-        // 默认为 input
-        folding: searchSchema.length > spanLength - 1,
-        itemRender: schemaItem.itemRender ? schemaItem.itemRender : itemRender,
-        field: schemaItem.field,
-        title: schemaItem.search?.title || schemaItem.title,
-        slots: schemaItem.search?.slots,
-        span: span
-      }
-      searchSchema.push(searchSchemaItem)
-    }
-  })
-  if (searchSchema.length > 0) {
-    // 添加搜索按钮
-    const buttons: VxeFormItemProps = {
-      span: 24,
-      align: 'right',
-      collapseNode: searchSchema.length > spanLength,
-      itemRender: {
-        name: '$buttons',
-        children: [
-          { props: { type: 'submit', content: t('common.query'), status: 'primary' } },
-          { props: { type: 'reset', content: t('common.reset') } }
-        ]
-      }
-    }
-    searchSchema.push(buttons)
-  }
-  return searchSchema
-}
-
-// 过滤 table 结构
-const filterTableSchema = (crudSchema: VxeCrudSchema): VxeGridPropTypes.Columns => {
-  const { t } = useI18n()
-  const tableSchema: VxeGridPropTypes.Columns = []
-  // 第一列
-  if (crudSchema.firstColumn) {
-    const tableSchemaItem = {
-      type: crudSchema.firstColumn,
-      width: '50px'
-    }
-    tableSchema.push(tableSchemaItem)
-  }
-  // 主键ID
-  if (crudSchema.primaryKey && crudSchema.primaryType) {
-    const primaryTitle = crudSchema.primaryTitle ? crudSchema.primaryTitle : t('common.index')
-    const primaryWidth = primaryTitle.length * 30 + 'px'
-
-    let tableSchemaItem: { [x: string]: any } = {
-      title: primaryTitle,
-      field: crudSchema.primaryKey,
-      width: primaryWidth
-    }
-    if (crudSchema.primaryType != 'id') {
-      tableSchemaItem = {
-        ...tableSchemaItem,
-        type: crudSchema.primaryType
-      }
-    }
-    tableSchema.push(tableSchemaItem)
-  }
-
-  eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
-    // 判断是否显示
-    if (schemaItem?.isTable !== false && schemaItem?.table?.show !== false) {
-      const tableSchemaItem = {
-        ...schemaItem.table,
-        field: schemaItem.field,
-        title: schemaItem.table?.title || schemaItem.title,
-        minWidth: '80px'
-      }
-      tableSchemaItem.showOverflow = 'tooltip'
-      if (schemaItem?.formatter) {
-        tableSchemaItem.formatter = schemaItem.formatter
-        tableSchemaItem.width = tableSchemaItem.width ? tableSchemaItem.width : 160
-      }
-      if (schemaItem?.dictType) {
-        tableSchemaItem.cellRender = {
-          name: 'XDict',
-          content: schemaItem.dictType
-        }
-        tableSchemaItem.width = tableSchemaItem.width ? tableSchemaItem.width : 160
-      }
-
-      tableSchema.push(tableSchemaItem)
-    }
-  })
-  // 操作栏插槽
-  if (crudSchema.action && crudSchema.action == true) {
-    const tableSchemaItem = {
-      title: crudSchema.actionTitle ? crudSchema.actionTitle : t('table.action'),
-      field: 'actionbtns',
-      fixed: 'right' as unknown as VxeColumnPropTypes.Fixed,
-      width: crudSchema.actionWidth ? crudSchema.actionWidth : '200px',
-      slots: {
-        default: 'actionbtns_default'
-      }
-    }
-    tableSchema.push(tableSchemaItem)
-  }
-  return tableSchema
-}
-
-// 过滤 form 结构
-const filterFormSchema = (crudSchema: VxeCrudSchema): FormSchema[] => {
-  const formSchema: FormSchema[] = []
-
-  eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
-    // 判断是否显示
-    if (schemaItem?.isForm !== false && schemaItem?.form?.show !== false) {
-      // 默认为 input
-      let component = schemaItem?.form?.component || 'Input'
-      let defaultValue: any = ''
-      if (schemaItem.form?.value) {
-        defaultValue = schemaItem.form?.value
-      } else {
-        if (component === 'InputNumber') {
-          defaultValue = 0
-        }
-      }
-      let comonentProps = {}
-      if (schemaItem.dictType) {
-        const options: ComponentOptions[] = []
-        if (schemaItem.dictClass && schemaItem.dictClass === 'number') {
-          getIntDictOptions(schemaItem.dictType).forEach((dict) => {
-            options.push(dict)
-          })
-        } else if (schemaItem.dictClass && schemaItem.dictClass === 'boolean') {
-          getBoolDictOptions(schemaItem.dictType).forEach((dict) => {
-            options.push(dict)
-          })
-        } else {
-          getDictOptions(schemaItem.dictType).forEach((dict) => {
-            options.push(dict)
-          })
-        }
-        comonentProps = {
-          options: options
-        }
-        if (!(schemaItem.form && schemaItem.form.component)) component = 'Select'
-      }
-      const formSchemaItem = {
-        component: component,
-        componentProps: comonentProps,
-        value: defaultValue,
-        ...schemaItem.form,
-        field: schemaItem.field,
-        label: schemaItem.form?.label || schemaItem.title
-      }
-
-      formSchema.push(formSchemaItem)
-    }
-  })
-
-  return formSchema
-}
-
-// 过滤 descriptions 结构
-const filterDescriptionsSchema = (crudSchema: VxeCrudSchema): DescriptionsSchema[] => {
-  const descriptionsSchema: DescriptionsSchema[] = []
-
-  eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
-    // 判断是否显示
-    if (schemaItem?.isDetail !== false && schemaItem.detail?.show !== false) {
-      const descriptionsSchemaItem = {
-        ...schemaItem.detail,
-        field: schemaItem.field,
-        label: schemaItem.detail?.label || schemaItem.title
-      }
-      if (schemaItem.dictType) {
-        descriptionsSchemaItem.dictType = schemaItem.dictType
-      }
-      if (schemaItem.detail?.dateFormat || schemaItem.formatter == 'formatDate') {
-        // 优先使用 detail 下的配置,如果没有默认为 YYYY-MM-DD HH:mm:ss
-        descriptionsSchemaItem.dateFormat = schemaItem?.detail?.dateFormat
-          ? schemaItem?.detail?.dateFormat
-          : 'YYYY-MM-DD HH:mm:ss'
-      }
-
-      descriptionsSchema.push(descriptionsSchemaItem)
-    }
-  })
-
-  return descriptionsSchema
-}
-
-// 过滤 打印 结构
-const filterPrintSchema = (crudSchema: VxeCrudSchema): any[] => {
-  const printSchema: any[] = []
-
-  eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
-    // 判断是否显示
-    if (schemaItem?.print?.show !== false) {
-      const printSchemaItem = {
-        field: schemaItem.field
-      }
-
-      printSchema.push(printSchemaItem)
-    }
-  })
-
-  return printSchema
-}

+ 0 - 264
src/hooks/web/useVxeGrid.ts

@@ -1,264 +0,0 @@
-import { computed, nextTick, reactive } from 'vue'
-import { SizeType, VxeGridProps, VxeTablePropTypes } from 'vxe-table'
-import { useAppStore } from '@/store/modules/app'
-import { VxeAllSchemas } from './useVxeCrudSchemas'
-
-import download from '@/utils/download'
-
-const { t } = useI18n()
-const message = useMessage() // 消息弹窗
-
-interface UseVxeGridConfig<T = any> {
-  allSchemas: VxeAllSchemas
-  height?: number // 高度 默认730
-  topActionSlots?: boolean // 是否开启表格内顶部操作栏插槽
-  treeConfig?: VxeTablePropTypes.TreeConfig // 树形表单配置
-  isList?: boolean // 是否不带分页的list
-  getListApi: (option: any) => Promise<T> // 获取列表接口
-  getAllListApi?: (option: any) => Promise<T> // 获取全部数据接口 用于VXE导出
-  deleteApi?: (option: any) => Promise<T> // 删除接口
-  exportListApi?: (option: any) => Promise<T> // 导出接口
-  exportName?: string // 导出文件夹名称
-  queryParams?: any // 其他查询参数
-}
-
-const appStore = useAppStore()
-
-const currentSize = computed(() => {
-  let resSize: SizeType = 'small'
-  const appsize = appStore.getCurrentSize
-  switch (appsize) {
-    case 'large':
-      resSize = 'medium'
-      break
-    case 'default':
-      resSize = 'small'
-      break
-    case 'small':
-      resSize = 'mini'
-      break
-  }
-  return resSize
-})
-
-export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => {
-  /**
-   * grid options 初始化
-   */
-  const gridOptions = reactive<VxeGridProps<any>>({
-    loading: true,
-    size: currentSize as any,
-    height: config?.height ? config.height : 730,
-    rowConfig: {
-      isCurrent: true, // 当鼠标点击行时,是否要高亮当前行
-      isHover: true // 当鼠标移到行时,是否要高亮当前行
-    },
-    toolbarConfig: {
-      slots:
-        !config?.topActionSlots && config?.topActionSlots != false
-          ? { buttons: 'toolbar_buttons' }
-          : {}
-    },
-    printConfig: {
-      columns: config?.allSchemas.printSchema
-    },
-    formConfig: {
-      enabled: true,
-      titleWidth: 100,
-      titleAlign: 'right',
-      items: config?.allSchemas.searchSchema
-    },
-    columns: config?.allSchemas.tableSchema,
-    proxyConfig: {
-      seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
-      form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
-      props: { result: 'list', total: 'total' },
-      ajax: {
-        query: ({ page, form }) => {
-          let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
-          if (config?.queryParams) {
-            queryParams = Object.assign(queryParams, config.queryParams)
-          }
-          if (!config?.treeConfig) {
-            queryParams.pageSize = page.pageSize
-            queryParams.pageNo = page.currentPage
-          }
-          gridOptions.loading = false
-          return new Promise(async (resolve) => {
-            resolve(await config?.getListApi(queryParams))
-          })
-        },
-        delete: ({ body }) => {
-          return new Promise(async (resolve) => {
-            if (config?.deleteApi) {
-              resolve(await config?.deleteApi(JSON.stringify(body)))
-            } else {
-              Promise.reject('未设置deleteApi')
-            }
-          })
-        },
-        queryAll: ({ form }) => {
-          const queryParams = Object.assign({}, JSON.parse(JSON.stringify(form)))
-          return new Promise(async (resolve) => {
-            if (config?.getAllListApi) {
-              resolve(await config?.getAllListApi(queryParams))
-            } else {
-              resolve(await config?.getListApi(queryParams))
-            }
-          })
-        }
-      }
-    },
-    exportConfig: {
-      filename: config?.exportName,
-      // 默认选中类型
-      type: 'csv',
-      // 自定义数据量列表
-      modes: config?.getAllListApi ? ['current', 'all'] : ['current'],
-      columns: config?.allSchemas.printSchema
-    }
-  })
-
-  if (config?.treeConfig) {
-    gridOptions.treeConfig = config.treeConfig
-  } else if (config?.isList) {
-    gridOptions.proxyConfig = {
-      seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
-      form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
-      props: { result: 'data' },
-      ajax: {
-        query: ({ form }) => {
-          let queryParams: any = Object.assign({}, JSON.parse(JSON.stringify(form)))
-          if (config?.queryParams) {
-            queryParams = Object.assign(queryParams, config.queryParams)
-          }
-          gridOptions.loading = false
-          return new Promise(async (resolve) => {
-            resolve(await config?.getListApi(queryParams))
-          })
-        }
-      }
-    }
-  } else {
-    gridOptions.pagerConfig = {
-      border: false, // 带边框
-      background: true, // 带背景颜色
-      perfect: false, // 配套的样式
-      pageSize: 10, // 每页大小
-      pagerCount: 7, // 显示页码按钮的数量
-      autoHidden: false, // 当只有一页时自动隐藏
-      pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表
-      layouts: [
-        'PrevJump',
-        'PrevPage',
-        'JumpNumber',
-        'NextPage',
-        'NextJump',
-        'Sizes',
-        'FullJump',
-        'Total'
-      ]
-    }
-  }
-
-  /**
-   * 刷新列表
-   * @param ref
-   * @returns
-   */
-  const getList = async (ref) => {
-    if (!ref) {
-      console.error('未传入gridRef')
-      return
-    }
-    await nextTick()
-    ref.value.commitProxy('query')
-  }
-
-  // 获取查询参数
-  const getSearchData = async (ref) => {
-    if (!ref) {
-      console.error('未传入gridRef')
-      return
-    }
-    await nextTick()
-    const queryParams = Object.assign(
-      {},
-      JSON.parse(JSON.stringify(ref.value.getProxyInfo()?.form))
-    )
-    return queryParams
-  }
-
-  /**
-   * 删除
-   * @param ref
-   * @param ids rowid
-   * @returns
-   */
-  const deleteData = async (ref, ids: string | number) => {
-    if (!ref) {
-      console.error('未传入gridRef')
-      return
-    }
-    if (!config?.deleteApi) {
-      console.error('未传入delListApi')
-      return
-    }
-    await nextTick()
-    return new Promise(async () => {
-      message.delConfirm().then(async () => {
-        await (config?.deleteApi && config?.deleteApi(ids))
-        message.success(t('common.delSuccess'))
-        // 刷新列表
-        ref.value.commitProxy('query')
-      })
-    })
-  }
-  /**
-   * 导出
-   * @param ref
-   * @param fileName 文件名,默认excel.xls
-   * @returns
-   */
-  const exportList = async (ref, fileName?: string) => {
-    if (!ref) {
-      console.error('未传入gridRef')
-      return
-    }
-    if (!config?.exportListApi) {
-      console.error('未传入exportListApi')
-      return
-    }
-    await nextTick()
-    const queryParams = Object.assign(
-      {},
-      JSON.parse(JSON.stringify(ref.value?.getProxyInfo()?.form))
-    )
-    message.exportConfirm().then(async () => {
-      const res = await (config?.exportListApi && config?.exportListApi(queryParams))
-      download.excel(res as unknown as Blob, fileName ? fileName : 'excel.xls')
-    })
-  }
-  /**
-   * 表格最大/最小化
-   * @param ref
-   * @returns
-   */
-  const zoom = async (ref) => {
-    if (!ref) {
-      console.error('未传入gridRef')
-      return
-    }
-    await nextTick()
-    ref.value.zoom(!ref.value.isMaximized())
-  }
-
-  return {
-    gridOptions,
-    getList,
-    getSearchData,
-    deleteData,
-    exportList,
-    zoom
-  }
-}

+ 0 - 39
src/hooks/web/useXTable.ts

@@ -1,39 +0,0 @@
-import { XTableProps } from '@/components/XTable/src/type'
-
-export interface tableMethod {
-  reload: () => void // 刷新表格
-  setProps: (props: XTableProps) => void
-  deleteData: (id: string | number) => void // 删除数据
-  deleteBatch: () => void // 批量删除
-  exportList: (fileName?: string) => void // 导出列表
-  getCurrentColumn: () => void // 获取当前列
-  getRadioRecord: () => void // 获取当前选中列,radio
-  getCheckboxRecords: () => void //获取当前选中列, checkbox
-}
-
-export const useXTable = (props: XTableProps): [Function, tableMethod] => {
-  const tableRef = ref<Nullable<tableMethod>>(null)
-
-  const register = (instance) => {
-    tableRef.value = instance
-    props && instance.setProps(props)
-  }
-  const getInstance = (): tableMethod => {
-    const table = unref(tableRef)
-    if (!table) {
-      console.error('表格实例不存在')
-    }
-    return table as tableMethod
-  }
-  const methods: tableMethod = {
-    reload: () => getInstance().reload(),
-    setProps: (props) => getInstance().setProps(props),
-    deleteData: (id: string | number) => getInstance().deleteData(id),
-    deleteBatch: () => getInstance().deleteBatch(),
-    exportList: (fileName?: string) => getInstance().exportList(fileName),
-    getCurrentColumn: () => getInstance().getCheckboxRecords(),
-    getRadioRecord: () => getInstance().getRadioRecord(),
-    getCheckboxRecords: () => getInstance().getCheckboxRecords()
-  }
-  return [register, methods]
-}

+ 6 - 5
src/layout/components/AppView.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="AppView" setup>
 import { useTagsViewStore } from '@/store/modules/tagsView'
 import { useAppStore } from '@/store/modules/app'
 import { Footer } from '@/layout/components/Footer'
@@ -21,16 +21,17 @@ const getCaches = computed((): string[] => {
 <template>
   <section
     :class="[
-      'p-[var(--app-content-padding)] w-[100%] bg-[var(--app-contnet-bg-color)] dark:bg-[var(--el-bg-color)]',
+      'p-[var(--app-content-padding)] w-[100%] bg-[var(--app-content-bg-color)] dark:bg-[var(--el-bg-color)]',
       {
         '!min-h-[calc(100%-var(--app-footer-height))]':
-          fixedHeader && (layout === 'classic' || layout === 'topLeft') && footer,
+          ((fixedHeader && (layout === 'classic' || layout === 'topLeft')) || layout === 'top') &&
+          footer,
 
         '!min-h-[calc(100%-var(--tags-view-height)-var(--top-tool-height)-var(--app-footer-height))]':
-          ((!fixedHeader && layout === 'classic') || layout === 'top') && footer,
+          !fixedHeader && layout === 'classic' && footer,
 
         '!min-h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]':
-          !fixedHeader && layout === 'topLeft' && footer,
+          !fixedHeader && (layout === 'topLeft' || layout === 'top') && footer,
 
         '!min-h-[calc(100%-var(--top-tool-height))]': fixedHeader && layout === 'cutMenu' && footer,
 

+ 3 - 3
src/layout/components/Collapse/src/Collapse.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="Collapse" setup>
 import { useAppStore } from '@/store/modules/app'
 import { propTypes } from '@/utils/propTypes'
 import { useDesign } from '@/hooks/web/useDesign'
@@ -24,9 +24,9 @@ const toggleCollapse = () => {
 <template>
   <div :class="prefixCls">
     <Icon
-      :size="18"
-      :icon="collapse ? 'ep:expand' : 'ep:fold'"
       :color="color"
+      :icon="collapse ? 'ep:expand' : 'ep:fold'"
+      :size="18"
       class="cursor-pointer"
       @click="toggleCollapse"
     />

+ 6 - 5
src/layout/components/ContextMenu/src/ContextMenu.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="ContextMenu" setup>
 import { PropType } from 'vue'
 
 import { useDesign } from '@/hooks/web/useDesign'
@@ -51,9 +51,9 @@ defineExpose({
     :class="prefixCls"
     :trigger="trigger"
     placement="bottom-start"
+    popper-class="v-context-menu-popper"
     @command="command"
     @visible-change="visibleChange"
-    popper-class="v-context-menu-popper"
   >
     <slot></slot>
     <template #dropdown>
@@ -61,11 +61,12 @@ defineExpose({
         <ElDropdownItem
           v-for="(item, index) in schema"
           :key="`dropdown${index}`"
-          :divided="item.divided"
-          :disabled="item.disabled"
           :command="item"
+          :disabled="item.disabled"
+          :divided="item.divided"
         >
-          <Icon :icon="item.icon" /> {{ t(item.label) }}
+          <Icon :icon="item.icon" />
+          {{ t(item.label) }}
         </ElDropdownItem>
       </ElDropdownMenu>
     </template>

+ 1 - 1
src/layout/components/Footer/src/Footer.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="Footer" setup>
 import { useAppStore } from '@/store/modules/app'
 import { useDesign } from '@/hooks/web/useDesign'
 

+ 4 - 4
src/layout/components/LocaleDropdown/src/LocaleDropdown.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="LocaleDropdown" setup>
 import { useLocaleStore } from '@/store/modules/locale'
 import { useLocale } from '@/hooks/web/useLocale'
 import { propTypes } from '@/utils/propTypes'
@@ -33,11 +33,11 @@ const setLang = (lang: LocaleType) => {
 <template>
   <ElDropdown :class="prefixCls" trigger="click" @command="setLang">
     <Icon
-      :size="18"
-      icon="ion:language-sharp"
-      class="cursor-pointer"
       :class="$attrs.class"
       :color="color"
+      :size="18"
+      class="cursor-pointer"
+      icon="ion:language-sharp"
     />
     <template #dropdown>
       <ElDropdownMenu>

+ 3 - 3
src/layout/components/Logo/src/Logo.vue

@@ -1,5 +1,5 @@
-<script setup lang="ts">
-import { ref, watch, computed, onMounted, unref } from 'vue'
+<script lang="ts" name="Logo" setup>
+import { computed, onMounted, ref, unref, watch } from 'vue'
 import { useAppStore } from '@/store/modules/app'
 import { useDesign } from '@/hooks/web/useDesign'
 
@@ -66,8 +66,8 @@ watch(
       to="/"
     >
       <img
-        src="@/assets/imgs/logo.png"
         class="w-[calc(var(--logo-height)-10px)] h-[calc(var(--logo-height)-10px)]"
+        src="@/assets/imgs/logo.png"
       />
       <div
         v-if="show"

+ 13 - 6
src/layout/components/Message/src/Message.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="Message" setup>
 import { formatDate } from '@/utils/formatTime'
 import * as NotifyMessageApi from '@/api/system/notify/message'
 
@@ -40,10 +40,10 @@ onMounted(() => {
 </script>
 <template>
   <div class="message">
-    <ElPopover placement="bottom" :width="400" trigger="click">
+    <ElPopover :width="400" placement="bottom" trigger="click">
       <template #reference>
         <ElBadge :is-dot="unreadCount > 0" class="item">
-          <Icon icon="ep:bell" :size="18" class="cursor-pointer" @click="getList" />
+          <Icon :size="18" class="cursor-pointer" icon="ep:bell" @click="getList" />
         </ElBadge>
       </template>
       <ElTabs v-model="activeName">
@@ -51,7 +51,7 @@ onMounted(() => {
           <div class="message-list">
             <template v-for="item in list" :key="item.id">
               <div class="message-item">
-                <img src="@/assets/imgs/avatar.gif" alt="" class="message-icon" />
+                <img alt="" class="message-icon" src="@/assets/imgs/avatar.gif" />
                 <div class="message-content">
                   <span class="message-title">
                     {{ item.templateNickname }}:{{ item.templateContent }}
@@ -67,12 +67,12 @@ onMounted(() => {
       </ElTabs>
       <!-- 更多 -->
       <div style="text-align: right; margin-top: 10px">
-        <XButton type="primary" preIcon="ep:view" title="查看全部" @click="goMyList" />
+        <XButton preIcon="ep:view" title="查看全部" type="primary" @click="goMyList" />
       </div>
     </ElPopover>
   </div>
 </template>
-<style scoped lang="scss">
+<style lang="scss" scoped>
 .message-empty {
   display: flex;
   flex-direction: column;
@@ -81,28 +81,35 @@ onMounted(() => {
   height: 260px;
   line-height: 45px;
 }
+
 .message-list {
   display: flex;
   flex-direction: column;
+
   .message-item {
     display: flex;
     align-items: center;
     padding: 20px 0;
     border-bottom: 1px solid var(--el-border-color-light);
+
     &:last-child {
       border: none;
     }
+
     .message-icon {
       width: 40px;
       height: 40px;
       margin: 0 20px 0 5px;
     }
+
     .message-content {
       display: flex;
       flex-direction: column;
+
       .message-title {
         margin-bottom: 5px;
       }
+
       .message-date {
         font-size: 12px;
         color: var(--el-text-color-secondary);

+ 3 - 3
src/layout/components/Screenfull/src/Screenfull.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="ScreenFull" setup>
 import { Icon } from '@/components/Icon'
 import { useFullscreen } from '@vueuse/core'
 import { propTypes } from '@/utils/propTypes'
@@ -22,9 +22,9 @@ const toggleFullscreen = () => {
 <template>
   <div :class="prefixCls" @click="toggleFullscreen">
     <Icon
-      :size="18"
-      :icon="isFullscreen ? 'zmdi:fullscreen-exit' : 'zmdi:fullscreen'"
       :color="color"
+      :icon="isFullscreen ? 'zmdi:fullscreen-exit' : 'zmdi:fullscreen'"
+      :size="18"
     />
   </div>
 </template>

+ 8 - 8
src/layout/components/Setting/src/Setting.vue

@@ -1,12 +1,12 @@
-<script setup lang="ts">
+<script lang="ts" name="Setting" setup>
 import { ElMessage } from 'element-plus'
-import { useCssVar, useClipboard } from '@vueuse/core'
+import { useClipboard, useCssVar } from '@vueuse/core'
 
 import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { useDesign } from '@/hooks/web/useDesign'
 
-import { trim, setCssVar } from '@/utils'
-import { colorIsDark, lighten, hexToRGB } from '@/utils/color'
+import { setCssVar, trim } from '@/utils'
+import { colorIsDark, hexToRGB, lighten } from '@/utils/color'
 import { useAppStore } from '@/store/modules/app'
 import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
 import ColorRadioPicker from './components/ColorRadioPicker.vue'
@@ -202,10 +202,10 @@ const clear = () => {
     class="fixed top-[45%] right-0 w-40px h-40px text-center leading-40px bg-[var(--el-color-primary)] cursor-pointer"
     @click="drawer = true"
   >
-    <Icon icon="ep:setting" color="#fff" />
+    <Icon color="#fff" icon="ep:setting" />
   </div>
 
-  <ElDrawer v-model="drawer" direction="rtl" size="350px" :z-index="4000">
+  <ElDrawer v-model="drawer" :z-index="4000" direction="rtl" size="350px">
     <template #header>
       <span class="text-16px font-700">{{ t('setting.projectSetting') }}</span>
     </template>
@@ -279,10 +279,10 @@ const clear = () => {
 
     <ElDivider />
     <div>
-      <ElButton type="primary" class="w-full" @click="copyConfig">{{ t('setting.copy') }}</ElButton>
+      <ElButton class="w-full" type="primary" @click="copyConfig">{{ t('setting.copy') }}</ElButton>
     </div>
     <div class="mt-5px">
-      <ElButton type="danger" class="w-full" @click="clear">
+      <ElButton class="w-full" type="danger" @click="clear">
         {{ t('setting.clearAndReset') }}
       </ElButton>
     </div>

+ 3 - 3
src/layout/components/Setting/src/components/ColorRadioPicker.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="ColorRadioPicker" setup>
 import { PropType } from 'vue'
 import { propTypes } from '@/utils/propTypes'
 import { useDesign } from '@/hooks/web/useDesign'
@@ -42,14 +42,14 @@ watch(
     <span
       v-for="(item, i) in schema"
       :key="`radio-${i}`"
-      class="w-20px h-20px cursor-pointer rounded-2px border-solid border-gray-300 border-2px text-center leading-20px mb-5px"
       :class="{ 'is-active': colorVal === item }"
       :style="{
         background: item
       }"
+      class="w-20px h-20px cursor-pointer rounded-2px border-solid border-gray-300 border-2px text-center leading-20px mb-5px"
       @click="colorVal = item"
     >
-      <Icon v-if="colorVal === item" color="#fff" icon="ep:check" :size="16" />
+      <Icon v-if="colorVal === item" :size="16" color="#fff" icon="ep:check" />
     </span>
   </div>
 </template>

+ 1 - 1
src/layout/components/Setting/src/components/InterfaceDisplay.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="InterfaceDisplay" setup>
 import { setCssVar } from '@/utils'
 
 import { useDesign } from '@/hooks/web/useDesign'

+ 1 - 1
src/layout/components/Setting/src/components/LayoutRadioPicker.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="LayoutRadioPicker" setup>
 import { useAppStore } from '@/store/modules/app'
 import { useDesign } from '@/hooks/web/useDesign'
 

+ 2 - 2
src/layout/components/SizeDropdown/src/SizeDropdown.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="SizeDropdown" setup>
 import { useAppStore } from '@/store/modules/app'
 
 import { propTypes } from '@/utils/propTypes'
@@ -26,7 +26,7 @@ const setCurrentSize = (size: ElementPlusSize) => {
 
 <template>
   <ElDropdown :class="prefixCls" trigger="click" @command="setCurrentSize">
-    <Icon :size="18" icon="mdi:format-size" :color="color" class="cursor-pointer" />
+    <Icon :color="color" :size="18" class="cursor-pointer" icon="mdi:format-size" />
     <template #dropdown>
       <ElDropdownMenu>
         <ElDropdownItem v-for="item in sizeMap" :key="item" :command="item">

+ 21 - 18
src/layout/components/TagsView/src/TagsView.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="TagsView" setup>
 import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router'
 import { usePermissionStore } from '@/store/modules/permission'
 import { useTagsViewStore } from '@/store/modules/tagsView'
@@ -266,15 +266,24 @@ watch(
       @click="move(-200)"
     >
       <Icon
-        icon="ep:d-arrow-left"
         :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
+        icon="ep:d-arrow-left"
       />
     </span>
     <div class="overflow-hidden flex-1">
       <ElScrollbar ref="scrollbarRef" class="h-full" @scroll="scroll">
         <div class="flex h-full">
           <ContextMenu
+            v-for="item in visitedViews"
+            :key="item.fullPath"
             :ref="itemRefs.set"
+            :class="[
+              `${prefixCls}__item`,
+              item?.meta?.affix ? `${prefixCls}__item--affix` : '',
+              {
+                'is-active': isActive(item)
+              }
+            ]"
             :schema="[
               {
                 icon: 'ep:refresh',
@@ -332,23 +341,14 @@ watch(
                 }
               }
             ]"
-            v-for="item in visitedViews"
-            :key="item.fullPath"
             :tag-item="item"
-            :class="[
-              `${prefixCls}__item`,
-              item?.meta?.affix ? `${prefixCls}__item--affix` : '',
-              {
-                'is-active': isActive(item)
-              }
-            ]"
             @visible-change="visibleChange"
           >
             <div>
-              <router-link :ref="tagLinksRefs.set" :to="{ ...item }" custom v-slot="{ navigate }">
+              <router-link :ref="tagLinksRefs.set" v-slot="{ navigate }" :to="{ ...item }" custom>
                 <div
-                  @click="navigate"
                   class="h-full flex justify-center items-center whitespace-nowrap pl-15px"
+                  @click="navigate"
                 >
                   <Icon
                     v-if="
@@ -364,9 +364,9 @@ watch(
                   {{ t(item?.meta?.title as string) }}
                   <Icon
                     :class="`${prefixCls}__item--close`"
+                    :size="12"
                     color="#333"
                     icon="ep:close"
-                    :size="12"
                     @click.prevent.stop="closeSelectedTag(item)"
                   />
                 </div>
@@ -382,8 +382,8 @@ watch(
       @click="move(200)"
     >
       <Icon
-        icon="ep:d-arrow-right"
         :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
+        icon="ep:d-arrow-right"
       />
     </span>
     <span
@@ -392,12 +392,11 @@ watch(
       @click="refreshSelectedTag(selectedTag)"
     >
       <Icon
-        icon="ep:refresh-right"
         :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
+        icon="ep:refresh-right"
       />
     </span>
     <ContextMenu
-      trigger="click"
       :schema="[
         {
           icon: 'ep:refresh',
@@ -449,14 +448,15 @@ watch(
           }
         }
       ]"
+      trigger="click"
     >
       <span
         :class="`${prefixCls}__tool`"
         class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer block"
       >
         <Icon
-          icon="ep:menu"
           :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'"
+          icon="ep:menu"
         />
       </span>
     </ContextMenu>
@@ -513,6 +513,7 @@ $prefix-cls: #{$namespace}-tags-view;
       display: none;
       transform: translate(0, -50%);
     }
+
     &:not(.#{$prefix-cls}__item--affix):hover {
       .#{$prefix-cls}__item--close {
         display: block;
@@ -530,6 +531,7 @@ $prefix-cls: #{$namespace}-tags-view;
     color: var(--el-color-white);
     background-color: var(--el-color-primary);
     border: 1px solid var(--el-color-primary);
+
     .#{$prefix-cls}__item--close {
       :deep(span) {
         color: var(--el-color-white) !important;
@@ -573,6 +575,7 @@ $prefix-cls: #{$namespace}-tags-view;
     &__item.is-active {
       color: var(--el-color-white);
       background-color: var(--el-color-primary);
+
       .#{$prefix-cls}__item--close {
         :deep(span) {
           color: var(--el-color-white) !important;

+ 5 - 5
src/layout/components/ThemeSwitch/src/ThemeSwitch.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="ThemeSwitch" setup>
 import { useAppStore } from '@/store/modules/app'
 import { useIcon } from '@/hooks/web/useIcon'
 import { useDesign } from '@/hooks/web/useDesign'
@@ -26,14 +26,14 @@ const themeChange = (val: boolean) => {
 
 <template>
   <ElSwitch
-    :class="prefixCls"
     v-model="isDark"
-    inline-prompt
-    :border-color="blackColor"
-    :inactive-color="blackColor"
     :active-color="blackColor"
     :active-icon="Sun"
+    :border-color="blackColor"
+    :class="prefixCls"
+    :inactive-color="blackColor"
     :inactive-icon="CrescentMoon"
+    inline-prompt
     @change="themeChange"
   />
 </template>

+ 1 - 1
src/layout/components/UserInfo/src/UserInfo.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" name="UserInfo" setup>
 import { ElMessageBox } from 'element-plus'
 
 import { CACHE_KEY, useCache } from '@/hooks/web/useCache'

+ 3 - 1
src/layout/components/useRenderLayout.tsx

@@ -177,7 +177,9 @@ export const useRenderLayout = () => {
             class={[
               `${prefixCls}-content-scrollbar`,
               {
-                'mt-[var(--tags-view-height)]': fixedHeader.value
+                'mt-[var(--tags-view-height)] !pb-[calc(var(--tags-view-height)+var(--app-footer-height))]':
+                  fixedHeader.value,
+                'pb-[var(--app-footer-height)]': !fixedHeader.value
               }
             ]}
           >

+ 0 - 32
src/main.ts

@@ -16,9 +16,6 @@ import { setupGlobCom } from '@/components'
 // 引入 element-plus
 import { setupElementPlus } from '@/plugins/elementPlus'
 
-// 引入 vxe-table
-import { setupVxeTable } from '@/plugins/vxeTable'
-
 // 引入 form-create
 import { setupFormCreate } from '@/plugins/formCreate'
 
@@ -40,51 +37,22 @@ import App from './App.vue'
 
 import './permission'
 
-import { isDevMode } from '@/utils/env'
-
-import { MyPD } from '@/components/bpmnProcessDesigner/package/index.js'
-import '@/components/bpmnProcessDesigner/package/theme/index.scss'
-import 'bpmn-js/dist/assets/diagram-js.css'
-import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
-import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
-import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
-
-import hljs from 'highlight.js' //导入代码高亮文件
-import 'highlight.js/styles/github.css' //导入代码高亮样式  新版
-
 import '@/plugins/tongji' // 百度统计
 
 import Logger from '@/utils/Logger'
 
-// 本地开发模式 全局引入 element-plus 样式,加快第一次进入速度
-if (isDevMode()) {
-  import('element-plus/dist/index.css')
-}
-
 // 创建实例
 const setupAll = async () => {
   const app = createApp(App)
 
-  //自定义一个代码高亮指令
-  app.directive('highlight', function (el) {
-    const blocks = el.querySelectorAll('code')
-    blocks.forEach((block: any) => {
-      hljs.highlightElement(block)
-    })
-  })
-
   await setupI18n(app)
 
-  MyPD(app)
-
   setupStore(app)
 
   setupGlobCom(app)
 
   setupElementPlus(app)
 
-  setupVxeTable(app)
-
   setupFormCreate(app)
 
   setupRouter(app)

+ 1 - 5
src/plugins/formCreate/index.ts

@@ -17,7 +17,6 @@ import {
 
 import formCreate from '@form-create/element-ui'
 import install from '@form-create/element-ui/auto-import'
-import FcDesigner from '@form-create/designer'
 
 const components = [
   ElAside,
@@ -34,14 +33,11 @@ const components = [
   ElTabPane
 ]
 
+// 参考 http://www.form-create.com/v3/element-ui/auto-import.html 文档
 export const setupFormCreate = (app: App<Element>) => {
   components.forEach((component) => {
     app.component(component.name, component)
   })
-
   formCreate.use(install)
-
   app.use(formCreate)
-
-  app.use(FcDesigner)
 }

+ 0 - 223
src/plugins/vxeTable/index.ts

@@ -1,223 +0,0 @@
-import { App } from 'vue'
-import XEUtils from 'xe-utils'
-import './renderer'
-import 'vxe-table/lib/style.css'
-import { i18n } from '@/plugins/vueI18n'
-import zhCN from 'vxe-table/lib/locale/lang/zh-CN'
-import enUS from 'vxe-table/lib/locale/lang/en-US'
-import {
-  // 全局对象
-  VXETable,
-  // 表格功能
-  Filter,
-  Edit,
-  Menu,
-  Export,
-  Keyboard,
-  Validator,
-  // 可选组件
-  Icon,
-  Column,
-  Colgroup,
-  Grid,
-  Tooltip,
-  Toolbar,
-  Pager,
-  Form,
-  FormItem,
-  FormGather,
-  Checkbox,
-  CheckboxGroup,
-  Radio,
-  RadioGroup,
-  RadioButton,
-  Switch,
-  Input,
-  Select,
-  Optgroup,
-  Option,
-  Textarea,
-  Button,
-  Modal,
-  List,
-  Pulldown,
-  // 表格
-  Table
-} from 'vxe-table'
-
-// 全局默认参数
-VXETable.setup({
-  size: 'medium', // 全局尺寸
-  version: 0, // 版本号,对于某些带数据缓存的功能有用到,上升版本号可以用于重置数据
-  zIndex: 1008, // 全局 zIndex 起始值,如果项目的的 z-index 样式值过大时就需要跟随设置更大,避免被遮挡
-  loadingText: '加载中...', // 全局loading提示内容,如果为null则不显示文本
-  height: 600,
-  table: {
-    border: 'inner', // default(默认), full(完整边框), outer(外边框), inner(内边框), none(无边框)
-    align: 'center', // eft(左对齐), center(居中对齐), right(右对齐)
-    autoResize: true, // 自动监听父元素的变化去重新计算表格
-    resizable: true, // 列是否允许拖动列宽调整大小
-    emptyText: '暂无数据', // 空表单
-    highlightHoverRow: true, // 自动监听父元素的变化去重新计算表格
-    treeConfig: {
-      rowField: 'id',
-      parentField: 'parentId',
-      children: 'children',
-      indent: 20,
-      showIcon: true
-    }
-  },
-  grid: {
-    toolbarConfig: {
-      refresh: true,
-      export: true,
-      print: true,
-      zoom: true,
-      custom: true
-    },
-    pagerConfig: {
-      border: false,
-      background: false,
-      autoHidden: true,
-      perfect: true,
-      pageSize: 10,
-      pagerCount: 7,
-      pageSizes: [5, 10, 15, 20, 50, 100, 200, 500],
-      layouts: [
-        'Sizes',
-        'PrevJump',
-        'PrevPage',
-        'Number',
-        'NextPage',
-        'NextJump',
-        'FullJump',
-        'Total'
-      ]
-    }
-  },
-  pager: {
-    background: false,
-    autoHidden: false,
-    perfect: true,
-    pageSize: 10,
-    pagerCount: 7,
-    pageSizes: [10, 15, 20, 50, 100],
-    layouts: ['PrevJump', 'PrevPage', 'Jump', 'PageCount', 'NextPage', 'NextJump', 'Sizes', 'Total']
-  },
-  input: {
-    clearable: true
-  },
-  form: {
-    titleColon: true // 是否显示标题冒号
-  },
-  modal: {
-    width: 800, // 窗口的宽度
-    height: 600, // 窗口的高度
-    minWidth: 460,
-    minHeight: 320,
-    showZoom: true, // 标题是否标显示最大化与还原按钮
-    resize: true, // 是否允许窗口边缘拖动调整窗口大小
-    marginSize: 0, // 只对 resize 启用后有效,用于设置可拖动界限范围,如果为负数则允许拖动超出屏幕边界
-    remember: false, // 记忆功能,会记住最后操作状态,再次打开窗口时还原窗口状态
-    destroyOnClose: true, // 在窗口关闭时销毁内容
-    storage: false, // 是否启用 localStorage 本地保存,会将窗口拖动的状态保存到本地
-    transfer: true, // 是否将弹框容器插入于 body 内
-    showFooter: true, // 是否显示底部
-    mask: true, // 是否显示遮罩层
-    maskClosable: true, // 是否允许点击遮罩层关闭窗口
-    escClosable: true // 是否允许按 Esc 键关闭窗口
-  },
-  i18n: (key, args) => {
-    return unref(i18n.global.locale) === 'zh-CN'
-      ? XEUtils.toFormatString(XEUtils.get(zhCN, key), args)
-      : XEUtils.toFormatString(XEUtils.get(enUS, key), args)
-  }
-})
-// 自定义全局的格式化处理函数
-VXETable.formats.mixin({
-  // 格式精简日期,默认 yyyy-MM-dd HH:mm:ss
-  formatDay({ cellValue }, format) {
-    if (cellValue != null) {
-      return XEUtils.toDateString(cellValue, format || 'yyyy-MM-dd')
-    } else {
-      return ''
-    }
-  },
-  // 格式完整日期,默认 yyyy-MM-dd HH:mm:ss
-  formatDate({ cellValue }, format) {
-    if (cellValue != null) {
-      return XEUtils.toDateString(cellValue, format || 'yyyy-MM-dd HH:mm:ss')
-    } else {
-      return ''
-    }
-  },
-  // 四舍五入金额,每隔3位逗号分隔,默认2位数
-  formatAmount({ cellValue }, digits = 2) {
-    return XEUtils.commafy(Number(cellValue), { digits })
-  },
-  // 格式化银行卡,默认每4位空格隔开
-  formatBankcard({ cellValue }) {
-    return XEUtils.commafy(XEUtils.toValueString(cellValue), { spaceNumber: 4, separator: ' ' })
-  },
-  // 四舍五入,默认两位数
-  formatFixedNumber({ cellValue }, digits = 2) {
-    return XEUtils.toFixed(XEUtils.round(cellValue, digits), digits)
-  },
-  // 向下舍入,默认两位数
-  formatCutNumber({ cellValue }, digits = 2) {
-    return XEUtils.toFixed(XEUtils.floor(cellValue, digits), digits)
-  },
-  // 格式化图片,将图片链接转换为html标签
-  formatImg({ cellValue }) {
-    return '<img height="40" src="' + cellValue + '"> '
-  },
-  // 格式化文件大小
-  formatSize({ cellValue }, digits = 0) {
-    const unitArr = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
-    const srcSize = parseFloat(cellValue)
-    const index = Math.floor(Math.log(srcSize) / Math.log(1024))
-    const size = srcSize / Math.pow(1024, index)
-    return XEUtils.toFixed(XEUtils.floor(size, 2), 2) + ' ' + unitArr[digits]
-  }
-})
-export const setupVxeTable = (app: App<Element>) => {
-  // 表格功能
-  app.use(Filter).use(Edit).use(Menu).use(Export).use(Keyboard).use(Validator)
-
-  // 可选组件
-  app
-    .use(Icon)
-    .use(Column)
-    .use(Colgroup)
-    .use(Grid)
-    .use(Tooltip)
-    .use(Toolbar)
-    .use(Pager)
-    .use(Form)
-    .use(FormItem)
-    .use(FormGather)
-    .use(Checkbox)
-    .use(CheckboxGroup)
-    .use(Radio)
-    .use(RadioGroup)
-    .use(RadioButton)
-    .use(Switch)
-    .use(Input)
-    .use(Select)
-    .use(Optgroup)
-    .use(Option)
-    .use(Textarea)
-    .use(Button)
-    .use(Modal)
-    .use(List)
-    .use(Pulldown)
-
-    // 安装表格
-    .use(Table)
-
-  // 给 vue 实例挂载内部对象,例如:
-  // app.config.globalProperties.$XModal = VXETable.modal
-  // app.config.globalProperties.$XPrint = VXETable.print
-  // app.config.globalProperties.$XSaveFile = VXETable.saveFile
-  // app.config.globalProperties.$XReadFile = VXETable.readFile
-}

+ 0 - 20
src/plugins/vxeTable/renderer/dataPicker.tsx

@@ -1,20 +0,0 @@
-import { ElDatePicker } from 'element-plus'
-import { VXETable } from 'vxe-table'
-
-// 日期区间选择渲染
-VXETable.renderer.add('XDataPicker', {
-  // 默认显示模板
-  renderItemContent(renderOpts, params) {
-    const { data, field } = params
-    const { content } = renderOpts
-    return (
-      <ElDatePicker
-        v-model={data[field]}
-        style="width: 100%"
-        type={content ? (content as any) : 'datetime'}
-        value-format="YYYY-MM-DD HH:mm:ss"
-        clearable
-      ></ElDatePicker>
-    )
-  }
-})

+ 0 - 23
src/plugins/vxeTable/renderer/dataTimeRangePicker.tsx

@@ -1,23 +0,0 @@
-import { ElDatePicker } from 'element-plus'
-import { VXETable } from 'vxe-table'
-
-// 日期区间选择渲染
-VXETable.renderer.add('XDataTimePicker', {
-  // 默认显示模板
-  renderItemContent(renderOpts, params) {
-    const { t } = useI18n()
-    const { data, field } = params
-    const { content } = renderOpts
-    return (
-      <ElDatePicker
-        v-model={data[field]}
-        style="width: 100%"
-        type={content ? (content as any) : 'datetimerange'}
-        value-format="YYYY-MM-DD HH:mm:ss"
-        range-separator="-"
-        start-placeholder={t('common.startTimeText')}
-        end-placeholder={t('common.endTimeText')}
-      ></ElDatePicker>
-    )
-  }
-})

+ 0 - 12
src/plugins/vxeTable/renderer/dict.tsx

@@ -1,12 +0,0 @@
-import { DictTag } from '@/components/DictTag'
-import { VXETable } from 'vxe-table'
-
-// 字典渲染
-VXETable.renderer.add('XDict', {
-  // 默认显示模板
-  renderDefault(renderOpts, params) {
-    const { row, column } = params
-    const { content } = renderOpts
-    return <DictTag type={content as unknown as string} value={row[column.field]}></DictTag>
-  }
-})

+ 0 - 10
src/plugins/vxeTable/renderer/html.tsx

@@ -1,10 +0,0 @@
-import { VXETable } from 'vxe-table'
-
-// 图片渲染
-VXETable.renderer.add('XHtml', {
-  // 默认显示模板
-  renderDefault(_renderOpts, params) {
-    const { row, column } = params
-    return <span v-html={row[column.field]}></span>
-  }
-})

+ 0 - 20
src/plugins/vxeTable/renderer/img.tsx

@@ -1,20 +0,0 @@
-import { VXETable } from 'vxe-table'
-import { ElImage } from 'element-plus'
-
-// 图片渲染
-VXETable.renderer.add('XImg', {
-  // 默认显示模板
-  renderDefault(_renderOpts, params) {
-    const { row, column } = params
-    return (
-      <ElImage
-        style="width: 80px; height: 50px"
-        src={row[column.field]}
-        key={row[column.field]}
-        preview-src-list={[row[column.field]]}
-        fit="contain"
-        lazy
-      ></ElImage>
-    )
-  }
-})

+ 0 - 7
src/plugins/vxeTable/renderer/index.tsx

@@ -1,7 +0,0 @@
-import './dataPicker'
-import './dataTimeRangePicker'
-import './dict'
-import './html'
-import './link'
-import './img'
-import './preview'

+ 0 - 15
src/plugins/vxeTable/renderer/link.tsx

@@ -1,15 +0,0 @@
-import { VXETable } from 'vxe-table'
-
-// 超链接渲染
-VXETable.renderer.add('XLink', {
-  // 默认显示模板
-  renderDefault(renderOpts, params) {
-    const { row, column } = params
-    const { events = {} } = renderOpts
-    return (
-      <a class="link" onClick={() => events.click(params)}>
-        {row[column.field]}
-      </a>
-    )
-  }
-})

+ 0 - 35
src/plugins/vxeTable/renderer/preview.tsx

@@ -1,35 +0,0 @@
-import { VXETable } from 'vxe-table'
-import { ElImage, ElLink } from 'element-plus'
-
-// 图片渲染
-VXETable.renderer.add('XPreview', {
-  // 默认显示模板
-  renderDefault(_renderOpts, params) {
-    const { row, column } = params
-    if (row.type.indexOf('image/') === 0) {
-      return (
-        <ElImage
-          style="width: 80px; height: 50px"
-          src={row[column.field]}
-          key={row[column.field]}
-          preview-src-list={[row[column.field]]}
-          fit="contain"
-          lazy
-        ></ElImage>
-      )
-    } else if (row.type.indexOf('video/') === 0) {
-      return (
-        <video>
-          <source src={row[column.field]}></source>
-        </video>
-      )
-    } else {
-      return (
-        // @ts-ignore
-        <ElLink href={row[column.field]} target="_blank">
-          {row[column.field]}
-        </ElLink>
-      )
-    }
-  }
-})

+ 41 - 6
src/router/modules/remaining.ts

@@ -2,9 +2,9 @@ import { Layout } from '@/utils/routerHelper'
 
 const { t } = useI18n()
 /**
-* redirect: noredirect        当设置 noredirect 的时候该路由在面包屑导航中不可被点击
-* name:'router-name'          设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
-* meta : {
+ * redirect: noredirect        当设置 noredirect 的时候该路由在面包屑导航中不可被点击
+ * name:'router-name'          设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
+ * meta : {
     hidden: true              当设置 true 的时候该路由不会再侧边栏出现 如404,login等页面(默认 false)
 
     alwaysShow: true          当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式,
@@ -31,7 +31,7 @@ const { t } = useI18n()
 
     canTo: true               设置为true即使hidden为true,也依然可以进行路由跳转(默认 false)
   }
-**/
+ **/
 const remainingRouter: AppRouteRecordRaw[] = [
   {
     path: '/redirect',
@@ -272,7 +272,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
       {
         path: '/manager/task-assign-rule',
         component: () => import('@/views/bpm/taskAssignRule/index.vue'),
-        name: 'BpmTaskAssignRule',
+        name: 'BpmTaskAssignRuleList',
         meta: {
           noCache: true,
           hidden: true,
@@ -313,7 +313,19 @@ const remainingRouter: AppRouteRecordRaw[] = [
           hidden: true,
           canTo: true,
           title: '发起 OA 请假',
-          activeMenu: 'bpm/oa/leave/create'
+          activeMenu: '/bpm/oa/leave'
+        }
+      },
+      {
+        path: '/bpm/oa/leave/detail',
+        component: () => import('@/views/bpm/oa/leave/detail.vue'),
+        name: 'OALeaveDetail',
+        meta: {
+          noCache: true,
+          hidden: true,
+          canTo: true,
+          title: '查看 OA 请假',
+          activeMenu: '/bpm/oa/leave'
         }
       }
     ]
@@ -355,6 +367,29 @@ const remainingRouter: AppRouteRecordRaw[] = [
         meta: { title: '商品属性值', icon: '', activeMenu: '/product/property' }
       }
     ]
+  },
+  {
+    path: '/product',
+    component: Layout,
+    name: 'ProductManagementEdit',
+    meta: {
+      hidden: true
+    },
+    children: [
+      {
+        path: 'productManagementAdd', // TODO @puhui999:最好拆成 add 和 edit 两个路由;添加商品;修改商品
+        component: () => import('@/views/mall/product/spu/addForm.vue'),
+        name: 'ProductManagementAdd',
+        meta: {
+          noCache: true,
+          hidden: true,
+          canTo: true,
+          icon: 'ep:edit',
+          title: '添加商品',
+          activeMenu: '/product/product-management'
+        }
+      }
+    ]
   }
 ]
 

+ 6 - 1
src/styles/index.scss

@@ -1,5 +1,4 @@
 @import './var.css';
-@import './vxe.css';
 @import 'element-plus/theme-chalk/dark/css-vars.css';
 
 .reset-margin [class*='el-icon'] + span {
@@ -11,6 +10,12 @@
   width: 100% !important;
 }
 
+// 解决表格内容超过表格总宽度后,横向滚动条前端顶不到表格边缘的问题
+.el-scrollbar__bar {
+  display: flex;
+  justify-content: flex-start;
+}
+
 /* nprogress 适配 element-plus 的主题色 */
 #nprogress {
   & .bar {

+ 0 - 2
src/styles/variables.scss

@@ -2,5 +2,3 @@
 $namespace: v;
 // el命名空间
 $elNamespace: el;
-// vxe命名空间
-$vxeNamespace: vxe;

Some files were not shown because too many files changed in this diff