Merge branch 'main' of github.com:pure-admin/vue-pure-admin into gitee
@ -15,10 +15,13 @@ const include = [
 | 
			
		||||
  "intro.js",
 | 
			
		||||
  "vue-i18n",
 | 
			
		||||
  "js-cookie",
 | 
			
		||||
  "vue-tippy",
 | 
			
		||||
  "cropperjs",
 | 
			
		||||
  "jsbarcode",
 | 
			
		||||
  "pinyin-pro",
 | 
			
		||||
  "sortablejs",
 | 
			
		||||
  "swiper/vue",
 | 
			
		||||
  "mint-filter",
 | 
			
		||||
  "md-editor-v3",
 | 
			
		||||
  "@vueuse/core",
 | 
			
		||||
  "vue3-danmaku",
 | 
			
		||||
 | 
			
		||||
@ -68,7 +68,7 @@ menus:
 | 
			
		||||
  hsguide: Guide
 | 
			
		||||
  hsAble: Able
 | 
			
		||||
  hsMenuTree: Menu Tree
 | 
			
		||||
  hsOptimize: Debounce、Throttle、Copy Directives
 | 
			
		||||
  hsOptimize: Debounce、Throttle、Copy、Longpress Directives
 | 
			
		||||
  hsWatermark: Water Mark
 | 
			
		||||
  hsPrint: Print
 | 
			
		||||
  hsDownload: Download
 | 
			
		||||
 | 
			
		||||
@ -68,7 +68,7 @@ menus:
 | 
			
		||||
  hsguide: 引导页
 | 
			
		||||
  hsAble: 功能
 | 
			
		||||
  hsMenuTree: 菜单树结构
 | 
			
		||||
  hsOptimize: 防抖、截流、复制指令
 | 
			
		||||
  hsOptimize: 防抖、截流、复制、长按指令
 | 
			
		||||
  hsWatermark: 水印
 | 
			
		||||
  hsPrint: 打印
 | 
			
		||||
  hsDownload: 下载
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								package.json
									
									
									
									
									
								
							
							
						
						@ -72,7 +72,8 @@
 | 
			
		||||
    "vue-json-pretty": "^2.2.4",
 | 
			
		||||
    "vue-pdf-embed": "^1.1.6",
 | 
			
		||||
    "vue-router": "^4.2.2",
 | 
			
		||||
    "vue-types": "^5.0.4",
 | 
			
		||||
    "vue-tippy": "^6.2.0",
 | 
			
		||||
    "vue-types": "^5.1.0",
 | 
			
		||||
    "vue-virtual-scroller": "2.0.0-beta.7",
 | 
			
		||||
    "vue-waterfall-plugin-next": "^2.2.1",
 | 
			
		||||
    "vue3-danmaku": "^1.4.0",
 | 
			
		||||
@ -81,8 +82,8 @@
 | 
			
		||||
    "xlsx": "^0.18.5"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@commitlint/cli": "^17.6.5",
 | 
			
		||||
    "@commitlint/config-conventional": "^17.6.5",
 | 
			
		||||
    "@commitlint/cli": "^17.6.6",
 | 
			
		||||
    "@commitlint/config-conventional": "^17.6.6",
 | 
			
		||||
    "@iconify-icons/ep": "^1.2.12",
 | 
			
		||||
    "@iconify-icons/ri": "^1.2.9",
 | 
			
		||||
    "@iconify/vue": "^4.1.1",
 | 
			
		||||
@ -107,7 +108,7 @@
 | 
			
		||||
    "cssnano": "^6.0.1",
 | 
			
		||||
    "eslint": "^8.43.0",
 | 
			
		||||
    "eslint-plugin-prettier": "^4.2.1",
 | 
			
		||||
    "eslint-plugin-vue": "^9.15.0",
 | 
			
		||||
    "eslint-plugin-vue": "^9.15.1",
 | 
			
		||||
    "husky": "^8.0.3",
 | 
			
		||||
    "lint-staged": "^13.2.2",
 | 
			
		||||
    "picocolors": "^1.0.0",
 | 
			
		||||
@ -119,9 +120,9 @@
 | 
			
		||||
    "pretty-quick": "^3.1.3",
 | 
			
		||||
    "rimraf": "^5.0.1",
 | 
			
		||||
    "rollup-plugin-visualizer": "^5.9.2",
 | 
			
		||||
    "sass": "^1.63.5",
 | 
			
		||||
    "sass": "^1.63.6",
 | 
			
		||||
    "sass-loader": "^13.3.2",
 | 
			
		||||
    "stylelint": "^15.8.0",
 | 
			
		||||
    "stylelint": "^15.9.0",
 | 
			
		||||
    "stylelint-config-html": "^1.1.0",
 | 
			
		||||
    "stylelint-config-recess-order": "^4.2.0",
 | 
			
		||||
    "stylelint-config-recommended": "^12.0.0",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										298
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						@ -2,8 +2,8 @@ lockfileVersion: 5.4
 | 
			
		||||
 | 
			
		||||
specifiers:
 | 
			
		||||
  "@amap/amap-jsapi-loader": ^1.0.1
 | 
			
		||||
  "@commitlint/cli": ^17.6.5
 | 
			
		||||
  "@commitlint/config-conventional": ^17.6.5
 | 
			
		||||
  "@commitlint/cli": ^17.6.6
 | 
			
		||||
  "@commitlint/config-conventional": ^17.6.6
 | 
			
		||||
  "@howdyjs/mouse-menu": ^2.0.7
 | 
			
		||||
  "@iconify-icons/ep": ^1.2.12
 | 
			
		||||
  "@iconify-icons/ri": ^1.2.9
 | 
			
		||||
@ -46,7 +46,7 @@ specifiers:
 | 
			
		||||
  element-plus: ^2.3.7
 | 
			
		||||
  eslint: ^8.43.0
 | 
			
		||||
  eslint-plugin-prettier: ^4.2.1
 | 
			
		||||
  eslint-plugin-vue: ^9.15.0
 | 
			
		||||
  eslint-plugin-vue: ^9.15.1
 | 
			
		||||
  husky: ^8.0.3
 | 
			
		||||
  intro.js: ^7.0.1
 | 
			
		||||
  js-cookie: ^3.0.5
 | 
			
		||||
@ -72,10 +72,10 @@ specifiers:
 | 
			
		||||
  responsive-storage: ^2.2.0
 | 
			
		||||
  rimraf: ^5.0.1
 | 
			
		||||
  rollup-plugin-visualizer: ^5.9.2
 | 
			
		||||
  sass: ^1.63.5
 | 
			
		||||
  sass: ^1.63.6
 | 
			
		||||
  sass-loader: ^13.3.2
 | 
			
		||||
  sortablejs: ^1.15.0
 | 
			
		||||
  stylelint: ^15.8.0
 | 
			
		||||
  stylelint: ^15.9.0
 | 
			
		||||
  stylelint-config-html: ^1.1.0
 | 
			
		||||
  stylelint-config-recess-order: ^4.2.0
 | 
			
		||||
  stylelint-config-recommended: ^12.0.0
 | 
			
		||||
@ -107,8 +107,9 @@ specifiers:
 | 
			
		||||
  vue-json-pretty: ^2.2.4
 | 
			
		||||
  vue-pdf-embed: ^1.1.6
 | 
			
		||||
  vue-router: ^4.2.2
 | 
			
		||||
  vue-tippy: ^6.2.0
 | 
			
		||||
  vue-tsc: ^1.8.1
 | 
			
		||||
  vue-types: ^5.0.4
 | 
			
		||||
  vue-types: ^5.1.0
 | 
			
		||||
  vue-virtual-scroller: 2.0.0-beta.7
 | 
			
		||||
  vue-waterfall-plugin-next: ^2.2.1
 | 
			
		||||
  vue3-danmaku: ^1.4.0
 | 
			
		||||
@ -161,7 +162,8 @@ dependencies:
 | 
			
		||||
  vue-json-pretty: 2.2.4_vue@3.3.4
 | 
			
		||||
  vue-pdf-embed: 1.1.6_vue@3.3.4
 | 
			
		||||
  vue-router: 4.2.2_vue@3.3.4
 | 
			
		||||
  vue-types: 5.0.4_vue@3.3.4
 | 
			
		||||
  vue-tippy: 6.2.0_vue@3.3.4
 | 
			
		||||
  vue-types: 5.1.0_vue@3.3.4
 | 
			
		||||
  vue-virtual-scroller: 2.0.0-beta.7_vue@3.3.4
 | 
			
		||||
  vue-waterfall-plugin-next: 2.2.1_vue@3.3.4
 | 
			
		||||
  vue3-danmaku: 1.4.0_vue@3.3.4
 | 
			
		||||
@ -170,8 +172,8 @@ dependencies:
 | 
			
		||||
  xlsx: 0.18.5
 | 
			
		||||
 | 
			
		||||
devDependencies:
 | 
			
		||||
  "@commitlint/cli": 17.6.5
 | 
			
		||||
  "@commitlint/config-conventional": 17.6.5
 | 
			
		||||
  "@commitlint/cli": 17.6.6
 | 
			
		||||
  "@commitlint/config-conventional": 17.6.6
 | 
			
		||||
  "@iconify-icons/ep": 1.2.12
 | 
			
		||||
  "@iconify-icons/ri": 1.2.9
 | 
			
		||||
  "@iconify/vue": 4.1.1_vue@3.3.4
 | 
			
		||||
@ -190,13 +192,13 @@ devDependencies:
 | 
			
		||||
  "@vitejs/plugin-vue": 4.2.3_vite@4.3.9+vue@3.3.4
 | 
			
		||||
  "@vitejs/plugin-vue-jsx": 3.0.1_vite@4.3.9+vue@3.3.4
 | 
			
		||||
  "@vue/eslint-config-prettier": 7.1.0_bxz4zaiplh63a3nbhxngrogoky
 | 
			
		||||
  "@vue/eslint-config-typescript": 11.0.3_xatovp6glrmk2fdmmi35pvc4ke
 | 
			
		||||
  "@vue/eslint-config-typescript": 11.0.3_5wcsfo7r24w3giceba2tzy7tfq
 | 
			
		||||
  autoprefixer: 10.4.14_postcss@8.4.24
 | 
			
		||||
  cloc: 2.11.0
 | 
			
		||||
  cssnano: 6.0.1_postcss@8.4.24
 | 
			
		||||
  eslint: 8.43.0
 | 
			
		||||
  eslint-plugin-prettier: 4.2.1_bxz4zaiplh63a3nbhxngrogoky
 | 
			
		||||
  eslint-plugin-vue: 9.15.0_eslint@8.43.0
 | 
			
		||||
  eslint-plugin-vue: 9.15.1_eslint@8.43.0
 | 
			
		||||
  husky: 8.0.3
 | 
			
		||||
  lint-staged: 13.2.2
 | 
			
		||||
  picocolors: 1.0.0
 | 
			
		||||
@ -208,24 +210,24 @@ devDependencies:
 | 
			
		||||
  pretty-quick: 3.1.3_prettier@2.8.8
 | 
			
		||||
  rimraf: 5.0.1
 | 
			
		||||
  rollup-plugin-visualizer: 5.9.2
 | 
			
		||||
  sass: 1.63.5
 | 
			
		||||
  sass-loader: 13.3.2_sass@1.63.5
 | 
			
		||||
  stylelint: 15.8.0
 | 
			
		||||
  stylelint-config-html: 1.1.0_mvog3pcismoqiofxpbzhc46kxq
 | 
			
		||||
  stylelint-config-recess-order: 4.2.0_stylelint@15.8.0
 | 
			
		||||
  stylelint-config-recommended: 12.0.0_stylelint@15.8.0
 | 
			
		||||
  stylelint-config-recommended-scss: 12.0.0_kljeyyq7v4k44dzugcnpkrggwa
 | 
			
		||||
  stylelint-config-recommended-vue: 1.4.0_mvog3pcismoqiofxpbzhc46kxq
 | 
			
		||||
  stylelint-config-standard: 33.0.0_stylelint@15.8.0
 | 
			
		||||
  stylelint-config-standard-scss: 9.0.0_kljeyyq7v4k44dzugcnpkrggwa
 | 
			
		||||
  stylelint-order: 6.0.3_stylelint@15.8.0
 | 
			
		||||
  stylelint-prettier: 3.0.0_l3rlt3ch3sxnybjesonr3v7dca
 | 
			
		||||
  stylelint-scss: 5.0.1_stylelint@15.8.0
 | 
			
		||||
  sass: 1.63.6
 | 
			
		||||
  sass-loader: 13.3.2_sass@1.63.6
 | 
			
		||||
  stylelint: 15.9.0
 | 
			
		||||
  stylelint-config-html: 1.1.0_43a2gdw3tlladwfsutfch6434a
 | 
			
		||||
  stylelint-config-recess-order: 4.2.0_stylelint@15.9.0
 | 
			
		||||
  stylelint-config-recommended: 12.0.0_stylelint@15.9.0
 | 
			
		||||
  stylelint-config-recommended-scss: 12.0.0_kg6gx255czvkalpavedathyz5a
 | 
			
		||||
  stylelint-config-recommended-vue: 1.4.0_43a2gdw3tlladwfsutfch6434a
 | 
			
		||||
  stylelint-config-standard: 33.0.0_stylelint@15.9.0
 | 
			
		||||
  stylelint-config-standard-scss: 9.0.0_kg6gx255czvkalpavedathyz5a
 | 
			
		||||
  stylelint-order: 6.0.3_stylelint@15.9.0
 | 
			
		||||
  stylelint-prettier: 3.0.0_di75xrvcz6maarrq4xt2dhjdje
 | 
			
		||||
  stylelint-scss: 5.0.1_stylelint@15.9.0
 | 
			
		||||
  svgo: 3.0.2
 | 
			
		||||
  tailwindcss: 3.3.2
 | 
			
		||||
  terser: 5.18.1
 | 
			
		||||
  typescript: 5.0.4
 | 
			
		||||
  vite: 4.3.9_pkrcaghuhlfdigptyvdajp2oau
 | 
			
		||||
  vite: 4.3.9_l6lbxg3wmltw2cpo2xi56qo4mi
 | 
			
		||||
  vite-plugin-cdn-import: 0.3.5
 | 
			
		||||
  vite-plugin-compression: 0.5.1_vite@4.3.9
 | 
			
		||||
  vite-plugin-mock: 2.9.6_mockjs@1.1.0+vite@4.3.9
 | 
			
		||||
@ -798,16 +800,16 @@ packages:
 | 
			
		||||
      }
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /@commitlint/cli/17.6.5:
 | 
			
		||||
  /@commitlint/cli/17.6.6:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-3PQrWr/uo6lzF5k7n5QuosCYnzaxP9qGBp3jhWP0Vmsa7XA6wrl9ccPqfQyXpSbQE3zBROVO3TDqgPKe4tfmLQ==
 | 
			
		||||
        integrity: sha512-sTKpr2i/Fjs9OmhU+beBxjPavpnLSqZaO6CzwKVq2Tc4UYVTMFgpKOslDhUBVlfAUBfjVO8ParxC/MXkIOevEA==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=v14" }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
    dependencies:
 | 
			
		||||
      "@commitlint/format": 17.4.4
 | 
			
		||||
      "@commitlint/lint": 17.6.5
 | 
			
		||||
      "@commitlint/lint": 17.6.6
 | 
			
		||||
      "@commitlint/load": 17.5.0
 | 
			
		||||
      "@commitlint/read": 17.5.1
 | 
			
		||||
      "@commitlint/types": 17.4.4
 | 
			
		||||
