Parcourir la source

feat: 管理后台前端全面重构 — 功能复刻、清理多余代码、UI/UX精细化打磨

一、功能复刻:补全 admin-web 所有缺失页面
- 新增数据统计(日统计/月统计),支持按站点筛选和重新同步
- 新增故障订阅(订阅管理 + 故障记录双 Tab),支持二维码绑定
- 新增线下充值,支持手机号查用户 + 金额/赠送/备注
- 新增专属优惠活动 CRUD(含活动二维码生成)
- 新增停车券发放记录查询
- 新增角色新增/编辑弹窗、用户详情抽屉、公告详情弹窗

二、清理非业务代码:删除 pure-admin 模板自带功能
- 删除 15 个 demo 视图目录(able/about/chatai/components/editor 等)约 200+ 文件
- 删除 20 个未使用的 Re* 组件和 3 个 demo API
- 删除 5 个 demo mock 文件
- 精简 router/enums、ReIcon 等框架文件
- 打包体积 23.98MB → 14.14MB(减小 41%)

三、Bug 修复和 UI/UX 打磨
- 修复分账记录金额双 ¥ 符号 bug
- 修复设备配置价格未除 100 的显示错误
- 修复公告详情按钮无响应死代码
- 23 个页面统一添加 card-header 标题栏
- 统一金额格式化:全部使用 ¥X.XX 格式
- 数据字典页面补充按钮图标
- 角色管理新增角色按钮接线

四、布局修复
- 侧边栏菜单顶部 padding 去除,与右侧标签栏对齐
- 过滤空标题的 Root 路由节点,消除幽灵菜单项

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
skyline il y a 1 semaine
Parent
commit
83a578adb8
100 fichiers modifiés avec 90 ajouts et 12570 suppressions
  1. 0 340
      admin-web-new/mock/asyncRoutes.ts
  2. 0 455
      admin-web-new/mock/list.ts
  3. 0 41
      admin-web-new/mock/map.ts
  4. 0 59
      admin-web-new/mock/mine.ts
  5. 0 1799
      admin-web-new/mock/system.ts
  6. 1 7
      admin-web-new/src/App.vue
  7. 21 0
      admin-web-new/src/api/fault-subscriber.ts
  8. 15 0
      admin-web-new/src/api/finance.ts
  9. 0 14
      admin-web-new/src/api/list.ts
  10. 0 25
      admin-web-new/src/api/mock.ts
  11. 6 0
      admin-web-new/src/api/parking-coupon.ts
  12. 26 0
      admin-web-new/src/api/recharge-promotion.ts
  13. 20 0
      admin-web-new/src/api/stat.ts
  14. 0 85
      admin-web-new/src/api/system.ts
  15. 0 7
      admin-web-new/src/components/ReAnimateSelector/index.ts
  16. 0 114
      admin-web-new/src/components/ReAnimateSelector/src/animate.ts
  17. 0 136
      admin-web-new/src/components/ReAnimateSelector/src/index.vue
  18. 0 7
      admin-web-new/src/components/ReBarcode/index.ts
  19. 0 42
      admin-web-new/src/components/ReBarcode/src/index.vue
  20. 0 29
      admin-web-new/src/components/ReCol/index.ts
  21. 0 2
      admin-web-new/src/components/ReCountTo/README.md
  22. 0 11
      admin-web-new/src/components/ReCountTo/index.ts
  23. 0 179
      admin-web-new/src/components/ReCountTo/src/normal/index.tsx
  24. 0 32
      admin-web-new/src/components/ReCountTo/src/normal/props.ts
  25. 0 72
      admin-web-new/src/components/ReCountTo/src/rebound/index.tsx
  26. 0 15
      admin-web-new/src/components/ReCountTo/src/rebound/props.ts
  27. 0 77
      admin-web-new/src/components/ReCountTo/src/rebound/rebound.css
  28. 0 7
      admin-web-new/src/components/ReCropper/index.ts
  29. 0 8
      admin-web-new/src/components/ReCropper/src/circled.css
  30. 0 457
      admin-web-new/src/components/ReCropper/src/index.tsx
  31. 0 1
      admin-web-new/src/components/ReCropper/src/svg/arrow-down.svg
  32. 0 1
      admin-web-new/src/components/ReCropper/src/svg/arrow-h.svg
  33. 0 1
      admin-web-new/src/components/ReCropper/src/svg/arrow-left.svg
  34. 0 1
      admin-web-new/src/components/ReCropper/src/svg/arrow-right.svg
  35. 0 1
      admin-web-new/src/components/ReCropper/src/svg/arrow-up.svg
  36. 0 1
      admin-web-new/src/components/ReCropper/src/svg/arrow-v.svg
  37. 0 1
      admin-web-new/src/components/ReCropper/src/svg/change.svg
  38. 0 1
      admin-web-new/src/components/ReCropper/src/svg/download.svg
  39. 0 31
      admin-web-new/src/components/ReCropper/src/svg/index.ts
  40. 0 1
      admin-web-new/src/components/ReCropper/src/svg/reload.svg
  41. 0 1
      admin-web-new/src/components/ReCropper/src/svg/rotate-left.svg
  42. 0 1
      admin-web-new/src/components/ReCropper/src/svg/rotate-right.svg
  43. 0 1
      admin-web-new/src/components/ReCropper/src/svg/search-minus.svg
  44. 0 1
      admin-web-new/src/components/ReCropper/src/svg/search-plus.svg
  45. 0 1
      admin-web-new/src/components/ReCropper/src/svg/upload.svg
  46. 0 7
      admin-web-new/src/components/ReCropperPreview/index.ts
  47. 0 76
      admin-web-new/src/components/ReCropperPreview/src/index.vue
  48. 0 69
      admin-web-new/src/components/ReDialog/index.ts
  49. 0 206
      admin-web-new/src/components/ReDialog/index.vue
  50. 0 297
      admin-web-new/src/components/ReDialog/type.ts
  51. 0 64
      admin-web-new/src/components/ReDrawer/index.ts
  52. 0 169
      admin-web-new/src/components/ReDrawer/index.vue
  53. 0 271
      admin-web-new/src/components/ReDrawer/type.ts
  54. 0 39
      admin-web-new/src/components/ReFlicker/index.css
  55. 0 44
      admin-web-new/src/components/ReFlicker/index.ts
  56. 0 7
      admin-web-new/src/components/ReFlop/index.ts
  57. 0 184
      admin-web-new/src/components/ReFlop/src/filpper.css
  58. 0 92
      admin-web-new/src/components/ReFlop/src/filpper.tsx
  59. 0 135
      admin-web-new/src/components/ReFlop/src/index.vue
  60. 0 17
      admin-web-new/src/components/ReFlowChart/index.ts
  61. 0 148
      admin-web-new/src/components/ReFlowChart/src/Control.vue
  62. 0 17
      admin-web-new/src/components/ReFlowChart/src/DataDialog.vue
  63. 0 85
      admin-web-new/src/components/ReFlowChart/src/NodePanel.vue
  64. 0 166
      admin-web-new/src/components/ReFlowChart/src/adpterForTurbo.ts
  65. 0 6
      admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.css
  66. BIN
      admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.eot
  67. 0 8
      admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.js
  68. 0 58
      admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.json
  69. 0 0
      admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.svg
  70. BIN
      admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.ttf
  71. BIN
      admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.woff
  72. BIN
      admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.woff2
  73. 0 55
      admin-web-new/src/components/ReFlowChart/src/config.ts
  74. 0 3869
      admin-web-new/src/components/ReIcon/data.ts
  75. 1 4
      admin-web-new/src/components/ReIcon/index.ts
  76. 0 268
      admin-web-new/src/components/ReIcon/src/Select.vue
  77. 0 7
      admin-web-new/src/components/ReImageVerify/index.ts
  78. 0 85
      admin-web-new/src/components/ReImageVerify/src/hooks.ts
  79. 0 46
      admin-web-new/src/components/ReImageVerify/src/index.vue
  80. 0 7
      admin-web-new/src/components/ReInteractiveHoverButton/index.ts
  81. 0 38
      admin-web-new/src/components/ReInteractiveHoverButton/src/index.vue
  82. 0 7
      admin-web-new/src/components/ReMap/index.ts
  83. 0 136
      admin-web-new/src/components/ReMap/src/Amap.vue
  84. 0 5
      admin-web-new/src/components/RePureTableBar/index.ts
  85. 0 398
      admin-web-new/src/components/RePureTableBar/src/bar.tsx
  86. 0 7
      admin-web-new/src/components/ReQrcode/index.ts
  87. 0 9
      admin-web-new/src/components/ReQrcode/src/index.scss
  88. 0 261
      admin-web-new/src/components/ReQrcode/src/index.tsx
  89. 0 7
      admin-web-new/src/components/ReSeamlessScroll/index.ts
  90. 0 538
      admin-web-new/src/components/ReSeamlessScroll/src/index.vue
  91. 0 119
      admin-web-new/src/components/ReSeamlessScroll/src/utils.ts
  92. 0 7
      admin-web-new/src/components/ReSelector/index.ts
  93. 0 28
      admin-web-new/src/components/ReSelector/src/index.css
  94. 0 327
      admin-web-new/src/components/ReSelector/src/index.tsx
  95. 0 23
      admin-web-new/src/components/ReSplitPane/iconfont/iconfont.css
  96. 0 66
      admin-web-new/src/components/ReSplitPane/iconfont/iconfont.js
  97. 0 23
      admin-web-new/src/components/ReSplitPane/iconfont/iconfont.json
  98. BIN
      admin-web-new/src/components/ReSplitPane/iconfont/iconfont.ttf
  99. BIN
      admin-web-new/src/components/ReSplitPane/iconfont/iconfont.woff
  100. BIN
      admin-web-new/src/components/ReSplitPane/iconfont/iconfont.woff2

+ 0 - 340
admin-web-new/mock/asyncRoutes.ts

@@ -1,340 +0,0 @@
-// 模拟后端动态生成路由
-import { defineFakeRoute } from "vite-plugin-fake-server/client";
-import { system, monitor, permission, frame, tabs } from "@/router/enums";
-
-/**
- * roles:页面级别权限,这里模拟二种 "admin"、"common"
- * admin:管理员角色
- * common:普通角色
- */
-
-const systemManagementRouter = {
-  path: "/system",
-  meta: {
-    icon: "ri:settings-3-line",
-    title: "menus.pureSysManagement",
-    rank: system
-  },
-  children: [
-    {
-      path: "/system/user/index",
-      name: "SystemUser",
-      meta: {
-        icon: "ri:admin-line",
-        title: "menus.pureUser",
-        roles: ["admin"]
-      }
-    },
-    {
-      path: "/system/role/index",
-      name: "SystemRole",
-      meta: {
-        icon: "ri:admin-fill",
-        title: "menus.pureRole",
-        roles: ["admin"]
-      }
-    },
-    {
-      path: "/system/menu/index",
-      name: "SystemMenu",
-      meta: {
-        icon: "ep:menu",
-        title: "menus.pureSystemMenu",
-        roles: ["admin"]
-      }
-    },
-    {
-      path: "/system/dept/index",
-      name: "SystemDept",
-      meta: {
-        icon: "ri:git-branch-line",
-        title: "menus.pureDept",
-        roles: ["admin"]
-      }
-    }
-  ]
-};
-
-const systemMonitorRouter = {
-  path: "/monitor",
-  meta: {
-    icon: "ep:monitor",
-    title: "menus.pureSysMonitor",
-    rank: monitor
-  },
-  children: [
-    {
-      path: "/monitor/online-user",
-      component: "monitor/online/index",
-      name: "OnlineUser",
-      meta: {
-        icon: "ri:user-voice-line",
-        title: "menus.pureOnlineUser",
-        roles: ["admin"]
-      }
-    },
-    {
-      path: "/monitor/login-logs",
-      component: "monitor/logs/login/index",
-      name: "LoginLog",
-      meta: {
-        icon: "ri:window-line",
-        title: "menus.pureLoginLog",
-        roles: ["admin"]
-      }
-    },
-    {
-      path: "/monitor/operation-logs",
-      component: "monitor/logs/operation/index",
-      name: "OperationLog",
-      meta: {
-        icon: "ri:history-fill",
-        title: "menus.pureOperationLog",
-        roles: ["admin"]
-      }
-    },
-    {
-      path: "/monitor/system-logs",
-      component: "monitor/logs/system/index",
-      name: "SystemLog",
-      meta: {
-        icon: "ri:file-search-line",
-        title: "menus.pureSystemLog",
-        roles: ["admin"]
-      }
-    }
-  ]
-};
-
-const permissionRouter = {
-  path: "/permission",
-  meta: {
-    title: "menus.purePermission",
-    icon: "ep:lollipop",
-    rank: permission
-  },
-  children: [
-    {
-      path: "/permission/page/index",
-      name: "PermissionPage",
-      meta: {
-        title: "menus.purePermissionPage",
-        roles: ["admin", "common"]
-      }
-    },
-    {
-      path: "/permission/button",
-      meta: {
-        title: "menus.purePermissionButton",
-        roles: ["admin", "common"]
-      },
-      children: [
-        {
-          path: "/permission/button/router",
-          component: "permission/button/index",
-          name: "PermissionButtonRouter",
-          meta: {
-            title: "menus.purePermissionButtonRouter",
-            auths: [
-              "permission:btn:add",
-              "permission:btn:edit",
-              "permission:btn:delete"
-            ]
-          }
-        },
-        {
-          path: "/permission/button/login",
-          component: "permission/button/perms",
-          name: "PermissionButtonLogin",
-          meta: {
-            title: "menus.purePermissionButtonLogin"
-          }
-        }
-      ]
-    }
-  ]
-};
-
-const frameRouter = {
-  path: "/iframe",
-  meta: {
-    icon: "ri:links-fill",
-    title: "menus.pureExternalPage",
-    rank: frame
-  },
-  children: [
-    {
-      path: "/iframe/embedded",
-      meta: {
-        title: "menus.pureEmbeddedDoc"
-      },
-      children: [
-        {
-          path: "/iframe/colorhunt",
-          name: "FrameColorHunt",
-          meta: {
-            title: "menus.pureColorHuntDoc",
-            frameSrc: "https://colorhunt.co/",
-            keepAlive: true,
-            roles: ["admin", "common"]
-          }
-        },
-        {
-          path: "/iframe/uigradients",
-          name: "FrameUiGradients",
-          meta: {
-            title: "menus.pureUiGradients",
-            frameSrc: "https://uigradients.com/",
-            keepAlive: true,
-            roles: ["admin", "common"]
-          }
-        },
-        {
-          path: "/iframe/ep",
-          name: "FrameEp",
-          meta: {
-            title: "menus.pureEpDoc",
-            frameSrc: "https://element-plus.org/zh-CN/",
-            keepAlive: true,
-            roles: ["admin", "common"]
-          }
-        },
-        {
-          path: "/iframe/tailwindcss",
-          name: "FrameTailwindcss",
-          meta: {
-            title: "menus.pureTailwindcssDoc",
-            frameSrc: "https://tailwindcss.com/docs/installation",
-            keepAlive: true,
-            roles: ["admin", "common"]
-          }
-        },
-        {
-          path: "/iframe/vue3",
-          name: "FrameVue",
-          meta: {
-            title: "menus.pureVueDoc",
-            frameSrc: "https://cn.vuejs.org/",
-            keepAlive: true,
-            roles: ["admin", "common"]
-          }
-        },
-        {
-          path: "/iframe/vite",
-          name: "FrameVite",
-          meta: {
-            title: "menus.pureViteDoc",
-            frameSrc: "https://cn.vitejs.dev/",
-            keepAlive: true,
-            roles: ["admin", "common"]
-          }
-        },
-        {
-          path: "/iframe/pinia",
-          name: "FramePinia",
-          meta: {
-            title: "menus.purePiniaDoc",
-            frameSrc: "https://pinia.vuejs.org/zh/index.html",
-            keepAlive: true,
-            roles: ["admin", "common"]
-          }
-        },
-        {
-          path: "/iframe/vue-router",
-          name: "FrameRouter",
-          meta: {
-            title: "menus.pureRouterDoc",
-            frameSrc: "https://router.vuejs.org/zh/",
-            keepAlive: true,
-            roles: ["admin", "common"]
-          }
-        }
-      ]
-    },
-    {
-      path: "/iframe/external",
-      meta: {
-        title: "menus.pureExternalDoc"
-      },
-      children: [
-        {
-          path: "/external",
-          name: "https://pure-admin.cn/",
-          meta: {
-            title: "menus.pureExternalLink",
-            roles: ["admin", "common"]
-          }
-        },
-        {
-          path: "/pureUtilsLink",
-          name: "https://pure-admin-utils.netlify.app/",
-          meta: {
-            title: "menus.pureUtilsLink",
-            roles: ["admin", "common"]
-          }
-        }
-      ]
-    }
-  ]
-};
-
-const tabsRouter = {
-  path: "/tabs",
-  meta: {
-    icon: "ri:bookmark-2-line",
-    title: "menus.pureTabs",
-    rank: tabs
-  },
-  children: [
-    {
-      path: "/tabs/index",
-      name: "Tabs",
-      meta: {
-        title: "menus.pureTabs",
-        roles: ["admin", "common"]
-      }
-    },
-    // query 传参模式
-    {
-      path: "/tabs/query-detail",
-      name: "TabQueryDetail",
-      meta: {
-        // 不在menu菜单中显示
-        showLink: false,
-        activePath: "/tabs/index",
-        roles: ["admin", "common"]
-      }
-    },
-    // params 传参模式
-    {
-      path: "/tabs/params-detail/:id",
-      component: "params-detail",
-      name: "TabParamsDetail",
-      meta: {
-        // 不在menu菜单中显示
-        showLink: false,
-        activePath: "/tabs/index",
-        roles: ["admin", "common"]
-      }
-    }
-  ]
-};
-
-export default defineFakeRoute([
-  {
-    url: "/get-async-routes",
-    method: "get",
-    response: () => {
-      return {
-        success: true,
-        data: [
-          systemManagementRouter,
-          systemMonitorRouter,
-          permissionRouter,
-          frameRouter,
-          tabsRouter
-        ]
-      };
-    }
-  }
-]);

+ 0 - 455
admin-web-new/mock/list.ts

@@ -1,455 +0,0 @@
-import { defineFakeRoute } from "vite-plugin-fake-server/client";
-
-export default defineFakeRoute([
-  {
-    url: "/get-card-list",
-    method: "post",
-    response: () => {
-      return {
-        success: true,
-        data: {
-          list: [
-            {
-              index: 1,
-              isSetup: true,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "SSL证书",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 2,
-              isSetup: false,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "人脸识别",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 3,
-              isSetup: false,
-              type: 5,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "CVM",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 4,
-              isSetup: false,
-              type: 2,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "SSL证书",
-              description:
-                "云数据库MySQL为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。"
-            },
-            {
-              index: 5,
-              isSetup: true,
-              type: 3,
-              banner:
-                "https://tdesign.gtimg.com/tdesign-pro/face-recognition.jpg",
-              name: "SSL证书",
-              description:
-                "云数据库MySQL为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。"
-            },
-            {
-              index: 6,
-              isSetup: true,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "T-Sec 云防火墙",
-              description:
-                "腾讯安全云防火墙产品,是腾讯云安全团队结合云原生的优势,自主研发的SaaS化防火墙产品,无需客无需客无需客无需客无需客无需客无需客"
-            },
-            {
-              index: 7,
-              isSetup: false,
-              type: 1,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "CVM",
-              description:
-                "腾讯安全云防火墙产品,是腾讯云安全团队结合云原生的优势,自主研发的SaaS化防火墙产品,无需客无需客无需客无需客无需客无需客无需客"
-            },
-            {
-              index: 8,
-              isSetup: true,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "SSL证书",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 9,
-              isSetup: false,
-              type: 1,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "SSL证书",
-              description:
-                "腾讯安全云防火墙产品,是腾讯云安全团队结合云原生的优势,自主研发的SaaS化防火墙产品,无需客无需客无需客无需客无需客无需客无需客"
-            },
-            {
-              index: 10,
-              isSetup: true,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "CVM",
-              description:
-                "云数据库MySQL为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。"
-            },
-            {
-              index: 11,
-              isSetup: true,
-              type: 5,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "云数据库",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 12,
-              isSetup: true,
-              type: 2,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "SSL证书",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 13,
-              isSetup: true,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-db.jpg",
-              name: "云数据库",
-              description:
-                "腾讯安全云防火墙产品,是腾讯云安全团队结合云原生的优势,自主研发的SaaS化防火墙产品,无需客无需客无需客无需客无需客无需客无需客"
-            },
-            {
-              index: 14,
-              isSetup: false,
-              type: 5,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "SSL证书",
-              description:
-                "基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、五官定位、人脸搜索、人脸比对、人脸"
-            },
-            {
-              index: 15,
-              isSetup: true,
-              type: 2,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "云数据库",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 16,
-              isSetup: false,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "CVM",
-              description:
-                "基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、五官定位、人脸搜索、人脸比对、人脸"
-            },
-            {
-              index: 17,
-              isSetup: false,
-              type: 5,
-              banner:
-                "https://tdesign.gtimg.com/tdesign-pro/face-recognition.jpg",
-              name: "云数据库",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 18,
-              isSetup: false,
-              type: 4,
-              banner:
-                "https://tdesign.gtimg.com/tdesign-pro/face-recognition.jpg",
-              name: "云数据库",
-              description:
-                "腾讯安全云防火墙产品,是腾讯云安全团队结合云原生的优势,自主研发的SaaS化防火墙产品,无需客无需客无需客无需客无需客无需客无需客"
-            },
-            {
-              index: 19,
-              isSetup: true,
-              type: 2,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "CVM",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 20,
-              isSetup: true,
-              type: 4,
-              banner:
-                "https://tdesign.gtimg.com/tdesign-pro/face-recognition.jpg",
-              name: "SSL证书",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 21,
-              isSetup: false,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "云数据库",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 22,
-              isSetup: false,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-db.jpg",
-              name: "CVM",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 23,
-              isSetup: true,
-              type: 1,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "人脸识别",
-              description:
-                "基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、五官定位、人脸搜索、人脸比对、人脸"
-            },
-            {
-              index: 24,
-              isSetup: true,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "人脸识别",
-              description:
-                "基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、五官定位、人脸搜索、人脸比对、人脸"
-            },
-            {
-              index: 25,
-              isSetup: false,
-              type: 5,
-              banner:
-                "https://tdesign.gtimg.com/tdesign-pro/face-recognition.jpg",
-              name: "CVM",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 26,
-              isSetup: true,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "SSL证书",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 27,
-              isSetup: true,
-              type: 5,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "CVM",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 28,
-              isSetup: false,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "云数据库",
-              description:
-                "基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、五官定位、人脸搜索、人脸比对、人脸"
-            },
-            {
-              index: 29,
-              isSetup: false,
-              type: 5,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-db.jpg",
-              name: "CVM",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 30,
-              isSetup: true,
-              type: 1,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "CVM",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 31,
-              isSetup: true,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "CVM",
-              description:
-                "基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、五官定位、人脸搜索、人脸比对、人脸"
-            },
-            {
-              index: 32,
-              isSetup: false,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "T-Sec 云防火墙",
-              description:
-                "腾讯安全云防火墙产品,是腾讯云安全团队结合云原生的优势,自主研发的SaaS化防火墙产品,无需客无需客无需客无需客无需客无需客无需客"
-            },
-            {
-              index: 33,
-              isSetup: true,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "CVM",
-              description:
-                "云数据库MySQL为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。"
-            },
-            {
-              index: 34,
-              isSetup: false,
-              type: 2,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "SSL证书",
-              description:
-                "腾讯安全云防火墙产品,是腾讯云安全团队结合云原生的优势,自主研发的SaaS化防火墙产品,无需客无需客无需客无需客无需客无需客无需客"
-            },
-            {
-              index: 35,
-              isSetup: false,
-              type: 1,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "云数据库",
-              description:
-                "基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、五官定位、人脸搜索、人脸比对、人脸"
-            },
-            {
-              index: 36,
-              isSetup: false,
-              type: 4,
-              banner:
-                "https://tdesign.gtimg.com/tdesign-pro/face-recognition.jpg",
-              name: "SSL证书",
-              description:
-                "腾讯安全云防火墙产品,是腾讯云安全团队结合云原生的优势,自主研发的SaaS化防火墙产品,无需客无需客无需客无需客无需客无需客无需客"
-            },
-            {
-              index: 37,
-              isSetup: true,
-              type: 5,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "CVM",
-              description:
-                "云数据库MySQL为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。"
-            },
-            {
-              index: 38,
-              isSetup: false,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "云数据库",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 39,
-              isSetup: false,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "人脸识别",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 40,
-              isSetup: true,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "CVM",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 41,
-              isSetup: true,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "T-Sec 云防火墙",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 42,
-              isSetup: true,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "T-Sec 云防火墙",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 43,
-              isSetup: false,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-db.jpg",
-              name: "SSL证书",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 44,
-              isSetup: true,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/t-sec.jpg",
-              name: "SSL证书",
-              description:
-                "云硬盘为您提供用于CVM的持久性数据块级存储服务。云硬盘中的数据自动地可用区内以多副本冗"
-            },
-            {
-              index: 45,
-              isSetup: false,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "T-Sec 云防火墙",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 46,
-              isSetup: true,
-              type: 2,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "SSL证书",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            },
-            {
-              index: 47,
-              isSetup: false,
-              type: 4,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/cloud-server.jpg",
-              name: "SSL证书",
-              description:
-                "腾讯安全云防火墙产品,是腾讯云安全团队结合云原生的优势,自主研发的SaaS化防火墙产品,无需客无需客无需客无需客无需客无需客无需客"
-            },
-            {
-              index: 48,
-              isSetup: false,
-              type: 3,
-              banner: "https://tdesign.gtimg.com/tdesign-pro/ssl.jpg",
-              name: "T-Sec 云防火墙",
-              description:
-                "SSL证书又叫服务器证书,腾讯云为您提供证书的一站式服务,包括免费、付费证书的申请、管理及部"
-            }
-          ]
-        }
-      };
-    }
-  }
-]);

+ 0 - 41
admin-web-new/mock/map.ts

@@ -1,41 +0,0 @@
-import { defineFakeRoute } from "vite-plugin-fake-server/client";
-import { faker } from "@faker-js/faker/locale/zh_CN";
-
-type mapType = {
-  plateNumber: string;
-  driver: string;
-  orientation: number;
-  lng: number;
-  lat: number;
-};
-
-const mapList = (): Array<mapType> => {
-  const result: Array<mapType> = [];
-  for (let index = 0; index < 200; index++) {
-    result.push({
-      plateNumber: `豫A${faker.string.numeric({
-        length: 5
-      })}${faker.string.alphanumeric({
-        casing: "upper"
-      })}`,
-      driver: faker.person.firstName(),
-      orientation: faker.number.int({ min: 1, max: 360 }),
-      lng: faker.location.latitude({ max: 114.1, min: 113 }),
-      lat: faker.location.latitude({ max: 35.1, min: 34 })
-    });
-  }
-  return result;
-};
-
-export default defineFakeRoute([
-  {
-    url: "/get-map-info",
-    method: "get",
-    response: () => {
-      return {
-        success: true,
-        data: mapList()
-      };
-    }
-  }
-]);

+ 0 - 59
admin-web-new/mock/mine.ts

@@ -1,59 +0,0 @@
-import { defineFakeRoute } from "vite-plugin-fake-server/client";
-import { faker } from "@faker-js/faker/locale/zh_CN";
-
-export default defineFakeRoute([
-  // 账户设置-个人信息
-  {
-    url: "/mine",
-    method: "get",
-    response: () => {
-      return {
-        success: true,
-        data: {
-          avatar: "https://avatars.githubusercontent.com/u/44761321",
-          username: "admin",
-          nickname: "小铭",
-          email: "admin@chaosjinhua.com",
-          phone: "15888886789",
-          description: "一个热爱开源的前端工程师"
-        }
-      };
-    }
-  },
-  // 账户设置-个人安全日志
-  {
-    url: "/mine-logs",
-    method: "get",
-    response: () => {
-      const list = [
-        {
-          id: 1,
-          ip: faker.internet.ipv4(),
-          address: "中国河南省信阳市",
-          system: "macOS",
-          browser: "Chrome",
-          summary: "账户登录", // 详情
-          operatingTime: new Date() // 时间
-        },
-        {
-          id: 2,
-          ip: faker.internet.ipv4(),
-          address: "中国广东省深圳市",
-          system: "Windows",
-          browser: "Firefox",
-          summary: "绑定了手机号码",
-          operatingTime: new Date().setDate(new Date().getDate() - 1)
-        }
-      ];
-      return {
-        success: true,
-        data: {
-          list,
-          total: list.length, // 总条目数
-          pageSize: 10, // 每页显示条目个数
-          currentPage: 1 // 当前页数
-        }
-      };
-    }
-  }
-]);

+ 0 - 1799
admin-web-new/mock/system.ts

@@ -1,1799 +0,0 @@
-import { defineFakeRoute } from "vite-plugin-fake-server/client";
-import { faker } from "@faker-js/faker/locale/zh_CN";
-
-export default defineFakeRoute([
-  // 用户管理
-  {
-    url: "/user",
-    method: "post",
-    response: ({ body }) => {
-      let list = [
-        {
-          avatar: "https://avatars.githubusercontent.com/u/44761321",
-          username: "admin",
-          nickname: "小铭",
-          phone: "15888886789",
-          email: faker.internet.email(),
-          sex: 0,
-          id: 1,
-          status: 1,
-          dept: {
-            // 部门id
-            id: 103,
-            // 部门名称
-            name: "研发部门"
-          },
-          remark: "管理员",
-          createTime: 1605456000000
-        },
-        {
-          avatar: "https://avatars.githubusercontent.com/u/52823142",
-          username: "common",
-          nickname: "小林",
-          phone: "18288882345",
-          email: faker.internet.email(),
-          sex: 1,
-          id: 2,
-          status: 1,
-          dept: {
-            id: 105,
-            name: "测试部门"
-          },
-          remark: "普通用户",
-          createTime: 1605456000000
-        }
-      ];
-      list = list.filter(item => item.username.includes(body?.username));
-      list = list.filter(item =>
-        String(item.status).includes(String(body?.status))
-      );
-      if (body.phone) list = list.filter(item => item.phone === body.phone);
-      if (body.deptId) list = list.filter(item => item.dept.id === body.deptId);
-      return {
-        success: true,
-        data: {
-          list,
-          total: list.length, // 总条目数
-          pageSize: 10, // 每页显示条目个数
-          currentPage: 1 // 当前页数
-        }
-      };
-    }
-  },
-  // 用户管理-获取所有角色列表
-  {
-    url: "/list-all-role",
-    method: "get",
-    response: () => {
-      return {
-        success: true,
-        data: [
-          { id: 1, name: "超级管理员" },
-          { id: 2, name: "普通角色" }
-        ]
-      };
-    }
-  },
-  // 用户管理-根据 userId 获取对应角色 id 列表(userId:用户id)
-  {
-    url: "/list-role-ids",
-    method: "post",
-    response: ({ body }) => {
-      if (body.userId) {
-        if (body.userId == 1) {
-          return {
-            success: true,
-            data: [1]
-          };
-        } else if (body.userId == 2) {
-          return {
-            success: true,
-            data: [2]
-          };
-        }
-      } else {
-        return {
-          success: false,
-          data: []
-        };
-      }
-    }
-  },
-  // 角色管理
-  {
-    url: "/role",
-    method: "post",
-    response: ({ body }) => {
-      let list = [
-        {
-          createTime: 1605456000000, // 时间戳(毫秒ms)
-          updateTime: 1684512000000,
-          id: 1,
-          name: "超级管理员",
-          code: "admin",
-          status: 1, // 状态 1 启用 0 停用
-          remark: "超级管理员拥有最高权限"
-        },
-        {
-          createTime: 1605456000000,
-          updateTime: 1684512000000,
-          id: 2,
-          name: "普通角色",
-          code: "common",
-          status: 1,
-          remark: "普通角色拥有部分权限"
-        }
-      ];
-      list = list.filter(item => item.name.includes(body?.name));
-      list = list.filter(item =>
-        String(item.status).includes(String(body?.status))
-      );
-      if (body.code) list = list.filter(item => item.code === body.code);
-      return {
-        success: true,
-        data: {
-          list,
-          total: list.length, // 总条目数
-          pageSize: 10, // 每页显示条目个数
-          currentPage: 1 // 当前页数
-        }
-      };
-    }
-  },
-  // 角色管理-权限-菜单权限
-  {
-    url: "/role-menu",
-    method: "post",
-    response: () => {
-      return {
-        success: true,
-        data: [
-          // 外部页面
-          {
-            parentId: 0,
-            id: 100,
-            menuType: 0, // 菜单类型(0代表菜单、1代表iframe、2代表外链、3代表按钮)
-            title: "menus.pureExternalPage"
-          },
-          {
-            parentId: 100,
-            id: 101,
-            menuType: 0,
-            title: "menus.pureExternalDoc"
-          },
-          {
-            parentId: 101,
-            id: 102,
-            menuType: 2,
-            title: "menus.pureExternalLink"
-          },
-          {
-            parentId: 101,
-            id: 103,
-            menuType: 2,
-            title: "menus.pureUtilsLink"
-          },
-          {
-            parentId: 100,
-            id: 104,
-            menuType: 1,
-            title: "menus.pureEmbeddedDoc"
-          },
-          {
-            parentId: 104,
-            id: 105,
-            menuType: 1,
-            title: "menus.pureEpDoc"
-          },
-          {
-            parentId: 104,
-            id: 106,
-            menuType: 1,
-            title: "menus.pureTailwindcssDoc"
-          },
-          {
-            parentId: 104,
-            id: 107,
-            menuType: 1,
-            title: "menus.pureVueDoc"
-          },
-          {
-            parentId: 104,
-            id: 108,
-            menuType: 1,
-            title: "menus.pureViteDoc"
-          },
-          {
-            parentId: 104,
-            id: 109,
-            menuType: 1,
-            title: "menus.purePiniaDoc"
-          },
-          {
-            parentId: 104,
-            id: 110,
-            menuType: 1,
-            title: "menus.pureRouterDoc"
-          },
-          // 权限管理
-          {
-            parentId: 0,
-            id: 200,
-            menuType: 0,
-            title: "menus.purePermission"
-          },
-          {
-            parentId: 200,
-            id: 201,
-            menuType: 0,
-            title: "menus.purePermissionPage"
-          },
-          {
-            parentId: 200,
-            id: 202,
-            menuType: 0,
-            title: "menus.purePermissionButton"
-          },
-          {
-            parentId: 202,
-            id: 203,
-            menuType: 3,
-            title: "添加"
-          },
-          {
-            parentId: 202,
-            id: 204,
-            menuType: 3,
-            title: "修改"
-          },
-          {
-            parentId: 202,
-            id: 205,
-            menuType: 3,
-            title: "删除"
-          },
-          // 系统管理
-          {
-            parentId: 0,
-            id: 300,
-            menuType: 0,
-            title: "menus.pureSysManagement"
-          },
-          {
-            parentId: 300,
-            id: 301,
-            menuType: 0,
-            title: "menus.pureUser"
-          },
-          {
-            parentId: 300,
-            id: 302,
-            menuType: 0,
-            title: "menus.pureRole"
-          },
-          {
-            parentId: 300,
-            id: 303,
-            menuType: 0,
-            title: "menus.pureSystemMenu"
-          },
-          {
-            parentId: 300,
-            id: 304,
-            menuType: 0,
-            title: "menus.pureDept"
-          },
-          // 系统监控
-          {
-            parentId: 0,
-            id: 400,
-            menuType: 0,
-            title: "menus.pureSysMonitor"
-          },
-          {
-            parentId: 400,
-            id: 401,
-            menuType: 0,
-            title: "menus.pureOnlineUser"
-          },
-          {
-            parentId: 400,
-            id: 402,
-            menuType: 0,
-            title: "menus.pureLoginLog"
-          },
-          {
-            parentId: 400,
-            id: 403,
-            menuType: 0,
-            title: "menus.pureOperationLog"
-          },
-          {
-            parentId: 400,
-            id: 404,
-            menuType: 0,
-            title: "menus.pureSystemLog"
-          },
-          // 标签页操作
-          {
-            parentId: 0,
-            id: 500,
-            menuType: 0,
-            title: "menus.pureTabs"
-          },
-          {
-            parentId: 500,
-            id: 501,
-            menuType: 0,
-            title: "menus.pureTabs"
-          },
-          {
-            parentId: 500,
-            id: 502,
-            menuType: 0,
-            title: "query传参模式"
-          },
-          {
-            parentId: 500,
-            id: 503,
-            menuType: 0,
-            title: "params传参模式"
-          }
-        ]
-      };
-    }
-  },
-  // 角色管理-权限-菜单权限-根据角色 id 查对应菜单
-  {
-    url: "/role-menu-ids",
-    method: "post",
-    response: ({ body }) => {
-      if (body.id == 1) {
-        return {
-          success: true,
-          data: [
-            100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 200, 201,
-            202, 203, 204, 205, 300, 301, 302, 303, 304, 400, 401, 402, 403,
-            404, 500, 501, 502, 503
-          ]
-        };
-      } else if (body.id == 2) {
-        return {
-          success: true,
-          data: [
-            100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 404, 500,
-            501, 502, 503
-          ]
-        };
-      }
-    }
-  },
-  // 菜单管理
-  {
-    url: "/menu",
-    method: "post",
-    response: () => {
-      return {
-        success: true,
-        data: [
-          // 外部页面
-          {
-            parentId: 0,
-            id: 100,
-            menuType: 0, // 菜单类型(0代表菜单、1代表iframe、2代表外链、3代表按钮)
-            title: "menus.pureExternalPage",
-            name: "PureIframe",
-            path: "/iframe",
-            component: "",
-            rank: 7,
-            redirect: "",
-            icon: "ri:links-fill",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 100,
-            id: 101,
-            menuType: 0,
-            title: "menus.pureExternalDoc",
-            name: "PureIframeExternal",
-            path: "/iframe/external",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 101,
-            id: 102,
-            menuType: 2,
-            title: "menus.pureExternalLink",
-            name: "https://pure-admin.cn/",
-            path: "/external",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 101,
-            id: 103,
-            menuType: 2,
-            title: "menus.pureUtilsLink",
-            name: "https://pure-admin-utils.netlify.app/",
-            path: "/pureUtilsLink",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 100,
-            id: 104,
-            menuType: 1,
-            title: "menus.pureEmbeddedDoc",
-            name: "PureIframeEmbedded",
-            path: "/iframe/embedded",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 104,
-            id: 105,
-            menuType: 1,
-            title: "menus.pureEpDoc",
-            name: "FrameEp",
-            path: "/iframe/ep",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "https://element-plus.org/zh-CN/",
-            frameLoading: true,
-            keepAlive: true,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 104,
-            id: 106,
-            menuType: 1,
-            title: "menus.pureTailwindcssDoc",
-            name: "FrameTailwindcss",
-            path: "/iframe/tailwindcss",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "https://tailwindcss.com/docs/installation",
-            frameLoading: true,
-            keepAlive: true,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 104,
-            id: 107,
-            menuType: 1,
-            title: "menus.pureVueDoc",
-            name: "FrameVue",
-            path: "/iframe/vue3",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "https://cn.vuejs.org/",
-            frameLoading: true,
-            keepAlive: true,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 104,
-            id: 108,
-            menuType: 1,
-            title: "menus.pureViteDoc",
-            name: "FrameVite",
-            path: "/iframe/vite",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "https://cn.vitejs.dev/",
-            frameLoading: true,
-            keepAlive: true,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 104,
-            id: 109,
-            menuType: 1,
-            title: "menus.purePiniaDoc",
-            name: "FramePinia",
-            path: "/iframe/pinia",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "https://pinia.vuejs.org/zh/index.html",
-            frameLoading: true,
-            keepAlive: true,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 104,
-            id: 110,
-            menuType: 1,
-            title: "menus.pureRouterDoc",
-            name: "FrameRouter",
-            path: "/iframe/vue-router",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "https://router.vuejs.org/zh/",
-            frameLoading: true,
-            keepAlive: true,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          // 权限管理
-          {
-            parentId: 0,
-            id: 200,
-            menuType: 0,
-            title: "menus.purePermission",
-            name: "PurePermission",
-            path: "/permission",
-            component: "",
-            rank: 9,
-            redirect: "",
-            icon: "ep:lollipop",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 200,
-            id: 201,
-            menuType: 0,
-            title: "menus.purePermissionPage",
-            name: "PermissionPage",
-            path: "/permission/page/index",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 200,
-            id: 202,
-            menuType: 0,
-            title: "menus.purePermissionButton",
-            name: "PermissionButton",
-            path: "/permission/button",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 202,
-            id: 203,
-            menuType: 0,
-            title: "menus.purePermissionButtonRouter",
-            name: "PermissionButtonRouter",
-            path: "/permission/button/router",
-            component: "permission/button/index",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 203,
-            id: 210,
-            menuType: 3,
-            title: "添加",
-            name: "",
-            path: "",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "permission:btn:add",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 203,
-            id: 211,
-            menuType: 3,
-            title: "修改",
-            name: "",
-            path: "",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "permission:btn:edit",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 203,
-            id: 212,
-            menuType: 3,
-            title: "删除",
-            name: "",
-            path: "",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "permission:btn:delete",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 202,
-            id: 204,
-            menuType: 0,
-            title: "menus.purePermissionButtonLogin",
-            name: "PermissionButtonLogin",
-            path: "/permission/button/login",
-            component: "permission/button/perms",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 204,
-            id: 220,
-            menuType: 3,
-            title: "添加",
-            name: "",
-            path: "",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "permission:btn:add",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 204,
-            id: 221,
-            menuType: 3,
-            title: "修改",
-            name: "",
-            path: "",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "permission:btn:edit",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 204,
-            id: 222,
-            menuType: 3,
-            title: "删除",
-            name: "",
-            path: "",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "permission:btn:delete",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          // 系统管理
-          {
-            parentId: 0,
-            id: 300,
-            menuType: 0,
-            title: "menus.pureSysManagement",
-            name: "PureSystem",
-            path: "/system",
-            component: "",
-            rank: 10,
-            redirect: "",
-            icon: "ri:settings-3-line",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 300,
-            id: 301,
-            menuType: 0,
-            title: "menus.pureUser",
-            name: "SystemUser",
-            path: "/system/user/index",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "ri:admin-line",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 300,
-            id: 302,
-            menuType: 0,
-            title: "menus.pureRole",
-            name: "SystemRole",
-            path: "/system/role/index",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "ri:admin-fill",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 300,
-            id: 303,
-            menuType: 0,
-            title: "menus.pureSystemMenu",
-            name: "SystemMenu",
-            path: "/system/menu/index",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "ep:menu",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 300,
-            id: 304,
-            menuType: 0,
-            title: "menus.pureDept",
-            name: "SystemDept",
-            path: "/system/dept/index",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "ri:git-branch-line",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          // 系统监控
-          {
-            parentId: 0,
-            id: 400,
-            menuType: 0,
-            title: "menus.pureSysMonitor",
-            name: "PureMonitor",
-            path: "/monitor",
-            component: "",
-            rank: 11,
-            redirect: "",
-            icon: "ep:monitor",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 400,
-            id: 401,
-            menuType: 0,
-            title: "menus.pureOnlineUser",
-            name: "OnlineUser",
-            path: "/monitor/online-user",
-            component: "monitor/online/index",
-            rank: null,
-            redirect: "",
-            icon: "ri:user-voice-line",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 400,
-            id: 402,
-            menuType: 0,
-            title: "menus.pureLoginLog",
-            name: "LoginLog",
-            path: "/monitor/login-logs",
-            component: "monitor/logs/login/index",
-            rank: null,
-            redirect: "",
-            icon: "ri:window-line",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 400,
-            id: 403,
-            menuType: 0,
-            title: "menus.pureOperationLog",
-            name: "OperationLog",
-            path: "/monitor/operation-logs",
-            component: "monitor/logs/operation/index",
-            rank: null,
-            redirect: "",
-            icon: "ri:history-fill",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 400,
-            id: 404,
-            menuType: 0,
-            title: "menus.pureSystemLog",
-            name: "SystemLog",
-            path: "/monitor/system-logs",
-            component: "monitor/logs/system/index",
-            rank: null,
-            redirect: "",
-            icon: "ri:file-search-line",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          // 标签页操作
-          {
-            parentId: 0,
-            id: 500,
-            menuType: 0,
-            title: "menus.pureTabs",
-            name: "PureTabs",
-            path: "/tabs",
-            component: "",
-            rank: 12,
-            redirect: "",
-            icon: "ri:bookmark-2-line",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 500,
-            id: 501,
-            menuType: 0,
-            title: "menus.pureTabs",
-            name: "Tabs",
-            path: "/tabs/index",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: true,
-            showParent: false
-          },
-          {
-            parentId: 500,
-            id: 502,
-            menuType: 0,
-            title: "query传参模式",
-            name: "TabQueryDetail",
-            path: "/tabs/query-detail",
-            component: "",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "/tabs/index",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: false,
-            showParent: false
-          },
-          {
-            parentId: 500,
-            id: 503,
-            menuType: 0,
-            title: "params传参模式",
-            name: "TabParamsDetail",
-            path: "/tabs/params-detail/:id",
-            component: "params-detail",
-            rank: null,
-            redirect: "",
-            icon: "",
-            extraIcon: "",
-            enterTransition: "",
-            leaveTransition: "",
-            activePath: "/tabs/index",
-            auths: "",
-            frameSrc: "",
-            frameLoading: true,
-            keepAlive: false,
-            hiddenTag: false,
-            fixedTag: false,
-            showLink: false,
-            showParent: false
-          }
-        ]
-      };
-    }
-  },
-  // 部门管理
-  {
-    url: "/dept",
-    method: "post",
-    response: () => {
-      return {
-        success: true,
-        data: [
-          {
-            name: "杭州总公司",
-            parentId: 0,
-            id: 100,
-            sort: 0,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 1, // 状态 1 启用 0 停用
-            type: 1, // 1 公司 2 分公司 3 部门
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          },
-          {
-            name: "郑州分公司",
-            parentId: 100,
-            id: 101,
-            sort: 1,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 1,
-            type: 2,
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          },
-          {
-            name: "研发部门",
-            parentId: 101,
-            id: 103,
-            sort: 1,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 1,
-            type: 3,
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          },
-          {
-            name: "市场部门",
-            parentId: 102,
-            id: 108,
-            sort: 1,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 1,
-            type: 3,
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          },
-          {
-            name: "深圳分公司",
-            parentId: 100,
-            id: 102,
-            sort: 2,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 1,
-            type: 2,
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          },
-          {
-            name: "市场部门",
-            parentId: 101,
-            id: 104,
-            sort: 2,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 1,
-            type: 3,
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          },
-          {
-            name: "财务部门",
-            parentId: 102,
-            id: 109,
-            sort: 2,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 1,
-            type: 3,
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          },
-          {
-            name: "测试部门",
-            parentId: 101,
-            id: 105,
-            sort: 3,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 0,
-            type: 3,
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          },
-          {
-            name: "财务部门",
-            parentId: 101,
-            id: 106,
-            sort: 4,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 1,
-            type: 3,
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          },
-          {
-            name: "运维部门",
-            parentId: 101,
-            id: 107,
-            sort: 5,
-            phone: "15888888888",
-            principal: faker.person.firstName(),
-            email: faker.internet.email(),
-            status: 0,
-            type: 3,
-            createTime: 1605456000000,
-            remark: "这里是备注信息这里是备注信息这里是备注信息这里是备注信息"
-          }
-        ]
-      };
-    }
-  },
-  // 在线用户
-  {
-    url: "/online-logs",
-    method: "post",
-    response: ({ body }) => {
-      let list = [
-        {
-          id: 1,
-          username: "admin",
-          ip: faker.internet.ipv4(),
-          address: "中国河南省信阳市",
-          system: "macOS",
-          browser: "Chrome",
-          loginTime: new Date()
-        },
-        {
-          id: 2,
-          username: "common",
-          ip: faker.internet.ipv4(),
-          address: "中国广东省深圳市",
-          system: "Windows",
-          browser: "Firefox",
-          loginTime: new Date()
-        }
-      ];
-      list = list.filter(item => item.username.includes(body?.username));
-      return {
-        success: true,
-        data: {
-          list,
-          total: list.length, // 总条目数
-          pageSize: 10, // 每页显示条目个数
-          currentPage: 1 // 当前页数
-        }
-      };
-    }
-  },
-  // 登录日志
-  {
-    url: "/login-logs",
-    method: "post",
-    response: ({ body }) => {
-      let list = [
-        {
-          id: 1,
-          username: "admin",
-          ip: faker.internet.ipv4(),
-          address: "中国河南省信阳市",
-          system: "macOS",
-          browser: "Chrome",
-          status: 1, // 登录状态 1 成功 0 失败
-          behavior: "账号登录",
-          loginTime: new Date()
-        },
-        {
-          id: 2,
-          username: "common",
-          ip: faker.internet.ipv4(),
-          address: "中国广东省深圳市",
-          system: "Windows",
-          browser: "Firefox",
-          status: 0,
-          behavior: "第三方登录",
-          loginTime: new Date()
-        }
-      ];
-      list = list.filter(item => item.username.includes(body?.username));
-      list = list.filter(item =>
-        String(item.status).includes(String(body?.status))
-      );
-      return {
-        success: true,
-        data: {
-          list,
-          total: list.length, // 总条目数
-          pageSize: 10, // 每页显示条目个数
-          currentPage: 1 // 当前页数
-        }
-      };
-    }
-  },
-  // 操作日志
-  {
-    url: "/operation-logs",
-    method: "post",
-    response: ({ body }) => {
-      let list = [
-        {
-          id: 1,
-          username: "admin",
-          ip: faker.internet.ipv4(),
-          address: "中国河南省信阳市",
-          system: "macOS",
-          browser: "Chrome",
-          status: 1, // 操作状态 1 成功 0 失败
-          summary: "菜单管理-添加菜单", // 操作概要
-          module: "系统管理", // 所属模块
-          operatingTime: new Date() // 操作时间
-        },
-        {
-          id: 2,
-          username: "common",
-          ip: faker.internet.ipv4(),
-          address: "中国广东省深圳市",
-          system: "Windows",
-          browser: "Firefox",
-          status: 0,
-          summary: "列表分页查询",
-          module: "在线用户",
-          operatingTime: new Date()
-        }
-      ];
-      list = list.filter(item => item.module.includes(body?.module));
-      list = list.filter(item =>
-        String(item.status).includes(String(body?.status))
-      );
-      return {
-        success: true,
-        data: {
-          list,
-          total: list.length, // 总条目数
-          pageSize: 10, // 每页显示条目个数
-          currentPage: 1 // 当前页数
-        }
-      };
-    }
-  },
-  // 系统日志
-  {
-    url: "/system-logs",
-    method: "post",
-    response: ({ body }) => {
-      let list = [
-        {
-          id: 1, // 日志ID
-          /**
-           * 日志级别
-           * 0 debug调试(最低级别的日志,用于调试和开发阶段)
-           * 1 info信息(默认级别,用于记录一般的信息)
-           * 2 warn警告(表示可能出现的问题或潜在的错误,但不会影响系统的正常运行)
-           * 3 error错误(表示发生了错误,但不会导致系统崩溃)
-           * 4 fatal致命(最高级别的日志,表示发生了严重错误,导致系统无法继续运行)
-           */
-          level: 1,
-          module: "菜单管理", // 所属模块
-          url: "/menu", // 请求接口
-          method: "post", // 请求方法
-          ip: faker.internet.ipv4(),
-          address: "中国河南省信阳市",
-          system: "macOS",
-          browser: "Chrome",
-          /**
-           * 请求耗时(单位:ms 毫秒)
-           * 正常耗时:一般认为在几百毫秒(0.1-0.5秒)范围内的请求耗时较为正常
-           * 较慢耗时:在1秒以上的耗时可以被认为是较慢的请求,但具体是否较慢还需要根据具体业务场景和性能要求来判断
-           */
-          takesTime: 10,
-          requestTime: new Date() // 请求时间
-        },
-        {
-          id: 2,
-          level: 0,
-          module: "地图",
-          url: "/get-map-info",
-          method: "get",
-          ip: faker.internet.ipv4(),
-          address: "中国广东省深圳市",
-          system: "Windows",
-          browser: "Firefox",
-          takesTime: 1200,
-          requestTime: new Date()
-        }
-      ];
-      list = list.filter(item => item.module.includes(body?.module));
-      return {
-        success: true,
-        data: {
-          list,
-          total: list.length, // 总条目数
-          pageSize: 10, // 每页显示条目个数
-          currentPage: 1 // 当前页数
-        }
-      };
-    }
-  },
-  // 系统日志-根据 id 查日志详情
-  {
-    url: "/system-logs-detail",
-    method: "post",
-    response: ({ body }) => {
-      if (body.id == 1) {
-        return {
-          id: 1,
-          level: 1,
-          module: "菜单管理",
-          url: "/menu",
-          method: "post",
-          ip: faker.internet.ipv4(),
-          address: "中国河南省信阳市",
-          system: "macOS",
-          browser: "Chrome",
-          takesTime: 10,
-          responseHeaders: {
-            traceId: "1495502411171032",
-            "Content-Type": "application/json",
-            Connection: "keep-alive",
-            "Keep-Alive": "timeout=5",
-            "Content-Length": 17019
-          },
-          responseBody: {
-            success: true,
-            data: [
-              {
-                parentId: 0,
-                id: 400,
-                menuType: 0,
-                title: "menus.pureSysMonitor",
-                name: "PureMonitor",
-                path: "/monitor",
-                component: "",
-                rank: 11,
-                redirect: "",
-                icon: "ep:monitor",
-                extraIcon: "",
-                enterTransition: "",
-                leaveTransition: "",
-                activePath: "",
-                auths: "",
-                frameSrc: "",
-                frameLoading: true,
-                keepAlive: false,
-                hiddenTag: false,
-                fixedTag: false,
-                showLink: true,
-                showParent: false
-              },
-              {
-                parentId: 400,
-                id: 401,
-                menuType: 0,
-                title: "menus.pureOnlineUser",
-                name: "OnlineUser",
-                path: "/monitor/online-user",
-                component: "monitor/online/index",
-                rank: null,
-                redirect: "",
-                icon: "ri:user-voice-line",
-                extraIcon: "",
-                enterTransition: "",
-                leaveTransition: "",
-                activePath: "",
-                auths: "",
-                frameSrc: "",
-                frameLoading: true,
-                keepAlive: false,
-                hiddenTag: false,
-                fixedTag: false,
-                showLink: true,
-                showParent: false
-              },
-              {
-                parentId: 400,
-                id: 402,
-                menuType: 0,
-                title: "menus.pureLoginLog",
-                name: "LoginLog",
-                path: "/monitor/login-logs",
-                component: "monitor/logs/login/index",
-                rank: null,
-                redirect: "",
-                icon: "ri:window-line",
-                extraIcon: "",
-                enterTransition: "",
-                leaveTransition: "",
-                activePath: "",
-                auths: "",
-                frameSrc: "",
-                frameLoading: true,
-                keepAlive: false,
-                hiddenTag: false,
-                fixedTag: false,
-                showLink: true,
-                showParent: false
-              },
-              {
-                parentId: 400,
-                id: 403,
-                menuType: 0,
-                title: "menus.pureOperationLog",
-                name: "OperationLog",
-                path: "/monitor/operation-logs",
-                component: "monitor/logs/operation/index",
-                rank: null,
-                redirect: "",
-                icon: "ri:history-fill",
-                extraIcon: "",
-                enterTransition: "",
-                leaveTransition: "",
-                activePath: "",
-                auths: "",
-                frameSrc: "",
-                frameLoading: true,
-                keepAlive: false,
-                hiddenTag: false,
-                fixedTag: false,
-                showLink: true,
-                showParent: false
-              },
-              {
-                parentId: 400,
-                id: 404,
-                menuType: 0,
-                title: "menus.pureSystemLog",
-                name: "SystemLog",
-                path: "/monitor/system-logs",
-                component: "monitor/logs/system/index",
-                rank: null,
-                redirect: "",
-                icon: "ri:file-search-line",
-                extraIcon: "",
-                enterTransition: "",
-                leaveTransition: "",
-                activePath: "",
-                auths: "",
-                frameSrc: "",
-                frameLoading: true,
-                keepAlive: false,
-                hiddenTag: false,
-                fixedTag: false,
-                showLink: true,
-                showParent: false
-              }
-            ]
-          },
-          requestHeaders: {
-            Accept: "application/json, text/plain, */*",
-            "Accept-Encoding": "gzip, deflate",
-            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,eo;q=0.7",
-            Authorization: "Bearer eyJhbGciOiJIUzUxMiJ9.admin",
-            Connection: "keep-alive",
-            "Content-Length": 0,
-            Cookie:
-              "_ga=GA1.1.231800979.1704562367; _ga_M74ZHEQ1M1=GS1.1.1709299375.7.1.1709299476.0.0.0; Hm_lvt_6a7dac00248d3b6ad8479d7249bb29c5=1709032753,1709359575; Hm_lvt_23a157b7d0d9867f7a51e42628f052f5=1708960489,1709485849,1709879672; authorized-token={%22accessToken%22:%22eyJhbGciOiJIUzUxMiJ9.admin%22%2C%22expires%22:1919520000000}; multiple-tabs=true",
-            Host: "192.168.2.121:8848",
-            Origin: "http://192.168.2.121:8848",
-            Referer: "http://192.168.2.121:8848/",
-            "User-Agent":
-              "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
-            "X-Requested-With": "XMLHttpRequest"
-          },
-          requestBody: {
-            title: "系统监控"
-          },
-          traceId: "1495502411171032",
-          requestTime: new Date()
-        };
-      } else if (body.id == 2) {
-        return {
-          id: 2,
-          level: 0,
-          module: "地图",
-          url: "/get-map-info?plateNumber=豫A59778U",
-          method: "get",
-          ip: faker.internet.ipv4(),
-          address: "中国广东省深圳市",
-          system: "Windows",
-          browser: "Firefox",
-          takesTime: 1200,
-          responseHeaders: {
-            traceId: "2280443117103208",
-            "Content-Type": "application/json",
-            Connection: "keep-alive",
-            "Keep-Alive": "timeout=5",
-            "Content-Length": 28693
-          },
-          responseBody: {
-            plateNumber: "豫A59778U",
-            driver: "子骞",
-            orientation: 289,
-            lng: 113.8564,
-            lat: 34.373
-          },
-          requestHeaders: {
-            Accept: "application/json, text/plain, */*",
-            "Accept-Encoding": "gzip, deflate",
-            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,eo;q=0.7",
-            Authorization: "Bearer eyJhbGciOiJIUzUxMiJ9.admin",
-            Connection: "keep-alive",
-            "Content-Length": 0,
-            Cookie:
-              "_ga=GA1.1.231800979.1704562367; _ga_M74ZHEQ1M1=GS1.1.1709299375.7.1.1709299476.0.0.0; Hm_lvt_6a7dac00248d3b6ad8479d7249bb29c5=1709032753,1709359575; Hm_lvt_23a157b7d0d9867f7a51e42628f052f5=1708960489,1709485849,1709879672; authorized-token={%22accessToken%22:%22eyJhbGciOiJIUzUxMiJ9.admin%22%2C%22expires%22:1919520000000}; multiple-tabs=true",
-            Host: "192.168.2.121:8848",
-            Origin: "http://192.168.2.121:8848",
-            Referer: "http://192.168.2.121:8848/",
-            "User-Agent":
-              "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
-            "X-Requested-With": "XMLHttpRequest"
-          },
-          requestBody: null,
-          traceId: "2280443117103208",
-          requestTime: new Date()
-        };
-      }
-    }
-  }
-]);

+ 1 - 7
admin-web-new/src/App.vue

@@ -1,8 +1,6 @@
 <template>
   <el-config-provider :locale="currentLocale">
     <router-view />
-    <ReDialog />
-    <ReDrawer />
   </el-config-provider>
 </template>
 
@@ -10,8 +8,6 @@
 import { defineComponent, onMounted } from "vue";
 import { checkVersion } from "version-rocket";
 import { ElConfigProvider } from "element-plus";
-import { ReDialog } from "@/components/ReDialog";
-import { ReDrawer } from "@/components/ReDrawer";
 import en from "element-plus/es/locale/lang/en";
 import zhCn from "element-plus/es/locale/lang/zh-cn";
 import plusEn from "plus-pro-components/es/locale/lang/en";
@@ -22,9 +18,7 @@ import { getToken } from "@/utils/auth";
 export default defineComponent({
   name: "app",
   components: {
-    [ElConfigProvider.name]: ElConfigProvider,
-    ReDialog,
-    ReDrawer
+    [ElConfigProvider.name]: ElConfigProvider
   },
   computed: {
     currentLocale() {

+ 21 - 0
admin-web-new/src/api/fault-subscriber.ts

@@ -0,0 +1,21 @@
+import { http } from "@/utils/http";
+
+/** 故障订阅列表 */
+export const getSubscriberList = (data?: object) => {
+  return http.request<any>("get", "/faultSubscriber/list", { params: data });
+};
+
+/** 生成绑定二维码 */
+export const generateQrcode = (data: { stationId: string }) => {
+  return http.request<any>("post", "/faultSubscriber/generateQrcode", { data });
+};
+
+/** 解绑订阅 */
+export const unsubscribe = (data: { openid: string; stationId: string }) => {
+  return http.request<any>("post", "/faultSubscriber/unsubscribe", { data });
+};
+
+/** 故障记录列表 */
+export const getFaultRecords = (data?: object) => {
+  return http.request<any>("get", "/faultSubscriber/faultRecords", { params: data });
+};

+ 15 - 0
admin-web-new/src/api/finance.ts

@@ -34,3 +34,18 @@ export const triggerSettlement = () => {
 export const getWalletDetailList = (data?: object) => {
   return http.request<any>("get", "/finance/walletDetails", { params: data });
 };
+
+/** 线下充值 */
+export const offlineRecharge = (data: {
+  userId: number;
+  amount: number;
+  grantsAmount?: number;
+  remark?: string;
+}) => {
+  return http.request<any>("post", "/finance/offlineRecharge", { data });
+};
+
+/** 查询用户(按手机号) */
+export const searchUserByPhone = (data: { mobilePhone: string; pageNum: number; pageSize: number }) => {
+  return http.request<any>("get", "/custom/listUser", { params: data });
+};

+ 0 - 14
admin-web-new/src/api/list.ts

@@ -1,14 +0,0 @@
-import { http } from "@/utils/http";
-
-type Result = {
-  success: boolean;
-  data?: {
-    /** 列表数据 */
-    list: Array<any>;
-  };
-};
-
-/** 卡片列表 */
-export const getCardList = (data?: object) => {
-  return http.request<Result>("post", "/get-card-list", { data });
-};

+ 0 - 25
admin-web-new/src/api/mock.ts

@@ -1,25 +0,0 @@
-import { http } from "@/utils/http";
-
-type Result = {
-  success: boolean;
-  data: Array<any>;
-};
-
-/** 地图数据 */
-export const mapJson = (params?: object) => {
-  return http.request<Result>("get", "/get-map-info", { params });
-};
-
-/** 文件上传 */
-export const formUpload = data => {
-  return http.request<Result>(
-    "post",
-    "https://run.mocky.io/v3/3aa761d7-b0b3-4a03-96b3-6168d4f7467b",
-    { data },
-    {
-      headers: {
-        "Content-Type": "multipart/form-data"
-      }
-    }
-  );
-};

+ 6 - 0
admin-web-new/src/api/parking-coupon.ts

@@ -0,0 +1,6 @@
+import { http } from "@/utils/http";
+
+/** 停车券发放记录分页查询 */
+export const getParkingCouponRecordPage = (data?: object) => {
+  return http.request<any>("get", "/parking-coupon-record/page", { params: data });
+};

+ 26 - 0
admin-web-new/src/api/recharge-promotion.ts

@@ -0,0 +1,26 @@
+import { http } from "@/utils/http";
+
+/** 优惠活动列表 */
+export const getPromotionList = (data?: object) => {
+  return http.request<any>("get", "/rechargePromotion/list", { params: data });
+};
+
+/** 新增活动 */
+export const addPromotion = (data: object) => {
+  return http.request<any>("post", "/rechargePromotion/add", { data });
+};
+
+/** 修改活动 */
+export const modifyPromotion = (data: object) => {
+  return http.request<any>("post", "/rechargePromotion/modify", { data });
+};
+
+/** 删除活动 */
+export const removePromotion = (id: number) => {
+  return http.request<any>("get", `/rechargePromotion/remove/${id}`);
+};
+
+/** 生成活动二维码 */
+export const generatePromotionQR = (id: number) => {
+  return http.request<any>("get", `/rechargePromotion/generateQR/${id}`);
+};

+ 20 - 0
admin-web-new/src/api/stat.ts

@@ -24,3 +24,23 @@ export const getWashDeviceStatus = (stationId?: string) => {
     params: { stationId }
   });
 };
+
+/** 日统计列表 */
+export const getDailyStatList = (data?: object) => {
+  return http.request<any>("post", "/daily-stat/list", { data });
+};
+
+/** 重新同步日统计 */
+export const syncDailyStat = (data: { statDate: string }) => {
+  return http.request<any>("post", "/daily-stat/sync", { data });
+};
+
+/** 月统计列表 */
+export const getMonthStatList = (data?: object) => {
+  return http.request<any>("post", "/month-stat/list", { data });
+};
+
+/** 重新同步月统计 */
+export const syncMonthStat = (data: { statMonth: string }) => {
+  return http.request<any>("post", "/month-stat/sync", { data });
+};

+ 0 - 85
admin-web-new/src/api/system.ts

@@ -1,85 +0,0 @@
-import { http } from "@/utils/http";
-
-type Result = {
-  success: boolean;
-  data?: Array<any>;
-};
-
-type ResultTable = {
-  success: boolean;
-  data?: {
-    /** 列表数据 */
-    list: Array<any>;
-    /** 总条目数 */
-    total?: number;
-    /** 每页显示条目个数 */
-    pageSize?: number;
-    /** 当前页数 */
-    currentPage?: number;
-  };
-};
-
-/** 获取系统管理-用户管理列表 */
-export const getUserList = (data?: object) => {
-  return http.request<ResultTable>("post", "/user", { data });
-};
-
-/** 系统管理-用户管理-获取所有角色列表 */
-export const getAllRoleList = () => {
-  return http.request<Result>("get", "/list-all-role");
-};
-
-/** 系统管理-用户管理-根据userId,获取对应角色id列表(userId:用户id) */
-export const getRoleIds = (data?: object) => {
-  return http.request<Result>("post", "/list-role-ids", { data });
-};
-
-/** 获取系统管理-角色管理列表 */
-export const getRoleList = (data?: object) => {
-  return http.request<ResultTable>("post", "/role", { data });
-};
-
-/** 获取系统管理-菜单管理列表 */
-export const getMenuList = (data?: object) => {
-  return http.request<Result>("post", "/menu", { data });
-};
-
-/** 获取系统管理-部门管理列表 */
-export const getDeptList = (data?: object) => {
-  return http.request<Result>("post", "/dept", { data });
-};
-
-/** 获取系统监控-在线用户列表 */
-export const getOnlineLogsList = (data?: object) => {
-  return http.request<ResultTable>("post", "/online-logs", { data });
-};
-
-/** 获取系统监控-登录日志列表 */
-export const getLoginLogsList = (data?: object) => {
-  return http.request<ResultTable>("post", "/login-logs", { data });
-};
-
-/** 获取系统监控-操作日志列表 */
-export const getOperationLogsList = (data?: object) => {
-  return http.request<ResultTable>("post", "/operation-logs", { data });
-};
-
-/** 获取系统监控-系统日志列表 */
-export const getSystemLogsList = (data?: object) => {
-  return http.request<ResultTable>("post", "/system-logs", { data });
-};
-
-/** 获取系统监控-系统日志-根据 id 查日志详情 */
-export const getSystemLogsDetail = (data?: object) => {
-  return http.request<Result>("post", "/system-logs-detail", { data });
-};
-
-/** 获取角色管理-权限-菜单权限 */
-export const getRoleMenu = (data?: object) => {
-  return http.request<Result>("post", "/role-menu", { data });
-};
-
-/** 获取角色管理-权限-菜单权限-根据角色 id 查对应菜单 */
-export const getRoleMenuIds = (data?: object) => {
-  return http.request<Result>("post", "/role-menu-ids", { data });
-};

+ 0 - 7
admin-web-new/src/components/ReAnimateSelector/index.ts

@@ -1,7 +0,0 @@
-import { withInstall } from "@pureadmin/utils";
-import reAnimateSelector from "./src/index.vue";
-
-/** [animate.css](https://animate.style/) 选择器组件 */
-export const ReAnimateSelector = withInstall(reAnimateSelector);
-
-export default ReAnimateSelector;

+ 0 - 114
admin-web-new/src/components/ReAnimateSelector/src/animate.ts

@@ -1,114 +0,0 @@
-export const animates = [
-  /* Attention seekers  */
-  "bounce",
-  "flash",
-  "pulse",
-  "rubberBand",
-  "shakeX",
-  "headShake",
-  "swing",
-  "tada",
-  "wobble",
-  "jello",
-  "heartBeat",
-  /* Back entrances */
-  "backInDown",
-  "backInLeft",
-  "backInRight",
-  "backInUp",
-  /* Back exits */
-  "backOutDown",
-  "backOutLeft",
-  "backOutRight",
-  "backOutUp",
-  /* Bouncing entrances  */
-  "bounceIn",
-  "bounceInDown",
-  "bounceInLeft",
-  "bounceInRight",
-  "bounceInUp",
-  /* Bouncing exits  */
-  "bounceOut",
-  "bounceOutDown",
-  "bounceOutLeft",
-  "bounceOutRight",
-  "bounceOutUp",
-  /* Fading entrances  */
-  "fadeIn",
-  "fadeInDown",
-  "fadeInDownBig",
-  "fadeInLeft",
-  "fadeInLeftBig",
-  "fadeInRight",
-  "fadeInRightBig",
-  "fadeInUp",
-  "fadeInUpBig",
-  "fadeInTopLeft",
-  "fadeInTopRight",
-  "fadeInBottomLeft",
-  "fadeInBottomRight",
-  /* Fading exits */
-  "fadeOut",
-  "fadeOutDown",
-  "fadeOutDownBig",
-  "fadeOutLeft",
-  "fadeOutLeftBig",
-  "fadeOutRight",
-  "fadeOutRightBig",
-  "fadeOutUp",
-  "fadeOutUpBig",
-  "fadeOutTopLeft",
-  "fadeOutTopRight",
-  "fadeOutBottomRight",
-  "fadeOutBottomLeft",
-  /* Flippers */
-  "flip",
-  "flipInX",
-  "flipInY",
-  "flipOutX",
-  "flipOutY",
-  /* Lightspeed */
-  "lightSpeedInRight",
-  "lightSpeedInLeft",
-  "lightSpeedOutRight",
-  "lightSpeedOutLeft",
-  /* Rotating entrances */
-  "rotateIn",
-  "rotateInDownLeft",
-  "rotateInDownRight",
-  "rotateInUpLeft",
-  "rotateInUpRight",
-  /* Rotating exits */
-  "rotateOut",
-  "rotateOutDownLeft",
-  "rotateOutDownRight",
-  "rotateOutUpLeft",
-  "rotateOutUpRight",
-  /* Specials */
-  "hinge",
-  "jackInTheBox",
-  "rollIn",
-  "rollOut",
-  /* Zooming entrances */
-  "zoomIn",
-  "zoomInDown",
-  "zoomInLeft",
-  "zoomInRight",
-  "zoomInUp",
-  /* Zooming exits */
-  "zoomOut",
-  "zoomOutDown",
-  "zoomOutLeft",
-  "zoomOutRight",
-  "zoomOutUp",
-  /* Sliding entrances */
-  "slideInDown",
-  "slideInLeft",
-  "slideInRight",
-  "slideInUp",
-  /* Sliding exits */
-  "slideOutDown",
-  "slideOutLeft",
-  "slideOutRight",
-  "slideOutUp"
-];

+ 0 - 136
admin-web-new/src/components/ReAnimateSelector/src/index.vue

@@ -1,136 +0,0 @@
-<script setup lang="ts">
-import { ref, computed } from "vue";
-import { animates } from "./animate";
-import { cloneDeep } from "@pureadmin/utils";
-
-defineOptions({
-  name: "ReAnimateSelector"
-});
-
-defineProps({
-  placeholder: {
-    type: String,
-    default: "请选择动画"
-  }
-});
-
-const inputValue = defineModel({ type: String });
-
-const searchVal = ref();
-const animatesList = ref(animates);
-const copyAnimatesList = cloneDeep(animatesList);
-
-const animateClass = computed(() => {
-  return [
-    "mt-1",
-    "flex",
-    "border",
-    "w-[130px]",
-    "h-[100px]",
-    "items-center",
-    "cursor-pointer",
-    "transition-all",
-    "justify-center",
-    "border-[#e5e7eb]",
-    "hover:text-primary",
-    "hover:duration-[700ms]"
-  ];
-});
-
-const animateStyle = computed(
-  () => (i: string) =>
-    inputValue.value === i
-      ? {
-          borderColor: "var(--el-color-primary)",
-          color: "var(--el-color-primary)"
-        }
-      : ""
-);
-
-function onChangeIcon(animate: string) {
-  inputValue.value = animate;
-}
-
-function onClear() {
-  inputValue.value = "";
-}
-
-function filterMethod(value: any) {
-  searchVal.value = value;
-  animatesList.value = copyAnimatesList.value.filter((i: string | any[]) =>
-    i.includes(value)
-  );
-}
-
-const animateMap = ref({});
-function onMouseEnter(index: string | number) {
-  animateMap.value[index] = animateMap.value[index]?.loading
-    ? Object.assign({}, animateMap.value[index], {
-        loading: false
-      })
-    : Object.assign({}, animateMap.value[index], {
-        loading: true
-      });
-}
-function onMouseleave() {
-  animateMap.value = {};
-}
-</script>
-
-<template>
-  <el-select
-    clearable
-    filterable
-    :placeholder="placeholder"
-    popper-class="pure-animate-popper"
-    :model-value="inputValue"
-    :filter-method="filterMethod"
-    @clear="onClear"
-  >
-    <template #empty>
-      <div class="w-[280px]">
-        <el-scrollbar
-          noresize
-          height="212px"
-          :view-style="{ overflow: 'hidden' }"
-          class="border-t border-[#e5e7eb]"
-        >
-          <ul class="flex flex-wrap justify-around mb-1!">
-            <li
-              v-for="(animate, index) in animatesList"
-              :key="index"
-              :class="animateClass"
-              :style="animateStyle(animate)"
-              @mouseenter.prevent="onMouseEnter(index)"
-              @mouseleave.prevent="onMouseleave"
-              @click="onChangeIcon(animate)"
-            >
-              <h4
-                :class="[
-                  `animate__animated animate__${
-                    animateMap[index]?.loading
-                      ? animate + ' animate__infinite'
-                      : ''
-                  } `
-                ]"
-              >
-                {{ animate }}
-              </h4>
-            </li>
-          </ul>
-          <el-empty
-            v-show="animatesList.length === 0"
-            :description="`${searchVal} 动画不存在`"
-            :image-size="60"
-          />
-        </el-scrollbar>
-      </div>
-    </template>
-  </el-select>
-</template>
-
-<style>
-.pure-animate-popper {
-  min-width: 0 !important;
-}
-</style>

+ 0 - 7
admin-web-new/src/components/ReBarcode/index.ts

@@ -1,7 +0,0 @@
-import { withInstall } from "@pureadmin/utils";
-import reBarcode from "./src/index.vue";
-
-/** 条形码组件 */
-export const ReBarcode = withInstall(reBarcode);
-
-export default ReBarcode;

+ 0 - 42
admin-web-new/src/components/ReBarcode/src/index.vue

@@ -1,42 +0,0 @@
-<script setup lang="ts">
-import JsBarcode from "jsbarcode";
-import { ref, onMounted } from "vue";
-
-defineOptions({
-  name: "ReBarcode"
-});
-
-const props = defineProps({
-  tag: {
-    type: String,
-    default: "canvas"
-  },
-  text: {
-    type: String,
-    default: null
-  },
-  // 完整配置 https://github.com/lindell/JsBarcode/wiki/Options
-  options: {
-    type: Object,
-    default() {
-      return {};
-    }
-  },
-  // type 相当于 options.format,如果 type 和 options.format 同时存在,type 值优先;
-  type: {
-    type: String,
-    default: "CODE128"
-  }
-});
-
-const wrapEl = ref(null);
-
-onMounted(() => {
-  const opt = { ...props.options, format: props.type };
-  JsBarcode(wrapEl.value, props.text, opt);
-});
-</script>
-
-<template>
-  <component :is="tag" ref="wrapEl" />
-</template>

+ 0 - 29
admin-web-new/src/components/ReCol/index.ts

@@ -1,29 +0,0 @@
-import { ElCol } from "element-plus";
-import { h, defineComponent } from "vue";
-
-// 封装element-plus的el-col组件
-export default defineComponent({
-  name: "ReCol",
-  props: {
-    value: {
-      type: Number,
-      default: 24
-    }
-  },
-  render() {
-    const attrs = this.$attrs;
-    const val = this.value;
-    return h(
-      ElCol,
-      {
-        xs: val,
-        sm: val,
-        md: val,
-        lg: val,
-        xl: val,
-        ...attrs
-      },
-      { default: () => this.$slots.default() }
-    );
-  }
-});

+ 0 - 2
admin-web-new/src/components/ReCountTo/README.md

@@ -1,2 +0,0 @@
-normal 普通数字动画组件  
-rebound 回弹式数字动画组件

+ 0 - 11
admin-web-new/src/components/ReCountTo/index.ts

@@ -1,11 +0,0 @@
-import reNormalCountTo from "./src/normal";
-import reboundCountTo from "./src/rebound";
-import { withInstall } from "@pureadmin/utils";
-
-/** 普通数字动画组件 */
-const ReNormalCountTo = withInstall(reNormalCountTo);
-
-/** 回弹式数字动画组件 */
-const ReboundCountTo = withInstall(reboundCountTo);
-
-export { ReNormalCountTo, ReboundCountTo };

+ 0 - 179
admin-web-new/src/components/ReCountTo/src/normal/index.tsx

@@ -1,179 +0,0 @@
-import {
-  watch,
-  unref,
-  computed,
-  reactive,
-  onMounted,
-  defineComponent
-} from "vue";
-import { countToProps } from "./props";
-import { isNumber } from "@pureadmin/utils";
-
-export default defineComponent({
-  name: "ReNormalCountTo",
-  props: countToProps,
-  emits: ["mounted", "callback"],
-  setup(props, { emit }) {
-    const state = reactive<{
-      localStartVal: number;
-      printVal: number | null;
-      displayValue: string;
-      paused: boolean;
-      localDuration: number | null;
-      startTime: number | null;
-      timestamp: number | null;
-      rAF: any;
-      remaining: number | null;
-      color: string;
-      fontSize: string;
-    }>({
-      localStartVal: props.startVal,
-      displayValue: formatNumber(props.startVal),
-      printVal: null,
-      paused: false,
-      localDuration: props.duration,
-      startTime: null,
-      timestamp: null,
-      remaining: null,
-      rAF: null,
-      color: null,
-      fontSize: "16px"
-    });
-
-    const getCountDown = computed(() => {
-      return props.startVal > props.endVal;
-    });
-
-    watch([() => props.startVal, () => props.endVal], () => {
-      if (props.autoplay) {
-        start();
-      }
-    });
-
-    function start() {
-      const { startVal, duration, color, fontSize } = props;
-      state.localStartVal = startVal;
-      state.startTime = null;
-      state.localDuration = duration;
-      state.paused = false;
-      state.color = color;
-      state.fontSize = fontSize;
-      state.rAF = requestAnimationFrame(count);
-    }
-
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    function pauseResume() {
-      if (state.paused) {
-        resume();
-        state.paused = false;
-      } else {
-        pause();
-        state.paused = true;
-      }
-    }
-
-    function pause() {
-      cancelAnimationFrame(state.rAF);
-    }
-
-    function resume() {
-      state.startTime = null;
-      state.localDuration = +(state.remaining as number);
-      state.localStartVal = +(state.printVal as number);
-      requestAnimationFrame(count);
-    }
-
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    function reset() {
-      state.startTime = null;
-      cancelAnimationFrame(state.rAF);
-      state.displayValue = formatNumber(props.startVal);
-    }
-
-    function count(timestamp: number) {
-      const { useEasing, easingFn, endVal } = props;
-      if (!state.startTime) state.startTime = timestamp;
-      state.timestamp = timestamp;
-      const progress = timestamp - state.startTime;
-      state.remaining = (state.localDuration as number) - progress;
-      if (useEasing) {
-        if (unref(getCountDown)) {
-          state.printVal =
-            state.localStartVal -
-            easingFn(
-              progress,
-              0,
-              state.localStartVal - endVal,
-              state.localDuration as number
-            );
-        } else {
-          state.printVal = easingFn(
-            progress,
-            state.localStartVal,
-            endVal - state.localStartVal,
-            state.localDuration as number
-          );
-        }
-      } else {
-        if (unref(getCountDown)) {
-          state.printVal =
-            state.localStartVal -
-            (state.localStartVal - endVal) *
-              (progress / (state.localDuration as number));
-        } else {
-          state.printVal =
-            state.localStartVal +
-            (endVal - state.localStartVal) *
-              (progress / (state.localDuration as number));
-        }
-      }
-      if (unref(getCountDown)) {
-        state.printVal = state.printVal < endVal ? endVal : state.printVal;
-      } else {
-        state.printVal = state.printVal > endVal ? endVal : state.printVal;
-      }
-      state.displayValue = formatNumber(state.printVal);
-      if (progress < (state.localDuration as number)) {
-        state.rAF = requestAnimationFrame(count);
-      } else {
-        emit("callback");
-      }
-    }
-
-    function formatNumber(num: number | string) {
-      const { decimals, decimal, separator, suffix, prefix } = props;
-      num = Number(num).toFixed(decimals);
-      num += "";
-      const x = num.split(".");
-      let x1 = x[0];
-      const x2 = x.length > 1 ? decimal + x[1] : "";
-      const rgx = /(\d+)(\d{3})/;
-      if (separator && !isNumber(separator)) {
-        while (rgx.test(x1)) {
-          x1 = x1.replace(rgx, "$1" + separator + "$2");
-        }
-      }
-      return prefix + x1 + x2 + suffix;
-    }
-
-    onMounted(() => {
-      if (props.autoplay) {
-        start();
-      }
-      emit("mounted");
-    });
-
-    return () => (
-      <>
-        <span
-          style={{
-            color: props.color,
-            fontSize: props.fontSize
-          }}
-        >
-          {state.displayValue}
-        </span>
-      </>
-    );
-  }
-});

+ 0 - 32
admin-web-new/src/components/ReCountTo/src/normal/props.ts

@@ -1,32 +0,0 @@
-import type { PropType } from "vue";
-import propTypes from "@/utils/propTypes";
-
-export const countToProps = {
-  startVal: propTypes.number.def(0),
-  endVal: propTypes.number.def(2020),
-  duration: propTypes.number.def(1300),
-  autoplay: propTypes.bool.def(true),
-  decimals: {
-    type: Number as PropType<number>,
-    required: false,
-    default: 0,
-    validator(value: number) {
-      return value >= 0;
-    }
-  },
-  color: propTypes.string.def(),
-  fontSize: propTypes.string.def(),
-  decimal: propTypes.string.def("."),
-  separator: propTypes.string.def(","),
-  prefix: propTypes.string.def(""),
-  suffix: propTypes.string.def(""),
-  useEasing: propTypes.bool.def(true),
-  easingFn: {
-    type: Function as PropType<
-      (t: number, b: number, c: number, d: number) => number
-    >,
-    default(t: number, b: number, c: number, d: number) {
-      return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
-    }
-  }
-};

+ 0 - 72
admin-web-new/src/components/ReCountTo/src/rebound/index.tsx

@@ -1,72 +0,0 @@
-import "./rebound.css";
-import {
-  ref,
-  unref,
-  onBeforeMount,
-  defineComponent,
-  onBeforeUnmount
-} from "vue";
-import { reboundProps } from "./props";
-
-export default defineComponent({
-  name: "ReboundCountTo",
-  props: reboundProps,
-  setup(props) {
-    const ulRef = ref();
-    const timer = ref(null);
-
-    onBeforeMount(() => {
-      const ua = navigator.userAgent.toLowerCase();
-      const testUA = regexp => regexp.test(ua);
-      const isSafari = testUA(/safari/g) && !testUA(/chrome/g);
-
-      // Safari浏览器的兼容代码
-      isSafari &&
-        (timer.value = setTimeout(() => {
-          ulRef.value.setAttribute(
-            "style",
-            `
-        animation: none;
-        transform: translateY(calc(var(--i) * -9.09%))
-      `
-          );
-        }, props.delay * 1000));
-    });
-
-    onBeforeUnmount(() => {
-      clearTimeout(unref(timer));
-    });
-
-    return () => (
-      <>
-        <div
-          class="scroll-num"
-          style={{ "--i": props.i, "--delay": props.delay }}
-        >
-          <ul ref="ulRef" style={{ fontSize: "32px" }}>
-            <li>0</li>
-            <li>1</li>
-            <li>2</li>
-            <li>3</li>
-            <li>4</li>
-            <li>5</li>
-            <li>6</li>
-            <li>7</li>
-            <li>8</li>
-            <li>9</li>
-            <li>0</li>
-          </ul>
-
-          <svg width="0" height="0">
-            <filter id="blur">
-              <feGaussianBlur
-                in="SourceGraphic"
-                stdDeviation={`0 ${props.blur}`}
-              />
-            </filter>
-          </svg>
-        </div>
-      </>
-    );
-  }
-});

+ 0 - 15
admin-web-new/src/components/ReCountTo/src/rebound/props.ts

@@ -1,15 +0,0 @@
-import type { PropType } from "vue";
-import propTypes from "@/utils/propTypes";
-
-export const reboundProps = {
-  delay: propTypes.number.def(1),
-  blur: propTypes.number.def(2),
-  i: {
-    type: Number as PropType<number>,
-    required: false,
-    default: 0,
-    validator(value: number) {
-      return value < 10 && value >= 0 && Number.isInteger(value);
-    }
-  }
-};

+ 0 - 77
admin-web-new/src/components/ReCountTo/src/rebound/rebound.css

@@ -1,77 +0,0 @@
-.scroll-num {
-  width: var(--width, 20px);
-  height: var(--height, calc(var(--width, 20px) * 1.8));
-  color: var(--color, #333);
-  font-size: var(--height, calc(var(--width, 20px) * 1.1));
-  line-height: var(--height, calc(var(--width, 20px) * 1.8));
-  text-align: center;
-  overflow: hidden;
-  animation: enhance-bounce-in-down 1s calc(var(--delay) * 1s) forwards;
-}
-
-ul {
-  animation:
-    move 0.3s linear infinite,
-    bounce-in-down 1s calc(var(--delay) * 1s) forwards;
-}
-
-@keyframes move {
-  from {
-    transform: translateY(-90%);
-    filter: url(#blur);
-  }
-
-  to {
-    transform: translateY(1%);
-    filter: url(#blur);
-  }
-}
-
-@keyframes bounce-in-down {
-  from {
-    transform: translateY(calc(var(--i) * -9.09% - 7%));
-    filter: none;
-  }
-
-  25% {
-    transform: translateY(calc(var(--i) * -9.09% + 3%));
-  }
-
-  50% {
-    transform: translateY(calc(var(--i) * -9.09% - 1%));
-  }
-
-  70% {
-    transform: translateY(calc(var(--i) * -9.09% + 0.6%));
-  }
-
-  85% {
-    transform: translateY(calc(var(--i) * -9.09% - 0.3%));
-  }
-
-  to {
-    transform: translateY(calc(var(--i) * -9.09%));
-  }
-}
-
-@keyframes enhance-bounce-in-down {
-  25% {
-    transform: translateY(8%);
-  }
-
-  50% {
-    transform: translateY(-4%);
-  }
-
-  70% {
-    transform: translateY(2%);
-  }
-
-  85% {
-    transform: translateY(-1%);
-  }
-
-  to {
-    transform: translateY(0);
-  }
-}

+ 0 - 7
admin-web-new/src/components/ReCropper/index.ts

@@ -1,7 +0,0 @@
-import reCropper from "./src";
-import { withInstall } from "@pureadmin/utils";
-
-/** 图片裁剪组件 */
-export const ReCropper = withInstall(reCropper);
-
-export default ReCropper;

+ 0 - 8
admin-web-new/src/components/ReCropper/src/circled.css

@@ -1,8 +0,0 @@
-@import "cropperjs/dist/cropper.css";
-
-.re-circled {
-  .cropper-view-box,
-  .cropper-face {
-    border-radius: 50%;
-  }
-}

+ 0 - 457
admin-web-new/src/components/ReCropper/src/index.tsx

@@ -1,457 +0,0 @@
-import "./circled.css";
-import Cropper from "cropperjs";
-import { ElUpload } from "element-plus";
-import type { CSSProperties } from "vue";
-import { useEventListener } from "@vueuse/core";
-import { longpress } from "@/directives/longpress";
-import { useTippy, directive as tippy } from "vue-tippy";
-import {
-  type PropType,
-  ref,
-  unref,
-  computed,
-  onMounted,
-  onUnmounted,
-  defineComponent
-} from "vue";
-import {
-  delay,
-  debounce,
-  isArray,
-  downloadByBase64,
-  useResizeObserver
-} from "@pureadmin/utils";
-import {
-  Reload,
-  Upload,
-  ArrowH,
-  ArrowV,
-  ArrowUp,
-  ArrowDown,
-  ArrowLeft,
-  ChangeIcon,
-  ArrowRight,
-  RotateLeft,
-  SearchPlus,
-  RotateRight,
-  SearchMinus,
-  DownloadIcon
-} from "./svg";
-
-type Options = Cropper.Options;
-
-const defaultOptions: Options = {
-  aspectRatio: 1,
-  zoomable: true,
-  zoomOnTouch: true,
-  zoomOnWheel: true,
-  cropBoxMovable: true,
-  cropBoxResizable: true,
-  toggleDragModeOnDblclick: true,
-  autoCrop: true,
-  background: true,
-  highlight: true,
-  center: true,
-  responsive: true,
-  restore: true,
-  checkCrossOrigin: true,
-  checkOrientation: true,
-  scalable: true,
-  modal: true,
-  guides: true,
-  movable: true,
-  rotatable: true
-};
-
-const props = {
-  src: { type: String, required: true },
-  alt: { type: String },
-  circled: { type: Boolean, default: false },
-  /** 是否可以通过点击裁剪区域关闭右键弹出的功能菜单,默认 `true` */
-  isClose: { type: Boolean, default: true },
-  realTimePreview: { type: Boolean, default: true },
-  height: { type: [String, Number], default: "360px" },
-  crossorigin: {
-    type: String as PropType<"" | "anonymous" | "use-credentials" | undefined>,
-    default: undefined
-  },
-  imageStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
-  options: { type: Object as PropType<Options>, default: () => ({}) }
-};
-
-export default defineComponent({
-  name: "ReCropper",
-  props,
-  setup(props, { attrs, emit }) {
-    const tippyElRef = ref<ElRef<HTMLImageElement>>();
-    const imgElRef = ref<ElRef<HTMLImageElement>>();
-    const cropper = ref<Nullable<Cropper>>();
-    const inCircled = ref(props.circled);
-    const isInClose = ref(props.isClose);
-    const inSrc = ref(props.src);
-    const isReady = ref(false);
-    const imgBase64 = ref();
-
-    let scaleX = 1;
-    let scaleY = 1;
-
-    const debounceRealTimeCroppered = debounce(realTimeCroppered, 80);
-
-    const getImageStyle = computed((): CSSProperties => {
-      return {
-        height: props.height,
-        maxWidth: "100%",
-        ...props.imageStyle
-      };
-    });
-
-    const getClass = computed(() => {
-      return [
-        attrs.class,
-        {
-          ["re-circled"]: inCircled.value
-        }
-      ];
-    });
-
-    const iconClass = computed(() => {
-      return [
-        "p-[6px]",
-        "h-[30px]",
-        "w-[30px]",
-        "outline-hidden",
-        "rounded-[4px]",
-        "cursor-pointer",
-        "hover:bg-[rgba(0,0,0,0.06)]"
-      ];
-    });
-
-    const getWrapperStyle = computed((): CSSProperties => {
-      return { height: `${props.height}`.replace(/px/, "") + "px" };
-    });
-
-    onMounted(init);
-
-    onUnmounted(() => {
-      cropper.value?.destroy();
-      isReady.value = false;
-      cropper.value = null;
-      imgBase64.value = "";
-      scaleX = 1;
-      scaleY = 1;
-    });
-
-    useResizeObserver(tippyElRef, () => handCropper("reset"));
-
-    async function init() {
-      const imgEl = unref(imgElRef);
-      if (!imgEl) return;
-      cropper.value = new Cropper(imgEl, {
-        ...defaultOptions,
-        ready: () => {
-          isReady.value = true;
-          realTimeCroppered();
-          delay(400).then(() => emit("readied", cropper.value));
-        },
-        crop() {
-          debounceRealTimeCroppered();
-        },
-        zoom() {
-          debounceRealTimeCroppered();
-        },
-        cropmove() {
-          debounceRealTimeCroppered();
-        },
-        ...props.options
-      });
-    }
-
-    function realTimeCroppered() {
-      props.realTimePreview && croppered();
-    }
-
-    function croppered() {
-      if (!cropper.value) return;
-      const canvas = inCircled.value
-        ? getRoundedCanvas()
-        : cropper.value.getCroppedCanvas();
-      // https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toBlob
-      canvas.toBlob(blob => {
-        if (!blob) return;
-        const fileReader: FileReader = new FileReader();
-        fileReader.readAsDataURL(blob);
-        fileReader.onloadend = e => {
-          if (!e.target?.result || !blob) return;
-          imgBase64.value = e.target.result;
-          emit("cropper", {
-            base64: e.target.result,
-            blob,
-            info: { size: blob.size, ...cropper.value.getData() }
-          });
-        };
-        fileReader.onerror = () => {
-          emit("error");
-        };
-      });
-    }
-
-    function getRoundedCanvas() {
-      const sourceCanvas = cropper.value!.getCroppedCanvas();
-      const canvas = document.createElement("canvas");
-      const context = canvas.getContext("2d")!;
-      const width = sourceCanvas.width;
-      const height = sourceCanvas.height;
-      canvas.width = width;
-      canvas.height = height;
-      context.imageSmoothingEnabled = true;
-      context.drawImage(sourceCanvas, 0, 0, width, height);
-      context.globalCompositeOperation = "destination-in";
-      context.beginPath();
-      context.arc(
-        width / 2,
-        height / 2,
-        Math.min(width, height) / 2,
-        0,
-        2 * Math.PI,
-        true
-      );
-      context.fill();
-      return canvas;
-    }
-
-    function handCropper(event: string, arg?: number | Array<number>) {
-      if (event === "scaleX") {
-        scaleX = arg = scaleX === -1 ? 1 : -1;
-      }
-
-      if (event === "scaleY") {
-        scaleY = arg = scaleY === -1 ? 1 : -1;
-      }
-      arg && isArray(arg)
-        ? cropper.value?.[event]?.(...arg)
-        : cropper.value?.[event]?.(arg);
-    }
-
-    function beforeUpload(file) {
-      const reader = new FileReader();
-      reader.readAsDataURL(file);
-      inSrc.value = "";
-      reader.onload = e => {
-        inSrc.value = e.target?.result as string;
-      };
-      reader.onloadend = () => {
-        init();
-      };
-      return false;
-    }
-
-    const menuContent = defineComponent({
-      directives: {
-        tippy,
-        longpress
-      },
-      setup() {
-        return () => (
-          <div class="flex flex-wrap w-[60px] justify-between">
-            <ElUpload
-              accept="image/*"
-              show-file-list={false}
-              before-upload={beforeUpload}
-            >
-              <Upload
-                class={iconClass.value}
-                v-tippy={{
-                  content: "上传",
-                  placement: "left-start"
-                }}
-              />
-            </ElUpload>
-            <DownloadIcon
-              class={iconClass.value}
-              v-tippy={{
-                content: "下载",
-                placement: "right-start"
-              }}
-              onClick={() => downloadByBase64(imgBase64.value, "cropping.png")}
-            />
-            <ChangeIcon
-              class={iconClass.value}
-              v-tippy={{
-                content: "圆形、矩形裁剪",
-                placement: "left-start"
-              }}
-              onClick={() => {
-                inCircled.value = !inCircled.value;
-                realTimeCroppered();
-              }}
-            />
-            <Reload
-              class={iconClass.value}
-              v-tippy={{
-                content: "重置",
-                placement: "right-start"
-              }}
-              onClick={() => handCropper("reset")}
-            />
-            <ArrowUp
-              class={iconClass.value}
-              v-tippy={{
-                content: "上移(可长按)",
-                placement: "left-start"
-              }}
-              v-longpress={[() => handCropper("move", [0, -10]), "0:100"]}
-            />
-            <ArrowDown
-              class={iconClass.value}
-              v-tippy={{
-                content: "下移(可长按)",
-                placement: "right-start"
-              }}
-              v-longpress={[() => handCropper("move", [0, 10]), "0:100"]}
-            />
-            <ArrowLeft
-              class={iconClass.value}
-              v-tippy={{
-                content: "左移(可长按)",
-                placement: "left-start"
-              }}
-              v-longpress={[() => handCropper("move", [-10, 0]), "0:100"]}
-            />
-            <ArrowRight
-              class={iconClass.value}
-              v-tippy={{
-                content: "右移(可长按)",
-                placement: "right-start"
-              }}
-              v-longpress={[() => handCropper("move", [10, 0]), "0:100"]}
-            />
-            <ArrowH
-              class={iconClass.value}
-              v-tippy={{
-                content: "水平翻转",
-                placement: "left-start"
-              }}
-              onClick={() => handCropper("scaleX", -1)}
-            />
-            <ArrowV
-              class={iconClass.value}
-              v-tippy={{
-                content: "垂直翻转",
-                placement: "right-start"
-              }}
-              onClick={() => handCropper("scaleY", -1)}
-            />
-            <RotateLeft
-              class={iconClass.value}
-              v-tippy={{
-                content: "逆时针旋转",
-                placement: "left-start"
-              }}
-              onClick={() => handCropper("rotate", -45)}
-            />
-            <RotateRight
-              class={iconClass.value}
-              v-tippy={{
-                content: "顺时针旋转",
-                placement: "right-start"
-              }}
-              onClick={() => handCropper("rotate", 45)}
-            />
-            <SearchPlus
-              class={iconClass.value}
-              v-tippy={{
-                content: "放大(可长按)",
-                placement: "left-start"
-              }}
-              v-longpress={[() => handCropper("zoom", 0.1), "0:100"]}
-            />
-            <SearchMinus
-              class={iconClass.value}
-              v-tippy={{
-                content: "缩小(可长按)",
-                placement: "right-start"
-              }}
-              v-longpress={[() => handCropper("zoom", -0.1), "0:100"]}
-            />
-          </div>
-        );
-      }
-    });
-
-    function onContextmenu(event) {
-      event.preventDefault();
-
-      const { show, setProps, destroy, state } = useTippy(tippyElRef, {
-        content: menuContent,
-        arrow: false,
-        theme: "light",
-        trigger: "manual",
-        interactive: true,
-        appendTo: "parent",
-        // hideOnClick: false,
-        placement: "bottom-end"
-      });
-
-      setProps({
-        getReferenceClientRect: () => ({
-          width: 0,
-          height: 0,
-          top: event.clientY,
-          bottom: event.clientY,
-          left: event.clientX,
-          right: event.clientX
-        })
-      });
-
-      show();
-
-      if (isInClose.value) {
-        if (!state.value.isShown && !state.value.isVisible) return;
-        useEventListener(tippyElRef, "click", destroy);
-      }
-    }
-
-    return {
-      inSrc,
-      props,
-      imgElRef,
-      tippyElRef,
-      getClass,
-      getWrapperStyle,
-      getImageStyle,
-      isReady,
-      croppered,
-      onContextmenu
-    };
-  },
-
-  render() {
-    const {
-      inSrc,
-      isReady,
-      getClass,
-      getImageStyle,
-      onContextmenu,
-      getWrapperStyle
-    } = this;
-    const { alt, crossorigin } = this.props;
-
-    return inSrc ? (
-      <div
-        ref="tippyElRef"
-        class={getClass}
-        style={getWrapperStyle}
-        onContextmenu={event => onContextmenu(event)}
-      >
-        <img
-          v-show={isReady}
-          ref="imgElRef"
-          style={getImageStyle}
-          src={inSrc}
-          alt={alt}
-          crossorigin={crossorigin}
-        />
-      </div>
-    ) : null;
-  }
-});

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/arrow-down.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M862 465.3h-81c-4.6 0-9 2-12.1 5.5L550 723.1V160c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v563.1L255.1 470.8c-3-3.5-7.4-5.5-12.1-5.5h-81c-6.8 0-10.5 8.1-6 13.2L487.9 861a31.96 31.96 0 0 0 48.3 0L868 478.5c4.5-5.2.8-13.2-6-13.2"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/arrow-h.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024"><path d="m296.992 216.992-272 272L3.008 512l21.984 23.008 272 272 46.016-46.016L126.016 544h772L680.992 760.992l46.016 46.016 272-272L1020.992 512l-21.984-23.008-272-272-46.048 46.048L898.016 480h-772l216.96-216.992z"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/arrow-left.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M872 474H286.9l350.2-304c5.6-4.9 2.2-14-5.2-14h-88.5c-3.9 0-7.6 1.4-10.5 3.9L155 487.8a31.96 31.96 0 0 0 0 48.3L535.1 866c1.5 1.3 3.3 2 5.2 2h91.5c7.4 0 10.8-9.2 5.2-14L286.9 550H872c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/arrow-right.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M869 487.8 491.2 159.9c-2.9-2.5-6.6-3.9-10.5-3.9h-88.5c-7.4 0-10.8 9.2-5.2 14l350.2 304H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h585.1L386.9 854c-5.6 4.9-2.2 14 5.2 14h91.5c1.9 0 3.8-.7 5.2-2L869 536.2a32.07 32.07 0 0 0 0-48.4"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/arrow-up.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M868 545.5 536.1 163a31.96 31.96 0 0 0-48.3 0L156 545.5a7.97 7.97 0 0 0 6 13.2h81c4.6 0 9-2 12.1-5.5L474 300.9V864c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V300.9l218.9 252.3c3 3.5 7.4 5.5 12.1 5.5h81c6.8 0 10.5-8 6-13.2"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/arrow-v.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024"><path d="m512 67.008-23.008 21.984-256 256 46.048 46.048L480 190.016v644L279.008 632.96l-46.048 46.08 256 256 23.008 21.984 23.008-21.984 256-256-46.016-46.016L544 834.016v-644l200.992 200.96 46.016-45.984-256-256z"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/change.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024"><path d="M956.8 988.8H585.6c-16 0-25.6-9.6-25.6-28.8V576c0-16 9.6-28.8 25.6-28.8h371.2c16 0 25.6 9.6 25.6 28.8v384c0 16-9.6 28.8-25.6 28.8M608 937.6h326.4V598.4H608zm-121.6 44.8C262.4 982.4 144 848 144 595.2c0-19.2 9.6-28.8 25.6-28.8s25.6 12.8 25.6 28.8c0 220.8 96 326.4 288 326.4 16 0 25.6 12.8 25.6 28.8s-6.4 32-22.4 32"/><path d="M262.4 694.4c-6.4 0-9.6-3.2-16-6.4L160 601.6c-9.6-9.6-9.6-22.4 0-28.8s22.4-9.6 28.8 0l86.4 86.4c9.6 9.6 9.6 22.4 0 28.8-3.2 3.2-6.4 6.4-12.8 6.4"/><path d="M86.4 694.4c-6.4 0-9.6-3.2-16-6.4-9.6-9.6-9.6-22.4 0-28.8l86.4-86.4c9.6-9.6 22.4-9.6 28.8 0 9.6 9.6 9.6 22.4 0 28.8L99.2 688c-3.2 3.2-6.4 6.4-12.8 6.4m790.4-249.6c-16 0-28.8-12.8-28.8-32 0-224-99.2-336-300.8-336-16 0-28.8-12.8-28.8-32s9.6-32 28.8-32c233.6 0 355.2 137.6 355.2 396.8 0 22.4-9.6 35.2-25.6 35.2"/><path d="M876.8 448c-6.4 0-9.6-3.2-16-6.4l-86.4-86.4c-9.6-9.6-9.6-22.4 0-28.8s22.4-9.6 28.8 0l86.4 86.4c9.6 9.6 9.6 22.4 0 28.8 0 3.2-6.4 6.4-12.8 6.4"/><path d="M876.8 448c-6.4 0-9.6-3.2-16-6.4-9.6-9.6-9.6-22.4 0-28.8l86.4-86.4c9.6-9.6 22.4-9.6 28.8 0s9.6 22.4 0 28.8l-86.4 86.4c-3.2 3.2-6.4 6.4-12.8 6.4M288 524.8C156.8 524.8 48 416 48 278.4S156.8 35.2 288 35.2 528 144 528 281.6 419.2 524.8 288 524.8m-3.2-432c-99.2 0-179.2 83.2-179.2 185.6S185.6 464 284.8 464 464 380.8 464 278.4 384 92.8 284.8 92.8"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/download.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8"/></svg>

+ 0 - 31
admin-web-new/src/components/ReCropper/src/svg/index.ts

@@ -1,31 +0,0 @@
-import Reload from "./reload.svg?component";
-import Upload from "./upload.svg?component";
-import ArrowH from "./arrow-h.svg?component";
-import ArrowV from "./arrow-v.svg?component";
-import ArrowUp from "./arrow-up.svg?component";
-import ChangeIcon from "./change.svg?component";
-import ArrowDown from "./arrow-down.svg?component";
-import ArrowLeft from "./arrow-left.svg?component";
-import DownloadIcon from "./download.svg?component";
-import ArrowRight from "./arrow-right.svg?component";
-import RotateLeft from "./rotate-left.svg?component";
-import SearchPlus from "./search-plus.svg?component";
-import RotateRight from "./rotate-right.svg?component";
-import SearchMinus from "./search-minus.svg?component";
-
-export {
-  Reload,
-  Upload,
-  ArrowH,
-  ArrowV,
-  ArrowUp,
-  ArrowDown,
-  ArrowLeft,
-  ChangeIcon,
-  ArrowRight,
-  RotateLeft,
-  SearchPlus,
-  RotateRight,
-  SearchMinus,
-  DownloadIcon
-};

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/reload.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M168 504.2c1-43.7 10-86.1 26.9-126 17.3-41 42.1-77.7 73.7-109.4S337 212.3 378 195c42.4-17.9 87.4-27 133.9-27s91.5 9.1 133.8 27A341.5 341.5 0 0 1 755 268.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 0 0 3 14.1l175.7 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c0-6.7-7.7-10.5-12.9-6.3l-56.4 44.1C765.8 155.1 646.2 92 511.8 92 282.7 92 96.3 275.6 92 503.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8m756 7.8h-60c-4.4 0-7.9 3.5-8 7.8-1 43.7-10 86.1-26.9 126-17.3 41-42.1 77.8-73.7 109.4A342.45 342.45 0 0 1 512.1 856a342.24 342.24 0 0 1-243.2-100.8c-9.9-9.9-19.2-20.4-27.8-31.4l60.2-47a8 8 0 0 0-3-14.1l-175.7-43c-5-1.2-9.9 2.6-9.9 7.7l-.7 181c0 6.7 7.7 10.5 12.9 6.3l56.4-44.1C258.2 868.9 377.8 932 512.2 932c229.2 0 415.5-183.7 419.8-411.8a8 8 0 0 0-8-8.2"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/rotate-left.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M672 418H144c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32m-44 402H188V494h440z"/><path fill="currentColor" d="M819.3 328.5c-78.8-100.7-196-153.6-314.6-154.2l-.2-64c0-6.5-7.6-10.1-12.6-6.1l-128 101c-4 3.1-3.9 9.1 0 12.3L492 318.6c5.1 4 12.7.4 12.6-6.1v-63.9c12.9.1 25.9.9 38.8 2.5 42.1 5.2 82.1 18.2 119 38.7 38.1 21.2 71.2 49.7 98.4 84.3 27.1 34.7 46.7 73.7 58.1 115.8 11 40.7 14 82.7 8.9 124.8-.7 5.4-1.4 10.8-2.4 16.1h74.9c14.8-103.6-11.3-213-81-302.3"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/rotate-right.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M480.5 251.2c13-1.6 25.9-2.4 38.8-2.5v63.9c0 6.5 7.5 10.1 12.6 6.1L660 217.6c4-3.2 4-9.2 0-12.3l-128-101c-5.1-4-12.6-.4-12.6 6.1l-.2 64c-118.6.5-235.8 53.4-314.6 154.2-69.6 89.2-95.7 198.6-81.1 302.4h74.9c-.9-5.3-1.7-10.7-2.4-16.1-5.1-42.1-2.1-84.1 8.9-124.8 11.4-42.2 31-81.1 58.1-115.8 27.2-34.7 60.3-63.2 98.4-84.3 37-20.6 76.9-33.6 119.1-38.8"/><path fill="currentColor" d="M880 418H352c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32m-44 402H396V494h440z"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/search-minus.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M637 443H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h312c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8m284 424L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11M696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/search-plus.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M637 443H519V309c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v134H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h118v134c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V519h118c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8m284 424L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11M696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430"/></svg>

+ 0 - 1
admin-web-new/src/components/ReCropper/src/svg/upload.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M400 317.7h73.9V656c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V317.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 163a8 8 0 0 0-12.6 0l-112 141.7c-4.1 5.3-.4 13 6.3 13M878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8"/></svg>

+ 0 - 7
admin-web-new/src/components/ReCropperPreview/index.ts

@@ -1,7 +0,0 @@
-import reCropperPreview from "./src/index.vue";
-import { withInstall } from "@pureadmin/utils";
-
-/** 图片裁剪预览组件 */
-export const ReCropperPreview = withInstall(reCropperPreview);
-
-export default ReCropperPreview;

+ 0 - 76
admin-web-new/src/components/ReCropperPreview/src/index.vue

@@ -1,76 +0,0 @@
-<script setup lang="tsx">
-import { ref } from "vue";
-import ReCropper from "@/components/ReCropper";
-import { formatBytes } from "@pureadmin/utils";
-
-defineOptions({
-  name: "ReCropperPreview"
-});
-
-defineProps({
-  imgSrc: String
-});
-
-const emit = defineEmits(["cropper"]);
-
-const infos = ref();
-const popoverRef = ref();
-const refCropper = ref();
-const showPopover = ref(false);
-const cropperImg = ref<string>("");
-
-function onCropper({ base64, blob, info }) {
-  infos.value = info;
-  cropperImg.value = base64;
-  emit("cropper", { base64, blob, info });
-}
-
-function hidePopover() {
-  popoverRef.value.hide();
-}
-
-defineExpose({ hidePopover });
-</script>
-
-<template>
-  <div v-loading="!showPopover" element-loading-background="transparent">
-    <el-popover
-      ref="popoverRef"
-      :visible="showPopover"
-      placement="right"
-      width="18vw"
-    >
-      <template #reference>
-        <div class="w-[18vw]">
-          <ReCropper
-            ref="refCropper"
-            :src="imgSrc"
-            circled
-            @cropper="onCropper"
-            @readied="showPopover = true"
-          />
-          <p v-show="showPopover" class="mt-1 text-center">
-            温馨提示:右键上方裁剪区可开启功能菜单
-          </p>
-        </div>
-      </template>
-      <div class="flex flex-wrap justify-center items-center text-center">
-        <el-image
-          v-if="cropperImg"
-          :src="cropperImg"
-          :preview-src-list="Array.of(cropperImg)"
-          fit="cover"
-        />
-        <div v-if="infos" class="mt-1">
-          <p>
-            图像大小:{{ parseInt(infos.width) }} ×
-            {{ parseInt(infos.height) }}像素
-          </p>
-          <p>
-            文件大小:{{ formatBytes(infos.size) }}({{ infos.size }} 字节)
-          </p>
-        </div>
-      </div>
-    </el-popover>
-  </div>
-</template>

+ 0 - 69
admin-web-new/src/components/ReDialog/index.ts

@@ -1,69 +0,0 @@
-import { ref } from "vue";
-import reDialog from "./index.vue";
-import { useTimeoutFn } from "@vueuse/core";
-import { withInstall } from "@pureadmin/utils";
-import type {
-  EventType,
-  ArgsType,
-  DialogProps,
-  ButtonProps,
-  DialogOptions
-} from "./type";
-
-const dialogStore = ref<Array<DialogOptions>>([]);
-
-/** 打开弹框 */
-const addDialog = (options: DialogOptions) => {
-  const open = () =>
-    dialogStore.value.push(Object.assign(options, { visible: true }));
-  if (options?.openDelay) {
-    useTimeoutFn(() => {
-      open();
-    }, options.openDelay);
-  } else {
-    open();
-  }
-};
-
-/** 关闭弹框 */
-const closeDialog = (options: DialogOptions, index: number, args?: any) => {
-  dialogStore.value[index].visible = false;
-  options.closeCallBack && options.closeCallBack({ options, index, args });
-
-  const closeDelay = options?.closeDelay ?? 200;
-  useTimeoutFn(() => {
-    dialogStore.value.splice(index, 1);
-  }, closeDelay);
-};
-
-/**
- * @description 更改弹框自身属性值
- * @param value 属性值
- * @param key 属性,默认`title`
- * @param index 弹框索引(默认`0`,代表只有一个弹框,对于嵌套弹框要改哪个弹框的属性值就把该弹框索引赋给`index`)
- */
-const updateDialog = (value: any, key = "title", index = 0) => {
-  dialogStore.value[index][key] = value;
-};
-
-/** 关闭所有弹框 */
-const closeAllDialog = () => {
-  dialogStore.value = [];
-};
-
-/** 千万别忘了在下面这三处引入并注册下,放心注册,不使用`addDialog`调用就不会被挂载
- * https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L4
- * https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L12
- * https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L22
- */
-const ReDialog = withInstall(reDialog);
-
-export type { EventType, ArgsType, DialogProps, ButtonProps, DialogOptions };
-export {
-  ReDialog,
-  dialogStore,
-  addDialog,
-  closeDialog,
-  updateDialog,
-  closeAllDialog
-};

+ 0 - 206
admin-web-new/src/components/ReDialog/index.vue

@@ -1,206 +0,0 @@
-<script setup lang="ts">
-import {
-  type EventType,
-  type ButtonProps,
-  type DialogOptions,
-  closeDialog,
-  dialogStore
-} from "./index";
-import { ref, computed } from "vue";
-import { isFunction } from "@pureadmin/utils";
-import Fullscreen from "~icons/ri/fullscreen-fill";
-import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
-
-defineOptions({
-  name: "ReDialog"
-});
-
-const sureBtnMap = ref({});
-const fullscreen = ref(false);
-
-const footerButtons = computed(() => {
-  return (options: DialogOptions) => {
-    return options?.footerButtons?.length > 0
-      ? options.footerButtons
-      : ([
-          {
-            label: "取消",
-            text: true,
-            bg: true,
-            btnClick: ({ dialog: { options, index } }) => {
-              const done = () =>
-                closeDialog(options, index, { command: "cancel" });
-              if (options?.beforeCancel && isFunction(options?.beforeCancel)) {
-                options.beforeCancel(done, { options, index });
-              } else {
-                done();
-              }
-            }
-          },
-          {
-            label: "确定",
-            type: "primary",
-            text: true,
-            bg: true,
-            popconfirm: options?.popconfirm,
-            btnClick: ({ dialog: { options, index } }) => {
-              if (options?.sureBtnLoading) {
-                sureBtnMap.value[index] = Object.assign(
-                  {},
-                  sureBtnMap.value[index],
-                  {
-                    loading: true
-                  }
-                );
-              }
-              const closeLoading = () => {
-                if (options?.sureBtnLoading) {
-                  sureBtnMap.value[index].loading = false;
-                }
-              };
-              const done = () => {
-                closeLoading();
-                closeDialog(options, index, { command: "sure" });
-              };
-              if (options?.beforeSure && isFunction(options?.beforeSure)) {
-                options.beforeSure(done, { options, index, closeLoading });
-              } else {
-                done();
-              }
-            }
-          }
-        ] as Array<ButtonProps>);
-  };
-});
-
-const fullscreenClass = computed(() => {
-  return [
-    "el-icon",
-    "el-dialog__close",
-    "-translate-x-2",
-    "cursor-pointer",
-    "hover:text-[red]!"
-  ];
-});
-
-function eventsCallBack(
-  event: EventType,
-  options: DialogOptions,
-  index: number,
-  isClickFullScreen = false
-) {
-  if (!isClickFullScreen) fullscreen.value = options?.fullscreen ?? false;
-  if (options?.[event] && isFunction(options?.[event])) {
-    return options?.[event]({ options, index });
-  }
-}
-
-function handleClose(
-  options: DialogOptions,
-  index: number,
-  args = { command: "close" }
-) {
-  closeDialog(options, index, args);
-  eventsCallBack("close", options, index);
-}
-</script>
-
-<template>
-  <el-dialog
-    v-for="(options, index) in dialogStore"
-    :key="index"
-    v-bind="options"
-    v-model="options.visible"
-    class="pure-dialog"
-    :fullscreen="fullscreen ? true : options?.fullscreen ? true : false"
-    @closed="handleClose(options, index)"
-    @opened="eventsCallBack('open', options, index)"
-    @openAutoFocus="eventsCallBack('openAutoFocus', options, index)"
-    @closeAutoFocus="eventsCallBack('closeAutoFocus', options, index)"
-  >
-    <!-- header -->
-    <template
-      v-if="options?.fullscreenIcon || options?.headerRenderer"
-      #header="{ close, titleId, titleClass }"
-    >
-      <div
-        v-if="options?.fullscreenIcon"
-        class="flex items-center justify-between"
-      >
-        <span :id="titleId" :class="titleClass">{{ options?.title }}</span>
-        <i
-          v-if="!options?.fullscreen"
-          :class="fullscreenClass"
-          @click="
-            () => {
-              fullscreen = !fullscreen;
-              eventsCallBack(
-                'fullscreenCallBack',
-                { ...options, fullscreen },
-                index,
-                true
-              );
-            }
-          "
-        >
-          <IconifyIconOffline
-            class="pure-dialog-svg"
-            :icon="
-              options?.fullscreen
-                ? ExitFullscreen
-                : fullscreen
-                  ? ExitFullscreen
-                  : Fullscreen
-            "
-          />
-        </i>
-      </div>
-      <component
-        :is="options?.headerRenderer({ close, titleId, titleClass })"
-        v-else
-      />
-    </template>
-    <component
-      v-bind="options?.props"
-      :is="options.contentRenderer({ options, index })"
-      @close="args => handleClose(options, index, args)"
-    />
-    <!-- footer -->
-    <template v-if="!options?.hideFooter" #footer>
-      <template v-if="options?.footerRenderer">
-        <component :is="options?.footerRenderer({ options, index })" />
-      </template>
-      <span v-else>
-        <template v-for="(btn, key) in footerButtons(options)" :key="key">
-          <el-popconfirm
-            v-if="btn.popconfirm"
-            v-bind="btn.popconfirm"
-            @confirm="
-              btn.btnClick({
-                dialog: { options, index },
-                button: { btn, index: key }
-              })
-            "
-          >
-            <template #reference>
-              <el-button v-bind="btn">{{ btn?.label }}</el-button>
-            </template>
-          </el-popconfirm>
-          <el-button
-            v-else
-            v-bind="btn"
-            :loading="key === 1 && sureBtnMap[index]?.loading"
-            @click="
-              btn.btnClick({
-                dialog: { options, index },
-                button: { btn, index: key }
-              })
-            "
-          >
-            {{ btn?.label }}
-          </el-button>
-        </template>
-      </span>
-    </template>
-  </el-dialog>
-</template>

+ 0 - 297
admin-web-new/src/components/ReDialog/type.ts

@@ -1,297 +0,0 @@
-import type { CSSProperties, VNode, Component } from "vue";
-
-type DoneFn = (cancel?: boolean) => void;
-type EventType =
-  | "open"
-  | "close"
-  | "openAutoFocus"
-  | "closeAutoFocus"
-  | "fullscreenCallBack";
-type ArgsType = {
-  /** `cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了esc键 */
-  command: "cancel" | "sure" | "close";
-};
-type ButtonType =
-  | "primary"
-  | "success"
-  | "warning"
-  | "danger"
-  | "info"
-  | "text";
-
-/** https://element-plus.org/zh-CN/component/dialog.html#attributes */
-type DialogProps = {
-  /** `Dialog` 的显示与隐藏 */
-  visible?: boolean;
-  /** `Dialog` 的标题 */
-  title?: string;
-  /** `Dialog` 的宽度,默认 `50%` */
-  width?: string | number;
-  /** 是否为全屏 `Dialog`(会一直处于全屏状态,除非弹框关闭),默认 `false`,`fullscreen` 和 `fullscreenIcon` 都传时只有 `fullscreen` 会生效 */
-  fullscreen?: boolean;
-  /** 是否显示全屏操作图标,默认 `false`,`fullscreen` 和 `fullscreenIcon` 都传时只有 `fullscreen` 会生效 */
-  fullscreenIcon?: boolean;
-  /** `Dialog CSS` 中的 `margin-top` 值,默认 `15vh` */
-  top?: string;
-  /** 是否需要遮罩层,默认 `true` */
-  modal?: boolean;
-  /** 是否允许穿透遮罩层,默认 `false`。使用时需将 `modal` 属性设置为 `false` */
-  modalPenetrable?: boolean;
-  /** 遮罩的自定义类名 */
-  modalClass?: string;
-  /** `header` 部分的自定义 `class` 名 */
-  headerClass?: string;
-  /** `body` 部分的自定义 `class` 名 */
-  bodyClass?: string;
-  /** `footer` 部分的自定义 `class` 名 */
-  footerClass?: string;
-  /** `Dialog` 自身是否插入至 `body` 元素上。嵌套的 `Dialog` 必须指定该属性并赋值为 `true`,默认 `false` */
-  appendToBody?: boolean;
-  /** `Dialog` 挂载到哪个 `DOM` 元素,该属性会覆盖 `append-to-body` 属性,默认 `body` */
-  appendTo?: string | HTMLElement;
-  /** 是否在 `Dialog` 出现时将 `body` 滚动锁定,默认 `true` */
-  lockScroll?: boolean;
-  /** `Dialog` 的自定义类名 */
-  class?: string;
-  /** `Dialog` 的自定义样式 */
-  style?: CSSProperties;
-  /** `Dialog` 打开的延时时间,单位毫秒,默认 `0` */
-  openDelay?: number;
-  /** `Dialog` 关闭的延时时间,单位毫秒,默认 `0` */
-  closeDelay?: number;
-  /** 是否可以通过点击 `modal` 关闭 `Dialog`,默认 `true` */
-  closeOnClickModal?: boolean;
-  /** 是否可以通过按下 `ESC` 关闭 `Dialog`,默认 `true` */
-  closeOnPressEscape?: boolean;
-  /** 是否显示关闭按钮,默认 `true` */
-  showClose?: boolean;
-  /** 关闭前的回调,会暂停 `Dialog` 的关闭. 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */
-  beforeClose?: (done: DoneFn) => void;
-  /** 为 `Dialog` 启用可拖拽功能,默认 `false` */
-  draggable?: boolean;
-  /** 拖动范围可以超出可视区,默认 `false` */
-  overflow?: boolean;
-  /** 是否让 `Dialog` 的 `header` 和 `footer` 部分居中排列,默认 `false` */
-  center?: boolean;
-  /** 是否水平垂直对齐对话框,默认 `false` */
-  alignCenter?: boolean;
-  /** 当关闭 `Dialog` 时,销毁其中的元素,默认 `false` */
-  destroyOnClose?: boolean;
-  /** 自定义关闭图标,默认 `Close` */
-  closeIcon?: string | Component;
-  /** 和原生的 `CSS` 的 `z-index` 相同,改变 `z` 轴的顺序 */
-  zIndex?: number;
-  /** `header` 的 `aria-level` 属性 */
-  headerAriaLevel?: string;
-  /** 对话框动画的自定义过渡配置。可以是一个字符串(过渡名称),也可以是一个包含 `Vue` 过渡属性的对象,默认 `dialog-fade` */
-  transition?: string | object;
-};
-
-//element-plus.org/zh-CN/component/popconfirm.html#attributes
-type Popconfirm = {
-  /** 标题 */
-  title?: string;
-  /** 确定按钮文字 */
-  confirmButtonText?: string;
-  /** 取消按钮文字 */
-  cancelButtonText?: string;
-  /** 确定按钮类型,默认 `primary` */
-  confirmButtonType?: ButtonType;
-  /** 取消按钮类型,默认 `text` */
-  cancelButtonType?: ButtonType;
-  /** 自定义图标,默认 `QuestionFilled` */
-  icon?: string | Component;
-  /** `Icon` 颜色,默认 `#f90` */
-  iconColor?: string;
-  /** 是否隐藏 `Icon`,默认 `false` */
-  hideIcon?: boolean;
-  /** 关闭时的延迟,默认 `200` */
-  hideAfter?: number;
-  /** 是否将 `popover` 的下拉列表插入至 `body` 元素,默认 `true` */
-  teleported?: boolean;
-  /** 当 `popover` 组件长时间不触发且 `persistent` 属性设置为 `false` 时, `popover` 将会被删除,默认 `false` */
-  persistent?: boolean;
-  /** 弹层宽度,最小宽度 `150px`,默认 `150` */
-  width?: string | number;
-};
-
-type BtnClickDialog = {
-  options?: DialogOptions;
-  index?: number;
-};
-type BtnClickButton = {
-  btn?: ButtonProps;
-  index?: number;
-};
-/** https://element-plus.org/zh-CN/component/button.html#button-attributes */
-type ButtonProps = {
-  /** 按钮文字 */
-  label: string;
-  /** 按钮尺寸 */
-  size?: "large" | "default" | "small";
-  /** 按钮类型 */
-  type?: "primary" | "success" | "warning" | "danger" | "info";
-  /** 是否为朴素按钮,默认 `false` */
-  plain?: boolean;
-  /** 是否为文字按钮,默认 `false` */
-  text?: boolean;
-  /** 是否显示文字按钮背景颜色,默认 `false` */
-  bg?: boolean;
-  /** 是否为链接按钮,默认 `false` */
-  link?: boolean;
-  /** 是否为圆角按钮,默认 `false` */
-  round?: boolean;
-  /** 是否为圆形按钮,默认 `false` */
-  circle?: boolean;
-  /** 确定按钮的 `Popconfirm` 气泡确认框相关配置 */
-  popconfirm?: Popconfirm;
-  /** 是否为加载中状态,默认 `false` */
-  loading?: boolean;
-  /** 自定义加载中状态图标组件 */
-  loadingIcon?: string | Component;
-  /** 按钮是否为禁用状态,默认 `false` */
-  disabled?: boolean;
-  /** 图标组件 */
-  icon?: string | Component;
-  /** 是否开启原生 `autofocus` 属性,默认 `false` */
-  autofocus?: boolean;
-  /** 原生 `type` 属性,默认 `button` */
-  nativeType?: "button" | "submit" | "reset";
-  /** 自动在两个中文字符之间插入空格 */
-  autoInsertSpace?: boolean;
-  /** 自定义按钮颜色, 并自动计算 `hover` 和 `active` 触发后的颜色 */
-  color?: string;
-  /** `dark` 模式, 意味着自动设置 `color` 为 `dark` 模式的颜色,默认 `false` */
-  dark?: boolean;
-  /** 自定义元素标签 */
-  tag?: string | Component;
-  /** 点击按钮后触发的回调 */
-  btnClick?: ({
-    dialog,
-    button
-  }: {
-    /** 当前 `Dialog` 信息 */
-    dialog: BtnClickDialog;
-    /** 当前 `button` 信息 */
-    button: BtnClickButton;
-  }) => void;
-};
-
-interface DialogOptions extends DialogProps {
-  /** 内容区组件的 `props`,可通过 `defineProps` 接收 */
-  props?: any;
-  /** 是否隐藏 `Dialog` 按钮操作区的内容 */
-  hideFooter?: boolean;
-  /** 确定按钮的 `Popconfirm` 气泡确认框相关配置 */
-  popconfirm?: Popconfirm;
-  /** 点击确定按钮后是否开启 `loading` 加载动画 */
-  sureBtnLoading?: boolean;
-  /**
-   * @description 自定义对话框标题的内容渲染器
-   * @see {@link https://element-plus.org/zh-CN/component/dialog.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%A4%B4%E9%83%A8}
-   */
-  headerRenderer?: ({
-    close,
-    titleId,
-    titleClass
-  }: {
-    close: Function;
-    titleId: string;
-    titleClass: string;
-  }) => VNode | Component;
-  /** 自定义内容渲染器 */
-  contentRenderer?: ({
-    options,
-    index
-  }: {
-    options: DialogOptions;
-    index: number;
-  }) => VNode | Component;
-  /** 自定义按钮操作区的内容渲染器,会覆盖`footerButtons`以及默认的 `取消` 和 `确定` 按钮 */
-  footerRenderer?: ({
-    options,
-    index
-  }: {
-    options: DialogOptions;
-    index: number;
-  }) => VNode | Component;
-  /** 自定义底部按钮操作 */
-  footerButtons?: Array<ButtonProps>;
-  /** `Dialog` 打开后的回调 */
-  open?: ({
-    options,
-    index
-  }: {
-    options: DialogOptions;
-    index: number;
-  }) => void;
-  /** `Dialog` 关闭后的回调(只有点击右上角关闭按钮或空白页或按下了esc键关闭页面时才会触发) */
-  close?: ({
-    options,
-    index
-  }: {
-    options: DialogOptions;
-    index: number;
-  }) => void;
-  /** `Dialog` 关闭后的回调。 `args` 返回的 `command` 值解析:`cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了esc键  */
-  closeCallBack?: ({
-    options,
-    index,
-    args
-  }: {
-    options: DialogOptions;
-    index: number;
-    args: any;
-  }) => void;
-  /** 点击全屏按钮时的回调 */
-  fullscreenCallBack?: ({
-    options,
-    index
-  }: {
-    options: DialogOptions;
-    index: number;
-  }) => void;
-  /** 输入焦点聚焦在 `Dialog` 内容时的回调 */
-  openAutoFocus?: ({
-    options,
-    index
-  }: {
-    options: DialogOptions;
-    index: number;
-  }) => void;
-  /** 输入焦点从 `Dialog` 内容失焦时的回调 */
-  closeAutoFocus?: ({
-    options,
-    index
-  }: {
-    options: DialogOptions;
-    index: number;
-  }) => void;
-  /** 点击底部取消按钮的回调,会暂停 `Dialog` 的关闭. 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */
-  beforeCancel?: (
-    done: Function,
-    {
-      options,
-      index
-    }: {
-      options: DialogOptions;
-      index: number;
-    }
-  ) => void;
-  /** 点击底部确定按钮的回调,会暂停 `Dialog` 的关闭. 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */
-  beforeSure?: (
-    done: Function,
-    {
-      options,
-      index,
-      closeLoading
-    }: {
-      options: DialogOptions;
-      index: number;
-      /** 关闭确定按钮的 `loading` 加载动画 */
-      closeLoading: Function;
-    }
-  ) => void;
-}
-
-export type { EventType, ArgsType, DialogProps, ButtonProps, DialogOptions };

+ 0 - 64
admin-web-new/src/components/ReDrawer/index.ts

@@ -1,64 +0,0 @@
-import { ref } from "vue";
-import reDrawer from "./index.vue";
-import { useTimeoutFn } from "@vueuse/core";
-import { withInstall } from "@pureadmin/utils";
-import type {
-  EventType,
-  ArgsType,
-  DrawerProps,
-  DrawerOptions,
-  ButtonProps
-} from "./type";
-
-const drawerStore = ref<Array<DrawerOptions>>([]);
-
-/** 打开抽屉 */
-const addDrawer = (options: DrawerOptions) => {
-  const open = () =>
-    drawerStore.value.push(Object.assign(options, { visible: true }));
-  if (options?.openDelay) {
-    useTimeoutFn(() => {
-      open();
-    }, options.openDelay);
-  } else {
-    open();
-  }
-};
-
-/** 关闭抽屉 */
-const closeDrawer = (options: DrawerOptions, index: number, args?: any) => {
-  drawerStore.value[index].visible = false;
-  options.closeCallBack && options.closeCallBack({ options, index, args });
-
-  const closeDelay = options?.closeDelay ?? 200;
-  useTimeoutFn(() => {
-    drawerStore.value.splice(index, 1);
-  }, closeDelay);
-};
-
-/**
- * @description 更改抽屉自身属性值
- * @param value 属性值
- * @param key 属性,默认`title`
- * @param index 弹框索引(默认`0`,代表只有一个弹框,对于嵌套弹框要改哪个弹框的属性值就把该弹框索引赋给`index`)
- */
-const updateDrawer = (value: any, key = "title", index = 0) => {
-  drawerStore.value[index][key] = value;
-};
-
-/** 关闭所有弹框 */
-const closeAllDrawer = () => {
-  drawerStore.value = [];
-};
-
-const ReDrawer = withInstall(reDrawer);
-
-export type { EventType, ArgsType, DrawerOptions, DrawerProps, ButtonProps };
-export {
-  ReDrawer,
-  drawerStore,
-  addDrawer,
-  closeDrawer,
-  updateDrawer,
-  closeAllDrawer
-};

+ 0 - 169
admin-web-new/src/components/ReDrawer/index.vue

@@ -1,169 +0,0 @@
-<script setup lang="ts">
-import {
-  type EventType,
-  type ButtonProps,
-  type DrawerOptions,
-  closeDrawer,
-  drawerStore
-} from "./index";
-import { computed, ref } from "vue";
-import { isFunction } from "@pureadmin/utils";
-
-defineOptions({
-  name: "ReDrawer"
-});
-
-const sureBtnMap = ref({});
-
-const footerButtons = computed(() => {
-  return (options: DrawerOptions) => {
-    return options?.footerButtons?.length > 0
-      ? options.footerButtons
-      : ([
-          {
-            label: "取消",
-            text: true,
-            bg: true,
-            btnClick: ({ drawer: { options, index } }) => {
-              const done = () =>
-                closeDrawer(options, index, { command: "cancel" });
-              if (options?.beforeCancel && isFunction(options?.beforeCancel)) {
-                options.beforeCancel(done, { options, index });
-              } else {
-                done();
-              }
-            }
-          },
-          {
-            label: "确定",
-            type: "primary",
-            text: true,
-            bg: true,
-            popConfirm: options?.popConfirm,
-            btnClick: ({ drawer: { options, index } }) => {
-              if (options?.sureBtnLoading) {
-                sureBtnMap.value[index] = Object.assign(
-                  {},
-                  sureBtnMap.value[index],
-                  {
-                    loading: true
-                  }
-                );
-              }
-              const closeLoading = () => {
-                if (options?.sureBtnLoading) {
-                  sureBtnMap.value[index].loading = false;
-                }
-              };
-              const done = () => {
-                closeLoading();
-                closeDrawer(options, index, { command: "sure" });
-              };
-              if (options?.beforeSure && isFunction(options?.beforeSure)) {
-                options.beforeSure(done, { options, index, closeLoading });
-              } else {
-                done();
-              }
-            }
-          }
-        ] as Array<ButtonProps>);
-  };
-});
-
-function eventsCallBack(
-  event: EventType,
-  options: DrawerOptions,
-  index: number
-) {
-  if (options?.[event] && isFunction(options?.[event])) {
-    return options?.[event]({ options, index });
-  }
-}
-
-/**
- *
- * @param {DrawerOptions} options - 包含抽屉相关配置的对象
- * @param {number} index - 抽屉的索引
- * @param {Object} args - 传递给关闭抽屉操作的参数对象,默认为 { command: 'close' }
- * @returns {void} 这个函数不返回任何值
- */
-function handleClose(
-  options: DrawerOptions,
-  index: number,
-  args = { command: "close" }
-) {
-  closeDrawer(options, index, args);
-  eventsCallBack("close", options, index);
-}
-</script>
-
-<template>
-  <el-drawer
-    v-for="(options, index) in drawerStore"
-    :key="index"
-    v-bind="options"
-    v-model="options.visible"
-    class="pure-drawer"
-    :append-to-body="!!options?.appendToBody"
-    :append-to="options?.appendTo ? options.appendTo : 'body'"
-    :destroy-on-close="!!options?.destroyOnClose"
-    :lock-scroll="!!options?.lockScroll"
-    @closed="handleClose(options, index)"
-    @opened="eventsCallBack('open', options, index)"
-    @open-auto-focus="eventsCallBack('openAutoFocus', options, index)"
-    @close-auto-focus="eventsCallBack('closeAutoFocus', options, index)"
-  >
-    <!-- header  -->
-    <template
-      v-if="options?.headerRenderer"
-      #header="{ close, titleId, titleClass }"
-    >
-      <component
-        :is="options?.headerRenderer({ close, titleId, titleClass })"
-      />
-    </template>
-    <!--  body  -->
-    <component
-      v-bind="options?.props"
-      :is="options.contentRenderer({ options, index })"
-      @close="args => handleClose(options, index, args)"
-    />
-    <!-- footer  -->
-    <template v-if="!options?.hideFooter" #footer>
-      <template v-if="options?.footerRenderer">
-        <component :is="options?.footerRenderer({ options, index })" />
-      </template>
-      <span v-else>
-        <template v-for="(btn, key) in footerButtons(options)" :key="key">
-          <el-popconfirm
-            v-if="btn.popConfirm"
-            v-bind="btn.popConfirm"
-            @confirm="
-              btn.btnClick({
-                drawer: { options, index },
-                button: { btn, index: key }
-              })
-            "
-          >
-            <template #reference>
-              <el-button v-bind="btn">{{ btn?.label }}</el-button>
-            </template>
-          </el-popconfirm>
-          <el-button
-            v-else
-            v-bind="btn"
-            :loading="key === 1 && sureBtnMap[index]?.loading"
-            @click="
-              btn.btnClick({
-                drawer: { options, index },
-                button: { btn, index: key }
-              })
-            "
-          >
-            {{ btn?.label }}
-          </el-button>
-        </template>
-      </span>
-    </template>
-  </el-drawer>
-</template>

+ 0 - 271
admin-web-new/src/components/ReDrawer/type.ts

@@ -1,271 +0,0 @@
-import type { CSSProperties, VNode, Component } from "vue";
-
-type DoneFn = (cancel?: boolean) => void;
-type EventType = "open" | "close" | "openAutoFocus" | "closeAutoFocus";
-type ArgsType = {
-  /** `cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了 `esc` 键 */
-  command: "cancel" | "sure" | "close";
-};
-type ButtonType =
-  | "primary"
-  | "success"
-  | "warning"
-  | "danger"
-  | "info"
-  | "text";
-
-type DrawerProps = {
-  /** `Drawer` 的显示与隐藏 */
-  visible?: boolean;
-  /** `Drawer` 自身是否插入至 `body` 元素上。嵌套的 `Drawer` 必须指定该属性并赋值为 `true`,默认 `false` */
-  appendToBody?: boolean;
-  /** 挂载到哪个 `DOM` 元素,会覆盖 `appendToBody` 属性,默认 `body` */
-  appendTo?: string;
-  /** 是否在 `Drawer` 出现时将 `body` 滚动锁定,默认 `true` */
-  lockScroll?: boolean;
-  /** 关闭前的回调,会暂停 `Drawer` 的关闭,回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */
-  beforeClose?: (done: DoneFn) => void;
-  /** 是否可以通过点击 `modal` 关闭 `Drawer` ,默认 `true` */
-  closeOnClickModal?: boolean;
-  /** 是否可以通过按下 `ESC` 关闭 `Drawer` ,默认 `true` */
-  closeOnPressEscape?: boolean;
-  /** 是否显示关闭按钮,默认 `true` */
-  showClose?: boolean;
-  /** `Drawer` 打开的延时时间,单位毫秒,默认 `0` */
-  openDelay?: number;
-  /** `Drawer` 关闭的延时时间,单位毫秒,默认 `0` */
-  closeDelay?: number;
-  /** `Drawer` 自定义类名 */
-  class?: string;
-  /** `Drawer` 的自定义样式 */
-  style?: CSSProperties;
-  /** 控制是否在关闭 `Drawer` 之后将子元素全部销毁,默认 `false` */
-  destroyOnClose?: boolean;
-  /** 是否需要遮罩层,默认 `true` */
-  modal?: boolean;
-  /** 是否允许穿透遮罩层,默认 `false`。使用时需将 `modal` 属性设置为 `false` */
-  modalPenetrable?: boolean;
-  /** `Drawer` 打开的方向,默认 `rtl` */
-  direction?: "rtl" | "ltr" | "ttb" | "btt";
-  /** 是否启用可调整大小的功能,默认 `false` */
-  resizable?: boolean;
-  /** `Drawer` 窗体的大小, 当使用 `number` 类型时, 以像素为单位, 当使用 `string` 类型时, 请传入 `'x%'`, 否则便会以 `number` 类型解释,默认 `30%` */
-  size?: string | number;
-  /** `Drawer` 的标题 */
-  title?: string;
-  /** 控制是否显示 `header` 栏, 默认为 `true`, 当此项为 `false` 时, `title attribute` 和 `title slot` 均不生效 */
-  withHeader?: boolean;
-  /** 遮罩层的自定义类名 */
-  modalClass?: string;
-  /** `header` 部分的自定义 `class` 名 */
-  headerClass?: string;
-  /** `body` 部分的自定义 `class` 名 */
-  bodyClass?: string;
-  /** `footer` 部分的自定义 `class` 名 */
-  footerClass?: string;
-  /** 设置 `z-index` */
-  zIndex?: number;
-  /** `header` 的 `aria-level` 属性,默认 `2` */
-  headerAriaLevel?: string;
-};
-
-//element-plus.org/zh-CN/component/popConfirm.html#attributes
-type PopConfirm = {
-  /** 标题 */
-  title?: string;
-  /** 确认按钮文字 */
-  confirmButtonText?: string;
-  /** 取消按钮文字 */
-  cancelButtonText?: string;
-  /** 确认按钮类型,默认 `primary` */
-  confirmButtonType?: ButtonType;
-  /** 取消按钮类型,默认 `text` */
-  cancelButtonType?: ButtonType;
-  /** 自定义图标,默认 `QuestionFilled` */
-  icon?: string | Component;
-  /** `Icon` 颜色,默认 `#f90` */
-  iconColor?: string;
-  /** 是否隐藏 `Icon`,默认 `false` */
-  hideIcon?: boolean;
-  /** 关闭时的延迟,默认 `200` */
-  hideAfter?: number;
-  /** 是否将 `popover` 的下拉列表插入至 `body` 元素,默认 `true` */
-  teleported?: boolean;
-  /** 当 `popover` 组件长时间不触发且 `persistent` 属性设置为 `false` 时, `popover` 将会被删除,默认 `false` */
-  persistent?: boolean;
-  /** 弹层宽度,最小宽度 `150px`,默认 `150` */
-  width?: string | number;
-};
-
-type BtnClickDrawer = {
-  options?: DrawerOptions;
-  index?: number;
-};
-type BtnClickButton = {
-  btn?: ButtonProps;
-  index?: number;
-};
-/** https://element-plus.org/zh-CN/component/button.html#button-attributes */
-type ButtonProps = {
-  /** 按钮文字 */
-  label: string;
-  /** 按钮尺寸 */
-  size?: "large" | "default" | "small";
-  /** 按钮类型 */
-  type?: "primary" | "success" | "warning" | "danger" | "info";
-  /** 是否为朴素按钮,默认 `false` */
-  plain?: boolean;
-  /** 是否为文字按钮,默认 `false` */
-  text?: boolean;
-  /** 是否显示文字按钮背景颜色,默认 `false` */
-  bg?: boolean;
-  /** 是否为链接按钮,默认 `false` */
-  link?: boolean;
-  /** 是否为圆角按钮,默认 `false` */
-  round?: boolean;
-  /** 是否为圆形按钮,默认 `false` */
-  circle?: boolean;
-  /** 确认按钮的 `PopConfirm` 气泡确认框相关配置 */
-  popConfirm?: PopConfirm;
-  /** 是否为加载中状态,默认 `false` */
-  loading?: boolean;
-  /** 自定义加载中状态图标组件 */
-  loadingIcon?: string | Component;
-  /** 按钮是否为禁用状态,默认 `false` */
-  disabled?: boolean;
-  /** 图标组件 */
-  icon?: string | Component;
-  /** 是否开启原生 `autofocus` 属性,默认 `false` */
-  autofocus?: boolean;
-  /** 原生 `type` 属性,默认 `button` */
-  nativeType?: "button" | "submit" | "reset";
-  /** 自动在两个中文字符之间插入空格 */
-  autoInsertSpace?: boolean;
-  /** 自定义按钮颜色, 并自动计算 `hover` 和 `active` 触发后的颜色 */
-  color?: string;
-  /** `dark` 模式, 意味着自动设置 `color` 为 `dark` 模式的颜色,默认 `false` */
-  dark?: boolean;
-  /** 自定义元素标签 */
-  tag?: string | Component;
-  /** 点击按钮后触发的回调 */
-  btnClick?: ({
-    drawer,
-    button
-  }: {
-    /** 当前 `Drawer` 信息 */
-    drawer: BtnClickDrawer;
-    /** 当前 `button` 信息 */
-    button: BtnClickButton;
-  }) => void;
-};
-
-interface DrawerOptions extends DrawerProps {
-  /** 内容区组件的 `props`,可通过 `defineProps` 接收 */
-  props?: any;
-  /** 是否隐藏 `Drawer` 按钮操作区的内容 */
-  hideFooter?: boolean;
-  /** 确认按钮的 `PopConfirm` 气泡确认框相关配置 */
-  popConfirm?: PopConfirm;
-  /** 点击确定按钮后是否开启 `loading` 加载动画 */
-  sureBtnLoading?: boolean;
-  /**
-   * @description 自定义抽屉标题的内容渲染器
-   * @see {@link https://element-plus.org/zh-CN/component/drawer.html#%E6%8F%92%E6%A7%BD}
-   */
-  headerRenderer?: ({
-    close,
-    titleId,
-    titleClass
-  }: {
-    close: Function;
-    titleId: string;
-    titleClass: string;
-  }) => VNode | Component;
-  /** 自定义内容渲染器 */
-  contentRenderer?: ({
-    options,
-    index
-  }: {
-    options: DrawerOptions;
-    index: number;
-  }) => VNode | Component;
-  /** 自定义按钮操作区的内容渲染器,会覆盖`footerButtons`以及默认的 `取消` 和 `确定` 按钮 */
-  footerRenderer?: ({
-    options,
-    index
-  }: {
-    options: DrawerOptions;
-    index: number;
-  }) => VNode | Component;
-  /** 自定义底部按钮操作 */
-  footerButtons?: Array<ButtonProps>;
-  /** `Drawer` 打开后的回调 */
-  open?: ({
-    options,
-    index
-  }: {
-    options: DrawerOptions;
-    index: number;
-  }) => void;
-  /** `Drawer` 关闭后的回调(只有点击右上角关闭按钮或空白页或按下了esc键关闭页面时才会触发) */
-  close?: ({
-    options,
-    index
-  }: {
-    options: DrawerOptions;
-    index: number;
-  }) => void;
-  /** `Drawer` 关闭后的回调。 `args` 返回的 `command` 值解析:`cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了esc键  */
-  closeCallBack?: ({
-    options,
-    index,
-    args
-  }: {
-    options: DrawerOptions;
-    index: number;
-    args: any;
-  }) => void;
-  /** 输入焦点聚焦在 `Drawer` 内容时的回调 */
-  openAutoFocus?: ({
-    options,
-    index
-  }: {
-    options: DrawerOptions;
-    index: number;
-  }) => void;
-  /** 输入焦点从 `Drawer` 内容失焦时的回调 */
-  closeAutoFocus?: ({
-    options,
-    index
-  }: {
-    options: DrawerOptions;
-    index: number;
-  }) => void;
-
-  /** 点击底部取消按钮的回调,会暂停 `Drawer` 的关闭. 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */
-  beforeCancel?: (
-    done: Function,
-    {
-      options,
-      index
-    }: {
-      options: DrawerOptions;
-      index: number;
-    }
-  ) => void;
-  /** 点击底部确定按钮的回调,会暂停 `Drawer` 的关闭. 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */
-  beforeSure?: (
-    done: Function,
-    {
-      options,
-      index,
-      closeLoading
-    }: {
-      options: DrawerOptions;
-      index: number;
-      closeLoading: Function;
-    }
-  ) => void;
-}
-
-export type { ButtonProps, DrawerOptions, ArgsType, DrawerProps, EventType };

+ 0 - 39
admin-web-new/src/components/ReFlicker/index.css

@@ -1,39 +0,0 @@
-.point {
-  width: var(--point-width);
-  height: var(--point-height);
-  background: var(--point-background);
-  position: relative;
-  border-radius: var(--point-border-radius);
-}
-
-.point-flicker:after {
-  background: var(--point-background);
-}
-
-.point-flicker:before,
-.point-flicker:after {
-  content: "";
-  width: 100%;
-  height: 100%;
-  top: 0;
-  left: 0;
-  position: absolute;
-  border-radius: var(--point-border-radius);
-  animation: flicker 1.2s ease-out infinite;
-}
-
-@keyframes flicker {
-  0% {
-    transform: scale(0.5);
-    opacity: 1;
-  }
-
-  30% {
-    opacity: 1;
-  }
-
-  100% {
-    transform: scale(var(--point-scale));
-    opacity: 0;
-  }
-}

+ 0 - 44
admin-web-new/src/components/ReFlicker/index.ts

@@ -1,44 +0,0 @@
-import "./index.css";
-import { type Component, h, defineComponent } from "vue";
-
-export interface attrsType {
-  width?: string;
-  height?: string;
-  borderRadius?: number | string;
-  background?: string;
-  scale?: number | string;
-}
-
-/**
- * 圆点、方形闪烁动画组件
- * @param width 可选 string 宽
- * @param height 可选 string 高
- * @param borderRadius 可选 number | string 传0为方形、传50%或者不传为圆形
- * @param background 可选 string 闪烁颜色
- * @param scale 可选 number | string 闪烁范围,默认2,值越大闪烁范围越大
- * @returns Component
- */
-export function useRenderFlicker(attrs?: attrsType): Component {
-  return defineComponent({
-    name: "ReFlicker",
-    render() {
-      return h(
-        "div",
-        {
-          class: "point point-flicker",
-          style: {
-            "--point-width": attrs?.width ?? "12px",
-            "--point-height": attrs?.height ?? "12px",
-            "--point-background":
-              attrs?.background ?? "var(--el-color-primary)",
-            "--point-border-radius": attrs?.borderRadius ?? "50%",
-            "--point-scale": attrs?.scale ?? "2"
-          }
-        },
-        {
-          default: () => []
-        }
-      );
-    }
-  });
-}

+ 0 - 7
admin-web-new/src/components/ReFlop/index.ts

@@ -1,7 +0,0 @@
-import reFlop from "./src/index.vue";
-import { withInstall } from "@pureadmin/utils";
-
-/** 时间翻牌组件 */
-export const ReFlop = withInstall(reFlop);
-
-export default ReFlop;

+ 0 - 184
admin-web-new/src/components/ReFlop/src/filpper.css

@@ -1,184 +0,0 @@
-.m-flipper {
-  display: inline-block;
-  position: relative;
-  width: 60px;
-  height: 100px;
-  line-height: 100px;
-  border: solid 1px #000;
-  border-radius: 10px;
-  background: #fff;
-  font-size: 66px;
-  color: #fff;
-  box-shadow: 0 0 6px rgb(0 0 0 / 50%);
-  text-align: center;
-  font-family: "Helvetica Neue";
-}
-
-.m-flipper .digital::before,
-.m-flipper .digital::after {
-  content: "";
-  position: absolute;
-  left: 0;
-  right: 0;
-  background: #000;
-  overflow: hidden;
-  box-sizing: border-box;
-}
-
-.m-flipper .digital::before {
-  top: 0;
-  bottom: 50%;
-  border-radius: 10px 10px 0 0;
-  border-bottom: solid 1px #666;
-}
-
-.m-flipper .digital::after {
-  top: 50%;
-  bottom: 0;
-  border-radius: 0 0 10px 10px;
-  line-height: 0;
-}
-
-/* 向下翻 */
-.m-flipper.down .front::before {
-  z-index: 3;
-}
-
-.m-flipper.down .back::after {
-  z-index: 2;
-  transform-origin: 50% 0%;
-  transform: perspective(160px) rotateX(180deg);
-}
-
-.m-flipper.down .front::after,
-.m-flipper.down .back::before {
-  z-index: 1;
-}
-
-.m-flipper.down.go .front::before {
-  transform-origin: 50% 100%;
-  animation: frontFlipDown 0.6s ease-in-out both;
-  box-shadow: 0 -2px 6px rgb(255 255 255 / 30%);
-  backface-visibility: hidden;
-}
-
-.m-flipper.down.go .back::after {
-  animation: backFlipDown 0.6s ease-in-out both;
-}
-
-/* 向上翻 */
-.m-flipper.up .front::after {
-  z-index: 3;
-}
-
-.m-flipper.up .back::before {
-  z-index: 2;
-  transform-origin: 50% 100%;
-  transform: perspective(160px) rotateX(-180deg);
-}
-
-.m-flipper.up .front::before,
-.m-flipper.up .back::after {
-  z-index: 1;
-}
-
-.m-flipper.up.go .front::after {
-  transform-origin: 50% 0;
-  animation: frontFlipUp 0.6s ease-in-out both;
-  box-shadow: 0 2px 6px rgb(255 255 255 / 30%);
-  backface-visibility: hidden;
-}
-
-.m-flipper.up.go .back::before {
-  animation: backFlipUp 0.6s ease-in-out both;
-}
-
-@keyframes frontFlipDown {
-  0% {
-    transform: perspective(160px) rotateX(0deg);
-  }
-
-  100% {
-    transform: perspective(160px) rotateX(-180deg);
-  }
-}
-
-@keyframes backFlipDown {
-  0% {
-    transform: perspective(160px) rotateX(180deg);
-  }
-
-  100% {
-    transform: perspective(160px) rotateX(0deg);
-  }
-}
-
-@keyframes frontFlipUp {
-  0% {
-    transform: perspective(160px) rotateX(0deg);
-  }
-
-  100% {
-    transform: perspective(160px) rotateX(180deg);
-  }
-}
-
-@keyframes backFlipUp {
-  0% {
-    transform: perspective(160px) rotateX(-180deg);
-  }
-
-  100% {
-    transform: perspective(160px) rotateX(0deg);
-  }
-}
-
-.m-flipper .number0::before,
-.m-flipper .number0::after {
-  content: "0";
-}
-
-.m-flipper .number1::before,
-.m-flipper .number1::after {
-  content: "1";
-}
-
-.m-flipper .number2::before,
-.m-flipper .number2::after {
-  content: "2";
-}
-
-.m-flipper .number3::before,
-.m-flipper .number3::after {
-  content: "3";
-}
-
-.m-flipper .number4::before,
-.m-flipper .number4::after {
-  content: "4";
-}
-
-.m-flipper .number5::before,
-.m-flipper .number5::after {
-  content: "5";
-}
-
-.m-flipper .number6::before,
-.m-flipper .number6::after {
-  content: "6";
-}
-
-.m-flipper .number7::before,
-.m-flipper .number7::after {
-  content: "7";
-}
-
-.m-flipper .number8::before,
-.m-flipper .number8::after {
-  content: "8";
-}
-
-.m-flipper .number9::before,
-.m-flipper .number9::after {
-  content: "9";
-}

+ 0 - 92
admin-web-new/src/components/ReFlop/src/filpper.tsx

@@ -1,92 +0,0 @@
-import "./filpper.css";
-import propTypes from "@/utils/propTypes";
-import { defineComponent, ref } from "vue";
-
-const props = {
-  // front paper text
-  // 前牌文字
-  frontText: propTypes.number.def(0),
-  // back paper text
-  // 后牌文字
-  backText: propTypes.number.def(1),
-  // flipping duration, please be consistent with the CSS animation-duration value.
-  // 翻牌动画时间,与CSS中设置的animation-duration保持一致
-  duration: propTypes.number.def(600)
-};
-
-export default defineComponent({
-  name: "ReFlop",
-  props,
-  setup(props) {
-    const { frontText, backText, duration } = props;
-    const isFlipping = ref(false);
-    const flipType = ref("down");
-    const frontTextFromData = ref(frontText);
-    const backTextFromData = ref(backText);
-
-    const textClass = (number: number) => {
-      return "number" + number;
-    };
-
-    const flip = (type: string, front: number, back: number) => {
-      // 如果处于翻转中,则不执行
-      if (isFlipping.value) return false;
-      frontTextFromData.value = front;
-      backTextFromData.value = back;
-      // 根据传递过来的type设置翻转方向
-      flipType.value = type;
-      // 设置翻转状态为true
-      isFlipping.value = true;
-
-      setTimeout(() => {
-        // 设置翻转状态为false
-        isFlipping.value = false;
-        frontTextFromData.value = back;
-      }, duration);
-    };
-
-    // 下翻牌
-    const flipDown = (front: any, back: any): void => {
-      flip("down", front, back);
-    };
-
-    // 上翻牌
-    const flipUp = (front: any, back: any): void => {
-      flip("up", front, back);
-    };
-
-    // 设置前牌文字
-    function setFront(text: number): void {
-      frontTextFromData.value = text;
-    }
-
-    // 设置后牌文字
-    const setBack = (text: number): void => {
-      backTextFromData.value = text;
-    };
-
-    return {
-      flipType,
-      isFlipping,
-      frontTextFromData,
-      backTextFromData,
-      textClass,
-      flipDown,
-      flipUp,
-      setFront,
-      setBack
-    };
-  },
-
-  render() {
-    const main = `m-flipper ${this.flipType} ${this.isFlipping ? "go" : ""}`;
-    const front = `digital front ${this.textClass(this.frontTextFromData)}`;
-    const back = `digital back ${this.textClass(this.backTextFromData)}`;
-    return (
-      <div class={main}>
-        <div class={front} />
-        <div class={back} />
-      </div>
-    );
-  }
-});

+ 0 - 135
admin-web-new/src/components/ReFlop/src/index.vue

@@ -1,135 +0,0 @@
-<script setup lang="ts">
-import flippers from "./filpper";
-import { ref, unref, nextTick, onUnmounted } from "vue";
-
-defineOptions({
-  name: "ReFlop"
-});
-
-const timer = ref(null);
-const flipObjs = ref([]);
-
-const flipperHour1 = ref();
-const flipperHour2 = ref();
-const flipperMinute1 = ref();
-const flipperMinute2 = ref();
-const flipperSecond1 = ref();
-const flipperSecond2 = ref();
-
-// 初始化数字
-const init = () => {
-  const now = new Date();
-  const nowTimeStr = formatDate(new Date(now.getTime()), "hhiiss");
-  for (let i = 0; i < flipObjs.value.length; i++) {
-    flipObjs?.value[i]?.setFront(nowTimeStr[i]);
-  }
-};
-
-// 开始计时
-const run = () => {
-  timer.value = setInterval(() => {
-    // 获取当前时间
-    const now = new Date();
-    const nowTimeStr = formatDate(new Date(now.getTime() - 1000), "hhiiss");
-    const nextTimeStr = formatDate(now, "hhiiss");
-    for (let i = 0; i < flipObjs.value.length; i++) {
-      if (nowTimeStr[i] === nextTimeStr[i]) {
-        continue;
-      }
-      flipObjs?.value[i]?.flipDown(nowTimeStr[i], nextTimeStr[i]);
-    }
-  }, 1000);
-};
-
-// 正则格式化日期
-const formatDate = (date: Date, dateFormat: string) => {
-  /* 单独格式化年份,根据y的字符数量输出年份
-     * 例如:yyyy => 2019
-            yy => 19
-            y => 9
-     */
-  if (/(y+)/.test(dateFormat)) {
-    dateFormat = dateFormat.replace(
-      RegExp.$1,
-      (date.getFullYear() + "").substr(4 - RegExp.$1.length)
-    );
-  }
-  // 格式化月、日、时、分、秒
-  const o = {
-    "m+": date.getMonth() + 1,
-    "d+": date.getDate(),
-    "h+": date.getHours(),
-    "i+": date.getMinutes(),
-    "s+": date.getSeconds()
-  };
-  for (const k in o) {
-    if (new RegExp(`(${k})`).test(dateFormat)) {
-      // 取出对应的值
-      const str = o[k] + "";
-      /* 根据设置的格式,输出对应的字符
-       * 例如: 早上8时,hh => 08,h => 8
-       * 但是,当数字>=10时,无论格式为一位还是多位,不做截取,这是与年份格式化不一致的地方
-       * 例如: 下午15时,hh => 15, h => 15
-       */
-      dateFormat = dateFormat.replace(
-        RegExp.$1,
-        RegExp.$1.length === 1 ? str : padLeftZero(str)
-      );
-    }
-  }
-  return dateFormat;
-};
-
-// 日期时间补零
-const padLeftZero = (str: string | any[]) => {
-  return ("00" + str).substr(str.length);
-};
-
-nextTick(() => {
-  flipObjs.value = [
-    unref(flipperHour1),
-    unref(flipperHour2),
-    unref(flipperMinute1),
-    unref(flipperMinute2),
-    unref(flipperSecond1),
-    unref(flipperSecond2)
-  ];
-
-  init();
-  run();
-});
-
-onUnmounted(() => {
-  if (timer.value) {
-    clearInterval(timer.value);
-    timer.value = null;
-  }
-});
-</script>
-
-<template>
-  <div class="flip-clock">
-    <flippers ref="flipperHour1" />
-    <flippers ref="flipperHour2" />
-    <em>:</em>
-    <flippers ref="flipperMinute1" />
-    <flippers ref="flipperMinute2" />
-    <em>:</em>
-    <flippers ref="flipperSecond1" />
-    <flippers ref="flipperSecond2" />
-  </div>
-</template>
-
-<style>
-.flip-clock .m-flipper {
-  margin: 0 3px;
-}
-
-.flip-clock em {
-  display: inline-block;
-  font-size: 66px;
-  font-style: normal;
-  line-height: 102px;
-  vertical-align: top;
-}
-</style>

+ 0 - 17
admin-web-new/src/components/ReFlowChart/index.ts

@@ -1,17 +0,0 @@
-import control from "./src/Control.vue";
-import nodePanel from "./src/NodePanel.vue";
-import dataDialog from "./src/DataDialog.vue";
-import { withInstall } from "@pureadmin/utils";
-
-/** LogicFlow流程图-控制面板 */
-const Control = withInstall(control);
-
-/** LogicFlow流程图-拖拽面板 */
-const NodePanel = withInstall(nodePanel);
-
-/** LogicFlow流程图-查看数据 */
-const DataDialog = withInstall(dataDialog);
-
-export { Control, NodePanel, DataDialog };
-
-// LogicFlow流程图文档:http://logic-flow.org/

+ 0 - 148
admin-web-new/src/components/ReFlowChart/src/Control.vue

@@ -1,148 +0,0 @@
-<script setup lang="ts">
-import { ref, unref, onMounted } from "vue";
-import { LogicFlow } from "@logicflow/core";
-
-interface Props {
-  lf?: LogicFlow;
-  catTurboData?: boolean;
-}
-
-const props = withDefaults(defineProps<Props>(), {
-  lf: null
-});
-
-const emit = defineEmits<{
-  (e: "catData"): void;
-}>();
-
-const controlButton3 = ref();
-const controlButton4 = ref();
-
-const focusIndex = ref<Number>(-1);
-const titleLists = ref([
-  {
-    icon: "icon-zoom-out-hs",
-    text: "缩小",
-    size: "18",
-    disabled: false
-  },
-  {
-    icon: "icon-enlarge-hs",
-    text: "放大",
-    size: "18",
-    disabled: false
-  },
-  {
-    icon: "icon-full-screen-hs",
-    text: "适应",
-    size: "15",
-    disabled: false
-  },
-  {
-    icon: "icon-previous-hs",
-    text: "上一步",
-    size: "15",
-    disabled: true
-  },
-  {
-    icon: "icon-next-step-hs",
-    text: "下一步",
-    size: "17",
-    disabled: true
-  },
-  {
-    icon: "icon-download-hs",
-    text: "下载图片",
-    size: "17",
-    disabled: false
-  },
-  {
-    icon: "icon-watch-hs",
-    text: "查看数据",
-    size: "17",
-    disabled: false
-  }
-]);
-
-const onControl = (item, key) => {
-  ["zoom", "zoom", "resetZoom", "undo", "redo", "getSnapshot"].forEach(
-    (v, i) => {
-      const domControl = props.lf;
-      if (key === 1) {
-        domControl.zoom(true);
-      }
-      if (key === 6) {
-        emit("catData");
-      }
-      if (key === i) {
-        domControl[v]();
-      }
-    }
-  );
-};
-
-const onEnter = key => {
-  focusIndex.value = key;
-};
-
-onMounted(() => {
-  props.lf.on("history:change", ({ data: { undoAble, redoAble } }) => {
-    unref(titleLists)[3].disabled = unref(controlButton3).disabled = !undoAble;
-    unref(titleLists)[4].disabled = unref(controlButton4).disabled = !redoAble;
-  });
-});
-</script>
-
-<template>
-  <div class="control-container">
-    <!-- 功能按钮 -->
-    <ul>
-      <li
-        v-for="(item, key) in titleLists"
-        :key="key"
-        :title="item.text"
-        class="dark:text-bg_color"
-        @mouseenter.prevent="onEnter(key)"
-        @mouseleave.prevent="focusIndex = -1"
-      >
-        <button
-          :ref="'controlButton' + key"
-          v-tippy="{
-            content: item.text
-          }"
-          :disabled="item.disabled"
-          :style="{
-            cursor: item.disabled === false ? 'pointer' : 'not-allowed',
-            color: item.disabled === false ? '' : '#00000040',
-            background: 'transparent',
-            border: 'none'
-          }"
-          @click="onControl(item, key)"
-        >
-          <span
-            :class="'iconfont ' + item.icon"
-            :style="{ fontSize: `${item.size}px` }"
-          />
-        </button>
-      </li>
-    </ul>
-  </div>
-</template>
-
-<style scoped>
-@import url("./assets/iconfont/iconfont.css");
-
-.control-container {
-  background: hsl(0deg 0% 100% / 80%);
-  box-shadow: 0 1px 4px rgb(0 0 0 / 20%);
-}
-
-.control-container ul li {
-  margin: 10px;
-  text-align: center;
-}
-
-.control-container ul li span:hover {
-  color: var(--el-color-primary);
-}
-</style>

+ 0 - 17
admin-web-new/src/components/ReFlowChart/src/DataDialog.vue

@@ -1,17 +0,0 @@
-<script setup lang="ts">
-import VueJsonPretty from "vue-json-pretty";
-import "vue-json-pretty/lib/styles.css";
-
-defineProps({
-  graphData: Object
-});
-</script>
-
-<template>
-  <vue-json-pretty
-    :path="'res'"
-    :deep="3"
-    :showLength="true"
-    :data="graphData"
-  />
-</template>

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 85
admin-web-new/src/components/ReFlowChart/src/NodePanel.vue


+ 0 - 166
admin-web-new/src/components/ReFlowChart/src/adpterForTurbo.ts

@@ -1,166 +0,0 @@
-const TurboType = {
-  SEQUENCE_FLOW: 1,
-  START_EVENT: 2,
-  END_EVENT: 3,
-  USER_TASK: 4,
-  SERVICE_TASK: 5,
-  EXCLUSIVE_GATEWAY: 6
-};
-
-function getTurboType(type) {
-  switch (type) {
-    case "bpmn:sequenceFlow":
-      return TurboType.SEQUENCE_FLOW;
-    case "bpmn:startEvent":
-      return TurboType.START_EVENT;
-    case "bpmn:endEvent":
-      return TurboType.END_EVENT;
-    case "bpmn:userTask":
-      return TurboType.USER_TASK;
-    case "bpmn:serviceTask":
-      return TurboType.SERVICE_TASK;
-    case "bpmn:exclusiveGateway":
-      return TurboType.EXCLUSIVE_GATEWAY;
-    default:
-      return type;
-  }
-}
-
-function convertNodeToTurboElement(node) {
-  const { id, type, x, y, text = "", properties } = node;
-  return {
-    incoming: [],
-    outgoing: [],
-    dockers: [],
-    type: getTurboType(node.type),
-    properties: {
-      ...properties,
-      name: (text && text.value) || "",
-      x: x,
-      y: y,
-      text,
-      logicFlowType: type
-    },
-    key: id
-  };
-}
-
-function convertEdgeToTurboElement(edge) {
-  const {
-    id,
-    type,
-    sourceNodeId,
-    targetNodeId,
-    startPoint,
-    endPoint,
-    pointsList,
-    text = "",
-    properties
-  } = edge;
-  return {
-    incoming: [sourceNodeId],
-    outgoing: [targetNodeId],
-    type: getTurboType(type),
-    dockers: [],
-    properties: {
-      ...properties,
-      name: (text && text.value) || "",
-      text,
-      startPoint,
-      endPoint,
-      pointsList,
-      logicFlowType: type
-    },
-    key: id
-  };
-}
-
-export function toTurboData(data) {
-  const nodeMap = new Map();
-  const turboData = {
-    flowElementList: []
-  };
-  data.nodes.forEach(node => {
-    const flowElement = convertNodeToTurboElement(node);
-    turboData.flowElementList.push(flowElement);
-    nodeMap.set(node.id, flowElement);
-  });
-  data.edges.forEach(edge => {
-    const flowElement = convertEdgeToTurboElement(edge);
-    const sourceElement = nodeMap.get(edge.sourceNodeId);
-    sourceElement.outgoing.push(flowElement.key);
-    const targetElement = nodeMap.get(edge.targetNodeId);
-    targetElement.incoming.push(flowElement.key);
-    turboData.flowElementList.push(flowElement);
-  });
-  return turboData;
-}
-
-function convertFlowElementToEdge(element) {
-  const { incoming, outgoing, properties, key } = element;
-  const { text, startPoint, endPoint, pointsList, logicFlowType } = properties;
-  const edge = {
-    id: key,
-    type: logicFlowType,
-    sourceNodeId: incoming[0],
-    targetNodeId: outgoing[0],
-    text,
-    startPoint,
-    endPoint,
-    pointsList,
-    properties: {}
-  };
-  const excludeProperties = [
-    "startPoint",
-    "endPoint",
-    "pointsList",
-    "text",
-    "logicFlowType"
-  ];
-  Object.keys(element.properties).forEach(property => {
-    if (excludeProperties.indexOf(property) === -1) {
-      edge.properties[property] = element.properties[property];
-    }
-  });
-  return edge;
-}
-
-function convertFlowElementToNode(element) {
-  const { properties, key } = element;
-  const { x, y, text, logicFlowType } = properties;
-  const node = {
-    id: key,
-    type: logicFlowType,
-    x,
-    y,
-    text,
-    properties: {}
-  };
-  const excludeProperties = ["x", "y", "text", "logicFlowType"];
-  Object.keys(element.properties).forEach(property => {
-    if (excludeProperties.indexOf(property) === -1) {
-      node.properties[property] = element.properties[property];
-    }
-  });
-  return node;
-}
-
-export function toLogicflowData(data) {
-  const lfData = {
-    nodes: [],
-    edges: []
-  };
-  const list = data.flowElementList;
-  list &&
-    list.length > 0 &&
-    list.forEach(element => {
-      if (element.type === TurboType.SEQUENCE_FLOW) {
-        const edge = convertFlowElementToEdge(element);
-        lfData.edges.push(edge);
-      } else {
-        const node = convertFlowElementToNode(element);
-        lfData.nodes.push(node);
-      }
-    });
-  return lfData;
-}

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 6
admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.css


BIN
admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.eot


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 8
admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.js


+ 0 - 58
admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.json

@@ -1,58 +0,0 @@
-{
-  "id": "2491438",
-  "name": "liu'c'tu",
-  "font_family": "iconfont",
-  "css_prefix_text": "icon-",
-  "description": "",
-  "glyphs": [
-    {
-      "icon_id": "755619",
-      "name": "自适应图标",
-      "font_class": "full-screen-hs",
-      "unicode": "e656",
-      "unicode_decimal": 58966
-    },
-    {
-      "icon_id": "14445801",
-      "name": "查看",
-      "font_class": "watch-hs",
-      "unicode": "e766",
-      "unicode_decimal": 59238
-    },
-    {
-      "icon_id": "9712640",
-      "name": "下载",
-      "font_class": "download-hs",
-      "unicode": "e6af",
-      "unicode_decimal": 59055
-    },
-    {
-      "icon_id": "1029099",
-      "name": "放大",
-      "font_class": "enlarge-hs",
-      "unicode": "e765",
-      "unicode_decimal": 59237
-    },
-    {
-      "icon_id": "20017362",
-      "name": "上一步",
-      "font_class": "previous-hs",
-      "unicode": "e84c",
-      "unicode_decimal": 59468
-    },
-    {
-      "icon_id": "1010015",
-      "name": "缩小",
-      "font_class": "zoom-out-hs",
-      "unicode": "e744",
-      "unicode_decimal": 59204
-    },
-    {
-      "icon_id": "20017363",
-      "name": "下一步",
-      "font_class": "next-step-hs",
-      "unicode": "e84b",
-      "unicode_decimal": 59467
-    }
-  ]
-}

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.svg


BIN
admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.ttf


BIN
admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.woff


BIN
admin-web-new/src/components/ReFlowChart/src/assets/iconfont/iconfont.woff2


+ 0 - 55
admin-web-new/src/components/ReFlowChart/src/config.ts

@@ -1,55 +0,0 @@
-export const nodeList = [
-  {
-    text: "开始",
-    type: "start",
-    class: "node-start"
-  },
-  {
-    text: "矩形",
-    type: "rect",
-    class: "node-rect"
-  },
-  {
-    type: "user",
-    text: "用户",
-    class: "node-user"
-  },
-  {
-    type: "push",
-    text: "推送",
-    class: "node-push"
-  },
-  {
-    type: "download",
-    text: "位置",
-    class: "node-download"
-  },
-  {
-    type: "end",
-    text: "结束",
-    class: "node-end"
-  }
-];
-
-export const BpmnNode = [
-  {
-    type: "bpmn:startEvent",
-    text: "开始",
-    class: "bpmn-start"
-  },
-  {
-    type: "bpmn:endEvent",
-    text: "结束",
-    class: "bpmn-end"
-  },
-  {
-    type: "bpmn:exclusiveGateway",
-    text: "网关",
-    class: "bpmn-exclusiveGateway"
-  },
-  {
-    type: "bpmn:userTask",
-    text: "用户",
-    class: "bpmn-user"
-  }
-];

+ 0 - 3869
admin-web-new/src/components/ReIcon/data.ts

@@ -1,3869 +0,0 @@
-/**
- * 想要哪个图标集 自行添加即可 请注意此处添加的图标集均为在线图标(https://iconify.design/docs/api/#public-api)
- * 如果项目在内网环境下 参考 https://www.bilibili.com/video/BV17S4y1J79d?p=4&vd_source=5a992808de6229d78e7810536c5f9ab3 教程自行离线部署图标
- * https://icones.js.org/collections/图标集前缀名-meta.json(如:https://icones.js.org/collections/ri-meta.json 取icons字段,可获得当前图标集的所有图标)
- */
-export const IconJson = {
-  // https://icones.js.org/collections/ep-meta.json
-  "ep:": [
-    "add-location",
-    "aim",
-    "alarm-clock",
-    "apple",
-    "arrow-down",
-    "arrow-down-bold",
-    "arrow-left",
-    "arrow-left-bold",
-    "arrow-right",
-    "arrow-right-bold",
-    "arrow-up",
-    "arrow-up-bold",
-    "avatar",
-    "back",
-    "baseball",
-    "basketball",
-    "bell",
-    "bell-filled",
-    "bicycle",
-    "bottom",
-    "bottom-left",
-    "bottom-right",
-    "bowl",
-    "box",
-    "briefcase",
-    "brush",
-    "brush-filled",
-    "burger",
-    "calendar",
-    "camera",
-    "camera-filled",
-    "caret-bottom",
-    "caret-left",
-    "caret-right",
-    "caret-top",
-    "cellphone",
-    "chat-dot-round",
-    "chat-dot-square",
-    "chat-line-round",
-    "chat-line-square",
-    "chat-round",
-    "chat-square",
-    "check",
-    "checked",
-    "cherry",
-    "chicken",
-    "chrome-filled",
-    "circle-check",
-    "circle-check-filled",
-    "circle-close",
-    "circle-close-filled",
-    "circle-plus",
-    "circle-plus-filled",
-    "clock",
-    "close",
-    "close-bold",
-    "cloudy",
-    "coffee",
-    "coffee-cup",
-    "coin",
-    "cold-drink",
-    "collection",
-    "collection-tag",
-    "comment",
-    "compass",
-    "connection",
-    "coordinate",
-    "copy-document",
-    "cpu",
-    "credit-card",
-    "crop",
-    "d-arrow-left",
-    "d-arrow-right",
-    "d-caret",
-    "data-analysis",
-    "data-board",
-    "data-line",
-    "delete",
-    "delete-filled",
-    "delete-location",
-    "dessert",
-    "discount",
-    "dish",
-    "dish-dot",
-    "document",
-    "document-add",
-    "document-checked",
-    "document-copy",
-    "document-delete",
-    "document-remove",
-    "download",
-    "drizzling",
-    "edit",
-    "edit-pen",
-    "eleme",
-    "eleme-filled",
-    "element-plus",
-    "expand",
-    "failed",
-    "female",
-    "files",
-    "film",
-    "filter",
-    "finished",
-    "first-aid-kit",
-    "flag",
-    "fold",
-    "folder",
-    "folder-add",
-    "folder-checked",
-    "folder-delete",
-    "folder-opened",
-    "folder-remove",
-    "food",
-    "football",
-    "fork-spoon",
-    "fries",
-    "full-screen",
-    "goblet",
-    "goblet-full",
-    "goblet-square",
-    "goblet-square-full",
-    "gold-medal",
-    "goods",
-    "goods-filled",
-    "grape",
-    "grid",
-    "guide",
-    "handbag",
-    "headset",
-    "help",
-    "help-filled",
-    "hide",
-    "histogram",
-    "home-filled",
-    "hot-water",
-    "house",
-    "ice-cream",
-    "ice-cream-round",
-    "ice-cream-square",
-    "ice-drink",
-    "ice-tea",
-    "info-filled",
-    "iphone",
-    "key",
-    "knife-fork",
-    "lightning",
-    "link",
-    "list",
-    "loading",
-    "location",
-    "location-filled",
-    "location-information",
-    "lock",
-    "lollipop",
-    "magic-stick",
-    "magnet",
-    "male",
-    "management",
-    "map-location",
-    "medal",
-    "memo",
-    "menu",
-    "message",
-    "message-box",
-    "mic",
-    "microphone",
-    "milk-tea",
-    "minus",
-    "money",
-    "monitor",
-    "moon",
-    "moon-night",
-    "more",
-    "more-filled",
-    "mostly-cloudy",
-    "mouse",
-    "mug",
-    "mute",
-    "mute-notification",
-    "no-smoking",
-    "notebook",
-    "notification",
-    "odometer",
-    "office-building",
-    "open",
-    "operation",
-    "opportunity",
-    "orange",
-    "paperclip",
-    "partly-cloudy",
-    "pear",
-    "phone",
-    "phone-filled",
-    "picture",
-    "picture-filled",
-    "picture-rounded",
-    "pie-chart",
-    "place",
-    "platform",
-    "plus",
-    "pointer",
-    "position",
-    "postcard",
-    "pouring",
-    "present",
-    "price-tag",
-    "printer",
-    "promotion",
-    "quartz-watch",
-    "question-filled",
-    "rank",
-    "reading",
-    "reading-lamp",
-    "refresh",
-    "refresh-left",
-    "refresh-right",
-    "refrigerator",
-    "remove",
-    "remove-filled",
-    "right",
-    "scale-to-original",
-    "school",
-    "scissor",
-    "search",
-    "select",
-    "sell",
-    "semi-select",
-    "service",
-    "set-up",
-    "setting",
-    "share",
-    "ship",
-    "shop",
-    "shopping-bag",
-    "shopping-cart",
-    "shopping-cart-full",
-    "shopping-trolley",
-    "smoking",
-    "soccer",
-    "sold-out",
-    "sort",
-    "sort-down",
-    "sort-up",
-    "stamp",
-    "star",
-    "star-filled",
-    "stopwatch",
-    "success-filled",
-    "sugar",
-    "suitcase",
-    "suitcase-line",
-    "sunny",
-    "sunrise",
-    "sunset",
-    "switch",
-    "switch-button",
-    "switch-filled",
-    "takeaway-box",
-    "ticket",
-    "tickets",
-    "timer",
-    "toilet-paper",
-    "tools",
-    "top",
-    "top-left",
-    "top-right",
-    "trend-charts",
-    "trophy",
-    "trophy-base",
-    "turn-off",
-    "umbrella",
-    "unlock",
-    "upload",
-    "upload-filled",
-    "user",
-    "user-filled",
-    "van",
-    "video-camera",
-    "video-camera-filled",
-    "video-pause",
-    "video-play",
-    "view",
-    "wallet",
-    "wallet-filled",
-    "warn-triangle-filled",
-    "warning",
-    "warning-filled",
-    "watch",
-    "watermelon",
-    "wind-power",
-    "zoom-in",
-    "zoom-out"
-  ],
-  // https://icones.js.org/collections/ri-meta.json
-  "ri:": [
-    "24-hours-fill",
-    "24-hours-line",
-    "4k-fill",
-    "4k-line",
-    "a-b",
-    "account-box-fill",
-    "account-box-line",
-    "account-circle-fill",
-    "account-circle-line",
-    "account-pin-box-fill",
-    "account-pin-box-line",
-    "account-pin-circle-fill",
-    "account-pin-circle-line",
-    "add-box-fill",
-    "add-box-line",
-    "add-circle-fill",
-    "add-circle-line",
-    "add-fill",
-    "add-line",
-    "admin-fill",
-    "admin-line",
-    "advertisement-fill",
-    "advertisement-line",
-    "ai-generate",
-    "airplay-fill",
-    "airplay-line",
-    "alarm-fill",
-    "alarm-line",
-    "alarm-warning-fill",
-    "alarm-warning-line",
-    "album-fill",
-    "album-line",
-    "alert-fill",
-    "alert-line",
-    "aliens-fill",
-    "aliens-line",
-    "align-bottom",
-    "align-center",
-    "align-justify",
-    "align-left",
-    "align-right",
-    "align-top",
-    "align-vertically",
-    "alipay-fill",
-    "alipay-line",
-    "amazon-fill",
-    "amazon-line",
-    "anchor-fill",
-    "anchor-line",
-    "ancient-gate-fill",
-    "ancient-gate-line",
-    "ancient-pavilion-fill",
-    "ancient-pavilion-line",
-    "android-fill",
-    "android-line",
-    "angularjs-fill",
-    "angularjs-line",
-    "anticlockwise-2-fill",
-    "anticlockwise-2-line",
-    "anticlockwise-fill",
-    "anticlockwise-line",
-    "app-store-fill",
-    "app-store-line",
-    "apple-fill",
-    "apple-line",
-    "apps-2-fill",
-    "apps-2-line",
-    "apps-fill",
-    "apps-line",
-    "archive-2-fill",
-    "archive-2-line",
-    "archive-drawer-fill",
-    "archive-drawer-line",
-    "archive-fill",
-    "archive-line",
-    "arrow-down-circle-fill",
-    "arrow-down-circle-line",
-    "arrow-down-double-fill",
-    "arrow-down-double-line",
-    "arrow-down-fill",
-    "arrow-down-line",
-    "arrow-down-s-fill",
-    "arrow-down-s-line",
-    "arrow-drop-down-fill",
-    "arrow-drop-down-line",
-    "arrow-drop-left-fill",
-    "arrow-drop-left-line",
-    "arrow-drop-right-fill",
-    "arrow-drop-right-line",
-    "arrow-drop-up-fill",
-    "arrow-drop-up-line",
-    "arrow-go-back-fill",
-    "arrow-go-back-line",
-    "arrow-go-forward-fill",
-    "arrow-go-forward-line",
-    "arrow-left-circle-fill",
-    "arrow-left-circle-line",
-    "arrow-left-double-fill",
-    "arrow-left-double-line",
-    "arrow-left-down-fill",
-    "arrow-left-down-line",
-    "arrow-left-fill",
-    "arrow-left-line",
-    "arrow-left-right-fill",
-    "arrow-left-right-line",
-    "arrow-left-s-fill",
-    "arrow-left-s-line",
-    "arrow-left-up-fill",
-    "arrow-left-up-line",
-    "arrow-right-circle-fill",
-    "arrow-right-circle-line",
-    "arrow-right-double-fill",
-    "arrow-right-double-line",
-    "arrow-right-down-fill",
-    "arrow-right-down-line",
-    "arrow-right-fill",
-    "arrow-right-line",
-    "arrow-right-s-fill",
-    "arrow-right-s-line",
-    "arrow-right-up-fill",
-    "arrow-right-up-line",
-    "arrow-turn-back-fill",
-    "arrow-turn-back-line",
-    "arrow-turn-forward-fill",
-    "arrow-turn-forward-line",
-    "arrow-up-circle-fill",
-    "arrow-up-circle-line",
-    "arrow-up-double-fill",
-    "arrow-up-double-line",
-    "arrow-up-down-fill",
-    "arrow-up-down-line",
-    "arrow-up-fill",
-    "arrow-up-line",
-    "arrow-up-s-fill",
-    "arrow-up-s-line",
-    "artboard-2-fill",
-    "artboard-2-line",
-    "artboard-fill",
-    "artboard-line",
-    "article-fill",
-    "article-line",
-    "aspect-ratio-fill",
-    "aspect-ratio-line",
-    "asterisk",
-    "at-fill",
-    "at-line",
-    "attachment-2",
-    "attachment-fill",
-    "attachment-line",
-    "auction-fill",
-    "auction-line",
-    "award-fill",
-    "award-line",
-    "baidu-fill",
-    "baidu-line",
-    "ball-pen-fill",
-    "ball-pen-line",
-    "bank-card-2-fill",
-    "bank-card-2-line",
-    "bank-card-fill",
-    "bank-card-line",
-    "bank-fill",
-    "bank-line",
-    "bar-chart-2-fill",
-    "bar-chart-2-line",
-    "bar-chart-box-fill",
-    "bar-chart-box-line",
-    "bar-chart-fill",
-    "bar-chart-grouped-fill",
-    "bar-chart-grouped-line",
-    "bar-chart-horizontal-fill",
-    "bar-chart-horizontal-line",
-    "bar-chart-line",
-    "barcode-box-fill",
-    "barcode-box-line",
-    "barcode-fill",
-    "barcode-line",
-    "bard-fill",
-    "bard-line",
-    "barricade-fill",
-    "barricade-line",
-    "base-station-fill",
-    "base-station-line",
-    "basketball-fill",
-    "basketball-line",
-    "battery-2-charge-fill",
-    "battery-2-charge-line",
-    "battery-2-fill",
-    "battery-2-line",
-    "battery-charge-fill",
-    "battery-charge-line",
-    "battery-fill",
-    "battery-line",
-    "battery-low-fill",
-    "battery-low-line",
-    "battery-saver-fill",
-    "battery-saver-line",
-    "battery-share-fill",
-    "battery-share-line",
-    "bear-smile-fill",
-    "bear-smile-line",
-    "beer-fill",
-    "beer-line",
-    "behance-fill",
-    "behance-line",
-    "bell-fill",
-    "bell-line",
-    "bike-fill",
-    "bike-line",
-    "bilibili-fill",
-    "bilibili-line",
-    "bill-fill",
-    "bill-line",
-    "billiards-fill",
-    "billiards-line",
-    "bit-coin-fill",
-    "bit-coin-line",
-    "blaze-fill",
-    "blaze-line",
-    "blender-fill",
-    "blender-line",
-    "bluetooth-connect-fill",
-    "bluetooth-connect-line",
-    "bluetooth-fill",
-    "bluetooth-line",
-    "blur-off-fill",
-    "blur-off-line",
-    "body-scan-fill",
-    "body-scan-line",
-    "bold",
-    "book-2-fill",
-    "book-2-line",
-    "book-3-fill",
-    "book-3-line",
-    "book-fill",
-    "book-line",
-    "book-mark-fill",
-    "book-mark-line",
-    "book-open-fill",
-    "book-open-line",
-    "book-read-fill",
-    "book-read-line",
-    "booklet-fill",
-    "booklet-line",
-    "bookmark-2-fill",
-    "bookmark-2-line",
-    "bookmark-3-fill",
-    "bookmark-3-line",
-    "bookmark-fill",
-    "bookmark-line",
-    "bootstrap-fill",
-    "bootstrap-line",
-    "box-1-fill",
-    "box-1-line",
-    "box-2-fill",
-    "box-2-line",
-    "box-3-fill",
-    "box-3-line",
-    "boxing-fill",
-    "boxing-line",
-    "braces-fill",
-    "braces-line",
-    "brackets-fill",
-    "brackets-line",
-    "brain-fill",
-    "brain-line",
-    "briefcase-2-fill",
-    "briefcase-2-line",
-    "briefcase-3-fill",
-    "briefcase-3-line",
-    "briefcase-4-fill",
-    "briefcase-4-line",
-    "briefcase-5-fill",
-    "briefcase-5-line",
-    "briefcase-fill",
-    "briefcase-line",
-    "bring-forward",
-    "bring-to-front",
-    "broadcast-fill",
-    "broadcast-line",
-    "brush-2-fill",
-    "brush-2-line",
-    "brush-3-fill",
-    "brush-3-line",
-    "brush-4-fill",
-    "brush-4-line",
-    "brush-fill",
-    "brush-line",
-    "bubble-chart-fill",
-    "bubble-chart-line",
-    "bug-2-fill",
-    "bug-2-line",
-    "bug-fill",
-    "bug-line",
-    "building-2-fill",
-    "building-2-line",
-    "building-3-fill",
-    "building-3-line",
-    "building-4-fill",
-    "building-4-line",
-    "building-fill",
-    "building-line",
-    "bus-2-fill",
-    "bus-2-line",
-    "bus-fill",
-    "bus-line",
-    "bus-wifi-fill",
-    "bus-wifi-line",
-    "cactus-fill",
-    "cactus-line",
-    "cake-2-fill",
-    "cake-2-line",
-    "cake-3-fill",
-    "cake-3-line",
-    "cake-fill",
-    "cake-line",
-    "calculator-fill",
-    "calculator-line",
-    "calendar-2-fill",
-    "calendar-2-line",
-    "calendar-check-fill",
-    "calendar-check-line",
-    "calendar-close-fill",
-    "calendar-close-line",
-    "calendar-event-fill",
-    "calendar-event-line",
-    "calendar-fill",
-    "calendar-line",
-    "calendar-todo-fill",
-    "calendar-todo-line",
-    "camera-2-fill",
-    "camera-2-line",
-    "camera-3-fill",
-    "camera-3-line",
-    "camera-fill",
-    "camera-lens-fill",
-    "camera-lens-line",
-    "camera-line",
-    "camera-off-fill",
-    "camera-off-line",
-    "camera-switch-fill",
-    "camera-switch-line",
-    "candle-fill",
-    "candle-line",
-    "capsule-fill",
-    "capsule-line",
-    "car-fill",
-    "car-line",
-    "car-washing-fill",
-    "car-washing-line",
-    "caravan-fill",
-    "caravan-line",
-    "cash-fill",
-    "cash-line",
-    "cast-fill",
-    "cast-line",
-    "cellphone-fill",
-    "cellphone-line",
-    "celsius-fill",
-    "celsius-line",
-    "centos-fill",
-    "centos-line",
-    "character-recognition-fill",
-    "character-recognition-line",
-    "charging-pile-2-fill",
-    "charging-pile-2-line",
-    "charging-pile-fill",
-    "charging-pile-line",
-    "chat-1-fill",
-    "chat-1-line",
-    "chat-2-fill",
-    "chat-2-line",
-    "chat-3-fill",
-    "chat-3-line",
-    "chat-4-fill",
-    "chat-4-line",
-    "chat-check-fill",
-    "chat-check-line",
-    "chat-delete-fill",
-    "chat-delete-line",
-    "chat-download-fill",
-    "chat-download-line",
-    "chat-follow-up-fill",
-    "chat-follow-up-line",
-    "chat-forward-fill",
-    "chat-forward-line",
-    "chat-heart-fill",
-    "chat-heart-line",
-    "chat-history-fill",
-    "chat-history-line",
-    "chat-new-fill",
-    "chat-new-line",
-    "chat-off-fill",
-    "chat-off-line",
-    "chat-poll-fill",
-    "chat-poll-line",
-    "chat-private-fill",
-    "chat-private-line",
-    "chat-quote-fill",
-    "chat-quote-line",
-    "chat-settings-fill",
-    "chat-settings-line",
-    "chat-smile-2-fill",
-    "chat-smile-2-line",
-    "chat-smile-3-fill",
-    "chat-smile-3-line",
-    "chat-smile-fill",
-    "chat-smile-line",
-    "chat-upload-fill",
-    "chat-upload-line",
-    "chat-voice-fill",
-    "chat-voice-line",
-    "check-double-fill",
-    "check-double-line",
-    "check-fill",
-    "check-line",
-    "checkbox-blank-circle-fill",
-    "checkbox-blank-circle-line",
-    "checkbox-blank-fill",
-    "checkbox-blank-line",
-    "checkbox-circle-fill",
-    "checkbox-circle-line",
-    "checkbox-fill",
-    "checkbox-indeterminate-fill",
-    "checkbox-indeterminate-line",
-    "checkbox-line",
-    "checkbox-multiple-blank-fill",
-    "checkbox-multiple-blank-line",
-    "checkbox-multiple-fill",
-    "checkbox-multiple-line",
-    "china-railway-fill",
-    "china-railway-line",
-    "chrome-fill",
-    "chrome-line",
-    "circle-fill",
-    "circle-line",
-    "clapperboard-fill",
-    "clapperboard-line",
-    "clipboard-fill",
-    "clipboard-line",
-    "clockwise-2-fill",
-    "clockwise-2-line",
-    "clockwise-fill",
-    "clockwise-line",
-    "close-circle-fill",
-    "close-circle-line",
-    "close-fill",
-    "close-line",
-    "closed-captioning-fill",
-    "closed-captioning-line",
-    "cloud-fill",
-    "cloud-line",
-    "cloud-off-fill",
-    "cloud-off-line",
-    "cloud-windy-fill",
-    "cloud-windy-line",
-    "cloudy-2-fill",
-    "cloudy-2-line",
-    "cloudy-fill",
-    "cloudy-line",
-    "code-box-fill",
-    "code-box-line",
-    "code-fill",
-    "code-line",
-    "code-s-fill",
-    "code-s-line",
-    "code-s-slash-fill",
-    "code-s-slash-line",
-    "code-view",
-    "codepen-fill",
-    "codepen-line",
-    "coin-fill",
-    "coin-line",
-    "coins-fill",
-    "coins-line",
-    "collage-fill",
-    "collage-line",
-    "command-fill",
-    "command-line",
-    "community-fill",
-    "community-line",
-    "compass-2-fill",
-    "compass-2-line",
-    "compass-3-fill",
-    "compass-3-line",
-    "compass-4-fill",
-    "compass-4-line",
-    "compass-discover-fill",
-    "compass-discover-line",
-    "compass-fill",
-    "compass-line",
-    "compasses-2-fill",
-    "compasses-2-line",
-    "compasses-fill",
-    "compasses-line",
-    "computer-fill",
-    "computer-line",
-    "contacts-book-2-fill",
-    "contacts-book-2-line",
-    "contacts-book-fill",
-    "contacts-book-line",
-    "contacts-book-upload-fill",
-    "contacts-book-upload-line",
-    "contacts-fill",
-    "contacts-line",
-    "contract-left-fill",
-    "contract-left-line",
-    "contract-left-right-fill",
-    "contract-left-right-line",
-    "contract-right-fill",
-    "contract-right-line",
-    "contract-up-down-fill",
-    "contract-up-down-line",
-    "contrast-2-fill",
-    "contrast-2-line",
-    "contrast-drop-2-fill",
-    "contrast-drop-2-line",
-    "contrast-drop-fill",
-    "contrast-drop-line",
-    "contrast-fill",
-    "contrast-line",
-    "copilot-fill",
-    "copilot-line",
-    "copper-coin-fill",
-    "copper-coin-line",
-    "copper-diamond-fill",
-    "copper-diamond-line",
-    "copyleft-fill",
-    "copyleft-line",
-    "copyright-fill",
-    "copyright-line",
-    "coreos-fill",
-    "coreos-line",
-    "corner-down-left-fill",
-    "corner-down-left-line",
-    "corner-down-right-fill",
-    "corner-down-right-line",
-    "corner-left-down-fill",
-    "corner-left-down-line",
-    "corner-left-up-fill",
-    "corner-left-up-line",
-    "corner-right-down-fill",
-    "corner-right-down-line",
-    "corner-right-up-fill",
-    "corner-right-up-line",
-    "corner-up-left-double-fill",
-    "corner-up-left-double-line",
-    "corner-up-left-fill",
-    "corner-up-left-line",
-    "corner-up-right-double-fill",
-    "corner-up-right-double-line",
-    "corner-up-right-fill",
-    "corner-up-right-line",
-    "coupon-2-fill",
-    "coupon-2-line",
-    "coupon-3-fill",
-    "coupon-3-line",
-    "coupon-4-fill",
-    "coupon-4-line",
-    "coupon-5-fill",
-    "coupon-5-line",
-    "coupon-fill",
-    "coupon-line",
-    "cpu-fill",
-    "cpu-line",
-    "creative-commons-by-fill",
-    "creative-commons-by-line",
-    "creative-commons-fill",
-    "creative-commons-line",
-    "creative-commons-nc-fill",
-    "creative-commons-nc-line",
-    "creative-commons-nd-fill",
-    "creative-commons-nd-line",
-    "creative-commons-sa-fill",
-    "creative-commons-sa-line",
-    "creative-commons-zero-fill",
-    "creative-commons-zero-line",
-    "criminal-fill",
-    "criminal-line",
-    "crop-2-fill",
-    "crop-2-line",
-    "crop-fill",
-    "crop-line",
-    "cross-fill",
-    "cross-line",
-    "crosshair-2-fill",
-    "crosshair-2-line",
-    "crosshair-fill",
-    "crosshair-line",
-    "css3-fill",
-    "css3-line",
-    "cup-fill",
-    "cup-line",
-    "currency-fill",
-    "currency-line",
-    "cursor-fill",
-    "cursor-line",
-    "customer-service-2-fill",
-    "customer-service-2-line",
-    "customer-service-fill",
-    "customer-service-line",
-    "dashboard-2-fill",
-    "dashboard-2-line",
-    "dashboard-3-fill",
-    "dashboard-3-line",
-    "dashboard-fill",
-    "dashboard-line",
-    "database-2-fill",
-    "database-2-line",
-    "database-fill",
-    "database-line",
-    "delete-back-2-fill",
-    "delete-back-2-line",
-    "delete-back-fill",
-    "delete-back-line",
-    "delete-bin-2-fill",
-    "delete-bin-2-line",
-    "delete-bin-3-fill",
-    "delete-bin-3-line",
-    "delete-bin-4-fill",
-    "delete-bin-4-line",
-    "delete-bin-5-fill",
-    "delete-bin-5-line",
-    "delete-bin-6-fill",
-    "delete-bin-6-line",
-    "delete-bin-7-fill",
-    "delete-bin-7-line",
-    "delete-bin-fill",
-    "delete-bin-line",
-    "delete-column",
-    "delete-row",
-    "device-fill",
-    "device-line",
-    "device-recover-fill",
-    "device-recover-line",
-    "dingding-fill",
-    "dingding-line",
-    "direction-fill",
-    "direction-line",
-    "disc-fill",
-    "disc-line",
-    "discord-fill",
-    "discord-line",
-    "discuss-fill",
-    "discuss-line",
-    "dislike-fill",
-    "dislike-line",
-    "disqus-fill",
-    "disqus-line",
-    "divide-fill",
-    "divide-line",
-    "donut-chart-fill",
-    "donut-chart-line",
-    "door-closed-fill",
-    "door-closed-line",
-    "door-fill",
-    "door-line",
-    "door-lock-box-fill",
-    "door-lock-box-line",
-    "door-lock-fill",
-    "door-lock-line",
-    "door-open-fill",
-    "door-open-line",
-    "dossier-fill",
-    "dossier-line",
-    "douban-fill",
-    "douban-line",
-    "double-quotes-l",
-    "double-quotes-r",
-    "download-2-fill",
-    "download-2-line",
-    "download-cloud-2-fill",
-    "download-cloud-2-line",
-    "download-cloud-fill",
-    "download-cloud-line",
-    "download-fill",
-    "download-line",
-    "draft-fill",
-    "draft-line",
-    "drag-drop-fill",
-    "drag-drop-line",
-    "drag-move-2-fill",
-    "drag-move-2-line",
-    "drag-move-fill",
-    "drag-move-line",
-    "draggable",
-    "dribbble-fill",
-    "dribbble-line",
-    "drive-fill",
-    "drive-line",
-    "drizzle-fill",
-    "drizzle-line",
-    "drop-fill",
-    "drop-line",
-    "dropbox-fill",
-    "dropbox-line",
-    "dropdown-list",
-    "dual-sim-1-fill",
-    "dual-sim-1-line",
-    "dual-sim-2-fill",
-    "dual-sim-2-line",
-    "dv-fill",
-    "dv-line",
-    "dvd-fill",
-    "dvd-line",
-    "e-bike-2-fill",
-    "e-bike-2-line",
-    "e-bike-fill",
-    "e-bike-line",
-    "earth-fill",
-    "earth-line",
-    "earthquake-fill",
-    "earthquake-line",
-    "edge-fill",
-    "edge-line",
-    "edge-new-fill",
-    "edge-new-line",
-    "edit-2-fill",
-    "edit-2-line",
-    "edit-box-fill",
-    "edit-box-line",
-    "edit-circle-fill",
-    "edit-circle-line",
-    "edit-fill",
-    "edit-line",
-    "eject-fill",
-    "eject-line",
-    "emoji-sticker-fill",
-    "emoji-sticker-line",
-    "emotion-2-fill",
-    "emotion-2-line",
-    "emotion-fill",
-    "emotion-happy-fill",
-    "emotion-happy-line",
-    "emotion-laugh-fill",
-    "emotion-laugh-line",
-    "emotion-line",
-    "emotion-normal-fill",
-    "emotion-normal-line",
-    "emotion-sad-fill",
-    "emotion-sad-line",
-    "emotion-unhappy-fill",
-    "emotion-unhappy-line",
-    "empathize-fill",
-    "empathize-line",
-    "emphasis",
-    "emphasis-cn",
-    "english-input",
-    "equal-fill",
-    "equal-line",
-    "equalizer-fill",
-    "equalizer-line",
-    "eraser-fill",
-    "eraser-line",
-    "error-warning-fill",
-    "error-warning-line",
-    "evernote-fill",
-    "evernote-line",
-    "exchange-box-fill",
-    "exchange-box-line",
-    "exchange-cny-fill",
-    "exchange-cny-line",
-    "exchange-dollar-fill",
-    "exchange-dollar-line",
-    "exchange-fill",
-    "exchange-funds-fill",
-    "exchange-funds-line",
-    "exchange-line",
-    "expand-left-fill",
-    "expand-left-line",
-    "expand-left-right-fill",
-    "expand-left-right-line",
-    "expand-right-fill",
-    "expand-right-line",
-    "expand-up-down-fill",
-    "expand-up-down-line",
-    "external-link-fill",
-    "external-link-line",
-    "eye-2-fill",
-    "eye-2-line",
-    "eye-close-fill",
-    "eye-close-line",
-    "eye-fill",
-    "eye-line",
-    "eye-off-fill",
-    "eye-off-line",
-    "facebook-box-fill",
-    "facebook-box-line",
-    "facebook-circle-fill",
-    "facebook-circle-line",
-    "facebook-fill",
-    "facebook-line",
-    "fahrenheit-fill",
-    "fahrenheit-line",
-    "feedback-fill",
-    "feedback-line",
-    "file-2-fill",
-    "file-2-line",
-    "file-3-fill",
-    "file-3-line",
-    "file-4-fill",
-    "file-4-line",
-    "file-add-fill",
-    "file-add-line",
-    "file-chart-2-fill",
-    "file-chart-2-line",
-    "file-chart-fill",
-    "file-chart-line",
-    "file-close-fill",
-    "file-close-line",
-    "file-cloud-fill",
-    "file-cloud-line",
-    "file-code-fill",
-    "file-code-line",
-    "file-copy-2-fill",
-    "file-copy-2-line",
-    "file-copy-fill",
-    "file-copy-line",
-    "file-damage-fill",
-    "file-damage-line",
-    "file-download-fill",
-    "file-download-line",
-    "file-edit-fill",
-    "file-edit-line",
-    "file-excel-2-fill",
-    "file-excel-2-line",
-    "file-excel-fill",
-    "file-excel-line",
-    "file-fill",
-    "file-forbid-fill",
-    "file-forbid-line",
-    "file-gif-fill",
-    "file-gif-line",
-    "file-history-fill",
-    "file-history-line",
-    "file-hwp-fill",
-    "file-hwp-line",
-    "file-image-fill",
-    "file-image-line",
-    "file-info-fill",
-    "file-info-line",
-    "file-line",
-    "file-list-2-fill",
-    "file-list-2-line",
-    "file-list-3-fill",
-    "file-list-3-line",
-    "file-list-fill",
-    "file-list-line",
-    "file-lock-fill",
-    "file-lock-line",
-    "file-mark-fill",
-    "file-mark-line",
-    "file-music-fill",
-    "file-music-line",
-    "file-paper-2-fill",
-    "file-paper-2-line",
-    "file-paper-fill",
-    "file-paper-line",
-    "file-pdf-2-fill",
-    "file-pdf-2-line",
-    "file-pdf-fill",
-    "file-pdf-line",
-    "file-ppt-2-fill",
-    "file-ppt-2-line",
-    "file-ppt-fill",
-    "file-ppt-line",
-    "file-reduce-fill",
-    "file-reduce-line",
-    "file-search-fill",
-    "file-search-line",
-    "file-settings-fill",
-    "file-settings-line",
-    "file-shield-2-fill",
-    "file-shield-2-line",
-    "file-shield-fill",
-    "file-shield-line",
-    "file-shred-fill",
-    "file-shred-line",
-    "file-text-fill",
-    "file-text-line",
-    "file-transfer-fill",
-    "file-transfer-line",
-    "file-unknow-fill",
-    "file-unknow-line",
-    "file-upload-fill",
-    "file-upload-line",
-    "file-user-fill",
-    "file-user-line",
-    "file-video-fill",
-    "file-video-line",
-    "file-warning-fill",
-    "file-warning-line",
-    "file-word-2-fill",
-    "file-word-2-line",
-    "file-word-fill",
-    "file-word-line",
-    "file-zip-fill",
-    "file-zip-line",
-    "film-fill",
-    "film-line",
-    "filter-2-fill",
-    "filter-2-line",
-    "filter-3-fill",
-    "filter-3-line",
-    "filter-fill",
-    "filter-line",
-    "filter-off-fill",
-    "filter-off-line",
-    "find-replace-fill",
-    "find-replace-line",
-    "finder-fill",
-    "finder-line",
-    "fingerprint-2-fill",
-    "fingerprint-2-line",
-    "fingerprint-fill",
-    "fingerprint-line",
-    "fire-fill",
-    "fire-line",
-    "firefox-fill",
-    "firefox-line",
-    "first-aid-kit-fill",
-    "first-aid-kit-line",
-    "flag-2-fill",
-    "flag-2-line",
-    "flag-fill",
-    "flag-line",
-    "flashlight-fill",
-    "flashlight-line",
-    "flask-fill",
-    "flask-line",
-    "flickr-fill",
-    "flickr-line",
-    "flight-land-fill",
-    "flight-land-line",
-    "flight-takeoff-fill",
-    "flight-takeoff-line",
-    "flood-fill",
-    "flood-line",
-    "flow-chart",
-    "flutter-fill",
-    "flutter-line",
-    "focus-2-fill",
-    "focus-2-line",
-    "focus-3-fill",
-    "focus-3-line",
-    "focus-fill",
-    "focus-line",
-    "foggy-fill",
-    "foggy-line",
-    "folder-2-fill",
-    "folder-2-line",
-    "folder-3-fill",
-    "folder-3-line",
-    "folder-4-fill",
-    "folder-4-line",
-    "folder-5-fill",
-    "folder-5-line",
-    "folder-add-fill",
-    "folder-add-line",
-    "folder-chart-2-fill",
-    "folder-chart-2-line",
-    "folder-chart-fill",
-    "folder-chart-line",
-    "folder-download-fill",
-    "folder-download-line",
-    "folder-fill",
-    "folder-forbid-fill",
-    "folder-forbid-line",
-    "folder-history-fill",
-    "folder-history-line",
-    "folder-image-fill",
-    "folder-image-line",
-    "folder-info-fill",
-    "folder-info-line",
-    "folder-keyhole-fill",
-    "folder-keyhole-line",
-    "folder-line",
-    "folder-lock-fill",
-    "folder-lock-line",
-    "folder-music-fill",
-    "folder-music-line",
-    "folder-open-fill",
-    "folder-open-line",
-    "folder-received-fill",
-    "folder-received-line",
-    "folder-reduce-fill",
-    "folder-reduce-line",
-    "folder-settings-fill",
-    "folder-settings-line",
-    "folder-shared-fill",
-    "folder-shared-line",
-    "folder-shield-2-fill",
-    "folder-shield-2-line",
-    "folder-shield-fill",
-    "folder-shield-line",
-    "folder-transfer-fill",
-    "folder-transfer-line",
-    "folder-unknow-fill",
-    "folder-unknow-line",
-    "folder-upload-fill",
-    "folder-upload-line",
-    "folder-user-fill",
-    "folder-user-line",
-    "folder-video-fill",
-    "folder-video-line",
-    "folder-warning-fill",
-    "folder-warning-line",
-    "folder-zip-fill",
-    "folder-zip-line",
-    "folders-fill",
-    "folders-line",
-    "font-color",
-    "font-family",
-    "font-mono",
-    "font-sans",
-    "font-sans-serif",
-    "font-size",
-    "font-size-2",
-    "football-fill",
-    "football-line",
-    "footprint-fill",
-    "footprint-line",
-    "forbid-2-fill",
-    "forbid-2-line",
-    "forbid-fill",
-    "forbid-line",
-    "format-clear",
-    "forward-10-fill",
-    "forward-10-line",
-    "forward-15-fill",
-    "forward-15-line",
-    "forward-30-fill",
-    "forward-30-line",
-    "forward-5-fill",
-    "forward-5-line",
-    "fridge-fill",
-    "fridge-line",
-    "fullscreen-exit-fill",
-    "fullscreen-exit-line",
-    "fullscreen-fill",
-    "fullscreen-line",
-    "function-fill",
-    "function-line",
-    "functions",
-    "funds-box-fill",
-    "funds-box-line",
-    "funds-fill",
-    "funds-line",
-    "gallery-fill",
-    "gallery-line",
-    "gallery-upload-fill",
-    "gallery-upload-line",
-    "game-fill",
-    "game-line",
-    "gamepad-fill",
-    "gamepad-line",
-    "gas-station-fill",
-    "gas-station-line",
-    "gatsby-fill",
-    "gatsby-line",
-    "genderless-fill",
-    "genderless-line",
-    "ghost-2-fill",
-    "ghost-2-line",
-    "ghost-fill",
-    "ghost-line",
-    "ghost-smile-fill",
-    "ghost-smile-line",
-    "gift-2-fill",
-    "gift-2-line",
-    "gift-fill",
-    "gift-line",
-    "git-branch-fill",
-    "git-branch-line",
-    "git-close-pull-request-fill",
-    "git-close-pull-request-line",
-    "git-commit-fill",
-    "git-commit-line",
-    "git-merge-fill",
-    "git-merge-line",
-    "git-pull-request-fill",
-    "git-pull-request-line",
-    "git-repository-commits-fill",
-    "git-repository-commits-line",
-    "git-repository-fill",
-    "git-repository-line",
-    "git-repository-private-fill",
-    "git-repository-private-line",
-    "github-fill",
-    "github-line",
-    "gitlab-fill",
-    "gitlab-line",
-    "global-fill",
-    "global-line",
-    "globe-fill",
-    "globe-line",
-    "goblet-fill",
-    "goblet-line",
-    "google-fill",
-    "google-line",
-    "google-play-fill",
-    "google-play-line",
-    "government-fill",
-    "government-line",
-    "gps-fill",
-    "gps-line",
-    "gradienter-fill",
-    "gradienter-line",
-    "graduation-cap-fill",
-    "graduation-cap-line",
-    "grid-fill",
-    "grid-line",
-    "group-2-fill",
-    "group-2-line",
-    "group-fill",
-    "group-line",
-    "guide-fill",
-    "guide-line",
-    "h-1",
-    "h-2",
-    "h-3",
-    "h-4",
-    "h-5",
-    "h-6",
-    "hail-fill",
-    "hail-line",
-    "hammer-fill",
-    "hammer-line",
-    "hand-coin-fill",
-    "hand-coin-line",
-    "hand-heart-fill",
-    "hand-heart-line",
-    "hand-sanitizer-fill",
-    "hand-sanitizer-line",
-    "handbag-fill",
-    "handbag-line",
-    "hard-drive-2-fill",
-    "hard-drive-2-line",
-    "hard-drive-3-fill",
-    "hard-drive-3-line",
-    "hard-drive-fill",
-    "hard-drive-line",
-    "hashtag",
-    "haze-2-fill",
-    "haze-2-line",
-    "haze-fill",
-    "haze-line",
-    "hd-fill",
-    "hd-line",
-    "heading",
-    "headphone-fill",
-    "headphone-line",
-    "health-book-fill",
-    "health-book-line",
-    "heart-2-fill",
-    "heart-2-line",
-    "heart-3-fill",
-    "heart-3-line",
-    "heart-add-fill",
-    "heart-add-line",
-    "heart-fill",
-    "heart-line",
-    "heart-pulse-fill",
-    "heart-pulse-line",
-    "hearts-fill",
-    "hearts-line",
-    "heavy-showers-fill",
-    "heavy-showers-line",
-    "hexagon-fill",
-    "hexagon-line",
-    "history-fill",
-    "history-line",
-    "home-2-fill",
-    "home-2-line",
-    "home-3-fill",
-    "home-3-line",
-    "home-4-fill",
-    "home-4-line",
-    "home-5-fill",
-    "home-5-line",
-    "home-6-fill",
-    "home-6-line",
-    "home-7-fill",
-    "home-7-line",
-    "home-8-fill",
-    "home-8-line",
-    "home-fill",
-    "home-gear-fill",
-    "home-gear-line",
-    "home-heart-fill",
-    "home-heart-line",
-    "home-line",
-    "home-office-fill",
-    "home-office-line",
-    "home-smile-2-fill",
-    "home-smile-2-line",
-    "home-smile-fill",
-    "home-smile-line",
-    "home-wifi-fill",
-    "home-wifi-line",
-    "honor-of-kings-fill",
-    "honor-of-kings-line",
-    "honour-fill",
-    "honour-line",
-    "hospital-fill",
-    "hospital-line",
-    "hotel-bed-fill",
-    "hotel-bed-line",
-    "hotel-fill",
-    "hotel-line",
-    "hotspot-fill",
-    "hotspot-line",
-    "hourglass-2-fill",
-    "hourglass-2-line",
-    "hourglass-fill",
-    "hourglass-line",
-    "hq-fill",
-    "hq-line",
-    "html5-fill",
-    "html5-line",
-    "ie-fill",
-    "ie-line",
-    "image-2-fill",
-    "image-2-line",
-    "image-add-fill",
-    "image-add-line",
-    "image-edit-fill",
-    "image-edit-line",
-    "image-fill",
-    "image-line",
-    "inbox-2-fill",
-    "inbox-2-line",
-    "inbox-archive-fill",
-    "inbox-archive-line",
-    "inbox-fill",
-    "inbox-line",
-    "inbox-unarchive-fill",
-    "inbox-unarchive-line",
-    "increase-decrease-fill",
-    "increase-decrease-line",
-    "indent-decrease",
-    "indent-increase",
-    "indeterminate-circle-fill",
-    "indeterminate-circle-line",
-    "infinity-fill",
-    "infinity-line",
-    "information-fill",
-    "information-line",
-    "infrared-thermometer-fill",
-    "infrared-thermometer-line",
-    "ink-bottle-fill",
-    "ink-bottle-line",
-    "input-cursor-move",
-    "input-method-fill",
-    "input-method-line",
-    "insert-column-left",
-    "insert-column-right",
-    "insert-row-bottom",
-    "insert-row-top",
-    "instagram-fill",
-    "instagram-line",
-    "install-fill",
-    "install-line",
-    "instance-fill",
-    "instance-line",
-    "invision-fill",
-    "invision-line",
-    "italic",
-    "javascript-fill",
-    "javascript-line",
-    "kakao-talk-fill",
-    "kakao-talk-line",
-    "key-2-fill",
-    "key-2-line",
-    "key-fill",
-    "key-line",
-    "keyboard-box-fill",
-    "keyboard-box-line",
-    "keyboard-fill",
-    "keyboard-line",
-    "keynote-fill",
-    "keynote-line",
-    "kick-fill",
-    "kick-line",
-    "knife-blood-fill",
-    "knife-blood-line",
-    "knife-fill",
-    "knife-line",
-    "landscape-fill",
-    "landscape-line",
-    "layout-2-fill",
-    "layout-2-line",
-    "layout-3-fill",
-    "layout-3-line",
-    "layout-4-fill",
-    "layout-4-line",
-    "layout-5-fill",
-    "layout-5-line",
-    "layout-6-fill",
-    "layout-6-line",
-    "layout-bottom-2-fill",
-    "layout-bottom-2-line",
-    "layout-bottom-fill",
-    "layout-bottom-line",
-    "layout-column-fill",
-    "layout-column-line",
-    "layout-fill",
-    "layout-grid-fill",
-    "layout-grid-line",
-    "layout-left-2-fill",
-    "layout-left-2-line",
-    "layout-left-fill",
-    "layout-left-line",
-    "layout-line",
-    "layout-masonry-fill",
-    "layout-masonry-line",
-    "layout-right-2-fill",
-    "layout-right-2-line",
-    "layout-right-fill",
-    "layout-right-line",
-    "layout-row-fill",
-    "layout-row-line",
-    "layout-top-2-fill",
-    "layout-top-2-line",
-    "layout-top-fill",
-    "layout-top-line",
-    "leaf-fill",
-    "leaf-line",
-    "lifebuoy-fill",
-    "lifebuoy-line",
-    "lightbulb-fill",
-    "lightbulb-flash-fill",
-    "lightbulb-flash-line",
-    "lightbulb-line",
-    "line-chart-fill",
-    "line-chart-line",
-    "line-fill",
-    "line-height",
-    "line-line",
-    "link",
-    "link-m",
-    "link-unlink",
-    "link-unlink-m",
-    "linkedin-box-fill",
-    "linkedin-box-line",
-    "linkedin-fill",
-    "linkedin-line",
-    "links-fill",
-    "links-line",
-    "list-check",
-    "list-check-2",
-    "list-check-3",
-    "list-indefinite",
-    "list-ordered",
-    "list-ordered-2",
-    "list-radio",
-    "list-settings-fill",
-    "list-settings-line",
-    "list-unordered",
-    "live-fill",
-    "live-line",
-    "loader-2-fill",
-    "loader-2-line",
-    "loader-3-fill",
-    "loader-3-line",
-    "loader-4-fill",
-    "loader-4-line",
-    "loader-5-fill",
-    "loader-5-line",
-    "loader-fill",
-    "loader-line",
-    "lock-2-fill",
-    "lock-2-line",
-    "lock-fill",
-    "lock-line",
-    "lock-password-fill",
-    "lock-password-line",
-    "lock-unlock-fill",
-    "lock-unlock-line",
-    "login-box-fill",
-    "login-box-line",
-    "login-circle-fill",
-    "login-circle-line",
-    "logout-box-fill",
-    "logout-box-line",
-    "logout-box-r-fill",
-    "logout-box-r-line",
-    "logout-circle-fill",
-    "logout-circle-line",
-    "logout-circle-r-fill",
-    "logout-circle-r-line",
-    "loop-left-fill",
-    "loop-left-line",
-    "loop-right-fill",
-    "loop-right-line",
-    "luggage-cart-fill",
-    "luggage-cart-line",
-    "luggage-deposit-fill",
-    "luggage-deposit-line",
-    "lungs-fill",
-    "lungs-line",
-    "mac-fill",
-    "mac-line",
-    "macbook-fill",
-    "macbook-line",
-    "magic-fill",
-    "magic-line",
-    "mail-add-fill",
-    "mail-add-line",
-    "mail-check-fill",
-    "mail-check-line",
-    "mail-close-fill",
-    "mail-close-line",
-    "mail-download-fill",
-    "mail-download-line",
-    "mail-fill",
-    "mail-forbid-fill",
-    "mail-forbid-line",
-    "mail-line",
-    "mail-lock-fill",
-    "mail-lock-line",
-    "mail-open-fill",
-    "mail-open-line",
-    "mail-send-fill",
-    "mail-send-line",
-    "mail-settings-fill",
-    "mail-settings-line",
-    "mail-star-fill",
-    "mail-star-line",
-    "mail-unread-fill",
-    "mail-unread-line",
-    "mail-volume-fill",
-    "mail-volume-line",
-    "map-2-fill",
-    "map-2-line",
-    "map-fill",
-    "map-line",
-    "map-pin-2-fill",
-    "map-pin-2-line",
-    "map-pin-3-fill",
-    "map-pin-3-line",
-    "map-pin-4-fill",
-    "map-pin-4-line",
-    "map-pin-5-fill",
-    "map-pin-5-line",
-    "map-pin-add-fill",
-    "map-pin-add-line",
-    "map-pin-fill",
-    "map-pin-line",
-    "map-pin-range-fill",
-    "map-pin-range-line",
-    "map-pin-time-fill",
-    "map-pin-time-line",
-    "map-pin-user-fill",
-    "map-pin-user-line",
-    "mark-pen-fill",
-    "mark-pen-line",
-    "markdown-fill",
-    "markdown-line",
-    "markup-fill",
-    "markup-line",
-    "mastercard-fill",
-    "mastercard-line",
-    "mastodon-fill",
-    "mastodon-line",
-    "medal-2-fill",
-    "medal-2-line",
-    "medal-fill",
-    "medal-line",
-    "medicine-bottle-fill",
-    "medicine-bottle-line",
-    "medium-fill",
-    "medium-line",
-    "megaphone-fill",
-    "megaphone-line",
-    "memories-fill",
-    "memories-line",
-    "men-fill",
-    "men-line",
-    "mental-health-fill",
-    "mental-health-line",
-    "menu-2-fill",
-    "menu-2-line",
-    "menu-3-fill",
-    "menu-3-line",
-    "menu-4-fill",
-    "menu-4-line",
-    "menu-5-fill",
-    "menu-5-line",
-    "menu-add-fill",
-    "menu-add-line",
-    "menu-fill",
-    "menu-fold-fill",
-    "menu-fold-line",
-    "menu-line",
-    "menu-search-fill",
-    "menu-search-line",
-    "menu-unfold-fill",
-    "menu-unfold-line",
-    "merge-cells-horizontal",
-    "merge-cells-vertical",
-    "message-2-fill",
-    "message-2-line",
-    "message-3-fill",
-    "message-3-line",
-    "message-fill",
-    "message-line",
-    "messenger-fill",
-    "messenger-line",
-    "meta-fill",
-    "meta-line",
-    "meteor-fill",
-    "meteor-line",
-    "mic-2-fill",
-    "mic-2-line",
-    "mic-fill",
-    "mic-line",
-    "mic-off-fill",
-    "mic-off-line",
-    "mickey-fill",
-    "mickey-line",
-    "microscope-fill",
-    "microscope-line",
-    "microsoft-fill",
-    "microsoft-line",
-    "microsoft-loop-fill",
-    "microsoft-loop-line",
-    "mind-map",
-    "mini-program-fill",
-    "mini-program-line",
-    "mist-fill",
-    "mist-line",
-    "money-cny-box-fill",
-    "money-cny-box-line",
-    "money-cny-circle-fill",
-    "money-cny-circle-line",
-    "money-dollar-box-fill",
-    "money-dollar-box-line",
-    "money-dollar-circle-fill",
-    "money-dollar-circle-line",
-    "money-euro-box-fill",
-    "money-euro-box-line",
-    "money-euro-circle-fill",
-    "money-euro-circle-line",
-    "money-pound-box-fill",
-    "money-pound-box-line",
-    "money-pound-circle-fill",
-    "money-pound-circle-line",
-    "moon-clear-fill",
-    "moon-clear-line",
-    "moon-cloudy-fill",
-    "moon-cloudy-line",
-    "moon-fill",
-    "moon-foggy-fill",
-    "moon-foggy-line",
-    "moon-line",
-    "more-2-fill",
-    "more-2-line",
-    "more-fill",
-    "more-line",
-    "motorbike-fill",
-    "motorbike-line",
-    "mouse-fill",
-    "mouse-line",
-    "movie-2-fill",
-    "movie-2-line",
-    "movie-fill",
-    "movie-line",
-    "music-2-fill",
-    "music-2-line",
-    "music-fill",
-    "music-line",
-    "mv-fill",
-    "mv-line",
-    "navigation-fill",
-    "navigation-line",
-    "netease-cloud-music-fill",
-    "netease-cloud-music-line",
-    "netflix-fill",
-    "netflix-line",
-    "newspaper-fill",
-    "newspaper-line",
-    "nft-fill",
-    "nft-line",
-    "node-tree",
-    "notification-2-fill",
-    "notification-2-line",
-    "notification-3-fill",
-    "notification-3-line",
-    "notification-4-fill",
-    "notification-4-line",
-    "notification-badge-fill",
-    "notification-badge-line",
-    "notification-fill",
-    "notification-line",
-    "notification-off-fill",
-    "notification-off-line",
-    "notion-fill",
-    "notion-line",
-    "npmjs-fill",
-    "npmjs-line",
-    "number-0",
-    "number-1",
-    "number-2",
-    "number-3",
-    "number-4",
-    "number-5",
-    "number-6",
-    "number-7",
-    "number-8",
-    "number-9",
-    "numbers-fill",
-    "numbers-line",
-    "nurse-fill",
-    "nurse-line",
-    "octagon-fill",
-    "octagon-line",
-    "oil-fill",
-    "oil-line",
-    "omega",
-    "open-arm-fill",
-    "open-arm-line",
-    "open-source-fill",
-    "open-source-line",
-    "openai-fill",
-    "openai-line",
-    "openbase-fill",
-    "openbase-line",
-    "opera-fill",
-    "opera-line",
-    "order-play-fill",
-    "order-play-line",
-    "organization-chart",
-    "outlet-2-fill",
-    "outlet-2-line",
-    "outlet-fill",
-    "outlet-line",
-    "overline",
-    "p2p-fill",
-    "p2p-line",
-    "page-separator",
-    "pages-fill",
-    "pages-line",
-    "paint-brush-fill",
-    "paint-brush-line",
-    "paint-fill",
-    "paint-line",
-    "palette-fill",
-    "palette-line",
-    "pantone-fill",
-    "pantone-line",
-    "paragraph",
-    "parent-fill",
-    "parent-line",
-    "parentheses-fill",
-    "parentheses-line",
-    "parking-box-fill",
-    "parking-box-line",
-    "parking-fill",
-    "parking-line",
-    "pass-expired-fill",
-    "pass-expired-line",
-    "pass-pending-fill",
-    "pass-pending-line",
-    "pass-valid-fill",
-    "pass-valid-line",
-    "passport-fill",
-    "passport-line",
-    "patreon-fill",
-    "patreon-line",
-    "pause-circle-fill",
-    "pause-circle-line",
-    "pause-fill",
-    "pause-line",
-    "pause-mini-fill",
-    "pause-mini-line",
-    "paypal-fill",
-    "paypal-line",
-    "pen-nib-fill",
-    "pen-nib-line",
-    "pencil-fill",
-    "pencil-line",
-    "pencil-ruler-2-fill",
-    "pencil-ruler-2-line",
-    "pencil-ruler-fill",
-    "pencil-ruler-line",
-    "pentagon-fill",
-    "pentagon-line",
-    "percent-fill",
-    "percent-line",
-    "phone-camera-fill",
-    "phone-camera-line",
-    "phone-fill",
-    "phone-find-fill",
-    "phone-find-line",
-    "phone-line",
-    "phone-lock-fill",
-    "phone-lock-line",
-    "picture-in-picture-2-fill",
-    "picture-in-picture-2-line",
-    "picture-in-picture-exit-fill",
-    "picture-in-picture-exit-line",
-    "picture-in-picture-fill",
-    "picture-in-picture-line",
-    "pie-chart-2-fill",
-    "pie-chart-2-line",
-    "pie-chart-box-fill",
-    "pie-chart-box-line",
-    "pie-chart-fill",
-    "pie-chart-line",
-    "pin-distance-fill",
-    "pin-distance-line",
-    "ping-pong-fill",
-    "ping-pong-line",
-    "pinterest-fill",
-    "pinterest-line",
-    "pinyin-input",
-    "pixelfed-fill",
-    "pixelfed-line",
-    "plane-fill",
-    "plane-line",
-    "planet-fill",
-    "planet-line",
-    "plant-fill",
-    "plant-line",
-    "play-circle-fill",
-    "play-circle-line",
-    "play-fill",
-    "play-line",
-    "play-list-2-fill",
-    "play-list-2-line",
-    "play-list-add-fill",
-    "play-list-add-line",
-    "play-list-fill",
-    "play-list-line",
-    "play-mini-fill",
-    "play-mini-line",
-    "playstation-fill",
-    "playstation-line",
-    "plug-2-fill",
-    "plug-2-line",
-    "plug-fill",
-    "plug-line",
-    "polaroid-2-fill",
-    "polaroid-2-line",
-    "polaroid-fill",
-    "polaroid-line",
-    "police-car-fill",
-    "police-car-line",
-    "presentation-fill",
-    "presentation-line",
-    "price-tag-2-fill",
-    "price-tag-2-line",
-    "price-tag-3-fill",
-    "price-tag-3-line",
-    "price-tag-fill",
-    "price-tag-line",
-    "printer-cloud-fill",
-    "printer-cloud-line",
-    "printer-fill",
-    "printer-line",
-    "product-hunt-fill",
-    "product-hunt-line",
-    "profile-fill",
-    "profile-line",
-    "prohibited-fill",
-    "prohibited-line",
-    "projector-2-fill",
-    "projector-2-line",
-    "projector-fill",
-    "projector-line",
-    "psychotherapy-fill",
-    "psychotherapy-line",
-    "pulse-fill",
-    "pulse-line",
-    "pushpin-2-fill",
-    "pushpin-2-line",
-    "pushpin-fill",
-    "pushpin-line",
-    "qq-fill",
-    "qq-line",
-    "qr-code-fill",
-    "qr-code-line",
-    "qr-scan-2-fill",
-    "qr-scan-2-line",
-    "qr-scan-fill",
-    "qr-scan-line",
-    "question-answer-fill",
-    "question-answer-line",
-    "question-fill",
-    "question-line",
-    "question-mark",
-    "questionnaire-fill",
-    "questionnaire-line",
-    "quill-pen-fill",
-    "quill-pen-line",
-    "quote-text",
-    "radar-fill",
-    "radar-line",
-    "radio-2-fill",
-    "radio-2-line",
-    "radio-button-fill",
-    "radio-button-line",
-    "radio-fill",
-    "radio-line",
-    "rainbow-fill",
-    "rainbow-line",
-    "rainy-fill",
-    "rainy-line",
-    "reactjs-fill",
-    "reactjs-line",
-    "record-circle-fill",
-    "record-circle-line",
-    "record-mail-fill",
-    "record-mail-line",
-    "rectangle-fill",
-    "rectangle-line",
-    "recycle-fill",
-    "recycle-line",
-    "red-packet-fill",
-    "red-packet-line",
-    "reddit-fill",
-    "reddit-line",
-    "refresh-fill",
-    "refresh-line",
-    "refund-2-fill",
-    "refund-2-line",
-    "refund-fill",
-    "refund-line",
-    "registered-fill",
-    "registered-line",
-    "remixicon-fill",
-    "remixicon-line",
-    "remote-control-2-fill",
-    "remote-control-2-line",
-    "remote-control-fill",
-    "remote-control-line",
-    "repeat-2-fill",
-    "repeat-2-line",
-    "repeat-fill",
-    "repeat-line",
-    "repeat-one-fill",
-    "repeat-one-line",
-    "replay-10-fill",
-    "replay-10-line",
-    "replay-15-fill",
-    "replay-15-line",
-    "replay-30-fill",
-    "replay-30-line",
-    "replay-5-fill",
-    "replay-5-line",
-    "reply-all-fill",
-    "reply-all-line",
-    "reply-fill",
-    "reply-line",
-    "reserved-fill",
-    "reserved-line",
-    "rest-time-fill",
-    "rest-time-line",
-    "restart-fill",
-    "restart-line",
-    "restaurant-2-fill",
-    "restaurant-2-line",
-    "restaurant-fill",
-    "restaurant-line",
-    "rewind-fill",
-    "rewind-line",
-    "rewind-mini-fill",
-    "rewind-mini-line",
-    "rfid-fill",
-    "rfid-line",
-    "rhythm-fill",
-    "rhythm-line",
-    "riding-fill",
-    "riding-line",
-    "road-map-fill",
-    "road-map-line",
-    "roadster-fill",
-    "roadster-line",
-    "robot-2-fill",
-    "robot-2-line",
-    "robot-fill",
-    "robot-line",
-    "rocket-2-fill",
-    "rocket-2-line",
-    "rocket-fill",
-    "rocket-line",
-    "rotate-lock-fill",
-    "rotate-lock-line",
-    "rounded-corner",
-    "route-fill",
-    "route-line",
-    "router-fill",
-    "router-line",
-    "rss-fill",
-    "rss-line",
-    "ruler-2-fill",
-    "ruler-2-line",
-    "ruler-fill",
-    "ruler-line",
-    "run-fill",
-    "run-line",
-    "safari-fill",
-    "safari-line",
-    "safe-2-fill",
-    "safe-2-line",
-    "safe-fill",
-    "safe-line",
-    "sailboat-fill",
-    "sailboat-line",
-    "save-2-fill",
-    "save-2-line",
-    "save-3-fill",
-    "save-3-line",
-    "save-fill",
-    "save-line",
-    "scales-2-fill",
-    "scales-2-line",
-    "scales-3-fill",
-    "scales-3-line",
-    "scales-fill",
-    "scales-line",
-    "scan-2-fill",
-    "scan-2-line",
-    "scan-fill",
-    "scan-line",
-    "school-fill",
-    "school-line",
-    "scissors-2-fill",
-    "scissors-2-line",
-    "scissors-cut-fill",
-    "scissors-cut-line",
-    "scissors-fill",
-    "scissors-line",
-    "screenshot-2-fill",
-    "screenshot-2-line",
-    "screenshot-fill",
-    "screenshot-line",
-    "sd-card-fill",
-    "sd-card-line",
-    "sd-card-mini-fill",
-    "sd-card-mini-line",
-    "search-2-fill",
-    "search-2-line",
-    "search-eye-fill",
-    "search-eye-line",
-    "search-fill",
-    "search-line",
-    "secure-payment-fill",
-    "secure-payment-line",
-    "seedling-fill",
-    "seedling-line",
-    "send-backward",
-    "send-plane-2-fill",
-    "send-plane-2-line",
-    "send-plane-fill",
-    "send-plane-line",
-    "send-to-back",
-    "sensor-fill",
-    "sensor-line",
-    "seo-fill",
-    "seo-line",
-    "separator",
-    "server-fill",
-    "server-line",
-    "service-fill",
-    "service-line",
-    "settings-2-fill",
-    "settings-2-line",
-    "settings-3-fill",
-    "settings-3-line",
-    "settings-4-fill",
-    "settings-4-line",
-    "settings-5-fill",
-    "settings-5-line",
-    "settings-6-fill",
-    "settings-6-line",
-    "settings-fill",
-    "settings-line",
-    "shake-hands-fill",
-    "shake-hands-line",
-    "shape-2-fill",
-    "shape-2-line",
-    "shape-fill",
-    "shape-line",
-    "shapes-fill",
-    "shapes-line",
-    "share-box-fill",
-    "share-box-line",
-    "share-circle-fill",
-    "share-circle-line",
-    "share-fill",
-    "share-forward-2-fill",
-    "share-forward-2-line",
-    "share-forward-box-fill",
-    "share-forward-box-line",
-    "share-forward-fill",
-    "share-forward-line",
-    "share-line",
-    "shield-check-fill",
-    "shield-check-line",
-    "shield-cross-fill",
-    "shield-cross-line",
-    "shield-fill",
-    "shield-flash-fill",
-    "shield-flash-line",
-    "shield-keyhole-fill",
-    "shield-keyhole-line",
-    "shield-line",
-    "shield-star-fill",
-    "shield-star-line",
-    "shield-user-fill",
-    "shield-user-line",
-    "shining-2-fill",
-    "shining-2-line",
-    "shining-fill",
-    "shining-line",
-    "ship-2-fill",
-    "ship-2-line",
-    "ship-fill",
-    "ship-line",
-    "shirt-fill",
-    "shirt-line",
-    "shopping-bag-2-fill",
-    "shopping-bag-2-line",
-    "shopping-bag-3-fill",
-    "shopping-bag-3-line",
-    "shopping-bag-fill",
-    "shopping-bag-line",
-    "shopping-basket-2-fill",
-    "shopping-basket-2-line",
-    "shopping-basket-fill",
-    "shopping-basket-line",
-    "shopping-cart-2-fill",
-    "shopping-cart-2-line",
-    "shopping-cart-fill",
-    "shopping-cart-line",
-    "showers-fill",
-    "showers-line",
-    "shuffle-fill",
-    "shuffle-line",
-    "shut-down-fill",
-    "shut-down-line",
-    "side-bar-fill",
-    "side-bar-line",
-    "signal-tower-fill",
-    "signal-tower-line",
-    "signal-wifi-1-fill",
-    "signal-wifi-1-line",
-    "signal-wifi-2-fill",
-    "signal-wifi-2-line",
-    "signal-wifi-3-fill",
-    "signal-wifi-3-line",
-    "signal-wifi-error-fill",
-    "signal-wifi-error-line",
-    "signal-wifi-fill",
-    "signal-wifi-line",
-    "signal-wifi-off-fill",
-    "signal-wifi-off-line",
-    "sim-card-2-fill",
-    "sim-card-2-line",
-    "sim-card-fill",
-    "sim-card-line",
-    "single-quotes-l",
-    "single-quotes-r",
-    "sip-fill",
-    "sip-line",
-    "sketching",
-    "skip-back-fill",
-    "skip-back-line",
-    "skip-back-mini-fill",
-    "skip-back-mini-line",
-    "skip-down-fill",
-    "skip-down-line",
-    "skip-forward-fill",
-    "skip-forward-line",
-    "skip-forward-mini-fill",
-    "skip-forward-mini-line",
-    "skip-left-fill",
-    "skip-left-line",
-    "skip-right-fill",
-    "skip-right-line",
-    "skip-up-fill",
-    "skip-up-line",
-    "skull-2-fill",
-    "skull-2-line",
-    "skull-fill",
-    "skull-line",
-    "skype-fill",
-    "skype-line",
-    "slack-fill",
-    "slack-line",
-    "slash-commands",
-    "slash-commands-2",
-    "slice-fill",
-    "slice-line",
-    "slideshow-2-fill",
-    "slideshow-2-line",
-    "slideshow-3-fill",
-    "slideshow-3-line",
-    "slideshow-4-fill",
-    "slideshow-4-line",
-    "slideshow-fill",
-    "slideshow-line",
-    "slow-down-fill",
-    "slow-down-line",
-    "smartphone-fill",
-    "smartphone-line",
-    "snapchat-fill",
-    "snapchat-line",
-    "snowy-fill",
-    "snowy-line",
-    "sort-asc",
-    "sort-desc",
-    "sound-module-fill",
-    "sound-module-line",
-    "soundcloud-fill",
-    "soundcloud-line",
-    "space",
-    "space-ship-fill",
-    "space-ship-line",
-    "spam-2-fill",
-    "spam-2-line",
-    "spam-3-fill",
-    "spam-3-line",
-    "spam-fill",
-    "spam-line",
-    "sparkling-2-fill",
-    "sparkling-2-line",
-    "sparkling-fill",
-    "sparkling-line",
-    "speak-fill",
-    "speak-line",
-    "speaker-2-fill",
-    "speaker-2-line",
-    "speaker-3-fill",
-    "speaker-3-line",
-    "speaker-fill",
-    "speaker-line",
-    "spectrum-fill",
-    "spectrum-line",
-    "speed-fill",
-    "speed-line",
-    "speed-mini-fill",
-    "speed-mini-line",
-    "speed-up-fill",
-    "speed-up-line",
-    "split-cells-horizontal",
-    "split-cells-vertical",
-    "spotify-fill",
-    "spotify-line",
-    "spy-fill",
-    "spy-line",
-    "square-fill",
-    "square-line",
-    "stack-fill",
-    "stack-line",
-    "stack-overflow-fill",
-    "stack-overflow-line",
-    "stackshare-fill",
-    "stackshare-line",
-    "star-fill",
-    "star-half-fill",
-    "star-half-line",
-    "star-half-s-fill",
-    "star-half-s-line",
-    "star-line",
-    "star-s-fill",
-    "star-s-line",
-    "star-smile-fill",
-    "star-smile-line",
-    "steam-fill",
-    "steam-line",
-    "steering-2-fill",
-    "steering-2-line",
-    "steering-fill",
-    "steering-line",
-    "stethoscope-fill",
-    "stethoscope-line",
-    "sticky-note-2-fill",
-    "sticky-note-2-line",
-    "sticky-note-fill",
-    "sticky-note-line",
-    "stock-fill",
-    "stock-line",
-    "stop-circle-fill",
-    "stop-circle-line",
-    "stop-fill",
-    "stop-line",
-    "stop-mini-fill",
-    "stop-mini-line",
-    "store-2-fill",
-    "store-2-line",
-    "store-3-fill",
-    "store-3-line",
-    "store-fill",
-    "store-line",
-    "strikethrough",
-    "strikethrough-2",
-    "subscript",
-    "subscript-2",
-    "subtract-fill",
-    "subtract-line",
-    "subway-fill",
-    "subway-line",
-    "subway-wifi-fill",
-    "subway-wifi-line",
-    "suitcase-2-fill",
-    "suitcase-2-line",
-    "suitcase-3-fill",
-    "suitcase-3-line",
-    "suitcase-fill",
-    "suitcase-line",
-    "sun-cloudy-fill",
-    "sun-cloudy-line",
-    "sun-fill",
-    "sun-foggy-fill",
-    "sun-foggy-line",
-    "sun-line",
-    "supabase-fill",
-    "supabase-line",
-    "superscript",
-    "superscript-2",
-    "surgical-mask-fill",
-    "surgical-mask-line",
-    "surround-sound-fill",
-    "surround-sound-line",
-    "survey-fill",
-    "survey-line",
-    "swap-box-fill",
-    "swap-box-line",
-    "swap-fill",
-    "swap-line",
-    "switch-fill",
-    "switch-line",
-    "sword-fill",
-    "sword-line",
-    "syringe-fill",
-    "syringe-line",
-    "t-box-fill",
-    "t-box-line",
-    "t-shirt-2-fill",
-    "t-shirt-2-line",
-    "t-shirt-air-fill",
-    "t-shirt-air-line",
-    "t-shirt-fill",
-    "t-shirt-line",
-    "table-2",
-    "table-alt-fill",
-    "table-alt-line",
-    "table-fill",
-    "table-line",
-    "tablet-fill",
-    "tablet-line",
-    "takeaway-fill",
-    "takeaway-line",
-    "taobao-fill",
-    "taobao-line",
-    "tape-fill",
-    "tape-line",
-    "task-fill",
-    "task-line",
-    "taxi-fill",
-    "taxi-line",
-    "taxi-wifi-fill",
-    "taxi-wifi-line",
-    "team-fill",
-    "team-line",
-    "telegram-fill",
-    "telegram-line",
-    "temp-cold-fill",
-    "temp-cold-line",
-    "temp-hot-fill",
-    "temp-hot-line",
-    "tent-fill",
-    "tent-line",
-    "terminal-box-fill",
-    "terminal-box-line",
-    "terminal-fill",
-    "terminal-line",
-    "terminal-window-fill",
-    "terminal-window-line",
-    "test-tube-fill",
-    "test-tube-line",
-    "text",
-    "text-direction-l",
-    "text-direction-r",
-    "text-spacing",
-    "text-wrap",
-    "thermometer-fill",
-    "thermometer-line",
-    "threads-fill",
-    "threads-line",
-    "thumb-down-fill",
-    "thumb-down-line",
-    "thumb-up-fill",
-    "thumb-up-line",
-    "thunderstorms-fill",
-    "thunderstorms-line",
-    "ticket-2-fill",
-    "ticket-2-line",
-    "ticket-fill",
-    "ticket-line",
-    "tiktok-fill",
-    "tiktok-line",
-    "time-fill",
-    "time-line",
-    "timer-2-fill",
-    "timer-2-line",
-    "timer-fill",
-    "timer-flash-fill",
-    "timer-flash-line",
-    "timer-line",
-    "todo-fill",
-    "todo-line",
-    "toggle-fill",
-    "toggle-line",
-    "token-swap-fill",
-    "token-swap-line",
-    "tools-fill",
-    "tools-line",
-    "tornado-fill",
-    "tornado-line",
-    "trademark-fill",
-    "trademark-line",
-    "traffic-light-fill",
-    "traffic-light-line",
-    "train-fill",
-    "train-line",
-    "train-wifi-fill",
-    "train-wifi-line",
-    "translate",
-    "translate-2",
-    "travesti-fill",
-    "travesti-line",
-    "treasure-map-fill",
-    "treasure-map-line",
-    "tree-fill",
-    "tree-line",
-    "trello-fill",
-    "trello-line",
-    "triangle-fill",
-    "triangle-line",
-    "trophy-fill",
-    "trophy-line",
-    "truck-fill",
-    "truck-line",
-    "tumblr-fill",
-    "tumblr-line",
-    "tv-2-fill",
-    "tv-2-line",
-    "tv-fill",
-    "tv-line",
-    "twitch-fill",
-    "twitch-line",
-    "twitter-fill",
-    "twitter-line",
-    "twitter-x-fill",
-    "twitter-x-line",
-    "typhoon-fill",
-    "typhoon-line",
-    "u-disk-fill",
-    "u-disk-line",
-    "ubuntu-fill",
-    "ubuntu-line",
-    "umbrella-fill",
-    "umbrella-line",
-    "underline",
-    "uninstall-fill",
-    "uninstall-line",
-    "unpin-fill",
-    "unpin-line",
-    "unsplash-fill",
-    "unsplash-line",
-    "upload-2-fill",
-    "upload-2-line",
-    "upload-cloud-2-fill",
-    "upload-cloud-2-line",
-    "upload-cloud-fill",
-    "upload-cloud-line",
-    "upload-fill",
-    "upload-line",
-    "usb-fill",
-    "usb-line",
-    "user-2-fill",
-    "user-2-line",
-    "user-3-fill",
-    "user-3-line",
-    "user-4-fill",
-    "user-4-line",
-    "user-5-fill",
-    "user-5-line",
-    "user-6-fill",
-    "user-6-line",
-    "user-add-fill",
-    "user-add-line",
-    "user-fill",
-    "user-follow-fill",
-    "user-follow-line",
-    "user-forbid-fill",
-    "user-forbid-line",
-    "user-heart-fill",
-    "user-heart-line",
-    "user-line",
-    "user-location-fill",
-    "user-location-line",
-    "user-received-2-fill",
-    "user-received-2-line",
-    "user-received-fill",
-    "user-received-line",
-    "user-search-fill",
-    "user-search-line",
-    "user-settings-fill",
-    "user-settings-line",
-    "user-shared-2-fill",
-    "user-shared-2-line",
-    "user-shared-fill",
-    "user-shared-line",
-    "user-smile-fill",
-    "user-smile-line",
-    "user-star-fill",
-    "user-star-line",
-    "user-unfollow-fill",
-    "user-unfollow-line",
-    "user-voice-fill",
-    "user-voice-line",
-    "verified-badge-fill",
-    "verified-badge-line",
-    "video-add-fill",
-    "video-add-line",
-    "video-chat-fill",
-    "video-chat-line",
-    "video-download-fill",
-    "video-download-line",
-    "video-fill",
-    "video-line",
-    "video-upload-fill",
-    "video-upload-line",
-    "vidicon-2-fill",
-    "vidicon-2-line",
-    "vidicon-fill",
-    "vidicon-line",
-    "vimeo-fill",
-    "vimeo-line",
-    "vip-crown-2-fill",
-    "vip-crown-2-line",
-    "vip-crown-fill",
-    "vip-crown-line",
-    "vip-diamond-fill",
-    "vip-diamond-line",
-    "vip-fill",
-    "vip-line",
-    "virus-fill",
-    "virus-line",
-    "visa-fill",
-    "visa-line",
-    "voice-recognition-fill",
-    "voice-recognition-line",
-    "voiceprint-fill",
-    "voiceprint-line",
-    "volume-down-fill",
-    "volume-down-line",
-    "volume-mute-fill",
-    "volume-mute-line",
-    "volume-off-vibrate-fill",
-    "volume-off-vibrate-line",
-    "volume-up-fill",
-    "volume-up-line",
-    "volume-vibrate-fill",
-    "volume-vibrate-line",
-    "vuejs-fill",
-    "vuejs-line",
-    "walk-fill",
-    "walk-line",
-    "wallet-2-fill",
-    "wallet-2-line",
-    "wallet-3-fill",
-    "wallet-3-line",
-    "wallet-fill",
-    "wallet-line",
-    "water-flash-fill",
-    "water-flash-line",
-    "water-percent-fill",
-    "water-percent-line",
-    "webcam-fill",
-    "webcam-line",
-    "wechat-2-fill",
-    "wechat-2-line",
-    "wechat-channels-fill",
-    "wechat-channels-line",
-    "wechat-fill",
-    "wechat-line",
-    "wechat-pay-fill",
-    "wechat-pay-line",
-    "weibo-fill",
-    "weibo-line",
-    "whatsapp-fill",
-    "whatsapp-line",
-    "wheelchair-fill",
-    "wheelchair-line",
-    "wifi-fill",
-    "wifi-line",
-    "wifi-off-fill",
-    "wifi-off-line",
-    "window-2-fill",
-    "window-2-line",
-    "window-fill",
-    "window-line",
-    "windows-fill",
-    "windows-line",
-    "windy-fill",
-    "windy-line",
-    "wireless-charging-fill",
-    "wireless-charging-line",
-    "women-fill",
-    "women-line",
-    "wordpress-fill",
-    "wordpress-line",
-    "wubi-input",
-    "xbox-fill",
-    "xbox-line",
-    "xing-fill",
-    "xing-line",
-    "youtube-fill",
-    "youtube-line",
-    "yuque-fill",
-    "yuque-line",
-    "zcool-fill",
-    "zcool-line",
-    "zhihu-fill",
-    "zhihu-line",
-    "zoom-in-fill",
-    "zoom-in-line",
-    "zoom-out-fill",
-    "zoom-out-line",
-    "zzz-fill",
-    "zzz-line"
-  ],
-  // https://icones.js.org/collections/fa-solid-meta.json
-  "fa-solid:": [
-    "abacus",
-    "ad",
-    "address-book",
-    "address-card",
-    "adjust",
-    "air-freshener",
-    "align-center",
-    "align-justify",
-    "align-left",
-    "align-right",
-    "allergies",
-    "ambulance",
-    "american-sign-language-interpreting",
-    "anchor",
-    "angle-double-down",
-    "angle-double-left",
-    "angle-double-right",
-    "angle-double-up",
-    "angle-down",
-    "angle-left",
-    "angle-right",
-    "angle-up",
-    "angry",
-    "ankh",
-    "apple-alt",
-    "archive",
-    "archway",
-    "arrow-alt-circle-down",
-    "arrow-alt-circle-left",
-    "arrow-alt-circle-right",
-    "arrow-alt-circle-up",
-    "arrow-circle-down",
-    "arrow-circle-left",
-    "arrow-circle-right",
-    "arrow-circle-up",
-    "arrow-down",
-    "arrow-left",
-    "arrow-right",
-    "arrow-up",
-    "arrows-alt",
-    "arrows-alt-h",
-    "arrows-alt-v",
-    "assistive-listening-systems",
-    "asterisk",
-    "at",
-    "atlas",
-    "atom",
-    "audio-description",
-    "award",
-    "baby",
-    "baby-carriage",
-    "backspace",
-    "backward",
-    "bacon",
-    "bacteria",
-    "bacterium",
-    "bahai",
-    "balance-scale",
-    "balance-scale-left",
-    "balance-scale-right",
-    "ban",
-    "band-aid",
-    "barcode",
-    "bars",
-    "baseball-ball",
-    "basketball-ball",
-    "bath",
-    "battery-empty",
-    "battery-full",
-    "battery-half",
-    "battery-quarter",
-    "battery-three-quarters",
-    "bed",
-    "beer",
-    "bell",
-    "bell-slash",
-    "bezier-curve",
-    "bible",
-    "bicycle",
-    "biking",
-    "binoculars",
-    "biohazard",
-    "birthday-cake",
-    "blender",
-    "blender-phone",
-    "blind",
-    "blog",
-    "bold",
-    "bolt",
-    "bomb",
-    "bone",
-    "bong",
-    "book",
-    "book-dead",
-    "book-medical",
-    "book-open",
-    "book-reader",
-    "bookmark",
-    "border-all",
-    "border-none",
-    "border-style",
-    "bowling-ball",
-    "box",
-    "box-open",
-    "box-tissue",
-    "boxes",
-    "braille",
-    "brain",
-    "bread-slice",
-    "briefcase",
-    "briefcase-medical",
-    "broadcast-tower",
-    "broom",
-    "brush",
-    "bug",
-    "building",
-    "bullhorn",
-    "bullseye",
-    "burn",
-    "bus",
-    "bus-alt",
-    "business-time",
-    "calculator",
-    "calculator-alt",
-    "calendar",
-    "calendar-alt",
-    "calendar-check",
-    "calendar-day",
-    "calendar-minus",
-    "calendar-plus",
-    "calendar-times",
-    "calendar-week",
-    "camera",
-    "camera-retro",
-    "campground",
-    "candy-cane",
-    "cannabis",
-    "capsules",
-    "car",
-    "car-alt",
-    "car-battery",
-    "car-crash",
-    "car-side",
-    "caravan",
-    "caret-down",
-    "caret-left",
-    "caret-right",
-    "caret-square-down",
-    "caret-square-left",
-    "caret-square-right",
-    "caret-square-up",
-    "caret-up",
-    "carrot",
-    "cart-arrow-down",
-    "cart-plus",
-    "cash-register",
-    "cat",
-    "certificate",
-    "chair",
-    "chalkboard",
-    "chalkboard-teacher",
-    "charging-station",
-    "chart-area",
-    "chart-bar",
-    "chart-line",
-    "chart-pie",
-    "check",
-    "check-circle",
-    "check-double",
-    "check-square",
-    "cheese",
-    "chess",
-    "chess-bishop",
-    "chess-board",
-    "chess-king",
-    "chess-knight",
-    "chess-pawn",
-    "chess-queen",
-    "chess-rook",
-    "chevron-circle-down",
-    "chevron-circle-left",
-    "chevron-circle-right",
-    "chevron-circle-up",
-    "chevron-down",
-    "chevron-left",
-    "chevron-right",
-    "chevron-up",
-    "child",
-    "church",
-    "circle",
-    "circle-notch",
-    "city",
-    "clinic-medical",
-    "clipboard",
-    "clipboard-check",
-    "clipboard-list",
-    "clock",
-    "clone",
-    "closed-captioning",
-    "cloud",
-    "cloud-download-alt",
-    "cloud-meatball",
-    "cloud-moon",
-    "cloud-moon-rain",
-    "cloud-rain",
-    "cloud-showers-heavy",
-    "cloud-sun",
-    "cloud-sun-rain",
-    "cloud-upload-alt",
-    "cocktail",
-    "code",
-    "code-branch",
-    "coffee",
-    "cog",
-    "cogs",
-    "coins",
-    "columns",
-    "comment",
-    "comment-alt",
-    "comment-dollar",
-    "comment-dots",
-    "comment-medical",
-    "comment-slash",
-    "comments",
-    "comments-dollar",
-    "compact-disc",
-    "compass",
-    "compress",
-    "compress-alt",
-    "compress-arrows-alt",
-    "concierge-bell",
-    "cookie",
-    "cookie-bite",
-    "copy",
-    "copyright",
-    "couch",
-    "credit-card",
-    "crop",
-    "crop-alt",
-    "cross",
-    "crosshairs",
-    "crow",
-    "crown",
-    "crutch",
-    "cube",
-    "cubes",
-    "cut",
-    "database",
-    "deaf",
-    "democrat",
-    "desktop",
-    "dharmachakra",
-    "diagnoses",
-    "dice",
-    "dice-d20",
-    "dice-d6",
-    "dice-five",
-    "dice-four",
-    "dice-one",
-    "dice-six",
-    "dice-three",
-    "dice-two",
-    "digital-tachograph",
-    "directions",
-    "disease",
-    "divide",
-    "dizzy",
-    "dna",
-    "dog",
-    "dollar-sign",
-    "dolly",
-    "dolly-flatbed",
-    "donate",
-    "door-closed",
-    "door-open",
-    "dot-circle",
-    "dove",
-    "download",
-    "drafting-compass",
-    "dragon",
-    "draw-polygon",
-    "drum",
-    "drum-steelpan",
-    "drumstick-bite",
-    "dumbbell",
-    "dumpster",
-    "dumpster-fire",
-    "dungeon",
-    "edit",
-    "egg",
-    "eject",
-    "ellipsis-h",
-    "ellipsis-v",
-    "empty-set",
-    "envelope",
-    "envelope-open",
-    "envelope-open-text",
-    "envelope-square",
-    "equals",
-    "eraser",
-    "ethernet",
-    "euro-sign",
-    "exchange-alt",
-    "exclamation",
-    "exclamation-circle",
-    "exclamation-triangle",
-    "expand",
-    "expand-alt",
-    "expand-arrows-alt",
-    "external-link-alt",
-    "external-link-square-alt",
-    "eye",
-    "eye-dropper",
-    "eye-slash",
-    "fan",
-    "fast-backward",
-    "fast-forward",
-    "faucet",
-    "fax",
-    "feather",
-    "feather-alt",
-    "female",
-    "fighter-jet",
-    "file",
-    "file-alt",
-    "file-archive",
-    "file-audio",
-    "file-code",
-    "file-contract",
-    "file-csv",
-    "file-download",
-    "file-excel",
-    "file-export",
-    "file-image",
-    "file-import",
-    "file-invoice",
-    "file-invoice-dollar",
-    "file-medical",
-    "file-medical-alt",
-    "file-pdf",
-    "file-powerpoint",
-    "file-prescription",
-    "file-signature",
-    "file-upload",
-    "file-video",
-    "file-word",
-    "fill",
-    "fill-drip",
-    "film",
-    "filter",
-    "fingerprint",
-    "fire",
-    "fire-alt",
-    "fire-extinguisher",
-    "first-aid",
-    "fish",
-    "fist-raised",
-    "flag",
-    "flag-checkered",
-    "flag-usa",
-    "flask",
-    "flushed",
-    "folder",
-    "folder-minus",
-    "folder-open",
-    "folder-plus",
-    "font",
-    "football-ball",
-    "forward",
-    "frog",
-    "frown",
-    "frown-open",
-    "function",
-    "funnel-dollar",
-    "futbol",
-    "gamepad",
-    "gas-pump",
-    "gavel",
-    "gem",
-    "genderless",
-    "ghost",
-    "gift",
-    "gifts",
-    "glass-cheers",
-    "glass-martini",
-    "glass-martini-alt",
-    "glass-whiskey",
-    "glasses",
-    "globe",
-    "globe-africa",
-    "globe-americas",
-    "globe-asia",
-    "globe-europe",
-    "golf-ball",
-    "gopuram",
-    "graduation-cap",
-    "greater-than",
-    "greater-than-equal",
-    "grimace",
-    "grin",
-    "grin-alt",
-    "grin-beam",
-    "grin-beam-sweat",
-    "grin-hearts",
-    "grin-squint",
-    "grin-squint-tears",
-    "grin-stars",
-    "grin-tears",
-    "grin-tongue",
-    "grin-tongue-squint",
-    "grin-tongue-wink",
-    "grin-wink",
-    "grip-horizontal",
-    "grip-lines",
-    "grip-lines-vertical",
-    "grip-vertical",
-    "guitar",
-    "h-square",
-    "hamburger",
-    "hammer",
-    "hamsa",
-    "hand-holding",
-    "hand-holding-heart",
-    "hand-holding-medical",
-    "hand-holding-usd",
-    "hand-holding-water",
-    "hand-lizard",
-    "hand-middle-finger",
-    "hand-paper",
-    "hand-peace",
-    "hand-point-down",
-    "hand-point-left",
-    "hand-point-right",
-    "hand-point-up",
-    "hand-pointer",
-    "hand-rock",
-    "hand-scissors",
-    "hand-sparkles",
-    "hand-spock",
-    "hands",
-    "hands-helping",
-    "hands-wash",
-    "handshake",
-    "handshake-alt-slash",
-    "handshake-slash",
-    "hanukiah",
-    "hard-hat",
-    "hashtag",
-    "hat-cowboy",
-    "hat-cowboy-side",
-    "hat-wizard",
-    "hdd",
-    "head-side-cough",
-    "head-side-cough-slash",
-    "head-side-mask",
-    "head-side-virus",
-    "heading",
-    "headphones",
-    "headphones-alt",
-    "headset",
-    "heart",
-    "heart-broken",
-    "heartbeat",
-    "helicopter",
-    "highlighter",
-    "hiking",
-    "hippo",
-    "history",
-    "hockey-puck",
-    "holly-berry",
-    "home",
-    "horse",
-    "horse-head",
-    "hospital",
-    "hospital-alt",
-    "hospital-symbol",
-    "hospital-user",
-    "hot-tub",
-    "hotdog",
-    "hotel",
-    "hourglass",
-    "hourglass-end",
-    "hourglass-half",
-    "hourglass-start",
-    "house-damage",
-    "house-user",
-    "hryvnia",
-    "i-cursor",
-    "ice-cream",
-    "icicles",
-    "icons",
-    "id-badge",
-    "id-card",
-    "id-card-alt",
-    "igloo",
-    "image",
-    "images",
-    "inbox",
-    "indent",
-    "industry",
-    "infinity",
-    "info",
-    "info-circle",
-    "integral",
-    "intersection",
-    "italic",
-    "jedi",
-    "joint",
-    "journal-whills",
-    "kaaba",
-    "key",
-    "keyboard",
-    "khanda",
-    "kiss",
-    "kiss-beam",
-    "kiss-wink-heart",
-    "kiwi-bird",
-    "lambda",
-    "landmark",
-    "language",
-    "laptop",
-    "laptop-code",
-    "laptop-house",
-    "laptop-medical",
-    "laugh",
-    "laugh-beam",
-    "laugh-squint",
-    "laugh-wink",
-    "layer-group",
-    "leaf",
-    "lemon",
-    "less-than",
-    "less-than-equal",
-    "level-down-alt",
-    "level-up-alt",
-    "life-ring",
-    "lightbulb",
-    "link",
-    "lira-sign",
-    "list",
-    "list-alt",
-    "list-ol",
-    "list-ul",
-    "location-arrow",
-    "lock",
-    "lock-open",
-    "long-arrow-alt-down",
-    "long-arrow-alt-left",
-    "long-arrow-alt-right",
-    "long-arrow-alt-up",
-    "low-vision",
-    "luggage-cart",
-    "lungs",
-    "lungs-virus",
-    "magic",
-    "magnet",
-    "mail-bulk",
-    "male",
-    "map",
-    "map-marked",
-    "map-marked-alt",
-    "map-marker",
-    "map-marker-alt",
-    "map-pin",
-    "map-signs",
-    "marker",
-    "mars",
-    "mars-double",
-    "mars-stroke",
-    "mars-stroke-h",
-    "mars-stroke-v",
-    "mask",
-    "medal",
-    "medkit",
-    "meh",
-    "meh-blank",
-    "meh-rolling-eyes",
-    "memory",
-    "menorah",
-    "mercury",
-    "meteor",
-    "microchip",
-    "microphone",
-    "microphone-alt",
-    "microphone-alt-slash",
-    "microphone-slash",
-    "microscope",
-    "minus",
-    "minus-circle",
-    "minus-square",
-    "mitten",
-    "mobile",
-    "mobile-alt",
-    "money-bill",
-    "money-bill-alt",
-    "money-bill-wave",
-    "money-bill-wave-alt",
-    "money-check",
-    "money-check-alt",
-    "monument",
-    "moon",
-    "mortar-pestle",
-    "mosque",
-    "motorcycle",
-    "mountain",
-    "mouse",
-    "mouse-pointer",
-    "mug-hot",
-    "music",
-    "network-wired",
-    "neuter",
-    "newspaper",
-    "not-equal",
-    "notes-medical",
-    "object-group",
-    "object-ungroup",
-    "oil-can",
-    "om",
-    "omega",
-    "otter",
-    "outdent",
-    "pager",
-    "paint-brush",
-    "paint-roller",
-    "palette",
-    "pallet",
-    "paper-plane",
-    "paperclip",
-    "parachute-box",
-    "paragraph",
-    "parking",
-    "passport",
-    "pastafarianism",
-    "paste",
-    "pause",
-    "pause-circle",
-    "paw",
-    "peace",
-    "pen",
-    "pen-alt",
-    "pen-fancy",
-    "pen-nib",
-    "pen-square",
-    "pencil-alt",
-    "pencil-ruler",
-    "people-arrows",
-    "people-carry",
-    "pepper-hot",
-    "percent",
-    "percentage",
-    "person-booth",
-    "phone",
-    "phone-alt",
-    "phone-slash",
-    "phone-square",
-    "phone-square-alt",
-    "phone-volume",
-    "photo-video",
-    "pi",
-    "piggy-bank",
-    "pills",
-    "pizza-slice",
-    "place-of-worship",
-    "plane",
-    "plane-arrival",
-    "plane-departure",
-    "plane-slash",
-    "play",
-    "play-circle",
-    "plug",
-    "plus",
-    "plus-circle",
-    "plus-square",
-    "podcast",
-    "poll",
-    "poll-h",
-    "poo",
-    "poo-storm",
-    "poop",
-    "portrait",
-    "pound-sign",
-    "power-off",
-    "pray",
-    "praying-hands",
-    "prescription",
-    "prescription-bottle",
-    "prescription-bottle-alt",
-    "print",
-    "procedures",
-    "project-diagram",
-    "pump-medical",
-    "pump-soap",
-    "puzzle-piece",
-    "qrcode",
-    "question",
-    "question-circle",
-    "quidditch",
-    "quote-left",
-    "quote-right",
-    "quran",
-    "radiation",
-    "radiation-alt",
-    "rainbow",
-    "random",
-    "receipt",
-    "record-vinyl",
-    "recycle",
-    "redo",
-    "redo-alt",
-    "registered",
-    "remove-format",
-    "reply",
-    "reply-all",
-    "republican",
-    "restroom",
-    "retweet",
-    "ribbon",
-    "ring",
-    "road",
-    "robot",
-    "rocket",
-    "route",
-    "rss",
-    "rss-square",
-    "ruble-sign",
-    "ruler",
-    "ruler-combined",
-    "ruler-horizontal",
-    "ruler-vertical",
-    "running",
-    "rupee-sign",
-    "sad-cry",
-    "sad-tear",
-    "satellite",
-    "satellite-dish",
-    "save",
-    "school",
-    "screwdriver",
-    "scroll",
-    "sd-card",
-    "search",
-    "search-dollar",
-    "search-location",
-    "search-minus",
-    "search-plus",
-    "seedling",
-    "server",
-    "shapes",
-    "share",
-    "share-alt",
-    "share-alt-square",
-    "share-square",
-    "shekel-sign",
-    "shield-alt",
-    "shield-virus",
-    "ship",
-    "shipping-fast",
-    "shoe-prints",
-    "shopping-bag",
-    "shopping-basket",
-    "shopping-cart",
-    "shower",
-    "shuttle-van",
-    "sigma",
-    "sign",
-    "sign-in-alt",
-    "sign-language",
-    "sign-out-alt",
-    "signal",
-    "signal-alt",
-    "signal-alt-slash",
-    "signal-slash",
-    "signature",
-    "sim-card",
-    "sink",
-    "sitemap",
-    "skating",
-    "skiing",
-    "skiing-nordic",
-    "skull",
-    "skull-crossbones",
-    "slash",
-    "sleigh",
-    "sliders-h",
-    "smile",
-    "smile-beam",
-    "smile-wink",
-    "smog",
-    "smoking",
-    "smoking-ban",
-    "sms",
-    "snowboarding",
-    "snowflake",
-    "snowman",
-    "snowplow",
-    "soap",
-    "socks",
-    "solar-panel",
-    "sort",
-    "sort-alpha-down",
-    "sort-alpha-down-alt",
-    "sort-alpha-up",
-    "sort-alpha-up-alt",
-    "sort-amount-down",
-    "sort-amount-down-alt",
-    "sort-amount-up",
-    "sort-amount-up-alt",
-    "sort-down",
-    "sort-numeric-down",
-    "sort-numeric-down-alt",
-    "sort-numeric-up",
-    "sort-numeric-up-alt",
-    "sort-up",
-    "spa",
-    "space-shuttle",
-    "spell-check",
-    "spider",
-    "spinner",
-    "splotch",
-    "spray-can",
-    "square",
-    "square-full",
-    "square-root",
-    "square-root-alt",
-    "stamp",
-    "star",
-    "star-and-crescent",
-    "star-half",
-    "star-half-alt",
-    "star-of-david",
-    "star-of-life",
-    "step-backward",
-    "step-forward",
-    "stethoscope",
-    "sticky-note",
-    "stop",
-    "stop-circle",
-    "stopwatch",
-    "stopwatch-20",
-    "store",
-    "store-alt",
-    "store-alt-slash",
-    "store-slash",
-    "stream",
-    "street-view",
-    "strikethrough",
-    "stroopwafel",
-    "subscript",
-    "subway",
-    "suitcase",
-    "suitcase-rolling",
-    "sun",
-    "superscript",
-    "surprise",
-    "swatchbook",
-    "swimmer",
-    "swimming-pool",
-    "synagogue",
-    "sync",
-    "sync-alt",
-    "syringe",
-    "table",
-    "table-tennis",
-    "tablet",
-    "tablet-alt",
-    "tablets",
-    "tachometer-alt",
-    "tag",
-    "tags",
-    "tally",
-    "tape",
-    "tasks",
-    "taxi",
-    "teeth",
-    "teeth-open",
-    "temperature-high",
-    "temperature-low",
-    "tenge",
-    "terminal",
-    "text-height",
-    "text-width",
-    "th",
-    "th-large",
-    "th-list",
-    "theater-masks",
-    "thermometer",
-    "thermometer-empty",
-    "thermometer-full",
-    "thermometer-half",
-    "thermometer-quarter",
-    "thermometer-three-quarters",
-    "theta",
-    "thumbs-down",
-    "thumbs-up",
-    "thumbtack",
-    "ticket-alt",
-    "tilde",
-    "times",
-    "times-circle",
-    "tint",
-    "tint-slash",
-    "tired",
-    "toggle-off",
-    "toggle-on",
-    "toilet",
-    "toilet-paper",
-    "toilet-paper-slash",
-    "toolbox",
-    "tools",
-    "tooth",
-    "torah",
-    "torii-gate",
-    "tractor",
-    "trademark",
-    "traffic-light",
-    "trailer",
-    "train",
-    "tram",
-    "transgender",
-    "transgender-alt",
-    "trash",
-    "trash-alt",
-    "trash-restore",
-    "trash-restore-alt",
-    "tree",
-    "trophy",
-    "truck",
-    "truck-loading",
-    "truck-monster",
-    "truck-moving",
-    "truck-pickup",
-    "tshirt",
-    "tty",
-    "tv",
-    "umbrella",
-    "umbrella-beach",
-    "underline",
-    "undo",
-    "undo-alt",
-    "union",
-    "universal-access",
-    "university",
-    "unlink",
-    "unlock",
-    "unlock-alt",
-    "upload",
-    "user",
-    "user-alt",
-    "user-alt-slash",
-    "user-astronaut",
-    "user-check",
-    "user-circle",
-    "user-clock",
-    "user-cog",
-    "user-edit",
-    "user-friends",
-    "user-graduate",
-    "user-injured",
-    "user-lock",
-    "user-md",
-    "user-minus",
-    "user-ninja",
-    "user-nurse",
-    "user-plus",
-    "user-secret",
-    "user-shield",
-    "user-slash",
-    "user-tag",
-    "user-tie",
-    "user-times",
-    "users",
-    "users-cog",
-    "users-slash",
-    "utensil-spoon",
-    "utensils",
-    "value-absolute",
-    "vector-square",
-    "venus",
-    "venus-double",
-    "venus-mars",
-    "vest",
-    "vest-patches",
-    "vial",
-    "vials",
-    "video",
-    "video-slash",
-    "vihara",
-    "virus",
-    "virus-slash",
-    "viruses",
-    "voicemail",
-    "volleyball-ball",
-    "volume",
-    "volume-down",
-    "volume-mute",
-    "volume-off",
-    "volume-slash",
-    "volume-up",
-    "vote-yea",
-    "vr-cardboard",
-    "walking",
-    "wallet",
-    "warehouse",
-    "water",
-    "wave-square",
-    "weight",
-    "weight-hanging",
-    "wheelchair",
-    "wifi",
-    "wifi-slash",
-    "wind",
-    "window-close",
-    "window-maximize",
-    "window-minimize",
-    "window-restore",
-    "wine-bottle",
-    "wine-glass",
-    "wine-glass-alt",
-    "won-sign",
-    "wrench",
-    "x-ray",
-    "yen-sign",
-    "yin-yang"
-  ]
-};

+ 1 - 4
admin-web-new/src/components/ReIcon/index.ts

@@ -1,15 +1,12 @@
 import iconifyIconOffline from "./src/iconifyIconOffline";
 import iconifyIconOnline from "./src/iconifyIconOnline";
-import iconSelect from "./src/Select.vue";
 import fontIcon from "./src/iconfont";
 
 /** 本地图标组件 */
 const IconifyIconOffline = iconifyIconOffline;
 /** 在线图标组件 */
 const IconifyIconOnline = iconifyIconOnline;
-/** `IconSelect`图标选择器组件 */
-const IconSelect = iconSelect;
 /** `iconfont`组件 */
 const FontIcon = fontIcon;
 
-export { IconifyIconOffline, IconifyIconOnline, IconSelect, FontIcon };
+export { IconifyIconOffline, IconifyIconOnline, FontIcon };

+ 0 - 268
admin-web-new/src/components/ReIcon/src/Select.vue

@@ -1,268 +0,0 @@
-<script setup lang="ts">
-import { IconJson } from "@/components/ReIcon/data";
-import { cloneDeep, isAllEmpty } from "@pureadmin/utils";
-import { ref, computed, CSSProperties, watch } from "vue";
-import Search from "~icons/ri/search-eye-line";
-
-type ParameterCSSProperties = (item?: string) => CSSProperties | undefined;
-
-defineOptions({
-  name: "IconSelect"
-});
-
-const inputValue = defineModel({ type: String });
-
-const iconList = ref(IconJson);
-const icon = ref();
-const currentActiveType = ref("ep:");
-// 深拷贝图标数据,前端做搜索
-const copyIconList = cloneDeep(iconList.value);
-const totalPage = ref(0);
-// 每页显示35个图标
-const pageSize = ref(35);
-const currentPage = ref(1);
-
-// 搜索条件
-const filterValue = ref("");
-
-const tabsList = [
-  {
-    label: "Element Plus",
-    name: "ep:"
-  },
-  {
-    label: "Remix Icon",
-    name: "ri:"
-  },
-  {
-    label: "Font Awesome 5 Solid",
-    name: "fa-solid:"
-  }
-];
-
-const pageList = computed(() =>
-  copyIconList[currentActiveType.value]
-    .filter(i => i.includes(filterValue.value))
-    .slice(
-      (currentPage.value - 1) * pageSize.value,
-      currentPage.value * pageSize.value
-    )
-);
-
-const iconItemStyle = computed((): ParameterCSSProperties => {
-  return item => {
-    if (inputValue.value === currentActiveType.value + item) {
-      return {
-        borderColor: "var(--el-color-primary)",
-        color: "var(--el-color-primary)"
-      };
-    }
-  };
-});
-
-function setVal() {
-  currentActiveType.value = inputValue.value.substring(
-    0,
-    inputValue.value.indexOf(":") + 1
-  );
-  icon.value = inputValue.value.substring(inputValue.value.indexOf(":") + 1);
-}
-
-function onBeforeEnter() {
-  if (isAllEmpty(icon.value)) return;
-  setVal();
-  // 寻找当前图标在第几页
-  const curIconIndex = copyIconList[currentActiveType.value].findIndex(
-    i => i === icon.value
-  );
-  currentPage.value = Math.ceil((curIconIndex + 1) / pageSize.value);
-}
-
-function onAfterLeave() {
-  filterValue.value = "";
-}
-
-function handleClick({ props }) {
-  currentPage.value = 1;
-  currentActiveType.value = props.name;
-}
-
-function onChangeIcon(item) {
-  icon.value = item;
-  inputValue.value = currentActiveType.value + item;
-}
-
-function onCurrentChange(page) {
-  currentPage.value = page;
-}
-
-function onClear() {
-  icon.value = "";
-  inputValue.value = "";
-}
-
-watch(
-  () => pageList.value,
-  () =>
-    (totalPage.value = copyIconList[currentActiveType.value].filter(i =>
-      i.includes(filterValue.value)
-    ).length),
-  { immediate: true }
-);
-watch(
-  () => inputValue.value,
-  val => val && setVal(),
-  { immediate: true }
-);
-watch(
-  () => filterValue.value,
-  () => (currentPage.value = 1)
-);
-</script>
-
-<template>
-  <div class="selector">
-    <el-input v-model="inputValue" disabled>
-      <template #append>
-        <el-popover
-          :width="350"
-          trigger="click"
-          popper-class="pure-popper"
-          :popper-options="{
-            placement: 'auto'
-          }"
-          @before-enter="onBeforeEnter"
-          @after-leave="onAfterLeave"
-        >
-          <template #reference>
-            <div
-              class="w-[40px] h-[32px] cursor-pointer flex justify-center items-center"
-            >
-              <IconifyIconOffline v-if="!icon" :icon="Search" />
-              <IconifyIconOnline v-else :icon="inputValue" />
-            </div>
-          </template>
-
-          <el-input
-            v-model="filterValue"
-            class="px-2 pt-2"
-            placeholder="搜索图标"
-            clearable
-          />
-
-          <el-tabs v-model="currentActiveType" @tab-click="handleClick">
-            <el-tab-pane
-              v-for="(pane, index) in tabsList"
-              :key="index"
-              :label="pane.label"
-              :name="pane.name"
-            >
-              <el-scrollbar height="220px">
-                <ul class="flex flex-wrap px-2! ml-2!">
-                  <li
-                    v-for="(item, key) in pageList"
-                    :key="key"
-                    :title="item"
-                    class="icon-item p-2 cursor-pointer mr-2 mt-1 flex justify-center items-center border border-[#e5e7eb]"
-                    :style="iconItemStyle(item)"
-                    @click="onChangeIcon(item)"
-                  >
-                    <IconifyIconOnline
-                      :icon="currentActiveType + item"
-                      width="20px"
-                      height="20px"
-                    />
-                  </li>
-                </ul>
-                <el-empty
-                  v-show="pageList.length === 0"
-                  :description="`${filterValue} 图标不存在`"
-                  :image-size="60"
-                />
-              </el-scrollbar>
-            </el-tab-pane>
-          </el-tabs>
-
-          <div
-            class="w-full h-9 flex items-center overflow-auto border-t border-[#e5e7eb]"
-          >
-            <el-pagination
-              class="flex-auto ml-2"
-              :total="totalPage"
-              :current-page="currentPage"
-              :page-size="pageSize"
-              :pager-count="5"
-              layout="pager"
-              background
-              size="small"
-              @current-change="onCurrentChange"
-            />
-            <el-button
-              class="justify-end mx-2!"
-              type="danger"
-              size="small"
-              text
-              bg
-              @click="onClear"
-            >
-              清空
-            </el-button>
-          </div>
-        </el-popover>
-      </template>
-    </el-input>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.icon-item {
-  &:hover {
-    color: var(--el-color-primary);
-    border-color: var(--el-color-primary);
-    transform: scaleX(1.05);
-    transition: all 0.4s;
-  }
-}
-
-:deep(.el-tabs__nav-next) {
-  font-size: 15px;
-  line-height: 32px;
-  box-shadow: -5px 0 5px -6px #ccc;
-}
-
-:deep(.el-tabs__nav-prev) {
-  font-size: 15px;
-  line-height: 32px;
-  box-shadow: 5px 0 5px -6px #ccc;
-}
-
-:deep(.el-input-group__append) {
-  padding: 0;
-}
-
-:deep(.el-tabs__item) {
-  height: 30px;
-  font-size: 12px;
-  font-weight: normal;
-  line-height: 30px;
-}
-
-:deep(.el-tabs__header),
-:deep(.el-tabs__nav-wrap) {
-  position: static;
-  margin: 0;
-  box-shadow: 0 2px 5px rgb(0 0 0 / 6%);
-}
-
-:deep(.el-tabs__nav-wrap::after) {
-  height: 0;
-}
-
-:deep(.el-tabs__nav-wrap) {
-  padding: 0 24px;
-}
-
-:deep(.el-tabs__content) {
-  margin-top: 4px;
-}
-</style>

+ 0 - 7
admin-web-new/src/components/ReImageVerify/index.ts

@@ -1,7 +0,0 @@
-import reImageVerify from "./src/index.vue";
-import { withInstall } from "@pureadmin/utils";
-
-/** 图形验证码组件 */
-export const ReImageVerify = withInstall(reImageVerify);
-
-export default ReImageVerify;

+ 0 - 85
admin-web-new/src/components/ReImageVerify/src/hooks.ts

@@ -1,85 +0,0 @@
-import { ref, onMounted } from "vue";
-
-/**
- * 绘制图形验证码
- * @param width - 图形宽度
- * @param height - 图形高度
- */
-export const useImageVerify = (width = 120, height = 40) => {
-  const domRef = ref<HTMLCanvasElement>();
-  const imgCode = ref("");
-
-  function setImgCode(code: string) {
-    imgCode.value = code;
-  }
-
-  function getImgCode() {
-    if (!domRef.value) return;
-    imgCode.value = draw(domRef.value, width, height);
-  }
-
-  onMounted(() => {
-    getImgCode();
-  });
-
-  return {
-    domRef,
-    imgCode,
-    setImgCode,
-    getImgCode
-  };
-};
-
-function randomNum(min: number, max: number) {
-  const num = Math.floor(Math.random() * (max - min) + min);
-  return num;
-}
-
-function randomColor(min: number, max: number) {
-  const r = randomNum(min, max);
-  const g = randomNum(min, max);
-  const b = randomNum(min, max);
-  return `rgb(${r},${g},${b})`;
-}
-
-function draw(dom: HTMLCanvasElement, width: number, height: number) {
-  let imgCode = "";
-
-  const NUMBER_STRING = "0123456789";
-
-  const ctx = dom.getContext("2d");
-  if (!ctx) return imgCode;
-
-  ctx.fillStyle = randomColor(180, 230);
-  ctx.fillRect(0, 0, width, height);
-  for (let i = 0; i < 4; i += 1) {
-    const text = NUMBER_STRING[randomNum(0, NUMBER_STRING.length)];
-    imgCode += text;
-    const fontSize = randomNum(18, 41);
-    const deg = randomNum(-30, 30);
-    ctx.font = `${fontSize}px Simhei`;
-    ctx.textBaseline = "top";
-    ctx.fillStyle = randomColor(80, 150);
-    ctx.save();
-    ctx.translate(30 * i + 15, 15);
-    ctx.rotate((deg * Math.PI) / 180);
-    ctx.fillText(text, -15 + 5, -15);
-    ctx.restore();
-  }
-  for (let i = 0; i < 5; i += 1) {
-    ctx.beginPath();
-    ctx.moveTo(randomNum(0, width), randomNum(0, height));
-    ctx.lineTo(randomNum(0, width), randomNum(0, height));
-    ctx.strokeStyle = randomColor(180, 230);
-    ctx.closePath();
-    ctx.stroke();
-  }
-  for (let i = 0; i < 41; i += 1) {
-    ctx.beginPath();
-    ctx.arc(randomNum(0, width), randomNum(0, height), 1, 0, 2 * Math.PI);
-    ctx.closePath();
-    ctx.fillStyle = randomColor(150, 200);
-    ctx.fill();
-  }
-  return imgCode;
-}

+ 0 - 46
admin-web-new/src/components/ReImageVerify/src/index.vue

@@ -1,46 +0,0 @@
-<script setup lang="ts">
-import { watch } from "vue";
-import { useImageVerify } from "./hooks";
-
-defineOptions({
-  name: "ReImageVerify"
-});
-
-interface Props {
-  code?: string;
-}
-
-interface Emits {
-  (e: "update:code", code: string): void;
-}
-
-const props = withDefaults(defineProps<Props>(), {
-  code: ""
-});
-
-const emit = defineEmits<Emits>();
-
-const { domRef, imgCode, setImgCode, getImgCode } = useImageVerify();
-
-watch(
-  () => props.code,
-  newValue => {
-    setImgCode(newValue);
-  }
-);
-watch(imgCode, newValue => {
-  emit("update:code", newValue);
-});
-
-defineExpose({ getImgCode });
-</script>
-
-<template>
-  <canvas
-    ref="domRef"
-    width="120"
-    height="40"
-    class="cursor-pointer"
-    @click="getImgCode"
-  />
-</template>

+ 0 - 7
admin-web-new/src/components/ReInteractiveHoverButton/index.ts

@@ -1,7 +0,0 @@
-import { withInstall } from "@pureadmin/utils";
-import reInteractiveHoverButton from "./src/index.vue";
-
-/** 悬浮交互按钮 */
-export const ReInteractiveHoverButton = withInstall(reInteractiveHoverButton);
-
-export default ReInteractiveHoverButton;

+ 0 - 38
admin-web-new/src/components/ReInteractiveHoverButton/src/index.vue

@@ -1,38 +0,0 @@
-<template>
-  <button
-    type="button"
-    :disabled="disabled || loading"
-    class="group relative w-full cursor-pointer overflow-hidden rounded-[4px] border border-[rgb(5_5_5_/_6%)] bg-[#fefefe] py-2.5 text-center font-semibold select-none disabled:opacity-60 disabled:cursor-not-allowed"
-    @click="$emit('click')"
-  >
-    <span class="inline-block transition-all duration-300 group-hover:translate-x-10 group-hover:opacity-0">
-      <slot />
-    </span>
-    <span
-      class="absolute inset-0 z-10 flex items-center justify-center gap-1.5 bg-[#C83A35] text-white opacity-0 transition-all duration-300 group-hover:opacity-100 rounded-[4px]"
-    >
-      <svg v-if="loading" class="inline-block size-4 animate-spin" viewBox="0 0 24 24" fill="none">
-        <circle cx="12" cy="12" r="10" stroke="rgb(255 255 255 / 25%)" stroke-width="3" />
-        <path d="M12 2a10 10 0 0 1 10 10" stroke="white" stroke-width="3" stroke-linecap="round" />
-      </svg>
-      <template v-else>
-        <slot />
-        <svg class="size-4 transition-transform duration-300 group-hover:translate-x-1" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
-          <path d="M5 12h14" />
-          <path d="m12 5 7 7-7 7" />
-        </svg>
-      </template>
-    </span>
-  </button>
-</template>
-
-<script setup lang="ts">
-defineProps<{
-  loading?: boolean;
-  disabled?: boolean;
-}>();
-
-defineEmits<{
-  click: [];
-}>();
-</script>

+ 0 - 7
admin-web-new/src/components/ReMap/index.ts

@@ -1,7 +0,0 @@
-import amap from "./src/Amap.vue";
-import { withInstall } from "@pureadmin/utils";
-
-/** 高德地图组件 */
-export const Amap = withInstall(amap);
-
-export default Amap;

+ 0 - 136
admin-web-new/src/components/ReMap/src/Amap.vue

@@ -1,136 +0,0 @@
-<script setup lang="ts">
-import { reactive, getCurrentInstance, onBeforeMount, onUnmounted } from "vue";
-import { deviceDetection } from "@pureadmin/utils";
-import AMapLoader from "@amap/amap-jsapi-loader";
-import { mapJson } from "@/api/mock";
-import car from "@/assets/car.png";
-
-export interface MapConfigureInter {
-  on: Fn;
-  destroy?: Fn;
-  clearEvents?: Fn;
-  addControl?: Fn;
-  setCenter?: Fn;
-  setZoom?: Fn;
-  plugin?: Fn;
-}
-
-defineOptions({
-  name: "Amap"
-});
-
-let MarkerCluster;
-let map: MapConfigureInter;
-
-const instance = getCurrentInstance();
-
-const mapSet = reactive({
-  loading: deviceDetection() ? false : true
-});
-
-// 地图创建完成(动画关闭)
-const complete = (): void => {
-  if (map) {
-    map.on("complete", () => {
-      mapSet.loading = false;
-    });
-  }
-};
-
-onBeforeMount(() => {
-  if (!instance) return;
-  const { MapConfigure } = instance.appContext.config.globalProperties.$config;
-  const { options } = MapConfigure;
-
-  AMapLoader.load({
-    key: MapConfigure.amapKey,
-    version: "2.0",
-    plugins: ["AMap.MarkerCluster"]
-  })
-    .then(AMap => {
-      // 创建地图实例
-      map = new AMap.Map(instance.refs.mapview, options);
-
-      //地图中添加地图操作ToolBar插件
-      map.plugin(["AMap.ToolBar", "AMap.MapType"], () => {
-        map.addControl(new AMap.ToolBar());
-        //地图类型切换
-        map.addControl(
-          new AMap.MapType({
-            defaultType: 0
-          })
-        );
-      });
-
-      MarkerCluster = new AMap.MarkerCluster(map, [], {
-        // 聚合网格像素大小
-        gridSize: 80,
-        maxZoom: 14,
-        renderMarker(ctx) {
-          const { marker, data } = ctx;
-          if (Array.isArray(data) && data[0]) {
-            const { driver, plateNumber, orientation } = data[0];
-            const content = `<img style="transform: scale(1) rotate(${
-              360 - Number(orientation)
-            }deg);" src='${car}' />`;
-            marker.setContent(content);
-            marker.setLabel({
-              direction: "bottom",
-              //设置文本标注偏移量
-              offset: new AMap.Pixel(-4, 0),
-              //设置文本标注内容
-              content: `<div> ${plateNumber}(${driver})</div>`
-            });
-            marker.setOffset(new AMap.Pixel(-18, -10));
-            marker.on("click", ({ lnglat }) => {
-              map.setZoom(13); //设置地图层级
-              map.setCenter(lnglat);
-            });
-          }
-        }
-      });
-
-      // 获取模拟车辆信息
-      mapJson()
-        .then(({ data }) => {
-          const points: object = data.map(v => {
-            return {
-              lnglat: [v.lng, v.lat],
-              ...v
-            };
-          });
-          if (MarkerCluster) MarkerCluster.setData(points);
-        })
-        .catch(err => {
-          console.log("err:", err);
-        });
-
-      complete();
-    })
-    .catch(() => {
-      mapSet.loading = false;
-      throw "地图加载失败,请重新加载";
-    });
-});
-
-onUnmounted(() => {
-  if (map) {
-    // 销毁地图实例
-    map.destroy() && map.clearEvents("click");
-  }
-});
-</script>
-
-<template>
-  <div id="mapview" ref="mapview" v-loading="mapSet.loading" />
-</template>
-
-<style lang="scss" scoped>
-#mapview {
-  height: calc(100vh - 86px);
-}
-
-:deep(.amap-marker-label) {
-  border: none !important;
-}
-</style>

+ 0 - 5
admin-web-new/src/components/RePureTableBar/index.ts

@@ -1,5 +0,0 @@
-import pureTableBar from "./src/bar";
-import { withInstall } from "@pureadmin/utils";
-
-/** 配合 `@pureadmin/table` 实现快速便捷的表格操作 https://github.com/pure-admin/pure-admin-table */
-export const PureTableBar = withInstall(pureTableBar);

+ 0 - 398
admin-web-new/src/components/RePureTableBar/src/bar.tsx

@@ -1,398 +0,0 @@
-import Sortable from "sortablejs";
-import { transformI18n } from "@/plugins/i18n";
-import { useEpThemeStoreHook } from "@/store/modules/epTheme";
-import {
-  type PropType,
-  ref,
-  unref,
-  computed,
-  nextTick,
-  defineComponent,
-  getCurrentInstance
-} from "vue";
-import {
-  delay,
-  cloneDeep,
-  isBoolean,
-  isFunction,
-  getKeyList
-} from "@pureadmin/utils";
-
-import Fullscreen from "~icons/ri/fullscreen-fill";
-import ExitFullscreen from "~icons/ri/fullscreen-exit-fill";
-import DragIcon from "@/assets/table-bar/drag.svg?component";
-import ExpandIcon from "@/assets/table-bar/expand.svg?component";
-import RefreshIcon from "@/assets/table-bar/refresh.svg?component";
-import SettingIcon from "@/assets/table-bar/settings.svg?component";
-import CollapseIcon from "@/assets/table-bar/collapse.svg?component";
-
-const props = {
-  /** 头部最左边的标题 */
-  title: {
-    type: String,
-    default: "列表"
-  },
-  /** 对于树形表格,如果想启用展开和折叠功能,传入当前表格的ref即可 */
-  tableRef: {
-    type: Object as PropType<any>
-  },
-  /** 需要展示的列 */
-  columns: {
-    type: Array as PropType<TableColumnList>,
-    default: () => []
-  },
-  isExpandAll: {
-    type: Boolean,
-    default: true
-  },
-  tableKey: {
-    type: [String, Number] as PropType<string | number>,
-    default: "0"
-  }
-};
-
-export default defineComponent({
-  name: "PureTableBar",
-  props,
-  emits: ["refresh", "fullscreen"],
-  setup(props, { emit, slots, attrs }) {
-    const size = ref("default");
-    const loading = ref(false);
-    const checkAll = ref(true);
-    const isFullscreen = ref(false);
-    const isIndeterminate = ref(false);
-    const instance = getCurrentInstance()!;
-    const isExpandAll = ref(props.isExpandAll);
-    const filterColumns = cloneDeep(props?.columns).filter(column =>
-      isBoolean(column?.hide)
-        ? !column.hide
-        : !(isFunction(column?.hide) && column?.hide())
-    );
-    let checkColumnList = getKeyList(cloneDeep(props?.columns), "label");
-    const checkedColumns = ref(getKeyList(cloneDeep(filterColumns), "label"));
-    const dynamicColumns = ref(cloneDeep(props?.columns));
-
-    const getDropdownItemStyle = computed(() => {
-      return s => {
-        return {
-          background:
-            s === size.value ? useEpThemeStoreHook().epThemeColor : "",
-          color: s === size.value ? "#fff" : "var(--el-text-color-primary)"
-        };
-      };
-    });
-
-    const iconClass = computed(() => {
-      return [
-        "text-black",
-        "dark:text-white",
-        "duration-100",
-        "hover:text-primary!",
-        "cursor-pointer",
-        "outline-hidden"
-      ];
-    });
-
-    const topClass = computed(() => {
-      return [
-        "flex",
-        "justify-between",
-        "pt-[3px]",
-        "px-[11px]",
-        "border-b-[1px]",
-        "border-b-solid",
-        "border-[#dcdfe6]",
-        "dark:border-[#303030]"
-      ];
-    });
-
-    function onReFresh() {
-      loading.value = true;
-      emit("refresh");
-      delay(500).then(() => (loading.value = false));
-    }
-
-    function onExpand() {
-      isExpandAll.value = !isExpandAll.value;
-      toggleRowExpansionAll(props.tableRef.data, isExpandAll.value);
-    }
-
-    function onFullscreen() {
-      isFullscreen.value = !isFullscreen.value;
-      emit("fullscreen", isFullscreen.value);
-    }
-
-    function toggleRowExpansionAll(data, isExpansion) {
-      data.forEach(item => {
-        props.tableRef.toggleRowExpansion(item, isExpansion);
-        if (item.children !== undefined && item.children !== null) {
-          toggleRowExpansionAll(item.children, isExpansion);
-        }
-      });
-    }
-
-    function handleCheckAllChange(val: boolean) {
-      checkedColumns.value = val ? checkColumnList : [];
-      isIndeterminate.value = false;
-      dynamicColumns.value.map(column =>
-        val ? (column.hide = false) : (column.hide = true)
-      );
-    }
-
-    function handleCheckedColumnsChange(value: string[]) {
-      checkedColumns.value = value;
-      const checkedCount = value.length;
-      checkAll.value = checkedCount === checkColumnList.length;
-      isIndeterminate.value =
-        checkedCount > 0 && checkedCount < checkColumnList.length;
-    }
-
-    function handleCheckColumnListChange(val: boolean, label: string) {
-      dynamicColumns.value.filter(
-        item => transformI18n(item.label) === transformI18n(label)
-      )[0].hide = !val;
-    }
-
-    async function onReset() {
-      checkAll.value = true;
-      isIndeterminate.value = false;
-      dynamicColumns.value = cloneDeep(props?.columns);
-      checkColumnList = [];
-      checkColumnList = await getKeyList(cloneDeep(props?.columns), "label");
-      checkedColumns.value = getKeyList(cloneDeep(filterColumns), "label");
-    }
-
-    const dropdown = {
-      dropdown: () => (
-        <el-dropdown-menu class="translation">
-          <el-dropdown-item
-            style={getDropdownItemStyle.value("large")}
-            onClick={() => (size.value = "large")}
-          >
-            宽松
-          </el-dropdown-item>
-          <el-dropdown-item
-            style={getDropdownItemStyle.value("default")}
-            onClick={() => (size.value = "default")}
-          >
-            默认
-          </el-dropdown-item>
-          <el-dropdown-item
-            style={getDropdownItemStyle.value("small")}
-            onClick={() => (size.value = "small")}
-          >
-            紧凑
-          </el-dropdown-item>
-        </el-dropdown-menu>
-      )
-    };
-
-    /** 列展示拖拽排序 */
-    const rowDrop = (event: { preventDefault: () => void }) => {
-      event.preventDefault();
-      nextTick(() => {
-        const wrapper: HTMLElement = (
-          instance?.proxy?.$refs[`GroupRef${unref(props.tableKey)}`] as any
-        ).$el.firstElementChild;
-        Sortable.create(wrapper, {
-          animation: 300,
-          handle: ".drag-btn",
-          onEnd: ({ newIndex, oldIndex, item }) => {
-            const targetThElem = item;
-            const wrapperElem = targetThElem.parentNode as HTMLElement;
-            const oldColumn = dynamicColumns.value[oldIndex];
-            const newColumn = dynamicColumns.value[newIndex];
-            if (oldColumn?.fixed || newColumn?.fixed) {
-              // 当前列存在fixed属性 则不可拖拽
-              const oldThElem = wrapperElem.children[oldIndex] as HTMLElement;
-              if (newIndex > oldIndex) {
-                wrapperElem.insertBefore(targetThElem, oldThElem);
-              } else {
-                wrapperElem.insertBefore(
-                  targetThElem,
-                  oldThElem ? oldThElem.nextElementSibling : oldThElem
-                );
-              }
-              return;
-            }
-            const currentRow = dynamicColumns.value.splice(oldIndex, 1)[0];
-            dynamicColumns.value.splice(newIndex, 0, currentRow);
-          }
-        });
-      });
-    };
-
-    const isFixedColumn = (label: string) => {
-      return dynamicColumns.value.filter(
-        item => transformI18n(item.label) === transformI18n(label)
-      )[0].fixed
-        ? true
-        : false;
-    };
-
-    const rendTippyProps = (content: string) => {
-      // https://vue-tippy.netlify.app/props
-      return {
-        content,
-        offset: [0, 18],
-        duration: [300, 0],
-        followCursor: true,
-        hideOnClick: "toggle"
-      };
-    };
-
-    const reference = {
-      reference: () => (
-        <SettingIcon
-          class={["w-[16px]", iconClass.value]}
-          v-tippy={rendTippyProps("列设置")}
-        />
-      )
-    };
-
-    return () => (
-      <>
-        <div
-          {...attrs}
-          class={[
-            "w-full",
-            "px-2",
-            "pb-2",
-            "bg-bg_color",
-            isFullscreen.value
-              ? ["h-full!", "z-2002", "fixed", "inset-0"]
-              : "mt-2"
-          ]}
-        >
-          <div class="flex justify-between w-full h-[60px] p-4">
-            {slots?.title ? (
-              slots.title()
-            ) : (
-              <p class="font-bold truncate">{props.title}</p>
-            )}
-            <div class="flex items-center justify-around">
-              {slots?.buttons ? (
-                <div class="flex mr-4">{slots.buttons()}</div>
-              ) : null}
-              {props.tableRef?.size ? (
-                <>
-                  <ExpandIcon
-                    class={["w-[16px]", iconClass.value]}
-                    style={{
-                      transform: isExpandAll.value ? "none" : "rotate(-90deg)"
-                    }}
-                    v-tippy={rendTippyProps(
-                      isExpandAll.value ? "折叠" : "展开"
-                    )}
-                    onClick={() => onExpand()}
-                  />
-                  <el-divider direction="vertical" />
-                </>
-              ) : null}
-              <RefreshIcon
-                class={[
-                  "w-[16px]",
-                  iconClass.value,
-                  loading.value ? "animate-spin" : ""
-                ]}
-                v-tippy={rendTippyProps("刷新")}
-                onClick={() => onReFresh()}
-              />
-              <el-divider direction="vertical" />
-              <el-dropdown
-                v-slots={dropdown}
-                trigger="click"
-                v-tippy={rendTippyProps("密度")}
-              >
-                <CollapseIcon class={["w-[16px]", iconClass.value]} />
-              </el-dropdown>
-              <el-divider direction="vertical" />
-
-              <el-popover
-                v-slots={reference}
-                placement="bottom-start"
-                popper-style={{ padding: 0 }}
-                width="200"
-                trigger="click"
-              >
-                <div class={[topClass.value]}>
-                  <el-checkbox
-                    class="-mr-1!"
-                    label="列展示"
-                    v-model={checkAll.value}
-                    indeterminate={isIndeterminate.value}
-                    onChange={value => handleCheckAllChange(value)}
-                  />
-                  <el-button type="primary" link onClick={() => onReset()}>
-                    重置
-                  </el-button>
-                </div>
-
-                <div class="pt-[6px] pl-[11px]">
-                  <el-scrollbar max-height="36vh">
-                    <el-checkbox-group
-                      ref={`GroupRef${unref(props.tableKey)}`}
-                      modelValue={checkedColumns.value}
-                      onChange={value => handleCheckedColumnsChange(value)}
-                    >
-                      <el-space
-                        direction="vertical"
-                        alignment="flex-start"
-                        size={0}
-                      >
-                        {checkColumnList.map((item, index) => {
-                          return (
-                            <div class="flex items-center">
-                              <DragIcon
-                                class={[
-                                  "drag-btn w-[16px] mr-2",
-                                  isFixedColumn(item)
-                                    ? "cursor-no-drop!"
-                                    : "cursor-grab!"
-                                ]}
-                                onMouseenter={(event: {
-                                  preventDefault: () => void;
-                                }) => rowDrop(event)}
-                              />
-                              <el-checkbox
-                                key={index}
-                                label={item}
-                                value={item}
-                                onChange={value =>
-                                  handleCheckColumnListChange(value, item)
-                                }
-                              >
-                                <span
-                                  title={transformI18n(item)}
-                                  class="inline-block w-[120px] truncate hover:text-text_color_primary"
-                                >
-                                  {transformI18n(item)}
-                                </span>
-                              </el-checkbox>
-                            </div>
-                          );
-                        })}
-                      </el-space>
-                    </el-checkbox-group>
-                  </el-scrollbar>
-                </div>
-              </el-popover>
-              <el-divider direction="vertical" />
-
-              <iconifyIconOffline
-                class={["w-[16px]", iconClass.value]}
-                icon={isFullscreen.value ? ExitFullscreen : Fullscreen}
-                v-tippy={isFullscreen.value ? "退出全屏" : "全屏"}
-                onClick={() => onFullscreen()}
-              />
-            </div>
-          </div>
-          {slots.default({
-            size: size.value,
-            dynamicColumns: dynamicColumns.value
-          })}
-        </div>
-      </>
-    );
-  }
-});

+ 0 - 7
admin-web-new/src/components/ReQrcode/index.ts

@@ -1,7 +0,0 @@
-import reQrcode from "./src/index";
-import { withInstall } from "@pureadmin/utils";
-
-/** 二维码组件 */
-export const ReQrcode = withInstall(reQrcode);
-
-export default ReQrcode;

+ 0 - 9
admin-web-new/src/components/ReQrcode/src/index.scss

@@ -1,9 +0,0 @@
-.qrcode {
-  &--disabled {
-    background: rgb(255 255 255 / 95%);
-
-    & > div {
-      transform: translate(-50%, -50%);
-    }
-  }
-}

+ 0 - 261
admin-web-new/src/components/ReQrcode/src/index.tsx

@@ -1,261 +0,0 @@
-import {
-  type PropType,
-  ref,
-  unref,
-  watch,
-  nextTick,
-  computed,
-  defineComponent
-} from "vue";
-import "./index.scss";
-import propTypes from "@/utils/propTypes";
-import { isString, cloneDeep } from "@pureadmin/utils";
-import QRCode, { type QRCodeRenderersOptions } from "qrcode";
-import RefreshRight from "~icons/ep/refresh-right";
-
-interface QrcodeLogo {
-  src?: string;
-  logoSize?: number;
-  bgColor?: string;
-  borderSize?: number;
-  crossOrigin?: string;
-  borderRadius?: number;
-  logoRadius?: number;
-}
-
-const props = {
-  // img 或者 canvas,img不支持logo嵌套
-  tag: propTypes.string
-    .validate((v: string) => ["canvas", "img"].includes(v))
-    .def("canvas"),
-  // 二维码内容
-  text: {
-    type: [String, Array] as PropType<string | Recordable[]>,
-    default: null
-  },
-  // qrcode.js配置项
-  options: {
-    type: Object as PropType<QRCodeRenderersOptions>,
-    default: (): QRCodeRenderersOptions => ({})
-  },
-  // 宽度
-  width: propTypes.number.def(200),
-  // logo
-  logo: {
-    type: [String, Object] as PropType<Partial<QrcodeLogo> | string>,
-    default: (): QrcodeLogo | string => ""
-  },
-  // 是否过期
-  disabled: propTypes.bool.def(false),
-  // 过期提示内容
-  disabledText: propTypes.string.def("")
-};
-
-export default defineComponent({
-  name: "ReQrcode",
-  props,
-  emits: ["done", "click", "disabled-click"],
-  setup(props, { emit }) {
-    const { toCanvas, toDataURL } = QRCode;
-    const loading = ref(true);
-    const wrapRef = ref<Nullable<HTMLCanvasElement | HTMLImageElement>>(null);
-    const renderText = computed(() => String(props.text));
-    const wrapStyle = computed(() => {
-      return {
-        width: props.width + "px",
-        height: props.width + "px"
-      };
-    });
-    const initQrcode = async () => {
-      await nextTick();
-      const options = cloneDeep(props.options || {});
-      if (props.tag === "canvas") {
-        // 容错率,默认对内容少的二维码采用高容错率,内容多的二维码采用低容错率
-        options.errorCorrectionLevel =
-          options.errorCorrectionLevel ||
-          getErrorCorrectionLevel(unref(renderText));
-        const _width: number = await getOriginWidth(unref(renderText), options);
-        options.scale =
-          props.width === 0 ? undefined : (props.width / _width) * 4;
-        const canvasRef: any = await toCanvas(
-          unref(wrapRef) as HTMLCanvasElement,
-          unref(renderText),
-          options
-        );
-        if (props.logo) {
-          const url = await createLogoCode(canvasRef);
-          emit("done", url);
-          loading.value = false;
-        } else {
-          emit("done", canvasRef.toDataURL());
-          loading.value = false;
-        }
-      } else {
-        const url = await toDataURL(renderText.value, {
-          errorCorrectionLevel: "H",
-          width: props.width,
-          ...options
-        });
-        (unref(wrapRef) as any).src = url;
-        emit("done", url);
-        loading.value = false;
-      }
-    };
-    watch(
-      () => renderText.value,
-      val => {
-        if (!val) return;
-        initQrcode();
-      },
-      {
-        deep: true,
-        immediate: true
-      }
-    );
-    const createLogoCode = (canvasRef: HTMLCanvasElement) => {
-      const canvasWidth = canvasRef.width;
-      const logoOptions: QrcodeLogo = Object.assign(
-        {
-          logoSize: 0.15,
-          bgColor: "#ffffff",
-          borderSize: 0.05,
-          crossOrigin: "anonymous",
-          borderRadius: 8,
-          logoRadius: 0
-        },
-        isString(props.logo) ? {} : props.logo
-      );
-      const {
-        logoSize = 0.15,
-        bgColor = "#ffffff",
-        borderSize = 0.05,
-        crossOrigin = "anonymous",
-        borderRadius = 8,
-        logoRadius = 0
-      } = logoOptions;
-      const logoSrc = isString(props.logo) ? props.logo : props.logo.src;
-      const logoWidth = canvasWidth * logoSize;
-      const logoXY = (canvasWidth * (1 - logoSize)) / 2;
-      const logoBgWidth = canvasWidth * (logoSize + borderSize);
-      const logoBgXY = (canvasWidth * (1 - logoSize - borderSize)) / 2;
-      const ctx = canvasRef.getContext("2d");
-      if (!ctx) return;
-      // logo 底色
-      canvasRoundRect(ctx)(
-        logoBgXY,
-        logoBgXY,
-        logoBgWidth,
-        logoBgWidth,
-        borderRadius
-      );
-      ctx.fillStyle = bgColor;
-      ctx.fill();
-      // logo
-      const image = new Image();
-      if (crossOrigin || logoRadius) {
-        image.setAttribute("crossOrigin", crossOrigin);
-      }
-      (image as any).src = logoSrc;
-      // 使用image绘制可以避免某些跨域情况
-      const drawLogoWithImage = (image: HTMLImageElement) => {
-        ctx.drawImage(image, logoXY, logoXY, logoWidth, logoWidth);
-      };
-      // 使用canvas绘制以获得更多的功能
-      const drawLogoWithCanvas = (image: HTMLImageElement) => {
-        const canvasImage = document.createElement("canvas");
-        canvasImage.width = logoXY + logoWidth;
-        canvasImage.height = logoXY + logoWidth;
-        const imageCanvas = canvasImage.getContext("2d");
-        if (!imageCanvas || !ctx) return;
-        imageCanvas.drawImage(image, logoXY, logoXY, logoWidth, logoWidth);
-        canvasRoundRect(ctx)(logoXY, logoXY, logoWidth, logoWidth, logoRadius);
-        if (!ctx) return;
-        const fillStyle = ctx.createPattern(canvasImage, "no-repeat");
-        if (fillStyle) {
-          ctx.fillStyle = fillStyle;
-          ctx.fill();
-        }
-      };
-      // 将 logo绘制到 canvas上
-      return new Promise((resolve: any) => {
-        image.onload = () => {
-          logoRadius ? drawLogoWithCanvas(image) : drawLogoWithImage(image);
-          resolve(canvasRef.toDataURL());
-        };
-      });
-    };
-    // 得到原QrCode的大小,以便缩放得到正确的QrCode大小
-    const getOriginWidth = async (
-      content: string,
-      options: QRCodeRenderersOptions
-    ) => {
-      const _canvas = document.createElement("canvas");
-      await toCanvas(_canvas, content, options);
-      return _canvas.width;
-    };
-    // 对于内容少的QrCode,增大容错率
-    const getErrorCorrectionLevel = (content: string) => {
-      if (content.length > 36) {
-        return "M";
-      } else if (content.length > 16) {
-        return "Q";
-      } else {
-        return "H";
-      }
-    };
-    // 用于绘制圆角
-    const canvasRoundRect = (ctx: CanvasRenderingContext2D) => {
-      return (x: number, y: number, w: number, h: number, r: number) => {
-        const minSize = Math.min(w, h);
-        if (r > minSize / 2) {
-          r = minSize / 2;
-        }
-        ctx.beginPath();
-        ctx.moveTo(x + r, y);
-        ctx.arcTo(x + w, y, x + w, y + h, r);
-        ctx.arcTo(x + w, y + h, x, y + h, r);
-        ctx.arcTo(x, y + h, x, y, r);
-        ctx.arcTo(x, y, x + w, y, r);
-        ctx.closePath();
-        return ctx;
-      };
-    };
-    const clickCode = () => {
-      emit("click");
-    };
-    const disabledClick = () => {
-      emit("disabled-click");
-    };
-    return () => (
-      <>
-        <div
-          v-loading={unref(loading)}
-          class="qrcode relative inline-block"
-          style={unref(wrapStyle)}
-        >
-          {props.tag === "canvas" ? (
-            <canvas ref={wrapRef} onClick={clickCode}></canvas>
-          ) : (
-            <img ref={wrapRef} onClick={clickCode}></img>
-          )}
-          {props.disabled && (
-            <div
-              class="qrcode--disabled absolute top-0 left-0 flex w-full h-full items-center justify-center"
-              onClick={disabledClick}
-            >
-              <div class="absolute top-[50%] left-[50%] font-bold">
-                <iconify-icon-offline
-                  class="cursor-pointer"
-                  icon={RefreshRight}
-                  width="30"
-                  color="var(--el-color-primary)"
-                />
-                <div>{props.disabledText}</div>
-              </div>
-            </div>
-          )}
-        </div>
-      </>
-    );
-  }
-});

+ 0 - 7
admin-web-new/src/components/ReSeamlessScroll/index.ts

@@ -1,7 +0,0 @@
-import reSeamlessScroll from "./src/index.vue";
-import { withInstall } from "@pureadmin/utils";
-
-/** 无缝滚动组件 */
-export const ReSeamlessScroll = withInstall(reSeamlessScroll);
-
-export default ReSeamlessScroll;

+ 0 - 538
admin-web-new/src/components/ReSeamlessScroll/src/index.vue

@@ -1,538 +0,0 @@
-<script setup lang="ts">
-import {
-  type PropType,
-  type CSSProperties,
-  ref,
-  unref,
-  nextTick,
-  computed
-} from "vue";
-import {
-  tryOnMounted,
-  tryOnUnmounted,
-  templateRef,
-  useDebounceFn
-} from "@vueuse/core";
-import * as utilsMethods from "./utils";
-const { animationFrame, copyObj } = utilsMethods;
-animationFrame();
-
-defineOptions({
-  name: "ReSeamlessScroll"
-});
-
-const props = defineProps({
-  data: {
-    type: Array as PropType<unknown>
-  },
-  classOption: {
-    type: Object as PropType<unknown>
-  }
-});
-
-const emit = defineEmits<{
-  (e: "scrollEnd"): void;
-}>();
-
-const xPos = ref<number>(0);
-const yPos = ref<number>(0);
-const delay = ref<number>(0);
-const height = ref<number>(0);
-// 外容器宽度
-const width = ref<number>(0);
-// 内容实际宽度
-const realBoxWidth = ref<number>(0);
-const realBoxHeight = ref<number>(0);
-const copyHtml = ref("");
-// single 单步滚动的定时器
-let singleWaitTime = null;
-// move动画的animationFrame定时器
-let reqFrame = null;
-let startPos = null;
-//记录touchStart时候的posY
-let startPosY = null;
-//记录touchStart时候的posX
-let startPosX = null;
-// mouseenter mouseleave 控制scrollMove()的开关
-let isHover = false;
-let ease = "ease-in";
-
-if (props.classOption["key"] === undefined) {
-  // eslint-disable-next-line vue/no-mutating-props
-  props.classOption["key"] = 0;
-}
-
-const wrap = templateRef<HTMLElement | null>(
-  `wrap${props.classOption["key"]}`,
-  null
-);
-const slotList = templateRef<HTMLElement | null>(
-  `slotList${props.classOption["key"]}`,
-  null
-);
-const realBox = templateRef<HTMLElement | null>(
-  `realBox${props.classOption["key"]}`,
-  null
-);
-
-const leftSwitchState = computed(() => {
-  return unref(xPos) < 0;
-});
-
-const rightSwitchState = computed(() => {
-  return Math.abs(unref(xPos)) < unref(realBoxWidth) - unref(width);
-});
-
-const defaultOption = computed(() => {
-  return {
-    //步长
-    step: 1,
-    //启动无缝滚动最小数据数
-    limitMoveNum: 5,
-    //是否启用鼠标hover控制
-    hoverStop: true,
-    // bottom 往下 top 往上(默认) left 向左 right 向右
-    direction: "top",
-    //开启移动端touch
-    openTouch: true,
-    //单条数据高度有值hoverStop关闭
-    singleHeight: 0,
-    //单条数据宽度有值hoverStop关闭
-    singleWidth: 0,
-    //单步停止等待时间
-    waitTime: 1000,
-    switchOffset: 30,
-    autoPlay: true,
-    navigation: false,
-    switchSingleStep: 134,
-    switchDelay: 400,
-    switchDisabledClass: "disabled",
-    // singleWidth/singleHeight 是否开启rem度量
-    isSingleRemUnit: false
-  };
-});
-
-const options = computed(() => {
-  // @ts-expect-error
-  return copyObj({}, unref(defaultOption), props.classOption);
-});
-
-const leftSwitchClass = computed(() => {
-  return unref(leftSwitchState) ? "" : unref(options).switchDisabledClass;
-});
-
-const rightSwitchClass = computed(() => {
-  return unref(rightSwitchState) ? "" : unref(options).switchDisabledClass;
-});
-
-const leftSwitch = computed((): CSSProperties => {
-  return {
-    position: "absolute",
-    margin: `${unref(height) / 2}px 0 0 -${unref(options).switchOffset}px`,
-    transform: "translate(-100%,-50%)"
-  };
-});
-
-const rightSwitch = computed((): CSSProperties => {
-  return {
-    position: "absolute",
-    margin: `${unref(height) / 2}px 0 0 ${
-      unref(width) + unref(options).switchOffset
-    }px`,
-    transform: "translateY(-50%)"
-  };
-});
-
-const isHorizontal = computed(() => {
-  return (
-    unref(options).direction !== "bottom" && unref(options).direction !== "top"
-  );
-});
-
-const float = computed((): CSSProperties => {
-  return unref(isHorizontal)
-    ? { float: "left", overflow: "hidden" }
-    : { overflow: "hidden" };
-});
-
-const pos = computed(() => {
-  return {
-    transform: `translate(${unref(xPos)}px,${unref(yPos)}px)`,
-    transition: `all ${ease} ${unref(delay)}ms`,
-    overflow: "hidden"
-  };
-});
-
-const navigation = computed(() => {
-  return unref(options).navigation;
-});
-
-const autoPlay = computed(() => {
-  if (unref(navigation)) return false;
-  return unref(options).autoPlay;
-});
-
-const scrollSwitch = computed(() => {
-  // 从 props 解构出来的 属性 不再具有响应性.
-  return (props.data as any).length >= unref(options).limitMoveNum;
-});
-
-const hoverStopSwitch = computed(() => {
-  return unref(options).hoverStop && unref(autoPlay) && unref(scrollSwitch);
-});
-
-const canTouchScroll = computed(() => {
-  return unref(options).openTouch;
-});
-
-const baseFontSize = computed(() => {
-  return unref(options).isSingleRemUnit
-    ? parseInt(window.getComputedStyle(document.documentElement, null).fontSize)
-    : 1;
-});
-
-const realSingleStopWidth = computed(() => {
-  return unref(options).singleWidth * unref(baseFontSize);
-});
-
-const realSingleStopHeight = computed(() => {
-  return unref(options).singleHeight * unref(baseFontSize);
-});
-
-const step = computed(() => {
-  let singleStep;
-  const step = unref(options).step;
-  if (unref(isHorizontal)) {
-    singleStep = unref(realSingleStopWidth);
-  } else {
-    singleStep = unref(realSingleStopHeight);
-  }
-  if (singleStep > 0 && singleStep % step > 0) {
-    throw "如果设置了单步滚动,step需是单步大小的约数,否则无法保证单步滚动结束的位置是否准确";
-  }
-  return step;
-});
-
-function reset() {
-  xPos.value = 0;
-  yPos.value = 0;
-  scrollCancle();
-  scrollInitMove();
-}
-
-function leftSwitchClick() {
-  if (!unref(leftSwitchState)) return;
-  // 小于单步距离
-  if (Math.abs(unref(xPos)) < unref(options).switchSingleStep) {
-    xPos.value = 0;
-    return;
-  }
-  xPos.value += unref(options).switchSingleStep;
-}
-
-function rightSwitchClick() {
-  if (!unref(rightSwitchState)) return;
-  // 小于单步距离
-  if (
-    unref(realBoxWidth) - unref(width) + unref(xPos) <
-    unref(options).switchSingleStep
-  ) {
-    xPos.value = unref(width) - unref(realBoxWidth);
-    return;
-  }
-  xPos.value -= unref(options).switchSingleStep;
-}
-
-function scrollCancle() {
-  cancelAnimationFrame(reqFrame || "");
-}
-
-function touchStart(e) {
-  if (!unref(canTouchScroll)) return;
-  let timer;
-  //touches数组对象获得屏幕上所有的touch,取第一个touch
-  const touch = e.targetTouches[0];
-  const { waitTime, singleHeight, singleWidth } = unref(options);
-  //取第一个touch的坐标值
-  startPos = {
-    x: touch.pageX,
-    y: touch.pageY
-  };
-  //记录touchStart时候的posY
-  startPosY = unref(yPos);
-  //记录touchStart时候的posX
-  startPosX = unref(xPos);
-  if (!!singleHeight && !!singleWidth) {
-    if (timer) clearTimeout(timer);
-    timer = setTimeout(() => {
-      scrollCancle();
-    }, waitTime + 20);
-  } else {
-    scrollCancle();
-  }
-}
-
-function touchMove(e) {
-  //当屏幕有多个touch或者页面被缩放过,就不执行move操作
-  if (
-    !unref(canTouchScroll) ||
-    e.targetTouches.length > 1 ||
-    (e.scale && e.scale !== 1)
-  )
-    return;
-  const touch = e.targetTouches[0];
-  const { direction } = unref(options);
-  const endPos = {
-    x: touch.pageX - startPos.x,
-    y: touch.pageY - startPos.y
-  };
-  //阻止触摸事件的默认行为,即阻止滚屏
-  e.preventDefault();
-  //dir,1表示纵向滑动,0为横向滑动
-  const dir = Math.abs(endPos.x) < Math.abs(endPos.y) ? 1 : 0;
-  if (
-    (dir === 1 && direction === "bottom") ||
-    (dir === 1 && direction === "top")
-  ) {
-    // 表示纵向滑动 && 运动方向为上下
-    yPos.value = startPosY + endPos.y;
-  } else if (
-    (dir === 0 && direction === "left") ||
-    (dir === 0 && direction === "right")
-  ) {
-    // 为横向滑动 && 运动方向为左右
-    xPos.value = startPosX + endPos.x;
-  }
-}
-
-function touchEnd() {
-  if (!unref(canTouchScroll)) return;
-
-  let timer: any;
-  const direction = unref(options).direction;
-  delay.value = 50;
-  if (direction === "top") {
-    if (unref(yPos) > 0) yPos.value = 0;
-  } else if (direction === "bottom") {
-    const h = (unref(realBoxHeight) / 2) * -1;
-    if (unref(yPos) < h) yPos.value = h;
-  } else if (direction === "left") {
-    if (unref(xPos) > 0) xPos.value = 0;
-  } else if (direction === "right") {
-    const w = unref(realBoxWidth) * -1;
-    if (unref(xPos) < w) xPos.value = w;
-  }
-  if (timer) clearTimeout(timer);
-  timer = setTimeout(() => {
-    delay.value = 0;
-    scrollMove();
-  }, unref(delay));
-}
-
-function enter() {
-  if (unref(hoverStopSwitch)) scrollStopMove();
-}
-
-function leave() {
-  if (unref(hoverStopSwitch)) scrollStartMove();
-}
-
-function scrollMove() {
-  // 鼠标移入时拦截scrollMove()
-  if (isHover) return;
-  //进入move立即先清除动画 防止频繁touchMove导致多动画同时进行
-  // scrollCancle();
-  reqFrame = requestAnimationFrame(function () {
-    //实际高度
-    const h = unref(realBoxHeight) / 2;
-    //宽度
-    const w = unref(realBoxWidth) / 2;
-    const { direction, waitTime } = unref(options);
-    if (direction === "top") {
-      // 上
-      if (Math.abs(unref(yPos)) >= h) {
-        emit("scrollEnd");
-        yPos.value = 0;
-      }
-      yPos.value -= step.value;
-    } else if (direction === "bottom") {
-      // 下
-      if (unref(yPos) >= 0) {
-        emit("scrollEnd");
-        yPos.value = h * -1;
-      }
-      yPos.value += step.value;
-    } else if (direction === "left") {
-      // 左
-      if (Math.abs(unref(xPos)) >= w) {
-        emit("scrollEnd");
-        xPos.value = 0;
-      }
-      xPos.value -= step.value;
-    } else if (direction === "right") {
-      // 右
-      if (unref(xPos) >= 0) {
-        emit("scrollEnd");
-        xPos.value = w * -1;
-      }
-      xPos.value += step.value;
-    }
-    if (singleWaitTime) clearTimeout(singleWaitTime);
-    if (unref(realSingleStopHeight)) {
-      //是否启动了单行暂停配置
-      if (Math.abs(unref(yPos)) % unref(realSingleStopHeight) < unref(step)) {
-        // 符合条件暂停waitTime
-        singleWaitTime = setTimeout(() => {
-          scrollMove();
-        }, waitTime);
-      } else {
-        scrollMove();
-      }
-    } else if (unref(realSingleStopWidth)) {
-      if (Math.abs(unref(xPos)) % unref(realSingleStopWidth) < unref(step)) {
-        // 符合条件暂停waitTime
-        singleWaitTime = setTimeout(() => {
-          scrollMove();
-        }, waitTime);
-      } else {
-        scrollMove();
-      }
-    } else {
-      scrollMove();
-    }
-  });
-}
-
-function scrollInitMove() {
-  nextTick(() => {
-    const { switchDelay } = unref(options);
-    //清空copy
-    copyHtml.value = "";
-    if (unref(isHorizontal)) {
-      height.value = unref(wrap).offsetHeight;
-      width.value = unref(wrap).offsetWidth;
-      let slotListWidth = unref(slotList).offsetWidth;
-      // 水平滚动设置warp width
-      if (unref(autoPlay)) {
-        // 修正offsetWidth四舍五入
-        slotListWidth = slotListWidth * 2 + 1;
-      }
-      unref(realBox).style.width = slotListWidth + "px";
-      realBoxWidth.value = slotListWidth;
-    }
-
-    if (unref(autoPlay)) {
-      ease = "ease-in";
-      delay.value = 0;
-    } else {
-      ease = "linear";
-      delay.value = switchDelay;
-      return;
-    }
-
-    // 是否可以滚动判断
-    if (unref(scrollSwitch)) {
-      let timer;
-      if (timer) clearTimeout(timer);
-      copyHtml.value = unref(slotList).innerHTML;
-      setTimeout(() => {
-        realBoxHeight.value = unref(realBox)?.offsetHeight;
-        scrollMove();
-      }, 0);
-    } else {
-      scrollCancle();
-      yPos.value = xPos.value = 0;
-    }
-  });
-}
-
-function scrollStartMove() {
-  //开启scrollMove
-  isHover = false;
-  scrollMove();
-}
-
-function scrollStopMove() {
-  //关闭scrollMove
-  isHover = true;
-  // 防止频频hover进出单步滚动,导致定时器乱掉
-  if (singleWaitTime) clearTimeout(singleWaitTime);
-  scrollCancle();
-}
-
-// 鼠标滚轮事件
-function wheel(e) {
-  if (
-    unref(options).direction === "left" ||
-    unref(options).direction === "right"
-  )
-    return;
-  useDebounceFn(() => {
-    e.deltaY > 0 ? (yPos.value -= step.value) : (yPos.value += step.value);
-  }, 50)();
-}
-
-// watchEffect(() => {
-//   const watchData = data;
-//   if (!watchData) return;
-//   nextTick(() => {
-//     reset();
-//   });
-
-//   const watchAutoPlay = unref(autoPlay);
-//   if (watchAutoPlay) {
-//     reset();
-//   } else {
-//     scrollStopMove();
-//   }
-// });
-
-tryOnMounted(() => {
-  scrollInitMove();
-});
-
-tryOnUnmounted(() => {
-  scrollCancle();
-  clearTimeout(singleWaitTime);
-});
-
-defineExpose({
-  reset
-});
-</script>
-
-<template>
-  <div :ref="'wrap' + classOption['key']">
-    <div
-      v-if="navigation"
-      :style="leftSwitch"
-      :class="leftSwitchClass"
-      @click="leftSwitchClick"
-    >
-      <slot name="left-switch" />
-    </div>
-    <div
-      v-if="navigation"
-      :style="rightSwitch"
-      :class="rightSwitchClass"
-      @click="rightSwitchClick"
-    >
-      <slot name="right-switch" />
-    </div>
-    <div
-      :ref="'realBox' + classOption['key']"
-      :style="pos"
-      @mouseenter="enter"
-      @mouseleave="leave"
-      @touchstart.passive="touchStart"
-      @touchmove.passive="touchMove"
-      @touchend="touchEnd"
-      @mousewheel.passive="wheel"
-    >
-      <div :ref="'slotList' + classOption['key']" :style="float">
-        <slot />
-      </div>
-      <div :style="float" v-html="copyHtml" />
-    </div>
-  </div>
-</template>

+ 0 - 119
admin-web-new/src/components/ReSeamlessScroll/src/utils.ts

@@ -1,119 +0,0 @@
-/**
- * @desc AnimationFrame简单兼容hack
- */
-export const animationFrame = () => {
-  window.cancelAnimationFrame = (() => {
-    return (
-      window.cancelAnimationFrame ||
-      window.webkitCancelAnimationFrame ||
-      window.mozCancelAnimationFrame ||
-      window.oCancelAnimationFrame ||
-      window.msCancelAnimationFrame ||
-      function (id) {
-        return window.clearTimeout(id);
-      }
-    );
-  })();
-  window.requestAnimationFrame = (function () {
-    return (
-      window.requestAnimationFrame ||
-      window.webkitRequestAnimationFrame ||
-      window.mozRequestAnimationFrame ||
-      window.oRequestAnimationFrame ||
-      window.msRequestAnimationFrame ||
-      function (callback) {
-        return window.setTimeout(callback, 1000 / 60);
-      }
-    );
-  })();
-};
-
-/**
- * @desc 判断数组是否相等
- * @return {Boolean}
- * @param arr1
- * @param arr2
- */
-export const arrayEqual = (arr1: Array<any>, arr2: Array<any>) => {
-  if (arr1 === arr2) return true;
-  if (arr1.length !== arr2.length) return false;
-  for (let i = 0; i < arr1.length; ++i) {
-    if (arr1[i] !== arr2[i]) return false;
-  }
-  return true;
-};
-
-/**
- * @desc 深浅合并拷贝
- */
-export function copyObj() {
-  if (!Array.isArray) {
-    // @ts-expect-error
-    Array.isArray = function (arg) {
-      return Object.prototype.toString.call(arg) === "[object Array]";
-    };
-  }
-  let name,
-    options,
-    src,
-    copy,
-    copyIsArray,
-    clone,
-    i = 1,
-    // eslint-disable-next-line prefer-rest-params
-    target = arguments[0] || {}, // 使用||运算符,排除隐式强制类型转换为false的数据类型
-    deep = false,
-    // eslint-disable-next-line prefer-const
-    len = arguments.length;
-  if (typeof target === "boolean") {
-    deep = target;
-
-    // eslint-disable-next-line prefer-rest-params
-    target = arguments[1] || {};
-    i++;
-  }
-  if (typeof target !== "object" && typeof target !== "function") {
-    target = {};
-  }
-  // 如果arguments.length === 1 或typeof arguments[0] === 'boolean',且存在arguments[1],则直接返回target对象
-  if (i === len) {
-    return target;
-  }
-  for (; i < len; i++) {
-    //所以如果源对象中数据类型为Undefined或Null那么就会跳过本次循环,接着循环下一个源对象
-
-    // eslint-disable-next-line prefer-rest-params
-    if ((options = arguments[i]) != null) {
-      // 如果遇到源对象的数据类型为Boolean, Number for in循环会被跳过,不执行for in循环// src用于判断target对象是否存在name属性
-      for (name in options) {
-        // src用于判断target对象是否存在name属性
-        src = target[name];
-        // 需要复制的属性当前源对象的name属性
-        copy = options[name];
-        // 判断copy是否是数组
-        copyIsArray = Array.isArray(copy);
-        // 如果是深复制且copy是一个对象或数组则需要递归直到copy成为一个基本数据类型为止
-        if (deep && copy && (typeof copy === "object" || copyIsArray)) {
-          if (copyIsArray) {
-            copyIsArray = false;
-            // 如果目标对象存在name属性且是一个数组
-            // 则使用目标对象的name属性,否则重新创建一个数组,用于复制
-            clone = src && Array.isArray(src) ? src : [];
-          } else {
-            // 如果目标对象存在name属性且是一个对象则使用目标对象的name属性,否则重新创建一个对象,用于复制
-            clone = src && typeof src === "object" ? src : {};
-          }
-          // 深复制,所以递归调用copyObject函数
-          // 返回值为target对象,即clone对象
-          // copy是一个源对象
-          // @ts-expect-error
-          target[name] = copyObj(deep, clone, copy);
-        } else if (copy !== undefined) {
-          // 浅复制,直接复制到target对象上
-          target[name] = copy;
-        }
-      }
-    }
-  }
-  return target;
-}

+ 0 - 7
admin-web-new/src/components/ReSelector/index.ts

@@ -1,7 +0,0 @@
-import reSelector from "./src";
-import { withInstall } from "@pureadmin/utils";
-
-/** 选择器组件 */
-export const ReSelector = withInstall(reSelector);
-
-export default ReSelector;

+ 0 - 28
admin-web-new/src/components/ReSelector/src/index.css

@@ -1,28 +0,0 @@
-.hs-rate__icon {
-  font-size: 18px;
-  transition: 0.3s;
-}
-
-.hs-item {
-  width: 30px;
-  height: 30px;
-  box-sizing: border-box;
-  line-height: 30px;
-}
-
-.hs-on {
-  background-color: var(--el-color-primary);
-  border-radius: 50%;
-}
-
-.hs-range {
-  background-color: #f2f6fc;
-}
-
-.both-left-sides {
-  border-radius: 50% 0 0 50%;
-}
-
-.both-right-sides {
-  border-radius: 0 50% 50% 0;
-}

+ 0 - 327
admin-web-new/src/components/ReSelector/src/index.tsx

@@ -1,327 +0,0 @@
-import "./index.css";
-import {
-  unref,
-  computed,
-  nextTick,
-  onBeforeMount,
-  defineComponent,
-  getCurrentInstance
-} from "vue";
-import { addClass, removeClass, toggleClass } from "@pureadmin/utils";
-
-const stayClass = "stay"; //鼠标点击
-const activeClass = "hs-on"; //鼠标移动上去
-const voidClass = "hs-off"; //鼠标移开
-const inRange = "hs-range"; //当前选中的两个元素之间的背景
-const bothLeftSides = "both-left-sides";
-const bothRightSides = "both-right-sides";
-let selectedDirection = "right"; //默认从左往右,索引变大
-
-let overList = [];
-// 存放第一个选中的元素和最后一个选中元素,只能存放这两个元素
-let selectedList = [];
-
-const props = {
-  HsKey: {
-    type: Number || String,
-    default: 0
-  },
-  disabled: {
-    type: Boolean,
-    default: false
-  },
-  value: {
-    type: Number,
-    default: 0
-  },
-  max: {
-    type: Array,
-    default() {
-      return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    }
-  },
-  // 回显数据的索引,长度必须是2
-  echo: {
-    type: Array,
-    default() {
-      return [];
-    }
-  }
-};
-
-export default defineComponent({
-  name: "ReSelector",
-  props,
-  emits: ["selectedVal"],
-  setup(props, { emit }) {
-    const instance = getCurrentInstance();
-    const currentValue = props.value;
-
-    const rateDisabled = computed(() => {
-      return props.disabled;
-    });
-
-    const classes = computed(() => {
-      const result = [];
-      let i = 0;
-      let threshold = currentValue;
-      if (currentValue !== Math.floor(currentValue)) {
-        threshold--;
-      }
-      for (; i < threshold; i++) {
-        result.push(activeClass);
-      }
-      for (; i < props.max.length; i++) {
-        result.push(voidClass);
-      }
-      return result;
-    });
-
-    // 鼠标移入
-    const setCurrentValue = index => {
-      if (props.disabled) return;
-      // 当选中一个元素后,开始添加背景色
-      if (selectedList.length === 1) {
-        if (overList.length < 1) overList.push({ index });
-
-        let firstIndex = overList[0].index;
-
-        // 往右走,索引变大
-        if (index > firstIndex) {
-          selectedDirection = "right";
-          toggleClass(
-            false,
-            bothRightSides,
-            document.querySelector(".hs-select__item" + selectedList[0].index)
-          );
-
-          while (index >= firstIndex) {
-            addClass(
-              document.querySelector(".hs-select__item" + firstIndex),
-              inRange
-            );
-            firstIndex++;
-          }
-        } else {
-          selectedDirection = "left";
-          toggleClass(
-            true,
-            bothRightSides,
-            document.querySelector(".hs-select__item" + selectedList[0].index)
-          );
-
-          while (index <= firstIndex) {
-            addClass(
-              document.querySelector(".hs-select__item" + firstIndex),
-              inRange
-            );
-            firstIndex--;
-          }
-        }
-      }
-
-      addClass(document.querySelector("." + voidClass + index), activeClass);
-    };
-
-    // 鼠标离开
-    const resetCurrentValue = index => {
-      if (props.disabled) return;
-      // 移除先检查是否选中 选中则返回false 不移除
-      const currentHsDom = document.querySelector("." + voidClass + index);
-      if (currentHsDom.className.includes(stayClass)) {
-        return false;
-      } else {
-        removeClass(currentHsDom, activeClass);
-      }
-
-      // 当选中一个元素后,开始移除背景色
-      if (selectedList.length === 1) {
-        const firstIndex = overList[0].index;
-        if (index >= firstIndex) {
-          for (let i = 0; i <= index; i++) {
-            removeClass(
-              document.querySelector(".hs-select__item" + i),
-              inRange
-            );
-          }
-        } else {
-          while (index <= firstIndex) {
-            removeClass(
-              document.querySelector(".hs-select__item" + index),
-              inRange
-            );
-            index++;
-          }
-        }
-      }
-    };
-
-    // 鼠标点击
-    const selectValue = (index, item) => {
-      if (props.disabled) return;
-      const len = selectedList.length;
-
-      if (len < 2) {
-        selectedList.push({ item, index });
-        addClass(document.querySelector("." + voidClass + index), stayClass);
-
-        addClass(
-          document.querySelector(".hs-select__item" + selectedList[0].index),
-          bothLeftSides
-        );
-
-        if (selectedList[1]) {
-          if (selectedDirection === "right") {
-            addClass(
-              document.querySelector(
-                ".hs-select__item" + selectedList[1].index
-              ),
-              bothRightSides
-            );
-          } else {
-            addClass(
-              document.querySelector(
-                ".hs-select__item" + selectedList[1].index
-              ),
-              bothLeftSides
-            );
-          }
-        }
-
-        if (len === 1) {
-          // 顺时针排序
-          if (selectedDirection === "right") {
-            emit("selectedVal", {
-              left: selectedList[0].item,
-              right: selectedList[1].item,
-              whole: selectedList
-            });
-          } else {
-            emit("selectedVal", {
-              left: selectedList[1].item,
-              right: selectedList[0].item,
-              whole: selectedList
-            });
-          }
-        }
-      } else {
-        nextTick(() => {
-          selectedList.forEach(v => {
-            removeClass(
-              document.querySelector("." + voidClass + v.index),
-              activeClass,
-              stayClass
-            );
-
-            removeClass(
-              document.querySelector(".hs-select__item" + v.index),
-              bothLeftSides,
-              bothRightSides
-            );
-          });
-
-          selectedList = [];
-          overList = [];
-          for (let i = 0; i <= props.max.length; i++) {
-            const currentDom = document.querySelector(".hs-select__item" + i);
-            if (currentDom) {
-              removeClass(currentDom, inRange);
-            }
-          }
-
-          selectedList.push({ item, index });
-          addClass(document.querySelector("." + voidClass + index), stayClass);
-
-          addClass(
-            document.querySelector(".hs-select__item" + selectedList[0].index),
-            bothLeftSides
-          );
-        });
-      }
-    };
-
-    // 回显数据
-    const echoView = item => {
-      if (item.length === 0) return;
-
-      if (item.length > 2 || item.length === 1) {
-        throw "传入的数组长度必须是2";
-      }
-
-      item.sort((a, b) => {
-        return a - b;
-      });
-
-      addClass(
-        instance.refs["hsdiv" + props.HsKey + item[0]] as Element,
-        activeClass,
-        stayClass
-      );
-
-      addClass(
-        instance.refs["hstd" + props.HsKey + item[0]] as Element,
-        bothLeftSides
-      );
-
-      addClass(
-        instance.refs["hsdiv" + props.HsKey + item[1]] as Element,
-        activeClass,
-        stayClass
-      );
-
-      addClass(
-        instance.refs["hstd" + props.HsKey + item[1]] as Element,
-        bothRightSides
-      );
-
-      while (item[1] >= item[0]) {
-        addClass(
-          instance.refs["hstd" + props.HsKey + item[0]] as Element,
-          inRange
-        );
-        item[0]++;
-      }
-    };
-
-    onBeforeMount(() => {
-      nextTick(() => {
-        echoView(props.echo);
-      });
-    });
-
-    return () => (
-      <>
-        <table cellspacing="0" cellpadding="0">
-          <tbody>
-            <tr>
-              {props.max.map((item, key) => {
-                return (
-                  <td
-                    data-index={props.HsKey}
-                    ref={`hstd${props.HsKey}${key}`}
-                    class={`hs-select__item${key}`}
-                    onMousemove={() => setCurrentValue(key)}
-                    onMouseleave={() => resetCurrentValue(key)}
-                    onClick={() => selectValue(key, item)}
-                    style={{
-                      cursor: unref(rateDisabled) ? "auto" : "pointer",
-                      textAlign: "center"
-                    }}
-                    key={key}
-                  >
-                    <div
-                      ref={`hsdiv${props.HsKey}${key}`}
-                      class={`hs-item ${[unref(classes)[key] + key]}`}
-                    >
-                      <span>{item}</span>
-                    </div>
-                  </td>
-                );
-              })}
-            </tr>
-          </tbody>
-        </table>
-      </>
-    );
-  }
-});

+ 0 - 23
admin-web-new/src/components/ReSplitPane/iconfont/iconfont.css

@@ -1,23 +0,0 @@
-@font-face {
-  font-family: "iconfont"; /* Project id 3268330 */
-  src:
-    url("iconfont.woff2?t=1647939915215") format("woff2"),
-    url("iconfont.woff?t=1647939915215") format("woff"),
-    url("iconfont.ttf?t=1647939915215") format("truetype");
-}
-
-.iconfont {
-  font-family: "iconfont" !important;
-  font-size: 16px;
-  font-style: normal;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-}
-
-.icon-tuozhuai1:before {
-  content: "\e647";
-}
-
-.icon-tuozhuai1-copy:before {
-  content: "\eda3";
-}

+ 0 - 66
admin-web-new/src/components/ReSplitPane/iconfont/iconfont.js

@@ -1,66 +0,0 @@
-!(function (e) {
-  var t,
-    n,
-    c,
-    o,
-    s,
-    i =
-      '<svg><symbol id="icon-tuozhuai1" viewBox="0 0 1024 1024"><path d="M576 896c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z m-256 0c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z m256-192c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z m-256 0c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z m256-192c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z m-256 0c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z m256-192c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z m-256 0c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z m256-192c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z m-256 0c0-35.2 28.8-64 64-64s64 28.8 64 64-28.8 64-64 64-64-28.8-64-64z" fill="#2c2c2c" ></path></symbol><symbol id="icon-tuozhuai1-copy" viewBox="0 0 1024 1024"><path d="M128 576c35.2 0 64 28.8 64 64s-28.8 64-64 64-64-28.8-64-64 28.8-64 64-64z m0-256c35.2 0 64 28.8 64 64s-28.8 64-64 64-64-28.8-64-64 28.8-64 64-64z m192 256c35.2 0 64 28.8 64 64s-28.8 64-64 64-64-28.8-64-64 28.8-64 64-64z m0-256c35.2 0 64 28.8 64 64s-28.8 64-64 64-64-28.8-64-64 28.8-64 64-64z m192 256.00000001c35.2 0 64 28.8 64 63.99999999s-28.8 64-64 64-64-28.8-64-64 28.8-64 64-63.99999999z m0-256.00000001c35.2 0 64 28.8 64 64s-28.8 64-64 63.99999999-64-28.8-64-63.99999999 28.8-64 64-64z m192 256c35.2 0 64 28.8 64 64s-28.8 64-64 64-64-28.8-64-64 28.8-64 64-64z m0-256c35.2 0 64 28.8 64 64s-28.8 64-64 64-64-28.8-64-64 28.8-64 64-64z m192 256c35.2 0 64 28.8 64 64s-28.8 64-64 64-64-28.8-64-64 28.8-64 64-64z m0-256c35.2 0 64 28.8 64 64s-28.8 64-64 64-64-28.8-64-64 28.8-64 64-64z" fill="#2c2c2c" ></path></symbol></svg>',
-    d = (d = document.getElementsByTagName("script"))[
-      d.length - 1
-    ].getAttribute("data-injectcss"),
-    m = function (e, t) {
-      t.parentNode.insertBefore(e, t);
-    };
-  if (d && !e.__iconfont__svg__cssinject__) {
-    e.__iconfont__svg__cssinject__ = !0;
-    try {
-      document.write(
-        "<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>"
-      );
-    } catch (e) {
-      console && console.log(e);
-    }
-  }
-  function l() {
-    s || ((s = !0), c());
-  }
-  function a() {
-    try {
-      o.documentElement.doScroll("left");
-    } catch (e) {
-      return void setTimeout(a, 50);
-    }
-    l();
-  }
-  ((t = function () {
-    var e,
-      t = document.createElement("div");
-    ((t.innerHTML = i),
-      (i = null),
-      (t = t.getElementsByTagName("svg")[0]) &&
-        ((t.style.position = "absolute"),
-        (t.style.width = 0),
-        (t.style.height = 0),
-        (t.style.overflow = "hidden"),
-        (t = t),
-        (e = document.body).firstChild
-          ? m(t, e.firstChild)
-          : e.appendChild(t)));
-  }),
-    document.addEventListener
-      ? ~["complete", "loaded", "interactive"].indexOf(document.readyState)
-        ? setTimeout(t, 0)
-        : ((n = function () {
-            (document.removeEventListener("DOMContentLoaded", n, !1), t());
-          }),
-          document.addEventListener("DOMContentLoaded", n, !1))
-      : document.attachEvent &&
-        ((c = t),
-        (o = e.document),
-        (s = !1),
-        a(),
-        (o.onreadystatechange = function () {
-          "complete" == o.readyState && ((o.onreadystatechange = null), l());
-        })));
-})(window);

+ 0 - 23
admin-web-new/src/components/ReSplitPane/iconfont/iconfont.json

@@ -1,23 +0,0 @@
-{
-  "id": "3268330",
-  "name": "split",
-  "font_family": "iconfont",
-  "css_prefix_text": "icon-",
-  "description": "",
-  "glyphs": [
-    {
-      "icon_id": "22378774",
-      "name": "拖拽",
-      "font_class": "tuozhuai1",
-      "unicode": "e647",
-      "unicode_decimal": 58951
-    },
-    {
-      "icon_id": "23570521",
-      "name": "拖拽",
-      "font_class": "tuozhuai1-copy",
-      "unicode": "eda3",
-      "unicode_decimal": 60835
-    }
-  ]
-}

BIN
admin-web-new/src/components/ReSplitPane/iconfont/iconfont.ttf


BIN
admin-web-new/src/components/ReSplitPane/iconfont/iconfont.woff


BIN
admin-web-new/src/components/ReSplitPane/iconfont/iconfont.woff2


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff