mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-27 01:32:03 +08:00
commit
893b6cf4f2
@ -170,7 +170,7 @@ ps:核心功能已经实现,正在对接微信小程序中...
|
|||||||
## 🐨 技术栈
|
## 🐨 技术栈
|
||||||
|
|
||||||
| 项目 | 说明 |
|
| 项目 | 说明 |
|
||||||
|-----------------------|--------------------|
|
|-------------------------|-----------------------|
|
||||||
| `yudao-dependencies` | Maven 依赖版本管理 |
|
| `yudao-dependencies` | Maven 依赖版本管理 |
|
||||||
| `yudao-framework` | Java 框架拓展 |
|
| `yudao-framework` | Java 框架拓展 |
|
||||||
| `yudao-server` | 管理后台 + 用户 APP 的服务端 |
|
| `yudao-server` | 管理后台 + 用户 APP 的服务端 |
|
||||||
@ -223,7 +223,7 @@ ps:核心功能已经实现,正在对接微信小程序中...
|
|||||||
| 框架 | 说明 | 版本 |
|
| 框架 | 说明 | 版本 |
|
||||||
|----------------------------------------------------------------------|:------------:|:------:|
|
|----------------------------------------------------------------------|:------------:|:------:|
|
||||||
| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.45 |
|
| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.45 |
|
||||||
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.0.2 |
|
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.0.3 |
|
||||||
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.27 |
|
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.27 |
|
||||||
| [TypeScript](https://www.typescriptlang.org/docs/) | TypeScript | 4.9.4 |
|
| [TypeScript](https://www.typescriptlang.org/docs/) | TypeScript | 4.9.4 |
|
||||||
| [pinia](https://pinia.vuejs.org/) | vuex5 | 2.0.28 |
|
| [pinia](https://pinia.vuejs.org/) | vuex5 | 2.0.28 |
|
||||||
@ -242,7 +242,7 @@ ps:核心功能已经实现,正在对接微信小程序中...
|
|||||||
### 系统功能
|
### 系统功能
|
||||||
|
|
||||||
| 模块 | biu | biu | biu |
|
| 模块 | biu | biu | biu |
|
||||||
|----------|--------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|
|
|------------|--------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|
|
||||||
| 登录 & 首页 | ![登录](https://static.iocoder.cn/images/ruoyi-vue-pro/登录.jpg?imageView2/2/format/webp/w/1280) | ![首页](https://static.iocoder.cn/images/ruoyi-vue-pro/首页.jpg?imageView2/2/format/webp/w/1280) | ![个人中心](https://static.iocoder.cn/images/ruoyi-vue-pro/个人中心.jpg?imageView2/2/format/webp/w/1280) |
|
| 登录 & 首页 | ![登录](https://static.iocoder.cn/images/ruoyi-vue-pro/登录.jpg?imageView2/2/format/webp/w/1280) | ![首页](https://static.iocoder.cn/images/ruoyi-vue-pro/首页.jpg?imageView2/2/format/webp/w/1280) | ![个人中心](https://static.iocoder.cn/images/ruoyi-vue-pro/个人中心.jpg?imageView2/2/format/webp/w/1280) |
|
||||||
| 用户 & 应用 | ![用户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/用户管理.jpg?imageView2/2/format/webp/w/1280) | ![令牌管理](https://static.iocoder.cn/images/ruoyi-vue-pro/令牌管理.jpg?imageView2/2/format/webp/w/1280) | ![应用管理](https://static.iocoder.cn/images/ruoyi-vue-pro/应用管理.jpg?imageView2/2/format/webp/w/1280) |
|
| 用户 & 应用 | ![用户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/用户管理.jpg?imageView2/2/format/webp/w/1280) | ![令牌管理](https://static.iocoder.cn/images/ruoyi-vue-pro/令牌管理.jpg?imageView2/2/format/webp/w/1280) | ![应用管理](https://static.iocoder.cn/images/ruoyi-vue-pro/应用管理.jpg?imageView2/2/format/webp/w/1280) |
|
||||||
| 租户 & 套餐 | ![租户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/租户管理.jpg?imageView2/2/format/webp/w/1280) | ![租户套餐](https://static.iocoder.cn/images/ruoyi-vue-pro/租户套餐.png) | - |
|
| 租户 & 套餐 | ![租户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/租户管理.jpg?imageView2/2/format/webp/w/1280) | ![租户套餐](https://static.iocoder.cn/images/ruoyi-vue-pro/租户套餐.png) | - |
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
<h1>🌈 yudao-ui-admin-vue3</h1>
|
# 🌈 yudao-ui-admin-vue3 #
|
||||||
|
|
||||||
<p align="center">
|
<p style="text-align: center">
|
||||||
<img src="https://img.shields.io/badge/-Vue3.2-34495e?logo=vue.j" />
|
<img src="https://img.shields.io/badge/-Vue3.2-34495e?logo=vue.j" alt="vue" />
|
||||||
<img src="https://img.shields.io/badge/-Vite4-646cff?logo=vite&logoColor=white" />
|
<img src="https://img.shields.io/badge/-Vite4-646cff?logo=vite&logoColor=white" alt="vite" />
|
||||||
<img src="https://img.shields.io/badge/-TypeScript4.9-blue?logo=typescript&logoColor=white" />
|
<img src="https://img.shields.io/badge/-TypeScript4.9-blue?logo=typescript&logoColor=white" alt="typescript" />
|
||||||
<img src="https://img.shields.io/badge/-Pinia2-yellow?logo=picpay&logoColor=white" />
|
<img src="https://img.shields.io/badge/-Pinia2-yellow?logo=picpay&logoColor=white" alt="Pinia2" />
|
||||||
<img src="https://img.shields.io/badge/-ESLint-4b32c3?logo=eslint&logoColor=white" />
|
<img src="https://img.shields.io/badge/-ESLint-4b32c3?logo=eslint&logoColor=white" alt="eslint" />
|
||||||
<img src="https://img.shields.io/badge/-pnpm7-F69220?logo=pnpm&logoColor=white" />
|
<img src="https://img.shields.io/badge/-pnpm7-F69220?logo=pnpm&logoColor=white" alt="pnpm" />
|
||||||
<img src="https://img.shields.io/badge/-Axios-008fc7?logo=axios.js&logoColor=white" />
|
|
||||||
<img src="https://img.shields.io/badge/-Prettier-ef9421?logo=Prettier&logoColor=white" alt="Prettier">
|
<img src="https://img.shields.io/badge/-Prettier-ef9421?logo=Prettier&logoColor=white" alt="Prettier">
|
||||||
<img src="https://img.shields.io/badge/-Sass-1D365D?logo=Sass&logoColor=white" alt="Sass">
|
<img src="https://img.shields.io/badge/-Sass-1D365D?logo=Sass&logoColor=white" alt="Sass">
|
||||||
<img src="https://img.shields.io/badge/-Wind%20CSS-06B6D4?logo=Tailwind%20CSS&logoColor=white" alt="Taiwind">
|
<img src="https://img.shields.io/badge/-Wind%20CSS-06B6D4?logo=Tailwind%20CSS&logoColor=white" alt="WindCSS">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## 介绍
|
## 介绍
|
||||||
@ -30,11 +29,11 @@
|
|||||||
| 框架 | 说明 | 版本 |
|
| 框架 | 说明 | 版本 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| [Vue](https://staging-cn.vuejs.org/) | vue 框架 | 3.2.45 |
|
| [Vue](https://staging-cn.vuejs.org/) | vue 框架 | 3.2.45 |
|
||||||
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.0.2 |
|
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.0.3 |
|
||||||
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.27 |
|
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.27 |
|
||||||
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.9.4 |
|
| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.9.4 |
|
||||||
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.28 |
|
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.28 |
|
||||||
| [vueuse](https://vueuse.org/) | 常用工具集 | 9.6.0 |
|
| [vueuse](https://vueuse.org/) | 常用工具集 | 9.8.2 |
|
||||||
| [vxe-table](https://vxetable.cn/) | vue 最强表单 | 4.3.7 |
|
| [vxe-table](https://vxetable.cn/) | vue 最强表单 | 4.3.7 |
|
||||||
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 |
|
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 |
|
||||||
| [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.6 |
|
| [vue-router](https://router.vuejs.org/) | vue 路由 | 4.1.6 |
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "yudao-ui-admin-vue3",
|
"name": "yudao-ui-admin-vue3",
|
||||||
"version": "1.6.5.1877",
|
"version": "1.6.5.1878",
|
||||||
"description": "基于vue3、vite4、element-plus、typesScript",
|
"description": "基于vue3、vite4、element-plus、typesScript",
|
||||||
"author": "xingyu",
|
"author": "xingyu",
|
||||||
"private": false,
|
"private": false,
|
||||||
@ -25,12 +25,13 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify/iconify": "^3.0.1",
|
"@iconify/iconify": "^3.0.1",
|
||||||
"@vueuse/core": "^9.7.0",
|
"@vueuse/core": "^9.8.2",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.10",
|
"@wangeditor/editor-for-vue": "^5.1.10",
|
||||||
"@zxcvbn-ts/core": "^2.1.0",
|
"@zxcvbn-ts/core": "^2.1.0",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.2.1",
|
||||||
|
"cropperjs": "^1.5.13",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"echarts": "^5.4.1",
|
"echarts": "^5.4.1",
|
||||||
@ -46,10 +47,9 @@
|
|||||||
"qs": "^6.11.0",
|
"qs": "^6.11.0",
|
||||||
"url": "^0.11.0",
|
"url": "^0.11.0",
|
||||||
"vue": "3.2.45",
|
"vue": "3.2.45",
|
||||||
"vue-cropper": "^1.0.3",
|
|
||||||
"vue-i18n": "9.2.2",
|
"vue-i18n": "9.2.2",
|
||||||
"vue-router": "^4.1.6",
|
"vue-router": "^4.1.6",
|
||||||
"vue-types": "^5.0.1",
|
"vue-types": "^5.0.2",
|
||||||
"vxe-table": "^4.3.7",
|
"vxe-table": "^4.3.7",
|
||||||
"web-storage-cache": "^1.1.1",
|
"web-storage-cache": "^1.1.1",
|
||||||
"xe-utils": "^3.5.7"
|
"xe-utils": "^3.5.7"
|
||||||
@ -57,7 +57,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.3.0",
|
"@commitlint/cli": "^17.3.0",
|
||||||
"@commitlint/config-conventional": "^17.3.0",
|
"@commitlint/config-conventional": "^17.3.0",
|
||||||
"@iconify/json": "^2.1.154",
|
"@iconify/json": "^2.1.155",
|
||||||
"@intlify/unplugin-vue-i18n": "^0.8.1",
|
"@intlify/unplugin-vue-i18n": "^0.8.1",
|
||||||
"@purge-icons/generated": "^0.9.0",
|
"@purge-icons/generated": "^0.9.0",
|
||||||
"@types/intro.js": "^5.1.0",
|
"@types/intro.js": "^5.1.0",
|
||||||
@ -84,7 +84,7 @@
|
|||||||
"postcss-scss": "^4.0.6",
|
"postcss-scss": "^4.0.6",
|
||||||
"prettier": "^2.8.1",
|
"prettier": "^2.8.1",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rollup": "^3.7.5",
|
"rollup": "^3.8.0",
|
||||||
"sass": "^1.57.1",
|
"sass": "^1.57.1",
|
||||||
"stylelint": "^14.16.0",
|
"stylelint": "^14.16.0",
|
||||||
"stylelint-config-html": "^1.1.0",
|
"stylelint-config-html": "^1.1.0",
|
||||||
@ -94,7 +94,7 @@
|
|||||||
"stylelint-order": "^5.0.0",
|
"stylelint-order": "^5.0.0",
|
||||||
"terser": "^5.16.1",
|
"terser": "^5.16.1",
|
||||||
"typescript": "4.9.4",
|
"typescript": "4.9.4",
|
||||||
"vite": "4.0.2",
|
"vite": "4.0.3",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-ejs": "^1.6.4",
|
"vite-plugin-ejs": "^1.6.4",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
@ -104,7 +104,7 @@
|
|||||||
"vite-plugin-svg-icons": "^2.0.1",
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||||
"vite-plugin-windicss": "^1.8.10",
|
"vite-plugin-windicss": "^1.8.10",
|
||||||
"vue-tsc": "^1.0.14",
|
"vue-tsc": "^1.0.16",
|
||||||
"windicss": "^3.5.6"
|
"windicss": "^3.5.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -4,7 +4,7 @@ specifiers:
|
|||||||
'@commitlint/cli': ^17.3.0
|
'@commitlint/cli': ^17.3.0
|
||||||
'@commitlint/config-conventional': ^17.3.0
|
'@commitlint/config-conventional': ^17.3.0
|
||||||
'@iconify/iconify': ^3.0.1
|
'@iconify/iconify': ^3.0.1
|
||||||
'@iconify/json': ^2.1.154
|
'@iconify/json': ^2.1.155
|
||||||
'@intlify/unplugin-vue-i18n': ^0.8.1
|
'@intlify/unplugin-vue-i18n': ^0.8.1
|
||||||
'@purge-icons/generated': ^0.9.0
|
'@purge-icons/generated': ^0.9.0
|
||||||
'@types/intro.js': ^5.1.0
|
'@types/intro.js': ^5.1.0
|
||||||
@ -18,7 +18,7 @@ specifiers:
|
|||||||
'@vitejs/plugin-legacy': ^3.0.1
|
'@vitejs/plugin-legacy': ^3.0.1
|
||||||
'@vitejs/plugin-vue': ^4.0.0
|
'@vitejs/plugin-vue': ^4.0.0
|
||||||
'@vitejs/plugin-vue-jsx': ^3.0.0
|
'@vitejs/plugin-vue-jsx': ^3.0.0
|
||||||
'@vueuse/core': ^9.7.0
|
'@vueuse/core': ^9.8.2
|
||||||
'@wangeditor/editor': ^5.1.23
|
'@wangeditor/editor': ^5.1.23
|
||||||
'@wangeditor/editor-for-vue': ^5.1.10
|
'@wangeditor/editor-for-vue': ^5.1.10
|
||||||
'@zxcvbn-ts/core': ^2.1.0
|
'@zxcvbn-ts/core': ^2.1.0
|
||||||
@ -26,6 +26,7 @@ specifiers:
|
|||||||
autoprefixer: ^10.4.13
|
autoprefixer: ^10.4.13
|
||||||
axios: ^1.2.1
|
axios: ^1.2.1
|
||||||
consola: ^2.15.3
|
consola: ^2.15.3
|
||||||
|
cropperjs: ^1.5.13
|
||||||
crypto-js: ^4.1.1
|
crypto-js: ^4.1.1
|
||||||
dayjs: ^1.11.7
|
dayjs: ^1.11.7
|
||||||
echarts: ^5.4.1
|
echarts: ^5.4.1
|
||||||
@ -50,7 +51,7 @@ specifiers:
|
|||||||
qrcode: ^1.5.1
|
qrcode: ^1.5.1
|
||||||
qs: ^6.11.0
|
qs: ^6.11.0
|
||||||
rimraf: ^3.0.2
|
rimraf: ^3.0.2
|
||||||
rollup: ^3.7.5
|
rollup: ^3.8.0
|
||||||
sass: ^1.57.1
|
sass: ^1.57.1
|
||||||
stylelint: ^14.16.0
|
stylelint: ^14.16.0
|
||||||
stylelint-config-html: ^1.1.0
|
stylelint-config-html: ^1.1.0
|
||||||
@ -61,7 +62,7 @@ specifiers:
|
|||||||
terser: ^5.16.1
|
terser: ^5.16.1
|
||||||
typescript: 4.9.4
|
typescript: 4.9.4
|
||||||
url: ^0.11.0
|
url: ^0.11.0
|
||||||
vite: 4.0.2
|
vite: 4.0.3
|
||||||
vite-plugin-compression: ^0.5.1
|
vite-plugin-compression: ^0.5.1
|
||||||
vite-plugin-ejs: ^1.6.4
|
vite-plugin-ejs: ^1.6.4
|
||||||
vite-plugin-eslint: ^1.8.1
|
vite-plugin-eslint: ^1.8.1
|
||||||
@ -72,11 +73,10 @@ specifiers:
|
|||||||
vite-plugin-vue-setup-extend: ^0.4.0
|
vite-plugin-vue-setup-extend: ^0.4.0
|
||||||
vite-plugin-windicss: ^1.8.10
|
vite-plugin-windicss: ^1.8.10
|
||||||
vue: 3.2.45
|
vue: 3.2.45
|
||||||
vue-cropper: ^1.0.3
|
|
||||||
vue-i18n: 9.2.2
|
vue-i18n: 9.2.2
|
||||||
vue-router: ^4.1.6
|
vue-router: ^4.1.6
|
||||||
vue-tsc: ^1.0.14
|
vue-tsc: ^1.0.16
|
||||||
vue-types: ^5.0.1
|
vue-types: ^5.0.2
|
||||||
vxe-table: ^4.3.7
|
vxe-table: ^4.3.7
|
||||||
web-storage-cache: ^1.1.1
|
web-storage-cache: ^1.1.1
|
||||||
windicss: ^3.5.6
|
windicss: ^3.5.6
|
||||||
@ -84,12 +84,13 @@ specifiers:
|
|||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@iconify/iconify': 3.0.1
|
'@iconify/iconify': 3.0.1
|
||||||
'@vueuse/core': 9.7.0_vue@3.2.45
|
'@vueuse/core': 9.8.2_vue@3.2.45
|
||||||
'@wangeditor/editor': 5.1.23
|
'@wangeditor/editor': 5.1.23
|
||||||
'@wangeditor/editor-for-vue': 5.1.12_3apfu3xbp6awzuex7ed3sbrv6y
|
'@wangeditor/editor-for-vue': 5.1.12_3apfu3xbp6awzuex7ed3sbrv6y
|
||||||
'@zxcvbn-ts/core': 2.1.0
|
'@zxcvbn-ts/core': 2.1.0
|
||||||
animate.css: 4.1.1
|
animate.css: 4.1.1
|
||||||
axios: 1.2.1
|
axios: 1.2.1
|
||||||
|
cropperjs: 1.5.13
|
||||||
crypto-js: 4.1.1
|
crypto-js: 4.1.1
|
||||||
dayjs: 1.11.7
|
dayjs: 1.11.7
|
||||||
echarts: registry.npmmirror.com/echarts/5.4.1
|
echarts: registry.npmmirror.com/echarts/5.4.1
|
||||||
@ -105,10 +106,9 @@ dependencies:
|
|||||||
qs: 6.11.0
|
qs: 6.11.0
|
||||||
url: 0.11.0
|
url: 0.11.0
|
||||||
vue: 3.2.45
|
vue: 3.2.45
|
||||||
vue-cropper: 1.0.5
|
|
||||||
vue-i18n: 9.2.2_vue@3.2.45
|
vue-i18n: 9.2.2_vue@3.2.45
|
||||||
vue-router: 4.1.6_vue@3.2.45
|
vue-router: 4.1.6_vue@3.2.45
|
||||||
vue-types: 5.0.1_vue@3.2.45
|
vue-types: 5.0.2_vue@3.2.45
|
||||||
vxe-table: registry.npmmirror.com/vxe-table/4.3.7_vue@3.2.45+xe-utils@3.5.7
|
vxe-table: registry.npmmirror.com/vxe-table/4.3.7_vue@3.2.45+xe-utils@3.5.7
|
||||||
web-storage-cache: 1.1.1
|
web-storage-cache: 1.1.1
|
||||||
xe-utils: 3.5.7
|
xe-utils: 3.5.7
|
||||||
@ -116,7 +116,7 @@ dependencies:
|
|||||||
devDependencies:
|
devDependencies:
|
||||||
'@commitlint/cli': 17.3.0
|
'@commitlint/cli': 17.3.0
|
||||||
'@commitlint/config-conventional': 17.3.0
|
'@commitlint/config-conventional': 17.3.0
|
||||||
'@iconify/json': 2.1.154
|
'@iconify/json': 2.1.155
|
||||||
'@intlify/unplugin-vue-i18n': 0.8.1_vue-i18n@9.2.2
|
'@intlify/unplugin-vue-i18n': 0.8.1_vue-i18n@9.2.2
|
||||||
'@purge-icons/generated': 0.9.0
|
'@purge-icons/generated': 0.9.0
|
||||||
'@types/intro.js': 5.1.0
|
'@types/intro.js': 5.1.0
|
||||||
@ -127,9 +127,9 @@ devDependencies:
|
|||||||
'@types/qs': 6.9.7
|
'@types/qs': 6.9.7
|
||||||
'@typescript-eslint/eslint-plugin': 5.47.0_ncmi6noazr3nzas7jxykisekym
|
'@typescript-eslint/eslint-plugin': 5.47.0_ncmi6noazr3nzas7jxykisekym
|
||||||
'@typescript-eslint/parser': 5.47.0_lzzuuodtsqwxnvqeq4g4likcqa
|
'@typescript-eslint/parser': 5.47.0_lzzuuodtsqwxnvqeq4g4likcqa
|
||||||
'@vitejs/plugin-legacy': registry.npmmirror.com/@vitejs/plugin-legacy/3.0.1_terser@5.16.1+vite@4.0.2
|
'@vitejs/plugin-legacy': registry.npmmirror.com/@vitejs/plugin-legacy/3.0.1_terser@5.16.1+vite@4.0.3
|
||||||
'@vitejs/plugin-vue': registry.npmmirror.com/@vitejs/plugin-vue/4.0.0_vite@4.0.2+vue@3.2.45
|
'@vitejs/plugin-vue': registry.npmmirror.com/@vitejs/plugin-vue/4.0.0_vite@4.0.3+vue@3.2.45
|
||||||
'@vitejs/plugin-vue-jsx': registry.npmmirror.com/@vitejs/plugin-vue-jsx/3.0.0_vite@4.0.2+vue@3.2.45
|
'@vitejs/plugin-vue-jsx': registry.npmmirror.com/@vitejs/plugin-vue-jsx/3.0.0_vite@4.0.3+vue@3.2.45
|
||||||
autoprefixer: 10.4.13_postcss@8.4.20
|
autoprefixer: 10.4.13_postcss@8.4.20
|
||||||
consola: 2.15.3
|
consola: 2.15.3
|
||||||
eslint: 8.30.0
|
eslint: 8.30.0
|
||||||
@ -143,7 +143,7 @@ devDependencies:
|
|||||||
postcss-scss: 4.0.6_postcss@8.4.20
|
postcss-scss: 4.0.6_postcss@8.4.20
|
||||||
prettier: 2.8.1
|
prettier: 2.8.1
|
||||||
rimraf: 3.0.2
|
rimraf: 3.0.2
|
||||||
rollup: 3.7.5
|
rollup: 3.8.0
|
||||||
sass: 1.57.1
|
sass: 1.57.1
|
||||||
stylelint: 14.16.0
|
stylelint: 14.16.0
|
||||||
stylelint-config-html: 1.1.0_bto6pmslw3cibsiuq6smxboytq
|
stylelint-config-html: 1.1.0_bto6pmslw3cibsiuq6smxboytq
|
||||||
@ -153,17 +153,17 @@ devDependencies:
|
|||||||
stylelint-order: 5.0.0_stylelint@14.16.0
|
stylelint-order: 5.0.0_stylelint@14.16.0
|
||||||
terser: 5.16.1
|
terser: 5.16.1
|
||||||
typescript: 4.9.4
|
typescript: 4.9.4
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
vite-plugin-compression: 0.5.1_vite@4.0.2
|
vite-plugin-compression: 0.5.1_vite@4.0.3
|
||||||
vite-plugin-ejs: 1.6.4
|
vite-plugin-ejs: 1.6.4
|
||||||
vite-plugin-eslint: 1.8.1_eslint@8.30.0+vite@4.0.2
|
vite-plugin-eslint: 1.8.1_eslint@8.30.0+vite@4.0.3
|
||||||
vite-plugin-progress: 0.0.6_vite@4.0.2
|
vite-plugin-progress: 0.0.6_vite@4.0.3
|
||||||
vite-plugin-purge-icons: registry.npmmirror.com/vite-plugin-purge-icons/0.9.2_vite@4.0.2
|
vite-plugin-purge-icons: registry.npmmirror.com/vite-plugin-purge-icons/0.9.2_vite@4.0.3
|
||||||
vite-plugin-style-import: 2.0.0_vite@4.0.2
|
vite-plugin-style-import: 2.0.0_vite@4.0.3
|
||||||
vite-plugin-svg-icons: 2.0.1_vite@4.0.2
|
vite-plugin-svg-icons: 2.0.1_vite@4.0.3
|
||||||
vite-plugin-vue-setup-extend: 0.4.0_vite@4.0.2
|
vite-plugin-vue-setup-extend: 0.4.0_vite@4.0.3
|
||||||
vite-plugin-windicss: registry.npmmirror.com/vite-plugin-windicss/1.8.10_vite@4.0.2
|
vite-plugin-windicss: registry.npmmirror.com/vite-plugin-windicss/1.8.10_vite@4.0.3
|
||||||
vue-tsc: 1.0.14_typescript@4.9.4
|
vue-tsc: 1.0.16_typescript@4.9.4
|
||||||
windicss: 3.5.6
|
windicss: 3.5.6
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
@ -631,8 +631,8 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@iconify/types': 2.0.0
|
'@iconify/types': 2.0.0
|
||||||
|
|
||||||
/@iconify/json/2.1.154:
|
/@iconify/json/2.1.155:
|
||||||
resolution: {integrity: sha512-RpUu4zDoeqIAzD54t8mfCKca+fzASgFf+lFE7Y9OzvScrf+IbUrvyZZEcOkjEB1cB4emDgmWGTAAkVTihhaqxQ==}
|
resolution: {integrity: sha512-Zr0809RkIKB/0pX3jFfLX4TI8fv1aW6+FHXlfRiDhFKQSmhcs2x5xYhtxI5GUzl+9o6Le544uUCljmHBYJUFrA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@iconify/types': 2.0.0
|
'@iconify/types': 2.0.0
|
||||||
pathe: 0.3.9
|
pathe: 0.3.9
|
||||||
@ -1079,44 +1079,44 @@ packages:
|
|||||||
nanoid: registry.npmmirror.com/nanoid/3.3.4
|
nanoid: registry.npmmirror.com/nanoid/3.3.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@volar/language-core/1.0.14:
|
/@volar/language-core/1.0.16:
|
||||||
resolution: {integrity: sha512-j1tMQgw0qCV2amM4qDJNG/zc0yj3ay8HoWNt05IaiCPsULtSSpF/9+F6Izvn0DF7nWOd6MUHTxaQAeZwLfr56Q==}
|
resolution: {integrity: sha512-IGnOxWTs4DZ81TDcmxBAkCBxs97hUblwcjpBsTx/pOGGaSSDQRJPn0wL8NYTybEObU0i7lhEpKZ+0vJfdIy1Kg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/source-map': 1.0.14
|
'@volar/source-map': 1.0.16
|
||||||
'@vue/reactivity': 3.2.45
|
'@vue/reactivity': 3.2.45
|
||||||
muggle-string: 0.1.0
|
muggle-string: 0.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@volar/source-map/1.0.14:
|
/@volar/source-map/1.0.16:
|
||||||
resolution: {integrity: sha512-8pHCbEWHWaSDGb/FM9zRIW1lY1OAo16MENVSQGCgTwz7PWf3Gw6WW3TFVKCtzaFhLjPH0i5e9hALy7vBPbSHoA==}
|
resolution: {integrity: sha512-PKjzmQcg8QOGC/1V9tmGh2jcy6bKLhkW5bGidElSr83iDbCzLvldt2/La/QlDxaRCHYLT0MeyuGJBZIChB1dYQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
muggle-string: 0.1.0
|
muggle-string: 0.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@volar/typescript/1.0.14:
|
/@volar/typescript/1.0.16:
|
||||||
resolution: {integrity: sha512-67qcjjz7KGFhMCG9EKMA9qJK3BRGQecO4dGyAKfMfClZ/PaVoKfDvJvYo89McGTQ8SeczD48I9TPnaJM0zK8JQ==}
|
resolution: {integrity: sha512-Yov+n4oO3iYnuMt9QJAFpJabfTRCzc7KvjlAwBaSuZy+Gc/f9611MgtqAh5/SIGmltFN8dXn1Ijno8ro8I4lyw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/language-core': 1.0.14
|
'@volar/language-core': 1.0.16
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@volar/vue-language-core/1.0.14:
|
/@volar/vue-language-core/1.0.16:
|
||||||
resolution: {integrity: sha512-grJ4dQ7c/suZmBBmZtw2O2XeDX+rtgpdBtHxMug1NMPRDxj5EZ9WGphWtGnMQj8RyVgpz9ByvV5GbQjk4/wfBw==}
|
resolution: {integrity: sha512-sQ/aW1Vuiyy4OQuh2lthyYicruM3qh9VSk/aDh8/bFvM8GoohHZqVpMN3LYldEJ9eT/rN6u4xmYP54vc/EjX4Q==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/language-core': 1.0.14
|
'@volar/language-core': 1.0.16
|
||||||
'@volar/source-map': 1.0.14
|
'@volar/source-map': 1.0.16
|
||||||
'@vue/compiler-dom': 3.2.45
|
'@vue/compiler-dom': 3.2.45
|
||||||
'@vue/compiler-sfc': 3.2.45
|
'@vue/compiler-sfc': 3.2.45
|
||||||
'@vue/reactivity': 3.2.45
|
'@vue/reactivity': 3.2.45
|
||||||
'@vue/shared': 3.2.45
|
'@vue/shared': 3.2.45
|
||||||
minimatch: 5.1.0
|
minimatch: 5.1.2
|
||||||
vue-template-compiler: 2.7.14
|
vue-template-compiler: 2.7.14
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@volar/vue-typescript/1.0.14:
|
/@volar/vue-typescript/1.0.16:
|
||||||
resolution: {integrity: sha512-2P0QeGLLY05fDTu8GqY8SR2+jldXRTrkQdD2Nc0sVOjMJ7j3RYYY0wJyZ9hCBDuxV4Micc6jdB8nKS0yxQgNvA==}
|
resolution: {integrity: sha512-M018Ulg/o2FVktAdlr5b/z4K69bYzekxNUA1o39y5Ur6CObc/o+5eDCCS7gIYijWnx9iNKkSQpWWWblJFv7kHQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/typescript': 1.0.14
|
'@volar/typescript': 1.0.16
|
||||||
'@volar/vue-language-core': 1.0.14
|
'@volar/vue-language-core': 1.0.16
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@vue/compiler-core/3.2.45:
|
/@vue/compiler-core/3.2.45:
|
||||||
@ -1196,24 +1196,24 @@ packages:
|
|||||||
/@vue/shared/3.2.45:
|
/@vue/shared/3.2.45:
|
||||||
resolution: {integrity: sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==}
|
resolution: {integrity: sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==}
|
||||||
|
|
||||||
/@vueuse/core/9.7.0_vue@3.2.45:
|
/@vueuse/core/9.8.2_vue@3.2.45:
|
||||||
resolution: {integrity: sha512-/AGY/t7jJPxCyRoVTygNKoroTiCvRaaZIW+yeSlBCnI7QRpQ9cvXNTdNaSl3GvSyFbn83+XwZwEZvI1OpQfeGw==}
|
resolution: {integrity: sha512-aWiCmcYIpPt7xjuqYiceODEMHchDYthrJ4AqI+FXPZrR23PZOqdiktbUVyQl2kGlR3H4i9UJ/uimQrwhz9UouQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/web-bluetooth': 0.0.16
|
'@types/web-bluetooth': 0.0.16
|
||||||
'@vueuse/metadata': 9.7.0
|
'@vueuse/metadata': 9.8.2
|
||||||
'@vueuse/shared': 9.7.0_vue@3.2.45
|
'@vueuse/shared': 9.8.2_vue@3.2.45
|
||||||
vue-demi: 0.13.11_vue@3.2.45
|
vue-demi: 0.13.11_vue@3.2.45
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@vueuse/metadata/9.7.0:
|
/@vueuse/metadata/9.8.2:
|
||||||
resolution: {integrity: sha512-M7WsAgw28FNtTH0bzsGuHEtJOPJqPpyeHS6PHq+8UesLgNjZ9waMAntiUrgUQlxt09M4i2lH7y9sRi0jkfeXGA==}
|
resolution: {integrity: sha512-N4E/BKS+9VsUeD4WLVRU1J2kCOLh+iikBcMtipFcTyL204132vDYHs27zLAVabJYGnhC0dIVGdhg9pbOZiY2TQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@vueuse/shared/9.7.0_vue@3.2.45:
|
/@vueuse/shared/9.8.2_vue@3.2.45:
|
||||||
resolution: {integrity: sha512-pwmt1y3TJ2s5KqWmkv9ZKEV59GwuZQZk8XLiU+hGswz0jej318ozbea9E4A/A50ksyM26swSFr7sZ9llNPsZHg==}
|
resolution: {integrity: sha512-ACjrPQzowd5dnabNJt9EoGVobco9/ENiA5qP53vjiuxndlJYuc/UegwhXC7KdQbPX4F45a50+45K3g1wNqOzmA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
vue-demi: 0.13.11_vue@3.2.45
|
vue-demi: 0.13.11_vue@3.2.45
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -2019,6 +2019,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/cropperjs/1.5.13:
|
||||||
|
resolution: {integrity: sha512-by7jKAo73y5/Do0K6sxdTKHgndY0NMjG2bEdgeJxycbcmHuCiMXqw8sxy5C5Y5WTOTcDGmbT7Sr5CgKOXR06OA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/cross-spawn/7.0.3:
|
/cross-spawn/7.0.3:
|
||||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@ -2319,7 +2323,7 @@ packages:
|
|||||||
'@popperjs/core': /@sxzz/popperjs-es/2.11.7
|
'@popperjs/core': /@sxzz/popperjs-es/2.11.7
|
||||||
'@types/lodash': 4.14.189
|
'@types/lodash': 4.14.189
|
||||||
'@types/lodash-es': 4.17.6
|
'@types/lodash-es': 4.17.6
|
||||||
'@vueuse/core': 9.7.0_vue@3.2.45
|
'@vueuse/core': 9.8.2_vue@3.2.45
|
||||||
async-validator: 4.2.5
|
async-validator: 4.2.5
|
||||||
dayjs: 1.11.7
|
dayjs: 1.11.7
|
||||||
escape-html: 1.0.3
|
escape-html: 1.0.3
|
||||||
@ -3831,6 +3835,13 @@ packages:
|
|||||||
brace-expansion: 2.0.1
|
brace-expansion: 2.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/minimatch/5.1.2:
|
||||||
|
resolution: {integrity: sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dependencies:
|
||||||
|
brace-expansion: 2.0.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/minimist-options/4.1.0:
|
/minimist-options/4.1.0:
|
||||||
resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==}
|
resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@ -4544,8 +4555,8 @@ packages:
|
|||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/rollup/3.7.5:
|
/rollup/3.8.0:
|
||||||
resolution: {integrity: sha512-z0ZbqHBtS/et2EEUKMrAl2CoSdwN7ZPzL17UMiKN9RjjqHShTlv7F9J6ZJZJNREYjBh3TvBrdfjkFDIXFNeuiQ==}
|
resolution: {integrity: sha512-+UR6PnUslneJNiJfLSzy4XH6R50ZGF0MS7UCv20ftXrktF/TkvZDwiBtXX65esblLR5p8w6LmXgPwt2f2B8SoQ==}
|
||||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@ -5338,7 +5349,7 @@ packages:
|
|||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite-plugin-compression/0.5.1_vite@4.0.2:
|
/vite-plugin-compression/0.5.1_vite@4.0.3:
|
||||||
resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
|
resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: '>=2.0.0'
|
vite: '>=2.0.0'
|
||||||
@ -5346,7 +5357,7 @@ packages:
|
|||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
fs-extra: 10.1.0
|
fs-extra: 10.1.0
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
@ -5357,7 +5368,7 @@ packages:
|
|||||||
ejs: 3.1.8
|
ejs: 3.1.8
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite-plugin-eslint/1.8.1_eslint@8.30.0+vite@4.0.2:
|
/vite-plugin-eslint/1.8.1_eslint@8.30.0+vite@4.0.3:
|
||||||
resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==}
|
resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=7'
|
eslint: '>=7'
|
||||||
@ -5367,10 +5378,10 @@ packages:
|
|||||||
'@types/eslint': 8.4.10
|
'@types/eslint': 8.4.10
|
||||||
eslint: 8.30.0
|
eslint: 8.30.0
|
||||||
rollup: 2.79.1
|
rollup: 2.79.1
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite-plugin-progress/0.0.6_vite@4.0.2:
|
/vite-plugin-progress/0.0.6_vite@4.0.3:
|
||||||
resolution: {integrity: sha512-pIK2TVEY4XFGrz10CQDdEufBBCDaV0geRHfXV3abGTBr+OF9O0Zmd3ZDrHJXDv4Rl3qAQP4BTCuPYQ3XqstmqA==}
|
resolution: {integrity: sha512-pIK2TVEY4XFGrz10CQDdEufBBCDaV0geRHfXV3abGTBr+OF9O0Zmd3ZDrHJXDv4Rl3qAQP4BTCuPYQ3XqstmqA==}
|
||||||
engines: {node: '>=14', pnpm: '>=7.0.0'}
|
engines: {node: '>=14', pnpm: '>=7.0.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -5379,10 +5390,10 @@ packages:
|
|||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
progress: 2.0.3
|
progress: 2.0.3
|
||||||
rd: 2.0.1
|
rd: 2.0.1
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite-plugin-style-import/2.0.0_vite@4.0.2:
|
/vite-plugin-style-import/2.0.0_vite@4.0.3:
|
||||||
resolution: {integrity: sha512-qtoHQae5dSUQPo/rYz/8p190VU5y19rtBaeV7ryLa/AYAU/e9CG89NrN/3+k7MR8mJy/GPIu91iJ3zk9foUOSA==}
|
resolution: {integrity: sha512-qtoHQae5dSUQPo/rYz/8p190VU5y19rtBaeV7ryLa/AYAU/e9CG89NrN/3+k7MR8mJy/GPIu91iJ3zk9foUOSA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: '>=2.0.0'
|
vite: '>=2.0.0'
|
||||||
@ -5394,10 +5405,10 @@ packages:
|
|||||||
fs-extra: 10.1.0
|
fs-extra: 10.1.0
|
||||||
magic-string: 0.25.9
|
magic-string: 0.25.9
|
||||||
pathe: 0.2.0
|
pathe: 0.2.0
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite-plugin-svg-icons/2.0.1_vite@4.0.2:
|
/vite-plugin-svg-icons/2.0.1_vite@4.0.3:
|
||||||
resolution: {integrity: sha512-6ktD+DhV6Rz3VtedYvBKKVA2eXF+sAQVaKkKLDSqGUfnhqXl3bj5PPkVTl3VexfTuZy66PmINi8Q6eFnVfRUmA==}
|
resolution: {integrity: sha512-6ktD+DhV6Rz3VtedYvBKKVA2eXF+sAQVaKkKLDSqGUfnhqXl3bj5PPkVTl3VexfTuZy66PmINi8Q6eFnVfRUmA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: '>=2.0.0'
|
vite: '>=2.0.0'
|
||||||
@ -5410,23 +5421,23 @@ packages:
|
|||||||
pathe: 0.2.0
|
pathe: 0.2.0
|
||||||
svg-baker: 1.7.0
|
svg-baker: 1.7.0
|
||||||
svgo: 2.8.0
|
svgo: 2.8.0
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite-plugin-vue-setup-extend/0.4.0_vite@4.0.2:
|
/vite-plugin-vue-setup-extend/0.4.0_vite@4.0.3:
|
||||||
resolution: {integrity: sha512-WMbjPCui75fboFoUTHhdbXzu4Y/bJMv5N9QT9a7do3wNMNHHqrk+Tn2jrSJU0LS5fGl/EG+FEDBYVUeWIkDqXQ==}
|
resolution: {integrity: sha512-WMbjPCui75fboFoUTHhdbXzu4Y/bJMv5N9QT9a7do3wNMNHHqrk+Tn2jrSJU0LS5fGl/EG+FEDBYVUeWIkDqXQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: '>=2.0.0'
|
vite: '>=2.0.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/compiler-sfc': 3.2.45
|
'@vue/compiler-sfc': 3.2.45
|
||||||
magic-string: 0.25.9
|
magic-string: 0.25.9
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite/4.0.2_amyfslv6hdwxqbf7f4ldebbtce:
|
/vite/4.0.3_amyfslv6hdwxqbf7f4ldebbtce:
|
||||||
resolution: {integrity: sha512-QJaY3R+tFlTagH0exVqbgkkw45B+/bXVBzF2ZD1KB5Z8RiAoiKo60vSUf6/r4c2Vh9jfGBKM4oBI9b4/1ZJYng==}
|
resolution: {integrity: sha512-HvuNv1RdE7deIfQb8mPk51UKjqptO/4RXZ5yXSAvurd5xOckwS/gg8h9Tky3uSbnjYTgUm0hVCet1cyhKd73ZA==}
|
||||||
engines: {node: ^14.18.0 || >=16.0.0}
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -5454,17 +5465,13 @@ packages:
|
|||||||
esbuild: 0.16.5
|
esbuild: 0.16.5
|
||||||
postcss: 8.4.20
|
postcss: 8.4.20
|
||||||
resolve: 1.22.1
|
resolve: 1.22.1
|
||||||
rollup: 3.7.5
|
rollup: 3.8.0
|
||||||
sass: 1.57.1
|
sass: 1.57.1
|
||||||
terser: 5.16.1
|
terser: 5.16.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vue-cropper/1.0.5:
|
|
||||||
resolution: {integrity: sha512-D4XXdqWmMWRLOIV9LIh7/mkH6OBOMQDFbRjwntkxmAtxOtwpC9U5ZZ6lSXw5F5cbd4g8znDjk6MuCwIL+fZSrA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/vue-demi/0.13.11_vue@3.2.45:
|
/vue-demi/0.13.11_vue@3.2.45:
|
||||||
resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==}
|
resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@ -5526,19 +5533,19 @@ packages:
|
|||||||
he: 1.2.0
|
he: 1.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vue-tsc/1.0.14_typescript@4.9.4:
|
/vue-tsc/1.0.16_typescript@4.9.4:
|
||||||
resolution: {integrity: sha512-HeqtyxMrSRUCnU5nxB0lQc3o7zirMppZ/V6HLL3l4FsObGepH3A3beNmNehpLQs0Gt7DkSWVi3CpVCFgrf+/sQ==}
|
resolution: {integrity: sha512-yZaiJBbcKR1rSLhiF9KryAFH7R63po+N/invr2EAHGXxMzZksE5j1zyQKvrYiqK47ZHLAlCR+re/PHqWp/UzTg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '*'
|
typescript: '*'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/vue-language-core': 1.0.14
|
'@volar/vue-language-core': 1.0.16
|
||||||
'@volar/vue-typescript': 1.0.14
|
'@volar/vue-typescript': 1.0.16
|
||||||
typescript: 4.9.4
|
typescript: 4.9.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vue-types/5.0.1_vue@3.2.45:
|
/vue-types/5.0.2_vue@3.2.45:
|
||||||
resolution: {integrity: sha512-pHahh/Ht+mxAhSGXfFe0WQidZukYUoCevPoQtePpONrmNP+OjX3/ps/XjYLgw/Zbv4rks242eiVJcjE3EELsyw==}
|
resolution: {integrity: sha512-+/5hnQ65XOYqPs+tEUF8GGTJX95UFVH0wPQo71IJJYh5TKMfik2tGKTLkZ42JqAczANA9hGu5FrZmPgxn20nnA==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: ^2.0.0 || ^3.0.0
|
vue: ^2.0.0 || ^3.0.0
|
||||||
@ -6239,7 +6246,7 @@ packages:
|
|||||||
'@iconify/iconify': registry.npmmirror.com/@iconify/iconify/3.0.1
|
'@iconify/iconify': registry.npmmirror.com/@iconify/iconify/3.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@vitejs/plugin-legacy/3.0.1_terser@5.16.1+vite@4.0.2:
|
registry.npmmirror.com/@vitejs/plugin-legacy/3.0.1_terser@5.16.1+vite@4.0.3:
|
||||||
resolution: {integrity: sha512-XCtEjxoR3rmy000ujYRBp5kggWqzHz9+F20/yIMUWOzbvu0+KW1e14Fvb8h7SpNn+bfjGW1RiAs1Vrgb7Js+iQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vitejs/plugin-legacy/-/plugin-legacy-3.0.1.tgz}
|
resolution: {integrity: sha512-XCtEjxoR3rmy000ujYRBp5kggWqzHz9+F20/yIMUWOzbvu0+KW1e14Fvb8h7SpNn+bfjGW1RiAs1Vrgb7Js+iQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vitejs/plugin-legacy/-/plugin-legacy-3.0.1.tgz}
|
||||||
id: registry.npmmirror.com/@vitejs/plugin-legacy/3.0.1
|
id: registry.npmmirror.com/@vitejs/plugin-legacy/3.0.1
|
||||||
name: '@vitejs/plugin-legacy'
|
name: '@vitejs/plugin-legacy'
|
||||||
@ -6255,10 +6262,10 @@ packages:
|
|||||||
regenerator-runtime: registry.npmmirror.com/regenerator-runtime/0.13.11
|
regenerator-runtime: registry.npmmirror.com/regenerator-runtime/0.13.11
|
||||||
systemjs: registry.npmmirror.com/systemjs/6.13.0
|
systemjs: registry.npmmirror.com/systemjs/6.13.0
|
||||||
terser: 5.16.1
|
terser: 5.16.1
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@vitejs/plugin-vue-jsx/3.0.0_vite@4.0.2+vue@3.2.45:
|
registry.npmmirror.com/@vitejs/plugin-vue-jsx/3.0.0_vite@4.0.3+vue@3.2.45:
|
||||||
resolution: {integrity: sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.0.0.tgz}
|
resolution: {integrity: sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.0.0.tgz}
|
||||||
id: registry.npmmirror.com/@vitejs/plugin-vue-jsx/3.0.0
|
id: registry.npmmirror.com/@vitejs/plugin-vue-jsx/3.0.0
|
||||||
name: '@vitejs/plugin-vue-jsx'
|
name: '@vitejs/plugin-vue-jsx'
|
||||||
@ -6271,13 +6278,13 @@ packages:
|
|||||||
'@babel/core': registry.npmmirror.com/@babel/core/7.20.5
|
'@babel/core': registry.npmmirror.com/@babel/core/7.20.5
|
||||||
'@babel/plugin-transform-typescript': registry.npmmirror.com/@babel/plugin-transform-typescript/7.20.2_@babel+core@7.20.5
|
'@babel/plugin-transform-typescript': registry.npmmirror.com/@babel/plugin-transform-typescript/7.20.2_@babel+core@7.20.5
|
||||||
'@vue/babel-plugin-jsx': registry.npmmirror.com/@vue/babel-plugin-jsx/1.1.1_@babel+core@7.20.5
|
'@vue/babel-plugin-jsx': registry.npmmirror.com/@vue/babel-plugin-jsx/1.1.1_@babel+core@7.20.5
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
vue: 3.2.45
|
vue: 3.2.45
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@vitejs/plugin-vue/4.0.0_vite@4.0.2+vue@3.2.45:
|
registry.npmmirror.com/@vitejs/plugin-vue/4.0.0_vite@4.0.3+vue@3.2.45:
|
||||||
resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.0.0.tgz}
|
resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.0.0.tgz}
|
||||||
id: registry.npmmirror.com/@vitejs/plugin-vue/4.0.0
|
id: registry.npmmirror.com/@vitejs/plugin-vue/4.0.0
|
||||||
name: '@vitejs/plugin-vue'
|
name: '@vitejs/plugin-vue'
|
||||||
@ -6287,7 +6294,7 @@ packages:
|
|||||||
vite: ^4.0.0
|
vite: ^4.0.0
|
||||||
vue: ^3.2.25
|
vue: ^3.2.25
|
||||||
dependencies:
|
dependencies:
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
vue: 3.2.45
|
vue: 3.2.45
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
@ -7026,7 +7033,7 @@ packages:
|
|||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/vite-plugin-purge-icons/0.9.2_vite@4.0.2:
|
registry.npmmirror.com/vite-plugin-purge-icons/0.9.2_vite@4.0.3:
|
||||||
resolution: {integrity: sha512-vxJEMyNyckqLr/4HPsW9P6BMLUvOVMvjjFz3jLl4Wke1KWE8ITJUxIUwodxaOmEp9L2lxVk5an3TYeycZCfqFw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite-plugin-purge-icons/-/vite-plugin-purge-icons-0.9.2.tgz}
|
resolution: {integrity: sha512-vxJEMyNyckqLr/4HPsW9P6BMLUvOVMvjjFz3jLl4Wke1KWE8ITJUxIUwodxaOmEp9L2lxVk5an3TYeycZCfqFw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite-plugin-purge-icons/-/vite-plugin-purge-icons-0.9.2.tgz}
|
||||||
id: registry.npmmirror.com/vite-plugin-purge-icons/0.9.2
|
id: registry.npmmirror.com/vite-plugin-purge-icons/0.9.2
|
||||||
name: vite-plugin-purge-icons
|
name: vite-plugin-purge-icons
|
||||||
@ -7038,13 +7045,13 @@ packages:
|
|||||||
'@purge-icons/core': registry.npmmirror.com/@purge-icons/core/0.9.1
|
'@purge-icons/core': registry.npmmirror.com/@purge-icons/core/0.9.1
|
||||||
'@purge-icons/generated': registry.npmmirror.com/@purge-icons/generated/0.9.0
|
'@purge-icons/generated': registry.npmmirror.com/@purge-icons/generated/0.9.0
|
||||||
rollup-plugin-purge-icons: registry.npmmirror.com/rollup-plugin-purge-icons/0.9.1
|
rollup-plugin-purge-icons: registry.npmmirror.com/rollup-plugin-purge-icons/0.9.1
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/vite-plugin-windicss/1.8.10_vite@4.0.2:
|
registry.npmmirror.com/vite-plugin-windicss/1.8.10_vite@4.0.3:
|
||||||
resolution: {integrity: sha512-scywsuzo46lcTBohspmF0WiwhWEte6p+OUVrX4yr7VMRvLHMHVfLtJReyD5pppjijG7YOwVsZn7XBWWZtF658Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite-plugin-windicss/-/vite-plugin-windicss-1.8.10.tgz}
|
resolution: {integrity: sha512-scywsuzo46lcTBohspmF0WiwhWEte6p+OUVrX4yr7VMRvLHMHVfLtJReyD5pppjijG7YOwVsZn7XBWWZtF658Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite-plugin-windicss/-/vite-plugin-windicss-1.8.10.tgz}
|
||||||
id: registry.npmmirror.com/vite-plugin-windicss/1.8.10
|
id: registry.npmmirror.com/vite-plugin-windicss/1.8.10
|
||||||
name: vite-plugin-windicss
|
name: vite-plugin-windicss
|
||||||
@ -7055,7 +7062,7 @@ packages:
|
|||||||
'@windicss/plugin-utils': registry.npmmirror.com/@windicss/plugin-utils/1.8.10
|
'@windicss/plugin-utils': registry.npmmirror.com/@windicss/plugin-utils/1.8.10
|
||||||
debug: registry.npmmirror.com/debug/4.3.4
|
debug: registry.npmmirror.com/debug/4.3.4
|
||||||
kolorist: registry.npmmirror.com/kolorist/1.6.0
|
kolorist: registry.npmmirror.com/kolorist/1.6.0
|
||||||
vite: 4.0.2_amyfslv6hdwxqbf7f4ldebbtce
|
vite: 4.0.3_amyfslv6hdwxqbf7f4ldebbtce
|
||||||
windicss: registry.npmmirror.com/windicss/3.5.6
|
windicss: registry.npmmirror.com/windicss/3.5.6
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -73,5 +73,5 @@ export const updateUserPwdApi = (oldPassword: string, newPassword: string) => {
|
|||||||
|
|
||||||
// 用户头像上传
|
// 用户头像上传
|
||||||
export const uploadAvatarApi = (data) => {
|
export const uploadAvatarApi = (data) => {
|
||||||
return request.put({ url: '/system/user/profile/update-avatar', data })
|
return request.upload({ url: '/system/user/profile/update-avatar', data: data })
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { ElCard } from 'element-plus'
|
import { ElCard } from 'element-plus'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { ref, onMounted, defineEmits } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { Sticky } from '@/components/Sticky'
|
import { Sticky } from '@/components/Sticky'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
4
yudao-ui-admin-vue3/src/components/Cropper/index.ts
Normal file
4
yudao-ui-admin-vue3/src/components/Cropper/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import CropperImage from './src/Cropper.vue'
|
||||||
|
import CropperAvatar from './src/CropperAvatar.vue'
|
||||||
|
|
||||||
|
export { CropperImage, CropperAvatar }
|
257
yudao-ui-admin-vue3/src/components/Cropper/src/CopperModal.vue
Normal file
257
yudao-ui-admin-vue3/src/components/Cropper/src/CopperModal.vue
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Dialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="t('cropper.modalTitle')"
|
||||||
|
width="800px"
|
||||||
|
maxHeight="380px"
|
||||||
|
:canFullscreen="false"
|
||||||
|
>
|
||||||
|
<div :class="prefixCls">
|
||||||
|
<div :class="`${prefixCls}-left`">
|
||||||
|
<div :class="`${prefixCls}-cropper`">
|
||||||
|
<CropperImage
|
||||||
|
v-if="src"
|
||||||
|
:src="src"
|
||||||
|
height="300px"
|
||||||
|
:circled="circled"
|
||||||
|
@cropend="handleCropend"
|
||||||
|
@ready="handleReady"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div :class="`${prefixCls}-toolbar`">
|
||||||
|
<el-upload :fileList="[]" accept="image/*" :beforeUpload="handleBeforeUpload">
|
||||||
|
<el-tooltip :content="t('cropper.selectImage')" placement="bottom">
|
||||||
|
<XButton preIcon="ant-design:upload-outlined" type="primary" />
|
||||||
|
</el-tooltip>
|
||||||
|
</el-upload>
|
||||||
|
<el-space>
|
||||||
|
<el-tooltip :content="t('cropper.btn_reset')" placement="bottom">
|
||||||
|
<XButton
|
||||||
|
type="primary"
|
||||||
|
preIcon="ant-design:reload-outlined"
|
||||||
|
size="small"
|
||||||
|
:disabled="!src"
|
||||||
|
@click="handlerToolbar('reset')"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="t('cropper.btn_rotate_left')" placement="bottom">
|
||||||
|
<XButton
|
||||||
|
type="primary"
|
||||||
|
preIcon="ant-design:rotate-left-outlined"
|
||||||
|
size="small"
|
||||||
|
:disabled="!src"
|
||||||
|
@click="handlerToolbar('rotate', -45)"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="t('cropper.btn_rotate_right')" placement="bottom">
|
||||||
|
<XButton
|
||||||
|
type="primary"
|
||||||
|
preIcon="ant-design:rotate-right-outlined"
|
||||||
|
size="small"
|
||||||
|
:disabled="!src"
|
||||||
|
@click="handlerToolbar('rotate', 45)"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="t('cropper.btn_scale_x')" placement="bottom">
|
||||||
|
<XButton
|
||||||
|
type="primary"
|
||||||
|
preIcon="vaadin:arrows-long-h"
|
||||||
|
size="small"
|
||||||
|
:disabled="!src"
|
||||||
|
@click="handlerToolbar('scaleX')"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="t('cropper.btn_scale_y')" placement="bottom">
|
||||||
|
<XButton
|
||||||
|
type="primary"
|
||||||
|
preIcon="vaadin:arrows-long-v"
|
||||||
|
size="small"
|
||||||
|
:disabled="!src"
|
||||||
|
@click="handlerToolbar('scaleY')"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="t('cropper.btn_zoom_in')" placement="bottom">
|
||||||
|
<XButton
|
||||||
|
type="primary"
|
||||||
|
preIcon="ant-design:zoom-in-outlined"
|
||||||
|
size="small"
|
||||||
|
:disabled="!src"
|
||||||
|
@click="handlerToolbar('zoom', 0.1)"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="t('cropper.btn_zoom_out')" placement="bottom">
|
||||||
|
<XButton
|
||||||
|
type="primary"
|
||||||
|
preIcon="ant-design:zoom-out-outlined"
|
||||||
|
size="small"
|
||||||
|
:disabled="!src"
|
||||||
|
@click="handlerToolbar('zoom', -0.1)"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
</el-space>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div :class="`${prefixCls}-right`">
|
||||||
|
<div :class="`${prefixCls}-preview`">
|
||||||
|
<img :src="previewSource" v-if="previewSource" :alt="t('cropper.preview')" />
|
||||||
|
</div>
|
||||||
|
<template v-if="previewSource">
|
||||||
|
<div :class="`${prefixCls}-group`">
|
||||||
|
<el-avatar :src="previewSource" size="large" />
|
||||||
|
<el-avatar :src="previewSource" :size="48" />
|
||||||
|
<el-avatar :src="previewSource" :size="64" />
|
||||||
|
<el-avatar :src="previewSource" :size="80" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button type="primary" @click="handleOk">{{ t('cropper.okText') }}</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
import { dataURLtoBlob } from '@/utils/filt'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { ElUpload, ElAvatar, ElTooltip, ElSpace } from 'element-plus'
|
||||||
|
import { Dialog } from '@/components/Dialog'
|
||||||
|
import { CropperImage } from '@/components/Cropper'
|
||||||
|
import type { CropendResult, Cropper } from './types'
|
||||||
|
import { propTypes } from '@/utils/propTypes'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
srcValue: propTypes.string.def(''),
|
||||||
|
circled: propTypes.bool.def(true)
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['uploadSuccess'])
|
||||||
|
const { t } = useI18n()
|
||||||
|
const { getPrefixCls } = useDesign()
|
||||||
|
const prefixCls = getPrefixCls('cropper-am')
|
||||||
|
|
||||||
|
const src = ref(props.srcValue)
|
||||||
|
const previewSource = ref('')
|
||||||
|
const cropper = ref<Cropper>()
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
let filename = ''
|
||||||
|
let scaleX = 1
|
||||||
|
let scaleY = 1
|
||||||
|
|
||||||
|
// Block upload
|
||||||
|
function handleBeforeUpload(file: File) {
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
src.value = ''
|
||||||
|
previewSource.value = ''
|
||||||
|
reader.onload = function (e) {
|
||||||
|
src.value = (e.target?.result as string) ?? ''
|
||||||
|
filename = file.name
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCropend({ imgBase64 }: CropendResult) {
|
||||||
|
previewSource.value = imgBase64
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleReady(cropperInstance: Cropper) {
|
||||||
|
cropper.value = cropperInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlerToolbar(event: string, arg?: number) {
|
||||||
|
if (event === 'scaleX') {
|
||||||
|
scaleX = arg = scaleX === -1 ? 1 : -1
|
||||||
|
}
|
||||||
|
if (event === 'scaleY') {
|
||||||
|
scaleY = arg = scaleY === -1 ? 1 : -1
|
||||||
|
}
|
||||||
|
cropper?.value?.[event]?.(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleOk() {
|
||||||
|
const blob = dataURLtoBlob(previewSource.value)
|
||||||
|
emit('uploadSuccess', { source: previewSource.value, data: blob, filename: filename })
|
||||||
|
}
|
||||||
|
function openModal() {
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
function closeModal() {
|
||||||
|
dialogVisible.value = false
|
||||||
|
}
|
||||||
|
defineExpose({ openModal, closeModal })
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
$prefix-cls: #{$namespace}-cropper-am;
|
||||||
|
|
||||||
|
.#{$prefix-cls} {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&-left,
|
||||||
|
&-right {
|
||||||
|
height: 340px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-left {
|
||||||
|
width: 55%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-right {
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-cropper {
|
||||||
|
height: 300px;
|
||||||
|
background: #eee;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
45deg,
|
||||||
|
rgb(0 0 0 / 25%) 25%,
|
||||||
|
transparent 0,
|
||||||
|
transparent 75%,
|
||||||
|
rgb(0 0 0 / 25%) 0
|
||||||
|
),
|
||||||
|
linear-gradient(
|
||||||
|
45deg,
|
||||||
|
rgb(0 0 0 / 25%) 25%,
|
||||||
|
transparent 0,
|
||||||
|
transparent 75%,
|
||||||
|
rgb(0 0 0 / 25%) 0
|
||||||
|
);
|
||||||
|
background-position: 0 0, 12px 12px;
|
||||||
|
background-size: 24px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-toolbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-preview {
|
||||||
|
width: 220px;
|
||||||
|
height: 220px;
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-group {
|
||||||
|
display: flex;
|
||||||
|
padding-top: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
border-top: 1px solid;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
190
yudao-ui-admin-vue3/src/components/Cropper/src/Cropper.vue
Normal file
190
yudao-ui-admin-vue3/src/components/Cropper/src/Cropper.vue
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="getClass" :style="getWrapperStyle">
|
||||||
|
<img
|
||||||
|
v-show="isReady"
|
||||||
|
ref="imgElRef"
|
||||||
|
:src="src"
|
||||||
|
:alt="alt"
|
||||||
|
:crossorigin="crossorigin"
|
||||||
|
:style="getImageStyle"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
computed,
|
||||||
|
CSSProperties,
|
||||||
|
onMounted,
|
||||||
|
onUnmounted,
|
||||||
|
PropType,
|
||||||
|
ref,
|
||||||
|
unref,
|
||||||
|
useAttrs
|
||||||
|
} from 'vue'
|
||||||
|
import Cropper from 'cropperjs'
|
||||||
|
import 'cropperjs/dist/cropper.css'
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
import { useDebounceFn } from '@vueuse/core'
|
||||||
|
import { propTypes } from '@/utils/propTypes'
|
||||||
|
|
||||||
|
type Options = Cropper.Options
|
||||||
|
|
||||||
|
const defaultOptions: Options = {
|
||||||
|
aspectRatio: 1,
|
||||||
|
zoomable: true,
|
||||||
|
zoomOnTouch: true,
|
||||||
|
zoomOnWheel: true,
|
||||||
|
cropBoxMovable: true,
|
||||||
|
cropBoxResizable: true,
|
||||||
|
toggleDragModeOnDblclick: true,
|
||||||
|
autoCrop: true,
|
||||||
|
background: true,
|
||||||
|
highlight: true,
|
||||||
|
center: true,
|
||||||
|
responsive: true,
|
||||||
|
restore: true,
|
||||||
|
checkCrossOrigin: true,
|
||||||
|
checkOrientation: true,
|
||||||
|
scalable: true,
|
||||||
|
modal: true,
|
||||||
|
guides: true,
|
||||||
|
movable: true,
|
||||||
|
rotatable: true
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
src: propTypes.string.def(''),
|
||||||
|
alt: propTypes.string.def(''),
|
||||||
|
circled: propTypes.bool.def(false),
|
||||||
|
realTimePreview: propTypes.bool.def(true),
|
||||||
|
height: propTypes.string.def('360px'),
|
||||||
|
crossorigin: {
|
||||||
|
type: String as PropType<'' | 'anonymous' | 'use-credentials' | undefined>,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
imageStyle: { type: Object as PropType<CSSProperties>, default: () => ({}) },
|
||||||
|
options: { type: Object as PropType<Options>, default: () => ({}) }
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['cropend', 'ready', 'cropendError'])
|
||||||
|
const attrs = useAttrs()
|
||||||
|
const imgElRef = ref<ElRef<HTMLImageElement>>()
|
||||||
|
const cropper = ref<Nullable<Cropper>>()
|
||||||
|
const isReady = ref(false)
|
||||||
|
|
||||||
|
const { getPrefixCls } = useDesign()
|
||||||
|
const prefixCls = getPrefixCls('cropper-image')
|
||||||
|
const debounceRealTimeCroppered = useDebounceFn(realTimeCroppered, 80)
|
||||||
|
|
||||||
|
const getImageStyle = computed((): CSSProperties => {
|
||||||
|
return {
|
||||||
|
height: props.height,
|
||||||
|
maxWidth: '100%',
|
||||||
|
...props.imageStyle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const getClass = computed(() => {
|
||||||
|
return [
|
||||||
|
prefixCls,
|
||||||
|
attrs.class,
|
||||||
|
{
|
||||||
|
[`${prefixCls}--circled`]: props.circled
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
const getWrapperStyle = computed((): CSSProperties => {
|
||||||
|
return { height: `${props.height}`.replace(/px/, '') + 'px' }
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(init)
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
cropper.value?.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
const imgEl = unref(imgElRef)
|
||||||
|
if (!imgEl) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cropper.value = new Cropper(imgEl, {
|
||||||
|
...defaultOptions,
|
||||||
|
ready: () => {
|
||||||
|
isReady.value = true
|
||||||
|
realTimeCroppered()
|
||||||
|
emit('ready', cropper.value)
|
||||||
|
},
|
||||||
|
crop() {
|
||||||
|
debounceRealTimeCroppered()
|
||||||
|
},
|
||||||
|
zoom() {
|
||||||
|
debounceRealTimeCroppered()
|
||||||
|
},
|
||||||
|
cropmove() {
|
||||||
|
debounceRealTimeCroppered()
|
||||||
|
},
|
||||||
|
...props.options
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Real-time display preview
|
||||||
|
function realTimeCroppered() {
|
||||||
|
props.realTimePreview && croppered()
|
||||||
|
}
|
||||||
|
|
||||||
|
// event: return base64 and width and height information after cropping
|
||||||
|
function croppered() {
|
||||||
|
if (!cropper.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let imgInfo = cropper.value.getData()
|
||||||
|
const canvas = props.circled ? getRoundedCanvas() : cropper.value.getCroppedCanvas()
|
||||||
|
canvas.toBlob((blob) => {
|
||||||
|
if (!blob) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let fileReader: FileReader = new FileReader()
|
||||||
|
fileReader.readAsDataURL(blob)
|
||||||
|
fileReader.onloadend = (e) => {
|
||||||
|
emit('cropend', {
|
||||||
|
imgBase64: e.target?.result ?? '',
|
||||||
|
imgInfo
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fileReader.onerror = () => {
|
||||||
|
emit('cropendError')
|
||||||
|
}
|
||||||
|
}, 'image/png')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a circular picture canvas
|
||||||
|
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
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
$prefix-cls: #{$namespace}-cropper-image;
|
||||||
|
|
||||||
|
.#{$prefix-cls} {
|
||||||
|
&--circled {
|
||||||
|
.cropper-view-box,
|
||||||
|
.cropper-face {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
136
yudao-ui-admin-vue3/src/components/Cropper/src/CropperAvatar.vue
Normal file
136
yudao-ui-admin-vue3/src/components/Cropper/src/CropperAvatar.vue
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<div class="user-info-head" @click="open()">
|
||||||
|
<img :src="sourceValue" v-if="sourceValue" class="img-circle img-lg" alt="avatar" />
|
||||||
|
<el-button :class="`${prefixCls}-upload-btn`" @click="open()" v-if="showBtn">
|
||||||
|
{{ btnText ? btnText : t('cropper.selectImage') }}
|
||||||
|
</el-button>
|
||||||
|
<CopperModal
|
||||||
|
ref="cropperModelRef"
|
||||||
|
@upload-success="handleUploadSuccess"
|
||||||
|
:srcValue="sourceValue"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
import { useMessage } from '@/hooks/web/useMessage'
|
||||||
|
import { propTypes } from '@/utils/propTypes'
|
||||||
|
import { ref, watch, watchEffect } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import CopperModal from './CopperModal.vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
width: propTypes.string.def('200px'),
|
||||||
|
value: propTypes.string.def(''),
|
||||||
|
showBtn: propTypes.bool.def(true),
|
||||||
|
btnText: propTypes.string.def('')
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:value', 'change'])
|
||||||
|
const sourceValue = ref(props.value)
|
||||||
|
const { getPrefixCls } = useDesign()
|
||||||
|
const prefixCls = getPrefixCls('cropper-avatar')
|
||||||
|
const message = useMessage()
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const cropperModelRef = ref()
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
sourceValue.value = props.value
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => sourceValue.value,
|
||||||
|
(v: string) => {
|
||||||
|
emit('update:value', v)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
function handleUploadSuccess({ source, data, filename }) {
|
||||||
|
sourceValue.value = source
|
||||||
|
emit('change', { source, data, filename })
|
||||||
|
message.success(t('cropper.uploadSuccess'))
|
||||||
|
}
|
||||||
|
|
||||||
|
function open() {
|
||||||
|
cropperModelRef.value.openModal()
|
||||||
|
}
|
||||||
|
function close() {
|
||||||
|
cropperModelRef.value.closeModal()
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
close
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
$prefix-cls: #{$namespace}--cropper-avatar;
|
||||||
|
|
||||||
|
.#{$prefix-cls} {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&-image-wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-image-mask {
|
||||||
|
opacity: 0%;
|
||||||
|
position: absolute;
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
border-radius: inherit;
|
||||||
|
border: inherit;
|
||||||
|
background: rgb(0 0 0 / 40%);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.4s;
|
||||||
|
|
||||||
|
::v-deep(svg) {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-image-mask:hover {
|
||||||
|
opacity: 4000%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-upload-btn {
|
||||||
|
margin: 10px auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.user-info-head {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.img-circle {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.img-lg {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
.user-info-head:hover:after {
|
||||||
|
content: '+';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
color: #eee;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
font-size: 24px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 110px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
8
yudao-ui-admin-vue3/src/components/Cropper/src/types.ts
Normal file
8
yudao-ui-admin-vue3/src/components/Cropper/src/types.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import type Cropper from 'cropperjs'
|
||||||
|
|
||||||
|
export interface CropendResult {
|
||||||
|
imgBase64: string
|
||||||
|
imgInfo: Cropper.Data
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { Cropper }
|
@ -44,7 +44,7 @@ export default {
|
|||||||
},
|
},
|
||||||
upload: async <T = any>(option: any) => {
|
upload: async <T = any>(option: any) => {
|
||||||
option.headersType = 'multipart/form-data'
|
option.headersType = 'multipart/form-data'
|
||||||
const res = await request({ method: 'PUT', ...option })
|
const res = await request({ method: 'POST', ...option })
|
||||||
return res as unknown as Promise<T>
|
return res as unknown as Promise<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,6 +161,7 @@ $prefix-cls: #{$namespace}-menu;
|
|||||||
// 设置子菜单悬停的高亮和背景色
|
// 设置子菜单悬停的高亮和背景色
|
||||||
.#{$elNamespace}-sub-menu__title,
|
.#{$elNamespace}-sub-menu__title,
|
||||||
.#{$elNamespace}-menu-item {
|
.#{$elNamespace}-menu-item {
|
||||||
|
height: 59px;
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--left-menu-text-active-color) !important;
|
color: var(--left-menu-text-active-color) !important;
|
||||||
background-color: var(--left-menu-bg-color) !important;
|
background-color: var(--left-menu-bg-color) !important;
|
||||||
@ -170,6 +171,7 @@ $prefix-cls: #{$namespace}-menu;
|
|||||||
// 设置选中时的高亮背景和高亮颜色
|
// 设置选中时的高亮背景和高亮颜色
|
||||||
.#{$elNamespace}-sub-menu.is-active,
|
.#{$elNamespace}-sub-menu.is-active,
|
||||||
.#{$elNamespace}-menu-item.is-active {
|
.#{$elNamespace}-menu-item.is-active {
|
||||||
|
height: 59px;
|
||||||
color: var(--left-menu-text-active-color) !important;
|
color: var(--left-menu-text-active-color) !important;
|
||||||
background-color: var(--left-menu-bg-active-color) !important;
|
background-color: var(--left-menu-bg-active-color) !important;
|
||||||
|
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
import Message from './src/Message.vue'
|
||||||
|
|
||||||
|
export { Message }
|
@ -0,0 +1,119 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { ElTabs, ElTabPane, ElPopover, ElBadge } from 'element-plus'
|
||||||
|
|
||||||
|
const activeName = ref('notice')
|
||||||
|
|
||||||
|
const noticeList = ref([
|
||||||
|
{ id: 1, title: '版本升级1', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 2, title: '版本升级2', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 3, title: '版本升级3', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 4, title: '版本升级4', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 5, title: '版本升级5', date: '2022-12-12 10:00:00' }
|
||||||
|
])
|
||||||
|
const messageList = ref([
|
||||||
|
{ id: 1, title: '加班1', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 2, title: '加班2', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 3, title: '加班3', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 4, title: '加班4', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 5, title: '加班5', date: '2022-12-12 10:00:00' }
|
||||||
|
])
|
||||||
|
const needList = ref([
|
||||||
|
{ id: 1, title: '审批1', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 2, title: '审批2', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 3, title: '审批3', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 4, title: '审批4', date: '2022-12-12 10:00:00' },
|
||||||
|
{ id: 5, title: '审批5', date: '2022-12-12 10:00:00' }
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="message">
|
||||||
|
<ElPopover placement="bottom" :width="310" trigger="click">
|
||||||
|
<template #reference>
|
||||||
|
<ElBadge :value="noticeList.length" class="item">
|
||||||
|
<Icon icon="ep:bell" :size="18" class="cursor-pointer" />
|
||||||
|
</ElBadge>
|
||||||
|
</template>
|
||||||
|
<ElTabs v-model="activeName">
|
||||||
|
<ElTabPane label="通知(5)" name="notice">
|
||||||
|
<div class="message-list">
|
||||||
|
<template v-for="item in noticeList" :key="item.id">
|
||||||
|
<div class="message-item">
|
||||||
|
<img src="@/assets/imgs/avatar.gif" alt="" class="message-icon" />
|
||||||
|
<div class="message-content">
|
||||||
|
<span class="message-title">{{ item.title }}</span>
|
||||||
|
<span class="message-date">{{ item.date }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</ElTabPane>
|
||||||
|
<ElTabPane label="消息(0)" name="message">
|
||||||
|
<div class="message-list">
|
||||||
|
<template v-for="item in messageList" :key="item.id">
|
||||||
|
<div class="message-item">
|
||||||
|
<img src="@/assets/imgs/avatar.gif" alt="" class="message-icon" />
|
||||||
|
<div class="message-content">
|
||||||
|
<span class="message-title">{{ item.title }}</span>
|
||||||
|
<span class="message-date">{{ item.date }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</ElTabPane>
|
||||||
|
<ElTabPane label="代办(0)" name="need">
|
||||||
|
<div class="message-list">
|
||||||
|
<template v-for="item in needList" :key="item.id">
|
||||||
|
<div class="message-item">
|
||||||
|
<img src="@/assets/imgs/avatar.gif" alt="" class="message-icon" />
|
||||||
|
<div class="message-content">
|
||||||
|
<span class="message-title">{{ item.title }}</span>
|
||||||
|
<span class="message-date">{{ item.date }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</ElTabPane>
|
||||||
|
</ElTabs>
|
||||||
|
</ElPopover>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.message-empty {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 260px;
|
||||||
|
line-height: 45px;
|
||||||
|
}
|
||||||
|
.message-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.message-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px 0;
|
||||||
|
border-bottom: 1px solid var(--el-border-color-light);
|
||||||
|
&:last-child {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.message-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin: 0 20px 0 5px;
|
||||||
|
}
|
||||||
|
.message-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.message-title {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.message-date {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -122,6 +122,8 @@ const copyConfig = async () => {
|
|||||||
size: ${appStore.getSize},
|
size: ${appStore.getSize},
|
||||||
// 多语言图标
|
// 多语言图标
|
||||||
locale: ${appStore.getLocale},
|
locale: ${appStore.getLocale},
|
||||||
|
// 消息图标
|
||||||
|
message: ${appStore.getMessage},
|
||||||
// 标签页
|
// 标签页
|
||||||
tagsView: ${appStore.getTagsView},
|
tagsView: ${appStore.getTagsView},
|
||||||
// 标签页图标
|
// 标签页图标
|
||||||
|
@ -57,6 +57,13 @@ const localeChange = (show: boolean) => {
|
|||||||
appStore.setLocale(show)
|
appStore.setLocale(show)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 消息图标
|
||||||
|
const message = ref(appStore.getMessage)
|
||||||
|
|
||||||
|
const messageChange = (show: boolean) => {
|
||||||
|
appStore.setMessage(show)
|
||||||
|
}
|
||||||
|
|
||||||
// 标签页
|
// 标签页
|
||||||
const tagsView = ref(appStore.getTagsView)
|
const tagsView = ref(appStore.getTagsView)
|
||||||
|
|
||||||
@ -164,6 +171,11 @@ watch(
|
|||||||
<ElSwitch v-model="locale" @change="localeChange" />
|
<ElSwitch v-model="locale" @change="localeChange" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<span class="text-14px">{{ t('setting.messageIcon') }}</span>
|
||||||
|
<ElSwitch v-model="message" @change="messageChange" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<span class="text-14px">{{ t('setting.tagsView') }}</span>
|
<span class="text-14px">{{ t('setting.tagsView') }}</span>
|
||||||
<ElSwitch v-model="tagsView" @change="tagsViewChange" />
|
<ElSwitch v-model="tagsView" @change="tagsViewChange" />
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { defineComponent, computed } from 'vue'
|
import { defineComponent, computed } from 'vue'
|
||||||
|
import { Message } from '@/layout/components//Message'
|
||||||
import { Collapse } from '@/layout/components/Collapse'
|
import { Collapse } from '@/layout/components/Collapse'
|
||||||
import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
|
|
||||||
import { SizeDropdown } from '@/layout/components/SizeDropdown'
|
|
||||||
import { UserInfo } from '@/layout/components/UserInfo'
|
import { UserInfo } from '@/layout/components/UserInfo'
|
||||||
import { Screenfull } from '@/layout/components/Screenfull'
|
import { Screenfull } from '@/layout/components/Screenfull'
|
||||||
import { Breadcrumb } from '@/layout/components/Breadcrumb'
|
import { Breadcrumb } from '@/layout/components/Breadcrumb'
|
||||||
|
import { SizeDropdown } from '@/layout/components/SizeDropdown'
|
||||||
|
import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
@ -33,6 +34,9 @@ const layout = computed(() => appStore.getLayout)
|
|||||||
// 多语言图标
|
// 多语言图标
|
||||||
const locale = computed(() => appStore.getLocale)
|
const locale = computed(() => appStore.getLocale)
|
||||||
|
|
||||||
|
// 消息图标
|
||||||
|
const message = computed(() => appStore.getMessage)
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ToolHeader',
|
name: 'ToolHeader',
|
||||||
setup() {
|
setup() {
|
||||||
@ -66,6 +70,9 @@ export default defineComponent({
|
|||||||
color="var(--top-header-text-color)"
|
color="var(--top-header-text-color)"
|
||||||
></LocaleDropdown>
|
></LocaleDropdown>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
|
{message.value ? (
|
||||||
|
<Message class="hover-trigger" color="var(--top-header-text-color)"></Message>
|
||||||
|
) : undefined}
|
||||||
<UserInfo class="hover-trigger"></UserInfo>
|
<UserInfo class="hover-trigger"></UserInfo>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -80,6 +80,7 @@ export default {
|
|||||||
screenfullIcon: 'Screenfull icon',
|
screenfullIcon: 'Screenfull icon',
|
||||||
sizeIcon: 'Size icon',
|
sizeIcon: 'Size icon',
|
||||||
localeIcon: 'Locale icon',
|
localeIcon: 'Locale icon',
|
||||||
|
messageIcon: 'Message icon',
|
||||||
tagsView: 'Tags view',
|
tagsView: 'Tags view',
|
||||||
logo: 'Logo',
|
logo: 'Logo',
|
||||||
greyMode: 'Grey mode',
|
greyMode: 'Grey mode',
|
||||||
@ -426,5 +427,19 @@ export default {
|
|||||||
cfPwdMsg: 'Please Enter Confirm Password',
|
cfPwdMsg: 'Please Enter Confirm Password',
|
||||||
diffPwd: 'The Passwords Entered Twice No Match'
|
diffPwd: 'The Passwords Entered Twice No Match'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
cropper: {
|
||||||
|
selectImage: 'Select Image',
|
||||||
|
uploadSuccess: 'Uploaded success!',
|
||||||
|
modalTitle: 'Avatar upload',
|
||||||
|
okText: 'Confirm and upload',
|
||||||
|
btn_reset: 'Reset',
|
||||||
|
btn_rotate_left: 'Counterclockwise rotation',
|
||||||
|
btn_rotate_right: 'Clockwise rotation',
|
||||||
|
btn_scale_x: 'Flip horizontal',
|
||||||
|
btn_scale_y: 'Flip vertical',
|
||||||
|
btn_zoom_in: 'Zoom in',
|
||||||
|
btn_zoom_out: 'Zoom out',
|
||||||
|
preview: 'Preivew'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ export default {
|
|||||||
screenfullIcon: '全屏图标',
|
screenfullIcon: '全屏图标',
|
||||||
sizeIcon: '尺寸图标',
|
sizeIcon: '尺寸图标',
|
||||||
localeIcon: '多语言图标',
|
localeIcon: '多语言图标',
|
||||||
|
messageIcon: '消息图标',
|
||||||
tagsView: '标签页',
|
tagsView: '标签页',
|
||||||
logo: '标志',
|
logo: '标志',
|
||||||
greyMode: '灰色模式',
|
greyMode: '灰色模式',
|
||||||
@ -419,5 +420,19 @@ export default {
|
|||||||
pwdRules: '长度在 6 到 20 个字符',
|
pwdRules: '长度在 6 到 20 个字符',
|
||||||
diffPwd: '两次输入密码不一致'
|
diffPwd: '两次输入密码不一致'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
cropper: {
|
||||||
|
selectImage: '选择图片',
|
||||||
|
uploadSuccess: '上传成功',
|
||||||
|
modalTitle: '头像上传',
|
||||||
|
okText: '确认并上传',
|
||||||
|
btn_reset: '重置',
|
||||||
|
btn_rotate_left: '逆时针旋转',
|
||||||
|
btn_rotate_right: '顺时针旋转',
|
||||||
|
btn_scale_x: '水平翻转',
|
||||||
|
btn_scale_y: '垂直翻转',
|
||||||
|
btn_zoom_in: '放大',
|
||||||
|
btn_zoom_out: '缩小',
|
||||||
|
preview: '预览'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
|||||||
meta: {
|
meta: {
|
||||||
canTo: true,
|
canTo: true,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
noTagsView: true,
|
noTagsView: false,
|
||||||
icon: 'ep:user',
|
icon: 'ep:user',
|
||||||
title: t('common.profile')
|
title: t('common.profile')
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ interface AppState {
|
|||||||
screenfull: boolean
|
screenfull: boolean
|
||||||
size: boolean
|
size: boolean
|
||||||
locale: boolean
|
locale: boolean
|
||||||
|
message: boolean
|
||||||
tagsView: boolean
|
tagsView: boolean
|
||||||
tagsViewIcon: boolean
|
tagsViewIcon: boolean
|
||||||
logo: boolean
|
logo: boolean
|
||||||
@ -53,6 +54,7 @@ export const useAppStore = defineStore('app', {
|
|||||||
screenfull: true, // 全屏图标
|
screenfull: true, // 全屏图标
|
||||||
size: true, // 尺寸图标
|
size: true, // 尺寸图标
|
||||||
locale: true, // 多语言图标
|
locale: true, // 多语言图标
|
||||||
|
message: true, // 消息图标
|
||||||
tagsView: true, // 标签页
|
tagsView: true, // 标签页
|
||||||
tagsViewIcon: true, // 是否显示标签图标
|
tagsViewIcon: true, // 是否显示标签图标
|
||||||
logo: true, // logo
|
logo: true, // logo
|
||||||
@ -121,6 +123,9 @@ export const useAppStore = defineStore('app', {
|
|||||||
getLocale(): boolean {
|
getLocale(): boolean {
|
||||||
return this.locale
|
return this.locale
|
||||||
},
|
},
|
||||||
|
getMessage(): boolean {
|
||||||
|
return this.message
|
||||||
|
},
|
||||||
getTagsView(): boolean {
|
getTagsView(): boolean {
|
||||||
return this.tagsView
|
return this.tagsView
|
||||||
},
|
},
|
||||||
@ -195,6 +200,9 @@ export const useAppStore = defineStore('app', {
|
|||||||
setLocale(locale: boolean) {
|
setLocale(locale: boolean) {
|
||||||
this.locale = locale
|
this.locale = locale
|
||||||
},
|
},
|
||||||
|
setMessage(message: boolean) {
|
||||||
|
this.message = message
|
||||||
|
},
|
||||||
setTagsView(tagsView: boolean) {
|
setTagsView(tagsView: boolean) {
|
||||||
this.tagsView = tagsView
|
this.tagsView = tagsView
|
||||||
},
|
},
|
||||||
|
@ -1,245 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="user-info-head" @click="editCropper()">
|
<div class="change-avatar">
|
||||||
<img :src="props.img" title="点击上传头像" class="img-circle img-lg" alt="" />
|
<CropperAvatar
|
||||||
</div>
|
ref="cropperRef"
|
||||||
<el-dialog
|
:value="avatar"
|
||||||
v-model="dialogVisible"
|
:showBtn="false"
|
||||||
title="编辑头像"
|
@change="handelUpload"
|
||||||
:mask-closable="false"
|
:btnProps="{ preIcon: 'ant-design:cloud-upload-outlined' }"
|
||||||
width="800px"
|
width="120px"
|
||||||
append-to-body
|
|
||||||
@opened="cropperVisible = true"
|
|
||||||
>
|
|
||||||
<el-row>
|
|
||||||
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
|
||||||
<VueCropper
|
|
||||||
ref="cropper"
|
|
||||||
v-if="cropperVisible"
|
|
||||||
:img="options.img"
|
|
||||||
:info="true"
|
|
||||||
:infoTrue="options.infoTrue"
|
|
||||||
:autoCrop="options.autoCrop"
|
|
||||||
:autoCropWidth="options.autoCropWidth"
|
|
||||||
:autoCropHeight="options.autoCropHeight"
|
|
||||||
:fixedNumber="options.fixedNumber"
|
|
||||||
:fixedBox="options.fixedBox"
|
|
||||||
:centerBox="options.centerBox"
|
|
||||||
@real-time="realTime"
|
|
||||||
/>
|
/>
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
|
||||||
<div
|
|
||||||
class="avatar-upload-preview"
|
|
||||||
:style="{
|
|
||||||
width: previews.w + 'px',
|
|
||||||
height: previews.h + 'px',
|
|
||||||
overflow: 'hidden',
|
|
||||||
margin: '5px'
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div :style="previews.div">
|
|
||||||
<img :src="previews.url" :style="previews.img" style="!max-width: 100%" alt="" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<template #footer>
|
|
||||||
<el-row>
|
|
||||||
<el-col :lg="2" :md="2">
|
|
||||||
<el-upload
|
|
||||||
action="#"
|
|
||||||
:http-request="requestUpload"
|
|
||||||
:show-file-list="false"
|
|
||||||
:before-upload="beforeUpload"
|
|
||||||
>
|
|
||||||
<el-button size="small">
|
|
||||||
<Icon icon="ep:upload-filled" class="mr-5px" />
|
|
||||||
选择
|
|
||||||
</el-button>
|
|
||||||
</el-upload>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="{ span: 1, offset: 2 }" :md="2">
|
|
||||||
<el-button size="small" @click="changeScale(1)">
|
|
||||||
<Icon icon="ep:zoom-in" class="mr-5px" />
|
|
||||||
</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="{ span: 1, offset: 1 }" :md="2">
|
|
||||||
<el-button size="small" @click="changeScale(-1)">
|
|
||||||
<Icon icon="ep:zoom-out" class="mr-5px" />
|
|
||||||
</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="{ span: 1, offset: 1 }" :md="2">
|
|
||||||
<el-button size="small" @click="rotateLeft()">
|
|
||||||
<Icon icon="ep:arrow-left-bold" class="mr-5px" />
|
|
||||||
</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="{ span: 1, offset: 1 }" :md="2">
|
|
||||||
<el-button size="small" @click="rotateRight()">
|
|
||||||
<Icon icon="ep:arrow-right-bold" class="mr-5px" />
|
|
||||||
</el-button>
|
|
||||||
</el-col>
|
|
||||||
<el-col :lg="{ span: 2, offset: 6 }" :md="2">
|
|
||||||
<el-button size="small" type="primary" @click="uploadImg()">提 交</el-button>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, watch, Ref, UnwrapNestedRefs } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import VueCropper from 'vue-cropper/lib/vue-cropper.vue'
|
|
||||||
import 'vue-cropper/dist/index.css'
|
|
||||||
import { ElRow, ElCol, ElUpload, ElMessage, ElDialog } from 'element-plus'
|
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
|
import { CropperAvatar } from '@/components/Cropper'
|
||||||
import { uploadAvatarApi } from '@/api/system/user/profile'
|
import { uploadAvatarApi } from '@/api/system/user/profile'
|
||||||
|
|
||||||
const cropper = ref()
|
|
||||||
const dialogVisible = ref(false)
|
|
||||||
const cropperVisible = ref(false)
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
img: propTypes.string.def('')
|
img: propTypes.string.def('')
|
||||||
})
|
})
|
||||||
interface Options {
|
const avatar = computed(() => {
|
||||||
img: string | ArrayBuffer | null // 裁剪图片的地址
|
return props.img
|
||||||
info: true // 裁剪框的大小信息
|
|
||||||
outputSize: number // 裁剪生成图片的质量 [1至0.1]
|
|
||||||
outputType: 'jpeg' // 裁剪生成图片的格式
|
|
||||||
canScale: boolean // 图片是否允许滚轮缩放
|
|
||||||
autoCrop: boolean // 是否默认生成截图框
|
|
||||||
autoCropWidth: number // 默认生成截图框宽度
|
|
||||||
autoCropHeight: number // 默认生成截图框高度
|
|
||||||
fixedBox: boolean // 固定截图框大小 不允许改变
|
|
||||||
fixed: boolean // 是否开启截图框宽高固定比例
|
|
||||||
fixedNumber: Array<number> // 截图框的宽高比例 需要配合centerBox一起使用才能生效
|
|
||||||
full: boolean // 是否输出原图比例的截图
|
|
||||||
canMoveBox: boolean // 截图框能否拖动
|
|
||||||
original: boolean // 上传图片按照原始比例渲染
|
|
||||||
centerBox: boolean // 截图框是否被限制在图片里面
|
|
||||||
infoTrue: boolean // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
|
|
||||||
}
|
|
||||||
const options: UnwrapNestedRefs<Options> = reactive({
|
|
||||||
img: '', // 需要剪裁的图片
|
|
||||||
autoCrop: true, // 是否默认生成截图框
|
|
||||||
autoCropWidth: 200, // 默认生成截图框的宽度
|
|
||||||
autoCropHeight: 200, // 默认生成截图框的长度
|
|
||||||
fixedBox: false, // 是否固定截图框的大小 不允许改变
|
|
||||||
info: true, // 裁剪框的大小信息
|
|
||||||
outputSize: 1, // 裁剪生成图片的质量 [1至0.1]
|
|
||||||
outputType: 'jpeg', // 裁剪生成图片的格式
|
|
||||||
canScale: false, // 图片是否允许滚轮缩放
|
|
||||||
fixed: true, // 是否开启截图框宽高固定比例
|
|
||||||
fixedNumber: [1, 1], // 截图框的宽高比例 需要配合centerBox一起使用才能生效
|
|
||||||
full: true, // 是否输出原图比例的截图
|
|
||||||
canMoveBox: false, // 截图框能否拖动
|
|
||||||
original: false, // 上传图片按照原始比例渲染
|
|
||||||
centerBox: true, // 截图框是否被限制在图片里面
|
|
||||||
infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
|
|
||||||
})
|
})
|
||||||
const previews: Ref<any> = ref({})
|
|
||||||
/** 编辑头像 */
|
const cropperRef = ref()
|
||||||
const editCropper = () => {
|
const handelUpload = async ({ data }) => {
|
||||||
dialogVisible.value = true
|
await uploadAvatarApi({ avatarFile: data })
|
||||||
|
cropperRef.value.close()
|
||||||
}
|
}
|
||||||
/** 向左旋转 */
|
|
||||||
const rotateLeft = () => {
|
|
||||||
cropper.value.rotateLeft()
|
|
||||||
}
|
|
||||||
/** 向右旋转 */
|
|
||||||
const rotateRight = () => {
|
|
||||||
cropper.value.rotateRight()
|
|
||||||
}
|
|
||||||
/** 图片缩放 */
|
|
||||||
const changeScale = (num: number) => {
|
|
||||||
num = num || 1
|
|
||||||
cropper.value.changeScale(num)
|
|
||||||
}
|
|
||||||
// 覆盖默认的上传行为
|
|
||||||
const requestUpload: any = () => {}
|
|
||||||
/** 上传预处理 */
|
|
||||||
const beforeUpload = (file: Blob) => {
|
|
||||||
if (file.type.indexOf('image/') == -1) {
|
|
||||||
ElMessage('文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件。')
|
|
||||||
} else {
|
|
||||||
const reader = new FileReader()
|
|
||||||
// 转化为base64
|
|
||||||
reader.readAsDataURL(file)
|
|
||||||
reader.onload = () => {
|
|
||||||
if (reader.result) {
|
|
||||||
// 获取到需要剪裁的图片 展示到剪裁框中
|
|
||||||
options.img = reader.result as string
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** 上传图片 */
|
|
||||||
const uploadImg = () => {
|
|
||||||
cropper.value.getCropBlob((data: any) => {
|
|
||||||
let formData = new FormData()
|
|
||||||
formData.append('avatarFile', data)
|
|
||||||
uploadAvatarApi(formData).then((res) => {
|
|
||||||
options.img = res
|
|
||||||
window.location.reload()
|
|
||||||
})
|
|
||||||
dialogVisible.value = false
|
|
||||||
cropperVisible.value = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/** 实时预览 */
|
|
||||||
const realTime = (data: any) => {
|
|
||||||
previews.value = data
|
|
||||||
}
|
|
||||||
watch(
|
|
||||||
() => props.img,
|
|
||||||
() => {
|
|
||||||
if (props.img) {
|
|
||||||
options.img = props.img
|
|
||||||
previews.value.img = props.img
|
|
||||||
previews.value.url = props.img
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
.user-info-head {
|
.change-avatar {
|
||||||
position: relative;
|
img {
|
||||||
display: inline-block;
|
display: block;
|
||||||
}
|
margin-bottom: 15px;
|
||||||
.img-circle {
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
.img-lg {
|
|
||||||
width: 120px;
|
|
||||||
height: 120px;
|
|
||||||
}
|
|
||||||
.avatar-upload-preview {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
-webkit-transform: translate(50%, -50%);
|
|
||||||
transform: translate(50%, -50%);
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
border-radius: 50%;
|
|
||||||
-webkit-box-shadow: 0 0 4px #ccc;
|
|
||||||
box-shadow: 0 0 4px #ccc;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.user-info-head:hover:after {
|
|
||||||
content: '+';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
color: #eee;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
font-size: 24px;
|
|
||||||
font-style: normal;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
cursor: pointer;
|
|
||||||
line-height: 110px;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<el-option label="Integer" value="Integer" />
|
<el-option label="Integer" value="Integer" />
|
||||||
<el-option label="Double" value="Double" />
|
<el-option label="Double" value="Double" />
|
||||||
<el-option label="BigDecimal" value="BigDecimal" />
|
<el-option label="BigDecimal" value="BigDecimal" />
|
||||||
<el-option label="Date" value="Date" />
|
<el-option label="LocalDateTime" value="LocalDateTime" />
|
||||||
<el-option label="Boolean" value="Boolean" />
|
<el-option label="Boolean" value="Boolean" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
|
@ -90,7 +90,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-if="menuForm.type === 2">
|
<template v-if="menuForm.type === 2">
|
||||||
<el-col :span="16">
|
<el-col :span="16">
|
||||||
<el-form-item label="路由地址" prop="component">
|
<el-form-item label="组件地址" prop="component">
|
||||||
<el-input v-model="menuForm.component" placeholder="请输入组件地址" clearable />
|
<el-input v-model="menuForm.component" placeholder="请输入组件地址" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<el-option label="Integer" value="Integer" />
|
<el-option label="Integer" value="Integer" />
|
||||||
<el-option label="Double" value="Double" />
|
<el-option label="Double" value="Double" />
|
||||||
<el-option label="BigDecimal" value="BigDecimal" />
|
<el-option label="BigDecimal" value="BigDecimal" />
|
||||||
<el-option label="Date" value="Date" />
|
<el-option label="LocalDateTime" value="LocalDateTime" />
|
||||||
<el-option label="Boolean" value="Boolean" />
|
<el-option label="Boolean" value="Boolean" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
Reference in New Issue
Block a user