@ -821,10 +823,10 @@ packages:
 | 
			
		||||
      - "@swc/wasm"
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /@commitlint/config-conventional/17.6.5:
 | 
			
		||||
  /@commitlint/config-conventional/17.6.6:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-Xl9H9KLl86NZm5CYNTNF9dcz1xelE/EbvhWIWcYxG/rn3UWYWdWmmnX2q6ZduNdLFSGbOxzUpIx61j5zxbeXxg==
 | 
			
		||||
        integrity: sha512-phqPz3BDhfj49FUYuuZIuDiw+7T6gNAEy7Yew1IBHqSohVUCWOK2FXMSAExzS2/9X+ET93g0Uz83KjiHDOOFag==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=v14" }
 | 
			
		||||
    dependencies:
 | 
			
		||||
@ -876,25 +878,25 @@ packages:
 | 
			
		||||
      chalk: 4.1.2
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /@commitlint/is-ignored/17.6.5:
 | 
			
		||||
  /@commitlint/is-ignored/17.6.6:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-CQvAPt9gX7cuUbMrIaIMKczfWJqqr6m8IlJs0F2zYwyyMTQ87QMHIj5jJ5HhOaOkaj6dvTMVGx8Dd1I4xgUuoQ==
 | 
			
		||||
        integrity: sha512-4Fw875faAKO+2nILC04yW/2Vy/wlV3BOYCSQ4CEFzriPEprc1Td2LILmqmft6PDEK5Sr14dT9tEzeaZj0V56Gg==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=v14" }
 | 
			
		||||
    dependencies:
 | 
			
		||||
      "@commitlint/types": 17.4.4
 | 
			
		||||
      semver: 7.5.0
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /@commitlint/lint/17.6.5:
 | 
			
		||||
  /@commitlint/lint/17.6.6:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-BSJMwkE4LWXrOsiP9KoHG+/heSDfvOL/Nd16+ojTS/DX8HZr8dNl8l3TfVr/d/9maWD8fSegRGtBtsyGuugFrw==
 | 
			
		||||
        integrity: sha512-5bN+dnHcRLkTvwCHYMS7Xpbr+9uNi0Kq5NR3v4+oPNx6pYXt8ACuw9luhM/yMgHYwW0ajIR20wkPAFkZLEMGmg==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=v14" }
 | 
			
		||||
    dependencies:
 | 
			
		||||
      "@commitlint/is-ignored": 17.6.5
 | 
			
		||||
      "@commitlint/is-ignored": 17.6.6
 | 
			
		||||
      "@commitlint/parse": 17.6.5
 | 
			
		||||
      "@commitlint/rules": 17.6.5
 | 
			
		||||
      "@commitlint/types": 17.4.4
 | 
			
		||||
@ -2023,15 +2025,15 @@ packages:
 | 
			
		||||
      "@nodelib/fs.scandir": 2.1.5
 | 
			
		||||
      fastq: 1.15.0
 | 
			
		||||
 | 
			
		||||
  /@nuxt/kit/3.5.3:
 | 
			
		||||
  /@nuxt/kit/3.6.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-QzoOGqa1zjKQfg7Y50TrrFAL9DhtIpYYs10gihcM1ISPrn9ROht+VEjqsaMvT+L8JuQbNf8wDYl8qzsdWGU29Q==
 | 
			
		||||
        integrity: sha512-rqQYyWlhE42oWRQNR58KU1JYhoWryN78x8eYzFTHgalfpMjtPqZv2j9K4+hFRk0XLRUKnut4tE/3+UYyZ7ybVw==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ^14.18.0 || >=16.10.0 }
 | 
			
		||||
    requiresBuild: true
 | 
			
		||||
    dependencies:
 | 
			
		||||
      "@nuxt/schema": 3.5.3
 | 
			
		||||
      "@nuxt/schema": 3.6.0
 | 
			
		||||
      c12: 1.4.2
 | 
			
		||||
      consola: 3.1.0
 | 
			
		||||
      defu: 6.1.2
 | 
			
		||||
@ -2044,7 +2046,7 @@ packages:
 | 
			
		||||
      pathe: 1.1.1
 | 
			
		||||
      pkg-types: 1.0.3
 | 
			
		||||
      scule: 1.0.0
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
      unctx: 2.3.1
 | 
			
		||||
      unimport: 3.0.8
 | 
			
		||||
      untyped: 1.3.2
 | 
			
		||||
@ -2054,10 +2056,10 @@ packages:
 | 
			
		||||
    dev: false
 | 
			
		||||
    optional: true
 | 
			
		||||
 | 
			
		||||
  /@nuxt/schema/3.5.3:
 | 
			
		||||
  /@nuxt/schema/3.6.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-Tnon4mYfJZmsCtx4NZ9A+qjwo4DcZ6tERpEhYBY81PX7AiJ+hFPBFR1qR32Tff66/qJjZg5UXj6H9AdzwEYr2w==
 | 
			
		||||
        integrity: sha512-6/nq+W77JODDfhMBZTi7HCD3hT5oHegsasAzUnDmvwWuY1io7BXX9x2mDhL8E3LhVzQuN5vhi3GBgwHwCfdKEA==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ^14.18.0 || >=16.10.0 }
 | 
			
		||||
    dependencies:
 | 
			
		||||
@ -2086,6 +2088,13 @@ packages:
 | 
			
		||||
    dev: true
 | 
			
		||||
    optional: true
 | 
			
		||||
 | 
			
		||||
  /@popperjs/core/2.11.8:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
 | 
			
		||||
      }
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /@pureadmin/descriptions/1.1.1_element-plus@2.3.7:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
@ -2567,7 +2576,7 @@ packages:
 | 
			
		||||
      grapheme-splitter: 1.0.4
 | 
			
		||||
      ignore: 5.2.4
 | 
			
		||||
      natural-compare-lite: 1.4.0
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
      tsutils: 3.21.0_typescript@5.0.4
 | 
			
		||||
      typescript: 5.0.4
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
@ -2656,7 +2665,7 @@ packages:
 | 
			
		||||
      debug: 4.3.4
 | 
			
		||||
      globby: 11.1.0
 | 
			
		||||
      is-glob: 4.0.3
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
      tsutils: 3.21.0_typescript@5.0.4
 | 
			
		||||
      typescript: 5.0.4
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
@ -2680,7 +2689,7 @@ packages:
 | 
			
		||||
      "@typescript-eslint/typescript-estree": 5.60.0_typescript@5.0.4
 | 
			
		||||
      eslint: 8.43.0
 | 
			
		||||
      eslint-scope: 5.1.1
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - supports-color
 | 
			
		||||
      - typescript
 | 
			
		||||
@ -2765,8 +2774,8 @@ packages:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      "@babel/core": 7.22.5
 | 
			
		||||
      "@babel/plugin-transform-typescript": 7.22.5_@babel+core@7.22.5
 | 
			
		||||
      "@vue/babel-plugin-jsx": 1.1.1_@babel+core@7.22.5
 | 
			
		||||
      vite: 4.3.9_pkrcaghuhlfdigptyvdajp2oau
 | 
			
		||||
      "@vue/babel-plugin-jsx": 1.1.3_@babel+core@7.22.5
 | 
			
		||||
      vite: 4.3.9_l6lbxg3wmltw2cpo2xi56qo4mi
 | 
			
		||||
      vue: 3.3.4
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - supports-color
 | 
			
		||||
@ -2782,7 +2791,7 @@ packages:
 | 
			
		||||
      vite: ^4.0.0
 | 
			
		||||
      vue: ^3.2.25
 | 
			
		||||
    dependencies:
 | 
			
		||||
      vite: 4.3.9_pkrcaghuhlfdigptyvdajp2oau
 | 
			
		||||
      vite: 4.3.9_l6lbxg3wmltw2cpo2xi56qo4mi
 | 
			
		||||
      vue: 3.3.4
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
@ -2813,30 +2822,32 @@ packages:
 | 
			
		||||
      "@volar/language-core": 1.7.8
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /@vue/babel-helper-vue-transform-on/1.0.2:
 | 
			
		||||
  /@vue/babel-helper-vue-transform-on/1.1.3:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==
 | 
			
		||||
        integrity: sha512-iSaE7+1+/tPp79XnvsAVjaCjuY7dHjfsArPozi+1USJ1A5lf5JUovCP90Hbc+L9BUSHGlXMEYuQrL2vS3Yz9ow==
 | 
			
		||||
      }
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /@vue/babel-plugin-jsx/1.1.1_@babel+core@7.22.5:
 | 
			
		||||
  /@vue/babel-plugin-jsx/1.1.3_@babel+core@7.22.5:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==
 | 
			
		||||
        integrity: sha512-q4ekWt6KcWmM7GNTZjBO53EOM/5uczu7q1Ks39Sz0d0PJFJ+oNi6xyu17WZ/uoSi/s81ouq99G18cLoEX9X1OA==
 | 
			
		||||
      }
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      "@babel/core": ^7.0.0-0
 | 
			
		||||
    dependencies:
 | 
			
		||||
      "@babel/core": 7.22.5
 | 
			
		||||
      "@babel/helper-module-imports": 7.22.5
 | 
			
		||||
      "@babel/plugin-syntax-jsx": 7.22.5_@babel+core@7.22.5
 | 
			
		||||
      "@babel/template": 7.22.5
 | 
			
		||||
      "@babel/traverse": 7.22.5
 | 
			
		||||
      "@babel/types": 7.22.5
 | 
			
		||||
      "@vue/babel-helper-vue-transform-on": 1.0.2
 | 
			
		||||
      "@vue/babel-helper-vue-transform-on": 1.1.3
 | 
			
		||||
      camelcase: 6.3.0
 | 
			
		||||
      html-tags: 3.3.1
 | 
			
		||||
      svg-tags: 1.0.0
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - "@babel/core"
 | 
			
		||||
      - supports-color
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
@ -2907,7 +2918,7 @@ packages:
 | 
			
		||||
      prettier: 2.8.8
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /@vue/eslint-config-typescript/11.0.3_xatovp6glrmk2fdmmi35pvc4ke:
 | 
			
		||||
  /@vue/eslint-config-typescript/11.0.3_5wcsfo7r24w3giceba2tzy7tfq:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-dkt6W0PX6H/4Xuxg/BlFj5xHvksjpSlVjtkQCpaYJBIEuKj2hOVU7r+TIe+ysCwRYFz/lGqvklntRkCAibsbPw==
 | 
			
		||||
@ -2924,7 +2935,7 @@ packages:
 | 
			
		||||
      "@typescript-eslint/eslint-plugin": 5.60.0_i6u37blvulxlszyhkflwwnyave
 | 
			
		||||
      "@typescript-eslint/parser": 5.60.0_fsssjpk4ezl7mpaxdgpssv73ie
 | 
			
		||||
      eslint: 8.43.0
 | 
			
		||||
      eslint-plugin-vue: 9.15.0_eslint@8.43.0
 | 
			
		||||
      eslint-plugin-vue: 9.15.1_eslint@8.43.0
 | 
			
		||||
      typescript: 5.0.4
 | 
			
		||||
      vue-eslint-parser: 9.3.1_eslint@8.43.0
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
@ -2947,7 +2958,7 @@ packages:
 | 
			
		||||
      "@vue/compiler-dom": 3.3.4
 | 
			
		||||
      "@vue/reactivity": 3.3.4
 | 
			
		||||
      "@vue/shared": 3.3.4
 | 
			
		||||
      minimatch: 9.0.1
 | 
			
		||||
      minimatch: 9.0.2
 | 
			
		||||
      muggle-string: 0.3.1
 | 
			
		||||
      typescript: 5.0.4
 | 
			
		||||
      vue-template-compiler: 2.7.14
 | 
			
		||||
@ -3082,7 +3093,7 @@ packages:
 | 
			
		||||
      style-value-types: 5.1.2
 | 
			
		||||
      vue: 3.3.4
 | 
			
		||||
    optionalDependencies:
 | 
			
		||||
      "@nuxt/kit": 3.5.3
 | 
			
		||||
      "@nuxt/kit": 3.6.0
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - "@vue/composition-api"
 | 
			
		||||
      - rollup
 | 
			
		||||
@ -3665,7 +3676,7 @@ packages:
 | 
			
		||||
      postcss: ^8.1.0
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.21.9
 | 
			
		||||
      caniuse-lite: 1.0.30001506
 | 
			
		||||
      caniuse-lite: 1.0.30001507
 | 
			
		||||
      fraction.js: 4.2.0
 | 
			
		||||
      normalize-range: 0.1.2
 | 
			
		||||
      picocolors: 1.0.0
 | 
			
		||||
@ -3855,8 +3866,8 @@ packages:
 | 
			
		||||
    engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
    dependencies:
 | 
			
		||||
      caniuse-lite: 1.0.30001506
 | 
			
		||||
      electron-to-chromium: 1.4.435
 | 
			
		||||
      caniuse-lite: 1.0.30001507
 | 
			
		||||
      electron-to-chromium: 1.4.440
 | 
			
		||||
      node-releases: 2.0.12
 | 
			
		||||
      update-browserslist-db: 1.0.11_browserslist@4.21.9
 | 
			
		||||
 | 
			
		||||
@ -3971,15 +3982,15 @@ packages:
 | 
			
		||||
      }
 | 
			
		||||
    dependencies:
 | 
			
		||||
      browserslist: 4.21.9
 | 
			
		||||
      caniuse-lite: 1.0.30001506
 | 
			
		||||
      caniuse-lite: 1.0.30001507
 | 
			
		||||
      lodash.memoize: 4.1.2
 | 
			
		||||
      lodash.uniq: 4.5.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /caniuse-lite/1.0.30001506:
 | 
			
		||||
  /caniuse-lite/1.0.30001507:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-6XNEcpygZMCKaufIcgpQNZNf00GEqc7VQON+9Rd0K1bMYo8xhMZRAo5zpbnbMNizi4YNgIDAFrdykWsvY3H4Hw==
 | 
			
		||||
        integrity: sha512-SFpUDoSLCaE5XYL2jfqe9ova/pbQHEmbheDf5r4diNwbAgR3qxM9NQtfsiSscjqoya5K7kFcHPUQ+VsUkIJR4A==
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  /cfb/1.2.2:
 | 
			
		||||
@ -5156,10 +5167,10 @@ packages:
 | 
			
		||||
      - "@vue/composition-api"
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /electron-to-chromium/1.4.435:
 | 
			
		||||
  /electron-to-chromium/1.4.440:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-B0CBWVFhvoQCW/XtjRzgrmqcgVWg6RXOEM/dK59+wFV93BFGR6AeNKc4OyhM+T3IhJaOOG8o/V+33Y2mwJWtzw==
 | 
			
		||||
        integrity: sha512-r6dCgNpRhPwiWlxbHzZQ/d9swfPaEJGi8ekqRBwQYaR3WmA5VkqQfBWSDDjuJU1ntO+W9tHx8OHV/96Q8e0dVw==
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  /element-plus/2.3.7_vue@3.3.4:
 | 
			
		||||
@ -5469,10 +5480,10 @@ packages:
 | 
			
		||||
      prettier-linter-helpers: 1.0.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /eslint-plugin-vue/9.15.0_eslint@8.43.0:
 | 
			
		||||
  /eslint-plugin-vue/9.15.1_eslint@8.43.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-XYzpK6e2REli100+6iCeBA69v6Sm0D/yK2FZP+fCeNt0yH/m82qZQq+ztseyV0JsKdhFysuSEzeE1yCmSC92BA==
 | 
			
		||||
        integrity: sha512-CJE/oZOslvmAR9hf8SClTdQ9JLweghT6JCBQNrT2Iel1uVw0W0OLJxzvPd6CxmABKCvLrtyDnqGV37O7KQv6+A==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ^14.17.0 || >=16.0.0 }
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
@ -5483,7 +5494,7 @@ packages:
 | 
			
		||||
      natural-compare: 1.4.0
 | 
			
		||||
      nth-check: 2.1.1
 | 
			
		||||
      postcss-selector-parser: 6.0.13
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
      vue-eslint-parser: 9.3.1_eslint@8.43.0
 | 
			
		||||
      xml-name-validator: 4.0.0
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
@ -6168,17 +6179,17 @@ packages:
 | 
			
		||||
      is-glob: 4.0.3
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /glob/10.2.7:
 | 
			
		||||
  /glob/10.3.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA==
 | 
			
		||||
        integrity: sha512-AQ1/SB9HH0yCx1jXAT4vmCbTOPe5RQ+kCurjbel5xSCGhebumUv+GJZfa1rEqor3XIViqwSEmlkZCQD43RWrBg==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=16 || 14 >=14.17" }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
    dependencies:
 | 
			
		||||
      foreground-child: 3.1.1
 | 
			
		||||
      jackspeak: 2.2.1
 | 
			
		||||
      minimatch: 9.0.1
 | 
			
		||||
      minimatch: 9.0.2
 | 
			
		||||
      minipass: 6.0.2
 | 
			
		||||
      path-scurry: 1.9.2
 | 
			
		||||
    dev: true
 | 
			
		||||
@ -7401,7 +7412,7 @@ packages:
 | 
			
		||||
      jest-util: 27.5.1
 | 
			
		||||
      natural-compare: 1.4.0
 | 
			
		||||
      pretty-format: 27.5.1
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - supports-color
 | 
			
		||||
    dev: false
 | 
			
		||||
@ -8250,10 +8261,10 @@ packages:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      brace-expansion: 1.1.11
 | 
			
		||||
 | 
			
		||||
  /minimatch/9.0.1:
 | 
			
		||||
  /minimatch/9.0.2:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==
 | 
			
		||||
        integrity: sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=16 || 14 >=14.17" }
 | 
			
		||||
    dependencies:
 | 
			
		||||
@ -8513,7 +8524,7 @@ packages:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      hosted-git-info: 4.1.0
 | 
			
		||||
      is-core-module: 2.12.1
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
      validate-npm-package-license: 3.0.4
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
@ -10305,7 +10316,7 @@ packages:
 | 
			
		||||
    engines: { node: ">=14" }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
    dependencies:
 | 
			
		||||
      glob: 10.2.7
 | 
			
		||||
      glob: 10.3.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /rollup-plugin-external-globals/0.6.1:
 | 
			
		||||
@ -10344,10 +10355,10 @@ packages:
 | 
			
		||||
      yargs: 17.7.2
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /rollup/3.25.1:
 | 
			
		||||
  /rollup/3.25.2:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==
 | 
			
		||||
        integrity: sha512-VLnkxZMDr3jpxgtmS8pQZ0UvhslmF4ADq/9w4erkctbgjCqLW9oa89fJuXEs4ZmgyoF7Dm8rMDKSS5b5u2hHUg==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=14.18.0", npm: ">=8.0.0" }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
@ -10394,7 +10405,7 @@ packages:
 | 
			
		||||
      }
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /sass-loader/13.3.2_sass@1.63.5:
 | 
			
		||||
  /sass-loader/13.3.2_sass@1.63.6:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==
 | 
			
		||||
@ -10419,13 +10430,13 @@ packages:
 | 
			
		||||
        optional: true
 | 
			
		||||
    dependencies:
 | 
			
		||||
      neo-async: 2.6.2
 | 
			
		||||
      sass: 1.63.5
 | 
			
		||||
      sass: 1.63.6
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /sass/1.63.5:
 | 
			
		||||
  /sass/1.63.6:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-Q6c5gs482oezdAp+0fWF9cRisvpy7yfYb64knID0OE8AnMgtkluRPfpGMFjeD4/+M4+6QpJZCU6JRSxbjiktkg==
 | 
			
		||||
        integrity: sha512-MJuxGMHzaOW7ipp+1KdELtqKbfAWbH7OLIdoSMnVe3EXPMTmxTmlaZDCTsgIpPCs3w99lLo9/zDKkOrJuT5byw==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=14.0.0" }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
@ -10477,10 +10488,10 @@ packages:
 | 
			
		||||
      }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
 | 
			
		||||
  /semver/7.5.0:
 | 
			
		||||
  /semver/7.5.2:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==
 | 
			
		||||
        integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=10" }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
@ -10488,10 +10499,10 @@ packages:
 | 
			
		||||
      lru-cache: 6.0.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /semver/7.5.2:
 | 
			
		||||
  /semver/7.5.3:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==
 | 
			
		||||
        integrity: sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=10" }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
@ -10986,7 +10997,7 @@ packages:
 | 
			
		||||
      postcss-selector-parser: 6.0.13
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-config-html/1.1.0_mvog3pcismoqiofxpbzhc46kxq:
 | 
			
		||||
  /stylelint-config-html/1.1.0_43a2gdw3tlladwfsutfch6434a:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==
 | 
			
		||||
@ -10997,10 +11008,10 @@ packages:
 | 
			
		||||
      stylelint: ">=14.0.0"
 | 
			
		||||
    dependencies:
 | 
			
		||||
      postcss-html: 1.5.0
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-config-recess-order/4.2.0_stylelint@15.8.0:
 | 
			
		||||
  /stylelint-config-recess-order/4.2.0_stylelint@15.9.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-cWC66tUx74OgurUQaTAH4iJ4JbyisMwlJH8BO/oxglDLZBUNFggjwPFVtgsmd8rS+bUfm7sPlRrF00iAihESwA==
 | 
			
		||||
@ -11008,11 +11019,11 @@ packages:
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      stylelint: ">=15"
 | 
			
		||||
    dependencies:
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint-order: 6.0.3_stylelint@15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
      stylelint-order: 6.0.3_stylelint@15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-config-recommended-scss/11.0.0_kljeyyq7v4k44dzugcnpkrggwa:
 | 
			
		||||
  /stylelint-config-recommended-scss/11.0.0_kg6gx255czvkalpavedathyz5a:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-EDghTDU7aOv2LTsRZvcT1w8mcjUaMhuy+t38iV5I/0Qiu6ixdkRwhLEMul3K/fnB2v9Nwqvb3xpvJfPH+HduDw==
 | 
			
		||||
@ -11026,12 +11037,12 @@ packages:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      postcss: 8.4.24
 | 
			
		||||
      postcss-scss: 4.0.6_postcss@8.4.24
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint-config-recommended: 12.0.0_stylelint@15.8.0
 | 
			
		||||
      stylelint-scss: 4.7.0_stylelint@15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
      stylelint-config-recommended: 12.0.0_stylelint@15.9.0
 | 
			
		||||
      stylelint-scss: 4.7.0_stylelint@15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-config-recommended-scss/12.0.0_kljeyyq7v4k44dzugcnpkrggwa:
 | 
			
		||||
  /stylelint-config-recommended-scss/12.0.0_kg6gx255czvkalpavedathyz5a:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-5Bb2mlGy6WLa30oNeKpZvavv2lowJUsUJO25+OA68GFTemlwd1zbFsL7q0bReKipOSU3sG47hKneZ6Nd+ctrFA==
 | 
			
		||||
@ -11045,12 +11056,12 @@ packages:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      postcss: 8.4.24
 | 
			
		||||
      postcss-scss: 4.0.6_postcss@8.4.24
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint-config-recommended: 12.0.0_stylelint@15.8.0
 | 
			
		||||
      stylelint-scss: 5.0.1_stylelint@15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
      stylelint-config-recommended: 12.0.0_stylelint@15.9.0
 | 
			
		||||
      stylelint-scss: 5.0.1_stylelint@15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-config-recommended-vue/1.4.0_mvog3pcismoqiofxpbzhc46kxq:
 | 
			
		||||
  /stylelint-config-recommended-vue/1.4.0_43a2gdw3tlladwfsutfch6434a:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-DVJqyX2KvMCn9U0+keL12r7xlsH26K4Vg8NrIZuq5MoF7g82DpMp326Om4E0Q+Il1o+bTHuUyejf2XAI0iD04Q==
 | 
			
		||||
@ -11061,13 +11072,13 @@ packages:
 | 
			
		||||
      stylelint: ">=14.0.0"
 | 
			
		||||
    dependencies:
 | 
			
		||||
      postcss-html: 1.5.0
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint-config-html: 1.1.0_mvog3pcismoqiofxpbzhc46kxq
 | 
			
		||||
      stylelint-config-recommended: 12.0.0_stylelint@15.8.0
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
      stylelint-config-html: 1.1.0_43a2gdw3tlladwfsutfch6434a
 | 
			
		||||
      stylelint-config-recommended: 12.0.0_stylelint@15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-config-recommended/12.0.0_stylelint@15.8.0:
 | 
			
		||||
  /stylelint-config-recommended/12.0.0_stylelint@15.9.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==
 | 
			
		||||
@ -11075,10 +11086,10 @@ packages:
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      stylelint: ^15.5.0
 | 
			
		||||
    dependencies:
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-config-standard-scss/9.0.0_kljeyyq7v4k44dzugcnpkrggwa:
 | 
			
		||||
  /stylelint-config-standard-scss/9.0.0_kg6gx255czvkalpavedathyz5a:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-yPKpJsrZn4ybuQZx/DkEHuCjw7pJginErE/47dFhCnrvD48IJ4UYec8tSiCuJWMA3HRjbIa3nh5ZeSauDGuVAg==
 | 
			
		||||
@ -11091,12 +11102,12 @@ packages:
 | 
			
		||||
        optional: true
 | 
			
		||||
    dependencies:
 | 
			
		||||
      postcss: 8.4.24
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint-config-recommended-scss: 11.0.0_kljeyyq7v4k44dzugcnpkrggwa
 | 
			
		||||
      stylelint-config-standard: 33.0.0_stylelint@15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
      stylelint-config-recommended-scss: 11.0.0_kg6gx255czvkalpavedathyz5a
 | 
			
		||||
      stylelint-config-standard: 33.0.0_stylelint@15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-config-standard/33.0.0_stylelint@15.8.0:
 | 
			
		||||
  /stylelint-config-standard/33.0.0_stylelint@15.9.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg==
 | 
			
		||||
@ -11104,11 +11115,11 @@ packages:
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      stylelint: ^15.5.0
 | 
			
		||||
    dependencies:
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint-config-recommended: 12.0.0_stylelint@15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
      stylelint-config-recommended: 12.0.0_stylelint@15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-order/6.0.3_stylelint@15.8.0:
 | 
			
		||||
  /stylelint-order/6.0.3_stylelint@15.9.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==
 | 
			
		||||
@ -11118,10 +11129,10 @@ packages:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      postcss: 8.4.24
 | 
			
		||||
      postcss-sorting: 8.0.2_postcss@8.4.24
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-prettier/3.0.0_l3rlt3ch3sxnybjesonr3v7dca:
 | 
			
		||||
  /stylelint-prettier/3.0.0_di75xrvcz6maarrq4xt2dhjdje:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-kIks1xw6np0zElokMT2kP6ar3S4MBoj6vUtPJuND1pFELMpZxVS/0uHPR4HDAVn0WAD3I5oF0IA3qBFxBpMkLg==
 | 
			
		||||
@ -11133,10 +11144,10 @@ packages:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      prettier: 2.8.8
 | 
			
		||||
      prettier-linter-helpers: 1.0.0
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-scss/4.7.0_stylelint@15.8.0:
 | 
			
		||||
  /stylelint-scss/4.7.0_stylelint@15.9.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==
 | 
			
		||||
@ -11148,10 +11159,10 @@ packages:
 | 
			
		||||
      postcss-resolve-nested-selector: 0.1.1
 | 
			
		||||
      postcss-selector-parser: 6.0.13
 | 
			
		||||
      postcss-value-parser: 4.2.0
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint-scss/5.0.1_stylelint@15.8.0:
 | 
			
		||||
  /stylelint-scss/5.0.1_stylelint@15.9.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-n87iCRZrr2J7//I/QFsDXxFLnHKw633U4qvWZ+mOW6KDAp/HLj06H+6+f9zOuTYy+MdGdTuCSDROCpQIhw5fvQ==
 | 
			
		||||
@ -11163,13 +11174,13 @@ packages:
 | 
			
		||||
      postcss-resolve-nested-selector: 0.1.1
 | 
			
		||||
      postcss-selector-parser: 6.0.13
 | 
			
		||||
      postcss-value-parser: 4.2.0
 | 
			
		||||
      stylelint: 15.8.0
 | 
			
		||||
      stylelint: 15.9.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /stylelint/15.8.0:
 | 
			
		||||
  /stylelint/15.9.0:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-x9qBk84F3MEjMEUNCE7MtWmfj9G9y5XzJ0cpQeJdy2l/IoqjC8Ih0N0ytmOTnXE4Yv0J7I1cmVRQUVNSPCxTsA==
 | 
			
		||||
        integrity: sha512-sXtAZi64CllWr6A+8ymDWnlIaYwuAa7XRmGnJxLQXFNnLjd3Izm4HAD+loKVaZ7cpK6SLxhAUX1lwPJKGCn0mg==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ^14.13.1 || >=16.0.0 }
 | 
			
		||||
    hasBin: true
 | 
			
		||||
@ -11525,6 +11536,15 @@ packages:
 | 
			
		||||
      }
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /tippy.js/6.3.7:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==
 | 
			
		||||
      }
 | 
			
		||||
    dependencies:
 | 
			
		||||
      "@popperjs/core": 2.11.8
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /tmpl/1.0.5:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
@ -12006,7 +12026,7 @@ packages:
 | 
			
		||||
      chalk: 4.1.2
 | 
			
		||||
      debug: 4.3.4
 | 
			
		||||
      fs-extra: 10.1.0
 | 
			
		||||
      vite: 4.3.9_pkrcaghuhlfdigptyvdajp2oau
 | 
			
		||||
      vite: 4.3.9_l6lbxg3wmltw2cpo2xi56qo4mi
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - supports-color
 | 
			
		||||
    dev: true
 | 
			
		||||
@ -12031,7 +12051,7 @@ packages:
 | 
			
		||||
      fast-glob: 3.2.12
 | 
			
		||||
      mockjs: 1.1.0
 | 
			
		||||
      path-to-regexp: 6.2.1
 | 
			
		||||
      vite: 4.3.9_pkrcaghuhlfdigptyvdajp2oau
 | 
			
		||||
      vite: 4.3.9_l6lbxg3wmltw2cpo2xi56qo4mi
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - rollup
 | 
			
		||||
      - supports-color
 | 
			
		||||
@ -12054,7 +12074,7 @@ packages:
 | 
			
		||||
      svgo: 3.0.2
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /vite/4.3.9_pkrcaghuhlfdigptyvdajp2oau:
 | 
			
		||||
  /vite/4.3.9_l6lbxg3wmltw2cpo2xi56qo4mi:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==
 | 
			
		||||
@ -12085,8 +12105,8 @@ packages:
 | 
			
		||||
      "@types/node": 18.16.18
 | 
			
		||||
      esbuild: 0.17.19
 | 
			
		||||
      postcss: 8.4.24
 | 
			
		||||
      rollup: 3.25.1
 | 
			
		||||
      sass: 1.63.5
 | 
			
		||||
      rollup: 3.25.2
 | 
			
		||||
      sass: 1.63.6
 | 
			
		||||
      terser: 5.18.1
 | 
			
		||||
    optionalDependencies:
 | 
			
		||||
      fsevents: 2.3.2
 | 
			
		||||
@ -12126,7 +12146,7 @@ packages:
 | 
			
		||||
      espree: 9.5.2
 | 
			
		||||
      esquery: 1.5.0
 | 
			
		||||
      lodash: 4.17.21
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
    transitivePeerDependencies:
 | 
			
		||||
      - supports-color
 | 
			
		||||
    dev: true
 | 
			
		||||
@ -12213,6 +12233,18 @@ packages:
 | 
			
		||||
      he: 1.2.0
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /vue-tippy/6.2.0_vue@3.3.4:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-UytUItp2ZDLXUwAotmioz02uLQoaAl5iVM+5yKsQWrXr29L9ivavtkL684FqbmOfbeCypBw+rVKsXhwdnCt/Cg==
 | 
			
		||||
      }
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      vue: ^3.2.0
 | 
			
		||||
    dependencies:
 | 
			
		||||
      tippy.js: 6.3.7
 | 
			
		||||
      vue: 3.3.4
 | 
			
		||||
    dev: false
 | 
			
		||||
 | 
			
		||||
  /vue-tsc/1.8.1_typescript@5.0.4:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
@ -12224,14 +12256,14 @@ packages:
 | 
			
		||||
    dependencies:
 | 
			
		||||
      "@vue/language-core": 1.8.1_typescript@5.0.4
 | 
			
		||||
      "@vue/typescript": 1.8.1_typescript@5.0.4
 | 
			
		||||
      semver: 7.5.2
 | 
			
		||||
      semver: 7.5.3
 | 
			
		||||
      typescript: 5.0.4
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /vue-types/5.0.4_vue@3.3.4:
 | 
			
		||||
  /vue-types/5.1.0_vue@3.3.4:
 | 
			
		||||
    resolution:
 | 
			
		||||
      {
 | 
			
		||||
        integrity: sha512-ksYUQpvhk1Xl/K43OPkcm54VcX4tvxQoNYjYLk+n45NOocDsg9+DnviPq/KfDLjGs4P23iAosFPR8JSzuh9IPA==
 | 
			
		||||
        integrity: sha512-oCSq5MawTli+Jqaf07sCZgJr/FcDCFF5U/VE4WG58S3EAPxqi8nZlbrQ9I50rD5MZdJ3fjgi/IX1tVLL3QUFzA==
 | 
			
		||||
      }
 | 
			
		||||
    engines: { node: ">=14.0.0" }
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								src/components/ReCropper/src/circled.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,11 @@
 | 
			
		||||
@import "cropperjs/dist/cropper.css";
 | 
			
		||||
@import "tippy.js/dist/tippy.css";
 | 
			
		||||
@import "tippy.js/themes/light.css";
 | 
			
		||||
@import "tippy.js/animations/perspective.css";
 | 
			
		||||
 | 
			
		||||
.re-circled {
 | 
			
		||||
  .cropper-view-box,
 | 
			
		||||
  .cropper-face {
 | 
			
		||||
    border-radius: 50%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,22 +1,41 @@
 | 
			
		||||
import "./circled.css";
 | 
			
		||||
import Cropper from "cropperjs";
 | 
			
		||||
import { ElUpload } from "element-plus";
 | 
			
		||||
import type { CSSProperties } from "vue";
 | 
			
		||||
import { useResizeObserver } from "@vueuse/core";
 | 
			
		||||
import { longpress } from "@/directives/longpress";
 | 
			
		||||
import { useTippy, directive as tippy } from "vue-tippy";
 | 
			
		||||
import { delay, debounce, isArray, downloadByBase64 } from "@pureadmin/utils";
 | 
			
		||||
import {
 | 
			
		||||
  defineComponent,
 | 
			
		||||
  onMounted,
 | 
			
		||||
  nextTick,
 | 
			
		||||
  ref,
 | 
			
		||||
  unref,
 | 
			
		||||
  computed,
 | 
			
		||||
  PropType
 | 
			
		||||
  PropType,
 | 
			
		||||
  onMounted,
 | 
			
		||||
  onUnmounted,
 | 
			
		||||
  defineComponent
 | 
			
		||||
} from "vue";
 | 
			
		||||
import { useAttrs } from "@pureadmin/utils";
 | 
			
		||||
 | 
			
		||||
import Cropper from "cropperjs";
 | 
			
		||||
import "cropperjs/dist/cropper.css";
 | 
			
		||||
import {
 | 
			
		||||
  Reload,
 | 
			
		||||
  Upload,
 | 
			
		||||
  ArrowH,
 | 
			
		||||
  ArrowV,
 | 
			
		||||
  ArrowUp,
 | 
			
		||||
  ArrowDown,
 | 
			
		||||
  ArrowLeft,
 | 
			
		||||
  ChangeIcon,
 | 
			
		||||
  ArrowRight,
 | 
			
		||||
  RotateLeft,
 | 
			
		||||
  SearchPlus,
 | 
			
		||||
  RotateRight,
 | 
			
		||||
  SearchMinus,
 | 
			
		||||
  DownloadIcon
 | 
			
		||||
} from "./svg";
 | 
			
		||||
 | 
			
		||||
type Options = Cropper.Options;
 | 
			
		||||
 | 
			
		||||
const defaultOptions: Cropper.Options = {
 | 
			
		||||
  aspectRatio: 16 / 9,
 | 
			
		||||
const defaultOptions: Options = {
 | 
			
		||||
  aspectRatio: 1,
 | 
			
		||||
  zoomable: true,
 | 
			
		||||
  zoomOnTouch: true,
 | 
			
		||||
  zoomOnWheel: true,
 | 
			
		||||
@ -39,110 +58,382 @@ const defaultOptions: Cropper.Options = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const props = {
 | 
			
		||||
  src: {
 | 
			
		||||
    type: String,
 | 
			
		||||
    required: true
 | 
			
		||||
  },
 | 
			
		||||
  alt: {
 | 
			
		||||
    type: String
 | 
			
		||||
  },
 | 
			
		||||
  width: {
 | 
			
		||||
    type: [String, Number],
 | 
			
		||||
    default: ""
 | 
			
		||||
  },
 | 
			
		||||
  height: {
 | 
			
		||||
    type: [String, Number],
 | 
			
		||||
    default: "360px"
 | 
			
		||||
  },
 | 
			
		||||
  src: { type: String, required: true },
 | 
			
		||||
  alt: { type: String },
 | 
			
		||||
  circled: { type: Boolean, default: false },
 | 
			
		||||
  realTimePreview: { type: Boolean, default: true },
 | 
			
		||||
  height: { type: [String, Number], default: "360px" },
 | 
			
		||||
  crossorigin: {
 | 
			
		||||
    type: String || Object,
 | 
			
		||||
    type: String as PropType<"" | "anonymous" | "use-credentials" | undefined>,
 | 
			
		||||
    default: undefined
 | 
			
		||||
  },
 | 
			
		||||
  imageStyle: {
 | 
			
		||||
    type: Object as PropType<CSSProperties>,
 | 
			
		||||
    default() {
 | 
			
		||||
      return {};
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  options: {
 | 
			
		||||
    type: Object as PropType<Options>,
 | 
			
		||||
    default() {
 | 
			
		||||
      return {};
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  imageStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
 | 
			
		||||
  options: { type: Object as PropType<Options>, default: () => ({}) }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  name: "ReCropper",
 | 
			
		||||
  props,
 | 
			
		||||
  setup(props) {
 | 
			
		||||
    const cropper: any = ref<Nullable<Cropper>>(null);
 | 
			
		||||
    const imgElRef = ref();
 | 
			
		||||
  setup(props, { attrs, emit }) {
 | 
			
		||||
    const tippyElRef = ref<ElRef<HTMLImageElement>>();
 | 
			
		||||
    const imgElRef = ref<ElRef<HTMLImageElement>>();
 | 
			
		||||
    const cropper = ref<Nullable<Cropper>>();
 | 
			
		||||
    const isReady = ref(false);
 | 
			
		||||
    const imgBase64 = ref();
 | 
			
		||||
    const inCircled = ref(props.circled);
 | 
			
		||||
    const inSrc = ref(props.src);
 | 
			
		||||
    let scaleX = 1;
 | 
			
		||||
    let scaleY = 1;
 | 
			
		||||
 | 
			
		||||
    const isReady = ref<boolean>(false);
 | 
			
		||||
    const debounceRealTimeCroppered = debounce(realTimeCroppered, 80);
 | 
			
		||||
 | 
			
		||||
    const getImageStyle = computed((): CSSProperties => {
 | 
			
		||||
      return {
 | 
			
		||||
        height: props.height,
 | 
			
		||||
        width: props.width,
 | 
			
		||||
        maxWidth: "100%",
 | 
			
		||||
        ...props.imageStyle
 | 
			
		||||
      };
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const getWrapperStyle = computed((): CSSProperties => {
 | 
			
		||||
      const { height, width } = props;
 | 
			
		||||
      return {
 | 
			
		||||
        width: `${width}`.replace(/px/, "") + "px",
 | 
			
		||||
        height: `${height}`.replace(/px/, "") + "px"
 | 
			
		||||
      };
 | 
			
		||||
    const getClass = computed(() => {
 | 
			
		||||
      return [
 | 
			
		||||
        attrs.class,
 | 
			
		||||
        {
 | 
			
		||||
          ["re-circled"]: inCircled.value
 | 
			
		||||
        }
 | 
			
		||||
      ];
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function init() {
 | 
			
		||||
    const iconClass = computed(() => {
 | 
			
		||||
      return [
 | 
			
		||||
        "p-[6px]",
 | 
			
		||||
        "h-[30px]",
 | 
			
		||||
        "w-[30px]",
 | 
			
		||||
        "outline-none",
 | 
			
		||||
        "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();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    useResizeObserver(tippyElRef, () => {
 | 
			
		||||
      handCropper("reset");
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    async function init() {
 | 
			
		||||
      const imgEl = unref(imgElRef);
 | 
			
		||||
      if (!imgEl) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      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
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onMounted(() => {
 | 
			
		||||
      nextTick(() => {
 | 
			
		||||
        init();
 | 
			
		||||
    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 } = useTippy(tippyElRef, {
 | 
			
		||||
        content: menuContent,
 | 
			
		||||
        arrow: false,
 | 
			
		||||
        theme: "light",
 | 
			
		||||
        trigger: "manual",
 | 
			
		||||
        interactive: true,
 | 
			
		||||
        appendTo: "parent",
 | 
			
		||||
        // hideOnClick: false,
 | 
			
		||||
        animation: "perspective",
 | 
			
		||||
        placement: "bottom-start"
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      setProps({
 | 
			
		||||
        getReferenceClientRect: () => ({
 | 
			
		||||
          width: 0,
 | 
			
		||||
          height: 0,
 | 
			
		||||
          top: event.clientY,
 | 
			
		||||
          bottom: event.clientY,
 | 
			
		||||
          left: event.clientX,
 | 
			
		||||
          right: event.clientX
 | 
			
		||||
        })
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      inSrc,
 | 
			
		||||
      props,
 | 
			
		||||
      imgElRef,
 | 
			
		||||
      cropper,
 | 
			
		||||
      tippyElRef,
 | 
			
		||||
      getClass,
 | 
			
		||||
      getWrapperStyle,
 | 
			
		||||
      getImageStyle
 | 
			
		||||
      getImageStyle,
 | 
			
		||||
      isReady,
 | 
			
		||||
      croppered,
 | 
			
		||||
      onContextmenu
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    return (
 | 
			
		||||
      <>
 | 
			
		||||
    const {
 | 
			
		||||
      inSrc,
 | 
			
		||||
      isReady,
 | 
			
		||||
      getClass,
 | 
			
		||||
      getImageStyle,
 | 
			
		||||
      onContextmenu,
 | 
			
		||||
      getWrapperStyle
 | 
			
		||||
    } = this;
 | 
			
		||||
    const { alt, crossorigin } = this.props;
 | 
			
		||||
 | 
			
		||||
    return inSrc ? (
 | 
			
		||||
      <div
 | 
			
		||||
          class={useAttrs({ excludeListeners: true, excludeKeys: ["class"] })}
 | 
			
		||||
          style={this.getWrapperStyle}
 | 
			
		||||
        ref="tippyElRef"
 | 
			
		||||
        class={getClass}
 | 
			
		||||
        style={getWrapperStyle}
 | 
			
		||||
        onContextmenu={event => onContextmenu(event)}
 | 
			
		||||
      >
 | 
			
		||||
        <img
 | 
			
		||||
          v-show={isReady}
 | 
			
		||||
          ref="imgElRef"
 | 
			
		||||
            src={this.props.src}
 | 
			
		||||
            alt={this.props.alt}
 | 
			
		||||
            crossorigin={this.props.crossorigin}
 | 
			
		||||
            style={this.getImageStyle}
 | 
			
		||||
          style={getImageStyle}
 | 
			
		||||
          src={inSrc}
 | 
			
		||||
          alt={alt}
 | 
			
		||||
          crossorigin={crossorigin}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
      </>
 | 
			
		||||
    );
 | 
			
		||||
    ) : null;
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/arrow-down.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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.2z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 347 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/arrow-h.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 325 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/arrow-left.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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-8z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 344 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/arrow-right.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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.4z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 351 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/arrow-up.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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.2z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 339 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/arrow-v.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 323 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/change.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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.8zM608 937.6h326.4V598.4H608v339.2zm-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 32z"/><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.4z"/><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.4zm790.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.2z"/><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.4z"/><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.4zM288 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.8zm-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.8z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/download.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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.9l112 141.8zM878 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-8z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 428 B  | 
							
								
								
									
										31
									
								
								src/components/ReCropper/src/svg/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,31 @@
 | 
			
		||||
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
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/reload.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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.8zm756 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.2z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 865 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/rotate-left.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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-32zm-44 402H188V494h440v326z"/><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.3z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 636 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/rotate-right.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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.8z"/><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-32zm-44 402H396V494h440v326z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 639 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/search-minus.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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-8zm284 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-11zM696 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 430z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 535 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/search-plus.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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-8zm284 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-11zM696 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 430z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 631 B  | 
							
								
								
									
										1
									
								
								src/components/ReCropper/src/svg/upload.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
<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 13zM878 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-8z"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 423 B  | 
@ -1,6 +1,12 @@
 | 
			
		||||
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
 | 
			
		||||
import { delay, getKeyList, cloneDeep } from "@pureadmin/utils";
 | 
			
		||||
import { defineComponent, ref, computed, type PropType, nextTick } from "vue";
 | 
			
		||||
import {
 | 
			
		||||
  delay,
 | 
			
		||||
  cloneDeep,
 | 
			
		||||
  isBoolean,
 | 
			
		||||
  isFunction,
 | 
			
		||||
  getKeyList
 | 
			
		||||
} from "@pureadmin/utils";
 | 
			
		||||
 | 
			
		||||
import Sortable from "sortablejs";
 | 
			
		||||
import DragIcon from "./svg/drag.svg?component";
 | 
			
		||||
@ -37,8 +43,13 @@ export default defineComponent({
 | 
			
		||||
    const loading = ref(false);
 | 
			
		||||
    const checkAll = ref(true);
 | 
			
		||||
    const isIndeterminate = ref(false);
 | 
			
		||||
    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(checkColumnList);
 | 
			
		||||
    const checkedColumns = ref(getKeyList(cloneDeep(filterColumns), "label"));
 | 
			
		||||
    const dynamicColumns = ref(cloneDeep(props?.columns));
 | 
			
		||||
 | 
			
		||||
    const getDropdownItemStyle = computed(() => {
 | 
			
		||||
@ -120,7 +131,7 @@ export default defineComponent({
 | 
			
		||||
      dynamicColumns.value = cloneDeep(props?.columns);
 | 
			
		||||
      checkColumnList = [];
 | 
			
		||||
      checkColumnList = await getKeyList(cloneDeep(props?.columns), "label");
 | 
			
		||||
      checkedColumns.value = checkColumnList;
 | 
			
		||||
      checkedColumns.value = getKeyList(cloneDeep(filterColumns), "label");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const dropdown = {
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { hasAuth } from "@/router/utils";
 | 
			
		||||
import { Directive, type DirectiveBinding } from "vue";
 | 
			
		||||
import type { Directive, DirectiveBinding } from "vue";
 | 
			
		||||
 | 
			
		||||
export const auth: Directive = {
 | 
			
		||||
  mounted(el: HTMLElement, binding: DirectiveBinding) {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { message } from "@/utils/message";
 | 
			
		||||
import { useEventListener } from "@vueuse/core";
 | 
			
		||||
import { copyTextToClipboard } from "@pureadmin/utils";
 | 
			
		||||
import { Directive, type DirectiveBinding } from "vue";
 | 
			
		||||
import type { Directive, DirectiveBinding } from "vue";
 | 
			
		||||
 | 
			
		||||
interface CopyEl extends HTMLElement {
 | 
			
		||||
  copyValue: string;
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
export * from "./auth";
 | 
			
		||||
export * from "./copy";
 | 
			
		||||
export * from "./longpress";
 | 
			
		||||
export * from "./optimize";
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										63
									
								
								src/directives/longpress/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,63 @@
 | 
			
		||||
import { useEventListener } from "@vueuse/core";
 | 
			
		||||
import type { Directive, DirectiveBinding } from "vue";
 | 
			
		||||
import { subBefore, subAfter, isFunction } from "@pureadmin/utils";
 | 
			
		||||
 | 
			
		||||
export const longpress: Directive = {
 | 
			
		||||
  mounted(el: HTMLElement, binding: DirectiveBinding) {
 | 
			
		||||
    const cb = binding.value;
 | 
			
		||||
    if (cb && isFunction(cb)) {
 | 
			
		||||
      let timer = null;
 | 
			
		||||
      let interTimer = null;
 | 
			
		||||
      let num = 500;
 | 
			
		||||
      let interNum = null;
 | 
			
		||||
      const isInter = binding?.arg?.includes(":") ?? false;
 | 
			
		||||
 | 
			
		||||
      if (isInter) {
 | 
			
		||||
        num = Number(subBefore(binding.arg, ":"));
 | 
			
		||||
        interNum = Number(subAfter(binding.arg, ":"));
 | 
			
		||||
      } else if (binding.arg) {
 | 
			
		||||
        num = Number(binding.arg);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const clear = () => {
 | 
			
		||||
        if (timer) {
 | 
			
		||||
          clearTimeout(timer);
 | 
			
		||||
          timer = null;
 | 
			
		||||
        }
 | 
			
		||||
        if (interTimer) {
 | 
			
		||||
          clearInterval(interTimer);
 | 
			
		||||
          interTimer = null;
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      const onDownInter = (ev: PointerEvent) => {
 | 
			
		||||
        ev.preventDefault();
 | 
			
		||||
        if (interTimer === null) {
 | 
			
		||||
          interTimer = setInterval(() => cb(), interNum);
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      const onDown = (ev: PointerEvent) => {
 | 
			
		||||
        clear();
 | 
			
		||||
        ev.preventDefault();
 | 
			
		||||
        if (timer === null) {
 | 
			
		||||
          timer = isInter
 | 
			
		||||
            ? setTimeout(() => {
 | 
			
		||||
                cb();
 | 
			
		||||
                onDownInter(ev);
 | 
			
		||||
              }, num)
 | 
			
		||||
            : setTimeout(() => cb(), num);
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // Register using addEventListener on mounted, and removeEventListener automatically on unmounted
 | 
			
		||||
      useEventListener(el, "pointerdown", onDown);
 | 
			
		||||
      useEventListener(el, "pointerup", clear);
 | 
			
		||||
      useEventListener(el, "pointerleave", clear);
 | 
			
		||||
    } else {
 | 
			
		||||
      throw new Error(
 | 
			
		||||
        '[Directive: longpress]: need callback and callback must be a function! Like v-longpress="callback"'
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
@ -6,7 +6,7 @@ import {
 | 
			
		||||
  throttle
 | 
			
		||||
} from "@pureadmin/utils";
 | 
			
		||||
import { useEventListener } from "@vueuse/core";
 | 
			
		||||
import { Directive, type DirectiveBinding } from "vue";
 | 
			
		||||
import type { Directive, DirectiveBinding } from "vue";
 | 
			
		||||
 | 
			
		||||
/** 防抖(v-optimize或v-optimize:debounce)、节流(v-optimize:throttle)指令 */
 | 
			
		||||
export const optimize: Directive = {
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,9 @@ const searchFour = ref("");
 | 
			
		||||
const searchFive = ref("");
 | 
			
		||||
const searchSix = ref("copy");
 | 
			
		||||
const text = ref("可复制的文本");
 | 
			
		||||
const long = ref(false);
 | 
			
		||||
const cbText = ref("");
 | 
			
		||||
const idx = ref(0);
 | 
			
		||||
 | 
			
		||||
function onInput() {
 | 
			
		||||
  message(search.value);
 | 
			
		||||
@ -30,13 +33,30 @@ function onInputFour() {
 | 
			
		||||
function onInputFive({ name, sex }) {
 | 
			
		||||
  message(`${name}${sex}${searchFive.value}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onLongpress() {
 | 
			
		||||
  long.value = true;
 | 
			
		||||
}
 | 
			
		||||
function onCustomLongpress() {
 | 
			
		||||
  long.value = true;
 | 
			
		||||
}
 | 
			
		||||
function onCbLongpress() {
 | 
			
		||||
  idx.value += 1;
 | 
			
		||||
  long.value = true;
 | 
			
		||||
  cbText.value = `持续回调${idx.value}次`;
 | 
			
		||||
}
 | 
			
		||||
function onReset() {
 | 
			
		||||
  long.value = false;
 | 
			
		||||
  cbText.value = "";
 | 
			
		||||
  idx.value = 0;
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <el-card shadow="never">
 | 
			
		||||
    <template #header>
 | 
			
		||||
      <div class="card-header">
 | 
			
		||||
        <span class="font-medium">自定义防抖、截流、文本复制指令</span>
 | 
			
		||||
        <span class="font-medium">自定义防抖、截流、文本复制、长按指令</span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <div class="mb-2">
 | 
			
		||||
@ -113,5 +133,24 @@ function onInputFive({ name, sex }) {
 | 
			
		||||
      文本复制指令(自定义触发事件,单击复制)
 | 
			
		||||
      <span v-copy:click="text" class="text-sky-500">{{ text }}</span>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <el-divider />
 | 
			
		||||
    <el-space wrap>
 | 
			
		||||
      长按指令
 | 
			
		||||
      <el-button v-longpress="onLongpress">长按(默认500ms)</el-button>
 | 
			
		||||
      <el-button v-longpress:1000="onCustomLongpress">
 | 
			
		||||
        自定义长按时长(1000ms)
 | 
			
		||||
      </el-button>
 | 
			
		||||
      <el-button v-longpress:2000:200="onCbLongpress">
 | 
			
		||||
        2秒后每200ms持续回调
 | 
			
		||||
      </el-button>
 | 
			
		||||
      <el-button @click="onReset"> 重置状态 </el-button>
 | 
			
		||||
      <el-tag :type="long ? 'success' : 'info'" class="ml-2" size="large">
 | 
			
		||||
        {{ long ? "当前为长按状态" : "当前非长按状态" }}
 | 
			
		||||
      </el-tag>
 | 
			
		||||
      <el-tag v-if="cbText" type="danger" class="ml-2" size="large">
 | 
			
		||||
        {{ cbText }}
 | 
			
		||||
      </el-tag>
 | 
			
		||||
    </el-space>
 | 
			
		||||
  </el-card>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/views/components/cropping/avatar.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 53 KiB  | 
@ -1,60 +1,75 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, nextTick } from "vue";
 | 
			
		||||
import Cropper from "@/components/ReCropper";
 | 
			
		||||
import img from "./picture.jpeg";
 | 
			
		||||
<script setup lang="tsx">
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
import avatar from "./avatar.png";
 | 
			
		||||
import ReCropper from "@/components/ReCropper";
 | 
			
		||||
import { formatBytes } from "@pureadmin/utils";
 | 
			
		||||
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: "Cropping"
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const infos = ref();
 | 
			
		||||
const refCropper = ref();
 | 
			
		||||
const info = ref<object>(null);
 | 
			
		||||
const showPopover = ref(false);
 | 
			
		||||
const cropperImg = ref<string>("");
 | 
			
		||||
 | 
			
		||||
const onCropper = (): void => {
 | 
			
		||||
  nextTick(() => {
 | 
			
		||||
    refCropper.value.cropper.getCroppedCanvas().toBlob(blob => {
 | 
			
		||||
      const fileReader: FileReader = new FileReader();
 | 
			
		||||
      fileReader.onloadend = (e: ProgressEvent) => {
 | 
			
		||||
        cropperImg.value = (e.target as any).result;
 | 
			
		||||
        info.value = refCropper.value.cropper.getData();
 | 
			
		||||
      };
 | 
			
		||||
      fileReader.readAsDataURL(blob);
 | 
			
		||||
    }, "image/jpeg");
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
function onCropper({ base64, blob, info }) {
 | 
			
		||||
  console.log(blob);
 | 
			
		||||
  infos.value = info;
 | 
			
		||||
  cropperImg.value = base64;
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <el-card shadow="never">
 | 
			
		||||
    <template #header>
 | 
			
		||||
      <div class="card-header">
 | 
			
		||||
        <span class="font-medium">图片裁剪组件</span>
 | 
			
		||||
        <span class="font-medium">
 | 
			
		||||
          图片裁剪组件,基于开源的
 | 
			
		||||
          <el-link
 | 
			
		||||
            href="https://fengyuanchen.github.io/cropperjs/"
 | 
			
		||||
            target="_blank"
 | 
			
		||||
            style="margin: 0 4px 5px; font-size: 16px"
 | 
			
		||||
          >
 | 
			
		||||
            cropperjs
 | 
			
		||||
          </el-link>
 | 
			
		||||
          进行二次封装(提示:右键下面左侧裁剪区可开启功能菜单)
 | 
			
		||||
        </span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <div class="cropper-container">
 | 
			
		||||
      <Cropper ref="refCropper" :width="'40vw'" :src="img" />
 | 
			
		||||
      <img :src="cropperImg" class="croppered" v-if="cropperImg" />
 | 
			
		||||
    <el-popover
 | 
			
		||||
      :visible="showPopover"
 | 
			
		||||
      placement="right"
 | 
			
		||||
      width="300px"
 | 
			
		||||
      :teleported="false"
 | 
			
		||||
    >
 | 
			
		||||
      <template #reference>
 | 
			
		||||
        <ReCropper
 | 
			
		||||
          ref="refCropper"
 | 
			
		||||
          class="w-[30vw]"
 | 
			
		||||
          :src="avatar"
 | 
			
		||||
          circled
 | 
			
		||||
          @cropper="onCropper"
 | 
			
		||||
          @readied="showPopover = true"
 | 
			
		||||
        />
 | 
			
		||||
      </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>
 | 
			
		||||
    <el-button type="primary" @click="onCropper">裁剪</el-button>
 | 
			
		||||
    <p v-if="cropperImg">裁剪后图片信息:{{ info }}</p>
 | 
			
		||||
      </div>
 | 
			
		||||
    </el-popover>
 | 
			
		||||
  </el-card>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
.cropper-container {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-button {
 | 
			
		||||
  margin-top: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.croppered {
 | 
			
		||||
  display: block;
 | 
			
		||||
  width: 45%;
 | 
			
		||||
  height: 360px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 23 KiB  |