Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f9cda2e8c0 | ||
![]() |
913c22c84f | ||
![]() |
327d71b8fb | ||
![]() |
941ad59759 | ||
![]() |
d0b6c496d6 | ||
![]() |
20d7a25eb8 | ||
![]() |
59d3e8c80f | ||
![]() |
c73694ab8b | ||
![]() |
81a0f478af | ||
![]() |
d97aa92741 | ||
![]() |
480cfb914e | ||
![]() |
0e414ba3c1 | ||
![]() |
61d4efd55a | ||
![]() |
d5f9919b60 | ||
![]() |
aed622bd09 | ||
![]() |
e78af6f228 | ||
![]() |
4ae39c53b4 | ||
![]() |
fa64fc8a62 | ||
![]() |
a2a75a097f | ||
![]() |
a2d8be3ab2 | ||
![]() |
aec230ca19 | ||
![]() |
a6ef771fcc | ||
![]() |
4d8e39857e | ||
![]() |
c4b22a225d | ||
![]() |
60b80c96e8 | ||
![]() |
9298b3c988 | ||
![]() |
8d22231a5f | ||
![]() |
8eba7fb527 |
3
.gitignore
vendored
@@ -4,7 +4,8 @@ dist
|
||||
.npmrc
|
||||
.cache
|
||||
|
||||
test/server/static
|
||||
tests/server/static
|
||||
tests/server/static/upload
|
||||
|
||||
.local
|
||||
# local env files
|
||||
|
3
.vscode/settings.json
vendored
@@ -129,6 +129,7 @@
|
||||
"qrcode",
|
||||
"sider",
|
||||
"pinia",
|
||||
"sider"
|
||||
"sider",
|
||||
"nprogress"
|
||||
]
|
||||
}
|
||||
|
@@ -1,3 +1,71 @@
|
||||
## 2.5.2(2021-06-27)
|
||||
|
||||
### ⚡ Performance Improvements
|
||||
|
||||
- **Icon** Remove the global registration of Icon components to prevent hot update issues under certain circumstances
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **Menu** Added `permissionMode=PermissionModeEnum.ROUTE_MAPPING` mode
|
||||
- The project is changed to this mode by default, and the original menu file is deleted
|
||||
- If you have written the menu before, you can change to `PermissionModeEnum.ROLE` mode
|
||||
|
||||
## 2.5.1(2021-06-26)
|
||||
|
||||
### ⚡ Performance Improvements
|
||||
|
||||
- Upgrade `vue` and `ant-design-vue` versions to solve compatibility issues
|
||||
- **Tree** Performance optimization
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Table** Fix page jitter problem
|
||||
- **Upload** Make sure to carry custom parameters
|
||||
- **Dropdown** Fix the icon display problem of popConfirm
|
||||
- **Table** Fix the problem that the editing event of the tree table is abnormal
|
||||
- **Table** Fix the problem that when the table data is empty, the value returned by getDataSource is not the data source used by the table
|
||||
|
||||
## 2.5.0(2021-06-20)
|
||||
|
||||
## (Breaking changes) Breaking changes
|
||||
|
||||
- Change the project `windicss` to `tailwindcss` to solve the memory overflow problem
|
||||
- There are currently incompatible areas of the project
|
||||
- The wording of `!xl:m-4` needs to be changed to `xl:!m-4`, note that only `!` is incompatible. If you don’t use it, you don’t need to change it.
|
||||
- The new features of `windicss` itself need to be adjusted, for example, `Attribute` mode is not compatible
|
||||
|
||||
### ✨ Refactor
|
||||
|
||||
- Remove `useExpose` and use `expose` provided by the component itself instead
|
||||
|
||||
### ⚡ Performance Improvements
|
||||
|
||||
- **Locale** merge multi-language files to reduce the number of files
|
||||
- **Utils** Mitt default export is changed from `Class` to `Function`
|
||||
- **Axios** `isTransformRequestResult` is renamed to `isTransformResponse`
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **CropperImage** `Cropper` Avatar cropping adds circular cropping function
|
||||
- **CropperAvatar** Added avatar upload component
|
||||
- **Drawer** `useDrawer` added `closeDrawer` function
|
||||
- **Preview** Added `createImgPreview` picture preview function
|
||||
- **Setup** New guide page example
|
||||
- **Tests** Add jest test suite, Vue component single test is not currently supported
|
||||
- **Axios** Added `authenticationScheme` configuration to specify the authentication scheme
|
||||
- **Setting** Added `sessionTimeoutProcessing` project configuration item, used to configure how to deal with session timeout
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Modal** fix full screen height calculation error
|
||||
- **Modal** Fix the problem that the shutdown event is triggered multiple times
|
||||
- **PageWrapper** fix the height calculation problem
|
||||
- **FlowChart** Repair drag and drop menu missing
|
||||
- Fixed Iframe routing error in background mode
|
||||
- **PageWrapper** Fix the height calculation problem when footer and global footer are opened at the same time
|
||||
- **Menu** Fix the jitter problem of menu folding animation
|
||||
- **Store** fixed type error after pinia version upgrade
|
||||
|
||||
## 2.4.2(2021-06-10)
|
||||
|
||||
### ✨ Refactor
|
||||
|
255
CHANGELOG.md
@@ -1,3 +1,258 @@
|
||||
## [2.5.1](https://github.com/anncwb/vue-vben-admin/compare/v2.4.0...v2.5.1) (2021-06-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **comp-tree:** support comp-tree-foreach stop,add insertNodesByKey ([#818](https://github.com/anncwb/vue-vben-admin/issues/818)) ([d97aa92](https://github.com/anncwb/vue-vben-admin/commit/d97aa927417bf45a7c127ecfa9b8e835b6b68855))
|
||||
- fix antdv console warning ([480cfb9](https://github.com/anncwb/vue-vben-admin/commit/480cfb914e78c06eb7784e33465ed91b7d4c3eee))
|
||||
- fix defHttp baseUrl work ([d5f9919](https://github.com/anncwb/vue-vben-admin/commit/d5f9919b60fdd7d5c435129e8db519c0bbd37529))
|
||||
- **api:** select api type error ([b387681](https://github.com/anncwb/vue-vben-admin/commit/b387681c00ac018f5bc6a9251009ddffe37acae6))
|
||||
- **api-select:** ensure that the onchange function parameters are correct ([fa64fc8](https://github.com/anncwb/vue-vben-admin/commit/fa64fc8a622832b87fdf672965d55d543b5929a2))
|
||||
- **api-select:** loss option data on event callback ([c5f2577](https://github.com/anncwb/vue-vben-admin/commit/c5f2577f515e7ae96b27b509e5dd4b3317fcb7b4)), closes [#733](https://github.com/anncwb/vue-vben-admin/issues/733)
|
||||
- **ApiSelect demo:** add demo about ApiSelect's use ([#757](https://github.com/anncwb/vue-vben-admin/issues/757)) ([a03d3cc](https://github.com/anncwb/vue-vben-admin/commit/a03d3cc60c770eba644c1f3837850a2c1c015029))
|
||||
- **demo:** `breadcrumb` route invalid redirect ([84d9300](https://github.com/anncwb/vue-vben-admin/commit/84d9300e52fa73da575591aa4b71858a7e459c8c))
|
||||
- **demo:** account list page validate and save ([21f7a85](https://github.com/anncwb/vue-vben-admin/commit/21f7a854fe2455315287d04e895661ff739bce17))
|
||||
- **demo:** make sure the map https resource is correct ([7b9cd09](https://github.com/anncwb/vue-vben-admin/commit/7b9cd09ad8a50c45b2e661e07953d786d82f367d))
|
||||
- **demo:** style error,fix [#806](https://github.com/anncwb/vue-vben-admin/issues/806) ([a2d8be3](https://github.com/anncwb/vue-vben-admin/commit/a2d8be3ab29da88126f3ba971f6893cb12327759))
|
||||
- **demo-form:** add fieldMapToTime example,fix [#807](https://github.com/anncwb/vue-vben-admin/issues/807) ([a2a75a0](https://github.com/anncwb/vue-vben-admin/commit/a2a75a097ff6c9df12471eff0d62d44d2b88cfff))
|
||||
- **design:** correct tailwind configuration,fix [#800](https://github.com/anncwb/vue-vben-admin/issues/800) ([aec230c](https://github.com/anncwb/vue-vben-admin/commit/aec230ca19d541079b64c54ba00596ef9cd92ca0))
|
||||
- **dropdown:** icon and trigger work unexpected ([60b80c9](https://github.com/anncwb/vue-vben-admin/commit/60b80c96e82da9101d56b2e195e9e7571de11f0a)), closes [#796](https://github.com/anncwb/vue-vben-admin/issues/796) [#787](https://github.com/anncwb/vue-vben-admin/issues/787)
|
||||
- **flow-chart:** fix drag and drop menu loss ([fa828fd](https://github.com/anncwb/vue-vben-admin/commit/fa828fd972efeea87f364be76a1139ae53ec20d8))
|
||||
- **form:** loss args on component change event ([513823b](https://github.com/anncwb/vue-vben-admin/commit/513823bfbd3e8acc68098e0708c34bff2dd8dba6))
|
||||
- **layout:** props warn ([#756](https://github.com/anncwb/vue-vben-admin/issues/756)) ([bbce002](https://github.com/anncwb/vue-vben-admin/commit/bbce002be170c52db984647c931db88d7724cb52))
|
||||
- **menu:** fix the jitter problem of menu folding animation,fix [#732](https://github.com/anncwb/vue-vben-admin/issues/732) ([4c89ea7](https://github.com/anncwb/vue-vben-admin/commit/4c89ea7474f4315870df1790f99f3e431f343b90))
|
||||
- **mock:** make sure ignore matches the file correctly, fix [#745](https://github.com/anncwb/vue-vben-admin/issues/745) ([a222ec8](https://github.com/anncwb/vue-vben-admin/commit/a222ec8553f9b4477a43a8f7d113b5646fbfc373))
|
||||
- **mock:** type error ([7c1ffa3](https://github.com/anncwb/vue-vben-admin/commit/7c1ffa3d23de508a8d1590985806cb7a484b24e5))
|
||||
- **modal:** add v-model support for visible ([de12bab](https://github.com/anncwb/vue-vben-admin/commit/de12babd314ac831d3cb645f42dbf8a476075623))
|
||||
- **modal:** ensure that the full screen height is calculated correctly ([1c1755c](https://github.com/anncwb/vue-vben-admin/commit/1c1755cf5b4ada7263c05ddf4105abb52a2abb2f))
|
||||
- **modal:** ensure that the shutdown event is not triggered multiple times ([655b743](https://github.com/anncwb/vue-vben-admin/commit/655b74323653147943cbde2352208cb765c82b8a))
|
||||
- **pop-confirm:** fix event working unexpected ([a6ef771](https://github.com/anncwb/vue-vben-admin/commit/a6ef771fcce14c3644c965afaa69b3a17d0a7087))
|
||||
- **route:** dynamically introduce components error ([c6b766d](https://github.com/anncwb/vue-vben-admin/commit/c6b766d8ea902294ab1f7e4a06781f2bcfdd1f0b))
|
||||
- **router:** loss `directory` route ([df8cd86](https://github.com/anncwb/vue-vben-admin/commit/df8cd860514f32f44847dcf724f0737ed4d8b9e0)), closes [#722](https://github.com/anncwb/vue-vben-admin/issues/722)
|
||||
- **store:** fix type error after pinia version upgrade ([e8d6f88](https://github.com/anncwb/vue-vben-admin/commit/e8d6f8851efd7076946486864936f1797280d3ba))
|
||||
- **table:** event editCancel loss params ([8d22231](https://github.com/anncwb/vue-vben-admin/commit/8d22231a5fa4afed19201a4a4e5c29d674498516))
|
||||
- **table:** fix table jitter problem ([8eba7fb](https://github.com/anncwb/vue-vben-admin/commit/8eba7fb52786d1977e4cb7b67673d74c91c5c827))
|
||||
- **table:** getDataSource not worked on empty data ([e78af6f](https://github.com/anncwb/vue-vben-admin/commit/e78af6f228e25f052dc4c5a1859a6db50e0b112e)), closes [#752](https://github.com/anncwb/vue-vben-admin/issues/752)
|
||||
- **table:** treeTable editable error ([4ae39c5](https://github.com/anncwb/vue-vben-admin/commit/4ae39c53b49532fc6c31086a31e30429d2e236ed)), closes [#811](https://github.com/anncwb/vue-vben-admin/issues/811)
|
||||
- **upload:** make sure to carry custom parameters, fix [#802](https://github.com/anncwb/vue-vben-admin/issues/802) ([c4b22a2](https://github.com/anncwb/vue-vben-admin/commit/c4b22a225d0088d87be0c0068f543366312521db))
|
||||
- **use-message:** `content` not support vNode ([154ebc3](https://github.com/anncwb/vue-vben-admin/commit/154ebc3d96f73bb3ceab99ea0229a3619d585aba))
|
||||
- build error ([5212ea7](https://github.com/anncwb/vue-vben-admin/commit/5212ea79b43c832a5136354b549de8f89b6e2156))
|
||||
- **avatar:** mock data and Account center style ([2066f66](https://github.com/anncwb/vue-vben-admin/commit/2066f669715491f3e91ac6d0e905cd2b3e80b58d))
|
||||
- **axios:** make sure that the parameter is an object before processing, fix [#660](https://github.com/anncwb/vue-vben-admin/issues/660) ([834fa7e](https://github.com/anncwb/vue-vben-admin/commit/834fa7eb9c8aff252e083d38fdab4f6f53b4d43a))
|
||||
- **axios:** transformRequestHook logic error ([b69dcd7](https://github.com/anncwb/vue-vben-admin/commit/b69dcd79d742fd171302ce0f48c7750d60da217f))
|
||||
- **code-editor:** fix CodeEditor style problem, fix [#655](https://github.com/anncwb/vue-vben-admin/issues/655) ([5662804](https://github.com/anncwb/vue-vben-admin/commit/566280422de0537c4e31496eaaa95a9d51fe9458))
|
||||
- **codeeditor:** empty value set failed.fixed:[#659](https://github.com/anncwb/vue-vben-admin/issues/659) ([ba2bebb](https://github.com/anncwb/vue-vben-admin/commit/ba2bebb4069085817a90d065ed5877fdb50a8039))
|
||||
- **codeMirror:** fix the JsonEditor embedded in the bullet frame causing the style to be disordered ([#668](https://github.com/anncwb/vue-vben-admin/issues/668)) ([e1123a2](https://github.com/anncwb/vue-vben-admin/commit/e1123a2ccb5d5450a5072c19e5508a5dc0f14423))
|
||||
- **demo:** fix basic form page style ([8b6e07b](https://github.com/anncwb/vue-vben-admin/commit/8b6e07b768f110f13b4f2efa6c46e03266667a8c))
|
||||
- **form:** fix form update problem ([bcad95d](https://github.com/anncwb/vue-vben-admin/commit/bcad95d32a08a73f84ecbabab409cd64159f4077)), closes [#720](https://github.com/anncwb/vue-vben-admin/issues/720)
|
||||
- **form:** radioButtonGroup value support boolean ([9e2aa20](https://github.com/anncwb/vue-vben-admin/commit/9e2aa20daa08d2902cb5d56c1560306947e44939))
|
||||
- **form:** radioButtonGroup value support number ([bbddf30](https://github.com/anncwb/vue-vben-admin/commit/bbddf30e96feb1ab048323d93d3b8c1b18857acd))
|
||||
- **form:** schemas update problem ([808328d](https://github.com/anncwb/vue-vben-admin/commit/808328dc7e56b1cc07b678d501d9589290173443)), closes [#688](https://github.com/anncwb/vue-vben-admin/issues/688)
|
||||
- **keep-alive:** tablist cache updating effect ([d62d0ca](https://github.com/anncwb/vue-vben-admin/commit/d62d0ca08cff442c23eb9265851b066a2f24afa8)), closes [#695](https://github.com/anncwb/vue-vben-admin/issues/695)
|
||||
- **layout:** fix class loss ([d018363](https://github.com/anncwb/vue-vben-admin/commit/d018363ddcd68189a18829a2b2560f3b98da58a6))
|
||||
- **layout:** fix style compatibility issues ([905e5b7](https://github.com/anncwb/vue-vben-admin/commit/905e5b714b582548f32feca723012124343686a6))
|
||||
- **lock:** fix lock modal height ([40e3cb0](https://github.com/anncwb/vue-vben-admin/commit/40e3cb043c90a8343fa44a32acad2cb77de732da)), closes [#701](https://github.com/anncwb/vue-vben-admin/issues/701)
|
||||
- **log:** fix Wrong version number ([#653](https://github.com/anncwb/vue-vben-admin/issues/653)) ([4f0d45f](https://github.com/anncwb/vue-vben-admin/commit/4f0d45f1df48755eadc0b09fa19762ee68f9abd1))
|
||||
- **login:** login page modal style fixed: [#662](https://github.com/anncwb/vue-vben-admin/issues/662) ([#666](https://github.com/anncwb/vue-vben-admin/issues/666)) ([b218f10](https://github.com/anncwb/vue-vben-admin/commit/b218f10e25a9364c399a5fe42eedb549f57c01ea))
|
||||
- **mock:** menu list api loss `type` field ([4185412](https://github.com/anncwb/vue-vben-admin/commit/41854121f3713dbde236afd3a416e9f27bd0c673))
|
||||
- **modal:** redoModalHeight not work as expected ([5d554f1](https://github.com/anncwb/vue-vben-admin/commit/5d554f184f7b61774d1a1b2e61451677b38505de))
|
||||
- **page:** `basic form` action btns should be in line ([6c4f947](https://github.com/anncwb/vue-vben-admin/commit/6c4f947386c181f45253c94e4ef735d29a253053))
|
||||
- **radio-button:** fix RadioButton `disabled` support ([ee384b1](https://github.com/anncwb/vue-vben-admin/commit/ee384b1fa7e387b3680e9d54cbe4a1e2f15ec750)), closes [#710](https://github.com/anncwb/vue-vben-admin/issues/710)
|
||||
- **table:** wrong indeterminate state ([495b1da](https://github.com/anncwb/vue-vben-admin/commit/495b1da385e9b6428d2b994669d2065722445923))
|
||||
- **table:** make sure the table width is correct, fix [#593](https://github.com/anncwb/vue-vben-admin/issues/593) ([d73d43e](https://github.com/anncwb/vue-vben-admin/commit/d73d43ed91f30957cfd202c51552ca40a19cef08))
|
||||
- **table:** settings indeterminate state effect ([4fd2051](https://github.com/anncwb/vue-vben-admin/commit/4fd2051bc0403bfc5345ed6a5fc283a372ef7a92))
|
||||
- **table:** support change event ([9f4d171](https://github.com/anncwb/vue-vben-admin/commit/9f4d1719caa76de94e6362c16e4df3ac28df253c)), closes [#677](https://github.com/anncwb/vue-vben-admin/issues/677)
|
||||
- **table:** try to get close to the form stuck ([d81481c](https://github.com/anncwb/vue-vben-admin/commit/d81481c52186145dac130aaa1594f0ba8db4d392))
|
||||
- **table:** useTable support onChange ([9f5085c](https://github.com/anncwb/vue-vben-admin/commit/9f5085c9f9f46b09391156b17091c1771bc13026))
|
||||
- **table-action:** fix the split line style is missing,fix [#674](https://github.com/anncwb/vue-vben-admin/issues/674) ([b1cb863](https://github.com/anncwb/vue-vben-admin/commit/b1cb86350253dc5be095466966d9469775f4395d))
|
||||
- **Tinymce:** Read only status upload button can also be used ([#718](https://github.com/anncwb/vue-vben-admin/issues/718)) ([966571b](https://github.com/anncwb/vue-vben-admin/commit/966571bdcb11c2729ab9ce212bd3e195f7bf3a59))
|
||||
- **upload:** ensure preview items valid ([4376928](https://github.com/anncwb/vue-vben-admin/commit/437692869a232ee65c300c65ee473557ae0913c7))
|
||||
- ensure that roleList is not empty ([aebad61](https://github.com/anncwb/vue-vben-admin/commit/aebad61b3d3e11aaf720b37e762e53e2e6999d3c))
|
||||
- fix darkModeSwitch switch failure ([34a8054](https://github.com/anncwb/vue-vben-admin/commit/34a80542de670f0385dffaf5bf64bb9c3f6b90da))
|
||||
- fix if getDropdownList.length==0 show Dropdown component ([21c771b](https://github.com/anncwb/vue-vben-admin/commit/21c771b59cb45defbff37de21c5c1950370b8f92))
|
||||
- fix Login Page LocalePicker showLocale condition ([d683b0f](https://github.com/anncwb/vue-vben-admin/commit/d683b0f1e85b85b07090feba4ac7f741bd3bd482))
|
||||
- fix node12 version data mock error ([644dbe3](https://github.com/anncwb/vue-vben-admin/commit/644dbe315bb03ea1641a682359873237208a5303))
|
||||
- Fix the problem that the `lang` attribute of `HTML` will not be set when it is first loaded ([#682](https://github.com/anncwb/vue-vben-admin/issues/682)) ([eca8907](https://github.com/anncwb/vue-vben-admin/commit/eca8907a11c28d816c3da5a0667f45a38a499012))
|
||||
- login failed ([035f55a](https://github.com/anncwb/vue-vben-admin/commit/035f55af9778819d72adc1700d9de56a6569b58f))
|
||||
- session timeout login logic error ([#678](https://github.com/anncwb/vue-vben-admin/issues/678)) ([132c7fb](https://github.com/anncwb/vue-vben-admin/commit/132c7fb944df255c4d76a25d6d924439f91f9c54)), closes [#673](https://github.com/anncwb/vue-vben-admin/issues/673)
|
||||
- **tree:** support defaultExpandAll prop ([3ed2339](https://github.com/anncwb/vue-vben-admin/commit/3ed2339a6d75abbd6ccf723b6eaa762f9921409e))
|
||||
- **useViewHeight:** Fix the problem that useContentViewHeight does not calculate the footer ([#747](https://github.com/anncwb/vue-vben-admin/issues/747)) ([33cd8fe](https://github.com/anncwb/vue-vben-admin/commit/33cd8fe6533830176ab63ddfc4d74f75a384366c))
|
||||
- theme switching fails ([7e2ca79](https://github.com/anncwb/vue-vben-admin/commit/7e2ca79ece2f5209cb7ce4b0f5ee15012f9f51de))
|
||||
|
||||
### Features
|
||||
|
||||
- **demo:** add route multi tabs show ([0e414ba](https://github.com/anncwb/vue-vben-admin/commit/0e414ba3c10b4e47a85feb1a38cae66c815719d8)), closes [#817](https://github.com/anncwb/vue-vben-admin/issues/817)
|
||||
- add Tree LoadData demo ([9298b3c](https://github.com/anncwb/vue-vben-admin/commit/9298b3c988c10b81d83430ca31b9ce1d98a3fad9))
|
||||
- optimize error message for api failure ([ea6834a](https://github.com/anncwb/vue-vben-admin/commit/ea6834aeec3ef56d411b2c10a474f75d3d7bfdfc))
|
||||
- **api-select:** auto refetch after params changed ([50207ad](https://github.com/anncwb/vue-vben-admin/commit/50207ad702ef3faca1e27c873c89132ab92fae8e))
|
||||
- **app-search:** auto focus on show ([1ae6362](https://github.com/anncwb/vue-vben-admin/commit/1ae636296df2cf99e8a777f053c539c50e6ad49a))
|
||||
- **axios:** added authenticationScheme configuration,fix [#774](https://github.com/anncwb/vue-vben-admin/issues/774) ([b6d5b07](https://github.com/anncwb/vue-vben-admin/commit/b6d5b0796de4d0b66c0f33c335ec991d44f64ef2))
|
||||
- **demo:** `switch` use in table ([46899aa](https://github.com/anncwb/vue-vben-admin/commit/46899aa3cd6b1616c42ac263a28af75be839f6a0))
|
||||
- **demo:** added guide page example ([d196340](https://github.com/anncwb/vue-vben-admin/commit/d196340d270d2becbf2cc81b7d4f09273381bd09))
|
||||
- **echarts:** add getInstance for useECharts ([fb6c76d](https://github.com/anncwb/vue-vben-admin/commit/fb6c76db535bd0c6305d03c0cff876a1f079100b))
|
||||
- **modal:** add closeModal for useModal ([6d5f9aa](https://github.com/anncwb/vue-vben-admin/commit/6d5f9aa699c5da8af6bf5841baddc4a8bd603917))
|
||||
- **modal:** add redoModalHeight for useModalInner ([f732b56](https://github.com/anncwb/vue-vben-admin/commit/f732b569042f7fe77c85cb295538ddd85561f7e9))
|
||||
- **preview:** added createImgPreview picture preview function ([305630e](https://github.com/anncwb/vue-vben-admin/commit/305630e3fd886b3f690f890a934a8a6ba224fba1))
|
||||
- **project-setting:** added sessionTimeoutProcessing project configuration item,fix [#772](https://github.com/anncwb/vue-vben-admin/issues/772) ([0d07084](https://github.com/anncwb/vue-vben-admin/commit/0d0708409c4adbe7a0c5e33abf5307031147eaeb))
|
||||
- **table:** add editable DatePicker & TimePicker ([#654](https://github.com/anncwb/vue-vben-admin/issues/654)) ([93006c7](https://github.com/anncwb/vue-vben-admin/commit/93006c7dc7b5243b26637f444c8057c95935e622))
|
||||
- **table:** add updateTableDataRecord method ([8e4f486](https://github.com/anncwb/vue-vben-admin/commit/8e4f486fcf835f0b6f2a95676dba268ffdd0566e))
|
||||
- **table:** editable component text align ([8eaf575](https://github.com/anncwb/vue-vben-admin/commit/8eaf57562610a833c8083ae9957f458319d1cc93))
|
||||
- **table:** support columns-change event ([125a7d1](https://github.com/anncwb/vue-vben-admin/commit/125a7d14831642c9cbb2e4b3e75953c3b2e2cdef))
|
||||
- **table:** support custom update on row editing ([fe2bcfc](https://github.com/anncwb/vue-vben-admin/commit/fe2bcfc6f74159c355f3be153a316869fdb8b644)), closes [#646](https://github.com/anncwb/vue-vben-admin/issues/646)
|
||||
- **table:** updateTableDataRecord support functional rowKey ([448a4c2](https://github.com/anncwb/vue-vben-admin/commit/448a4c2809672480f8f635d7cc4661554112598a))
|
||||
- **table-action:** add stopButtonPropagation prop ([808012b](https://github.com/anncwb/vue-vben-admin/commit/808012b544b8c6f3cf467f42653c2783dbe8be6b)), closes [#699](https://github.com/anncwb/vue-vben-admin/issues/699)
|
||||
- **table-img:** support simple show mode and more props ([19d8e01](https://github.com/anncwb/vue-vben-admin/commit/19d8e01e11644c66222f137abd05940cbdec0bb6))
|
||||
- **test:** add jest test suite ([f6fe1dd](https://github.com/anncwb/vue-vben-admin/commit/f6fe1dd62df231ccbd063db0d32359b48aa5c76b))
|
||||
- **use-drawer:** add closeDrawer function ([639520a](https://github.com/anncwb/vue-vben-admin/commit/639520ad5ddf829875ab517067abf2b45ebc04c2))
|
||||
- add CropperAvatar component ([8e410fc](https://github.com/anncwb/vue-vben-admin/commit/8e410fc6401847d8e5545468b5ce6fd7ce9fc5cc))
|
||||
- **tabs:** add setTabTitle method ([#680](https://github.com/anncwb/vue-vben-admin/issues/680)) ([5ddccf6](https://github.com/anncwb/vue-vben-admin/commit/5ddccf6ba28453b9a35355d53d0db65f1a8876bc))
|
||||
- **tinymce:** support dark theme and I18n ([83c9cd7](https://github.com/anncwb/vue-vben-admin/commit/83c9cd77421e9c0888a41e2d8dcbca816da67488))
|
||||
- **Tinymce:** add dynamics to the read-only state of the rich text editor ([#725](https://github.com/anncwb/vue-vben-admin/issues/725)) ([efce482](https://github.com/anncwb/vue-vben-admin/commit/efce482b3215ddf9ed588f63a218d5f76939e947))
|
||||
- **tree:** add defaultExpandLevel prop ([6edca1c](https://github.com/anncwb/vue-vben-admin/commit/6edca1c19c3b0772f9ab82a7b09251a74fff2173)), closes [#672](https://github.com/anncwb/vue-vben-admin/issues/672)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- **component:** optimize tree and upload components ([3f6920f](https://github.com/anncwb/vue-vben-admin/commit/3f6920f7a9775fc06a34dead90b1724b23b7759c))
|
||||
- **cropper-avatar:** code optimization ([6dbbdba](https://github.com/anncwb/vue-vben-admin/commit/6dbbdbac76c2c3795e12dd346f6310d1b70f6a7d))
|
||||
- **i18n:** improve circular dependencies ([d677729](https://github.com/anncwb/vue-vben-admin/commit/d677729acbe2c024ab13cf490b205528507c4823))
|
||||
- **i18n:** improve warning prompt ([6ef62ba](https://github.com/anncwb/vue-vben-admin/commit/6ef62ba6ea7f5613a1fec982b30fe6b0f478bf59))
|
||||
- **locale:** reduce the number of multilingual files ([0acc4ab](https://github.com/anncwb/vue-vben-admin/commit/0acc4ab2dd70a239bd13929edede02b283feb7c2))
|
||||
- **pagewrapper:** 优化 PageWrapper 的高度自适应表现使用 getViewportOffset 替代 useContentViewHeight ([#792](https://github.com/anncwb/vue-vben-admin/issues/792)) ([4d8e398](https://github.com/anncwb/vue-vben-admin/commit/4d8e39857ea59fff99e69832b4a8cabf3a424c24))
|
||||
- **PageWrapper:** fix the height calculation problem when footer and global footer are opened at the same time ([#760](https://github.com/anncwb/vue-vben-admin/issues/760)) ([ab2c7ef](https://github.com/anncwb/vue-vben-admin/commit/ab2c7efe6994dacfe0ff407783f2c3b246427bfc))
|
||||
- **utils:** mitt default export is changed from Class to Function ([d3d620f](https://github.com/anncwb/vue-vben-admin/commit/d3d620f4fc75dd69270e4d090a71d426701272ef))
|
||||
- add createImgPreview func ([#713](https://github.com/anncwb/vue-vben-admin/issues/713)) ([b7c7c46](https://github.com/anncwb/vue-vben-admin/commit/b7c7c46853d332641d116d818e657447884784f3))
|
||||
- optimize components and add comments ([55e9d9f](https://github.com/anncwb/vue-vben-admin/commit/55e9d9fc2953643cec95c74b6ed34b0e68641fb6))
|
||||
|
||||
### Reverts
|
||||
|
||||
- **axios:** remove baseUrl config ([61d4efd](https://github.com/anncwb/vue-vben-admin/commit/61d4efd55a8b4f09990b5f1888e23ead43958164))
|
||||
|
||||
## [2.5.1](https://github.com/anncwb/vue-vben-admin/compare/v2.4.0...v2.5.1) (2021-06-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- fix antdv console warning ([480cfb9](https://github.com/anncwb/vue-vben-admin/commit/480cfb914e78c06eb7784e33465ed91b7d4c3eee))
|
||||
- fix defHttp baseUrl work ([d5f9919](https://github.com/anncwb/vue-vben-admin/commit/d5f9919b60fdd7d5c435129e8db519c0bbd37529))
|
||||
- **api:** select api type error ([b387681](https://github.com/anncwb/vue-vben-admin/commit/b387681c00ac018f5bc6a9251009ddffe37acae6))
|
||||
- **api-select:** ensure that the onchange function parameters are correct ([fa64fc8](https://github.com/anncwb/vue-vben-admin/commit/fa64fc8a622832b87fdf672965d55d543b5929a2))
|
||||
- **api-select:** loss option data on event callback ([c5f2577](https://github.com/anncwb/vue-vben-admin/commit/c5f2577f515e7ae96b27b509e5dd4b3317fcb7b4)), closes [#733](https://github.com/anncwb/vue-vben-admin/issues/733)
|
||||
- **ApiSelect demo:** add demo about ApiSelect's use ([#757](https://github.com/anncwb/vue-vben-admin/issues/757)) ([a03d3cc](https://github.com/anncwb/vue-vben-admin/commit/a03d3cc60c770eba644c1f3837850a2c1c015029))
|
||||
- **avatar:** mock data and Account center style ([2066f66](https://github.com/anncwb/vue-vben-admin/commit/2066f669715491f3e91ac6d0e905cd2b3e80b58d))
|
||||
- **axios:** make sure that the parameter is an object before processing, fix [#660](https://github.com/anncwb/vue-vben-admin/issues/660) ([834fa7e](https://github.com/anncwb/vue-vben-admin/commit/834fa7eb9c8aff252e083d38fdab4f6f53b4d43a))
|
||||
- **axios:** transformRequestHook logic error ([b69dcd7](https://github.com/anncwb/vue-vben-admin/commit/b69dcd79d742fd171302ce0f48c7750d60da217f))
|
||||
- **code-editor:** fix CodeEditor style problem, fix [#655](https://github.com/anncwb/vue-vben-admin/issues/655) ([5662804](https://github.com/anncwb/vue-vben-admin/commit/566280422de0537c4e31496eaaa95a9d51fe9458))
|
||||
- **codeeditor:** empty value set failed.fixed:[#659](https://github.com/anncwb/vue-vben-admin/issues/659) ([ba2bebb](https://github.com/anncwb/vue-vben-admin/commit/ba2bebb4069085817a90d065ed5877fdb50a8039))
|
||||
- **codeMirror:** fix the JsonEditor embedded in the bullet frame causing the style to be disordered ([#668](https://github.com/anncwb/vue-vben-admin/issues/668)) ([e1123a2](https://github.com/anncwb/vue-vben-admin/commit/e1123a2ccb5d5450a5072c19e5508a5dc0f14423))
|
||||
- **demo:** `breadcrumb` route invalid redirect ([84d9300](https://github.com/anncwb/vue-vben-admin/commit/84d9300e52fa73da575591aa4b71858a7e459c8c))
|
||||
- **demo:** account list page validate and save ([21f7a85](https://github.com/anncwb/vue-vben-admin/commit/21f7a854fe2455315287d04e895661ff739bce17))
|
||||
- **demo:** fix basic form page style ([8b6e07b](https://github.com/anncwb/vue-vben-admin/commit/8b6e07b768f110f13b4f2efa6c46e03266667a8c))
|
||||
- **demo:** make sure the map https resource is correct ([7b9cd09](https://github.com/anncwb/vue-vben-admin/commit/7b9cd09ad8a50c45b2e661e07953d786d82f367d))
|
||||
- **demo:** style error,fix [#806](https://github.com/anncwb/vue-vben-admin/issues/806) ([a2d8be3](https://github.com/anncwb/vue-vben-admin/commit/a2d8be3ab29da88126f3ba971f6893cb12327759))
|
||||
- **demo-form:** add fieldMapToTime example,fix [#807](https://github.com/anncwb/vue-vben-admin/issues/807) ([a2a75a0](https://github.com/anncwb/vue-vben-admin/commit/a2a75a097ff6c9df12471eff0d62d44d2b88cfff))
|
||||
- **design:** correct tailwind configuration,fix [#800](https://github.com/anncwb/vue-vben-admin/issues/800) ([aec230c](https://github.com/anncwb/vue-vben-admin/commit/aec230ca19d541079b64c54ba00596ef9cd92ca0))
|
||||
- **dropdown:** icon and trigger work unexpected ([60b80c9](https://github.com/anncwb/vue-vben-admin/commit/60b80c96e82da9101d56b2e195e9e7571de11f0a)), closes [#796](https://github.com/anncwb/vue-vben-admin/issues/796) [#787](https://github.com/anncwb/vue-vben-admin/issues/787)
|
||||
- **flow-chart:** fix drag and drop menu loss ([fa828fd](https://github.com/anncwb/vue-vben-admin/commit/fa828fd972efeea87f364be76a1139ae53ec20d8))
|
||||
- **form:** fix form update problem ([bcad95d](https://github.com/anncwb/vue-vben-admin/commit/bcad95d32a08a73f84ecbabab409cd64159f4077)), closes [#720](https://github.com/anncwb/vue-vben-admin/issues/720)
|
||||
- **form:** loss args on component change event ([513823b](https://github.com/anncwb/vue-vben-admin/commit/513823bfbd3e8acc68098e0708c34bff2dd8dba6))
|
||||
- **form:** radioButtonGroup value support boolean ([9e2aa20](https://github.com/anncwb/vue-vben-admin/commit/9e2aa20daa08d2902cb5d56c1560306947e44939))
|
||||
- **form:** radioButtonGroup value support number ([bbddf30](https://github.com/anncwb/vue-vben-admin/commit/bbddf30e96feb1ab048323d93d3b8c1b18857acd))
|
||||
- **form:** schemas update problem ([808328d](https://github.com/anncwb/vue-vben-admin/commit/808328dc7e56b1cc07b678d501d9589290173443)), closes [#688](https://github.com/anncwb/vue-vben-admin/issues/688)
|
||||
- **keep-alive:** tablist cache updating effect ([d62d0ca](https://github.com/anncwb/vue-vben-admin/commit/d62d0ca08cff442c23eb9265851b066a2f24afa8)), closes [#695](https://github.com/anncwb/vue-vben-admin/issues/695)
|
||||
- **layout:** fix class loss ([d018363](https://github.com/anncwb/vue-vben-admin/commit/d018363ddcd68189a18829a2b2560f3b98da58a6))
|
||||
- **layout:** fix style compatibility issues ([905e5b7](https://github.com/anncwb/vue-vben-admin/commit/905e5b714b582548f32feca723012124343686a6))
|
||||
- **layout:** props warn ([#756](https://github.com/anncwb/vue-vben-admin/issues/756)) ([bbce002](https://github.com/anncwb/vue-vben-admin/commit/bbce002be170c52db984647c931db88d7724cb52))
|
||||
- **lock:** fix lock modal height ([40e3cb0](https://github.com/anncwb/vue-vben-admin/commit/40e3cb043c90a8343fa44a32acad2cb77de732da)), closes [#701](https://github.com/anncwb/vue-vben-admin/issues/701)
|
||||
- **log:** fix Wrong version number ([#653](https://github.com/anncwb/vue-vben-admin/issues/653)) ([4f0d45f](https://github.com/anncwb/vue-vben-admin/commit/4f0d45f1df48755eadc0b09fa19762ee68f9abd1))
|
||||
- **login:** login page modal style fixed: [#662](https://github.com/anncwb/vue-vben-admin/issues/662) ([#666](https://github.com/anncwb/vue-vben-admin/issues/666)) ([b218f10](https://github.com/anncwb/vue-vben-admin/commit/b218f10e25a9364c399a5fe42eedb549f57c01ea))
|
||||
- **menu:** fix the jitter problem of menu folding animation,fix [#732](https://github.com/anncwb/vue-vben-admin/issues/732) ([4c89ea7](https://github.com/anncwb/vue-vben-admin/commit/4c89ea7474f4315870df1790f99f3e431f343b90))
|
||||
- **mock:** make sure ignore matches the file correctly, fix [#745](https://github.com/anncwb/vue-vben-admin/issues/745) ([a222ec8](https://github.com/anncwb/vue-vben-admin/commit/a222ec8553f9b4477a43a8f7d113b5646fbfc373))
|
||||
- **mock:** menu list api loss `type` field ([4185412](https://github.com/anncwb/vue-vben-admin/commit/41854121f3713dbde236afd3a416e9f27bd0c673))
|
||||
- **mock:** type error ([7c1ffa3](https://github.com/anncwb/vue-vben-admin/commit/7c1ffa3d23de508a8d1590985806cb7a484b24e5))
|
||||
- **modal:** add v-model support for visible ([de12bab](https://github.com/anncwb/vue-vben-admin/commit/de12babd314ac831d3cb645f42dbf8a476075623))
|
||||
- **modal:** ensure that the full screen height is calculated correctly ([1c1755c](https://github.com/anncwb/vue-vben-admin/commit/1c1755cf5b4ada7263c05ddf4105abb52a2abb2f))
|
||||
- **modal:** ensure that the shutdown event is not triggered multiple times ([655b743](https://github.com/anncwb/vue-vben-admin/commit/655b74323653147943cbde2352208cb765c82b8a))
|
||||
- **modal:** redoModalHeight not work as expected ([5d554f1](https://github.com/anncwb/vue-vben-admin/commit/5d554f184f7b61774d1a1b2e61451677b38505de))
|
||||
- **page:** `basic form` action btns should be in line ([6c4f947](https://github.com/anncwb/vue-vben-admin/commit/6c4f947386c181f45253c94e4ef735d29a253053))
|
||||
- **pop-confirm:** fix event working unexpected ([a6ef771](https://github.com/anncwb/vue-vben-admin/commit/a6ef771fcce14c3644c965afaa69b3a17d0a7087))
|
||||
- **radio-button:** fix RadioButton `disabled` support ([ee384b1](https://github.com/anncwb/vue-vben-admin/commit/ee384b1fa7e387b3680e9d54cbe4a1e2f15ec750)), closes [#710](https://github.com/anncwb/vue-vben-admin/issues/710)
|
||||
- **route:** dynamically introduce components error ([c6b766d](https://github.com/anncwb/vue-vben-admin/commit/c6b766d8ea902294ab1f7e4a06781f2bcfdd1f0b))
|
||||
- **router:** loss `directory` route ([df8cd86](https://github.com/anncwb/vue-vben-admin/commit/df8cd860514f32f44847dcf724f0737ed4d8b9e0)), closes [#722](https://github.com/anncwb/vue-vben-admin/issues/722)
|
||||
- **store:** fix type error after pinia version upgrade ([e8d6f88](https://github.com/anncwb/vue-vben-admin/commit/e8d6f8851efd7076946486864936f1797280d3ba))
|
||||
- **table:** wrong indeterminate state ([495b1da](https://github.com/anncwb/vue-vben-admin/commit/495b1da385e9b6428d2b994669d2065722445923))
|
||||
- **table:** event editCancel loss params ([8d22231](https://github.com/anncwb/vue-vben-admin/commit/8d22231a5fa4afed19201a4a4e5c29d674498516))
|
||||
- **table:** fix table jitter problem ([8eba7fb](https://github.com/anncwb/vue-vben-admin/commit/8eba7fb52786d1977e4cb7b67673d74c91c5c827))
|
||||
- **table:** getDataSource not worked on empty data ([e78af6f](https://github.com/anncwb/vue-vben-admin/commit/e78af6f228e25f052dc4c5a1859a6db50e0b112e)), closes [#752](https://github.com/anncwb/vue-vben-admin/issues/752)
|
||||
- **table:** make sure the table width is correct, fix [#593](https://github.com/anncwb/vue-vben-admin/issues/593) ([d73d43e](https://github.com/anncwb/vue-vben-admin/commit/d73d43ed91f30957cfd202c51552ca40a19cef08))
|
||||
- **table:** settings indeterminate state effect ([4fd2051](https://github.com/anncwb/vue-vben-admin/commit/4fd2051bc0403bfc5345ed6a5fc283a372ef7a92))
|
||||
- **table:** support change event ([9f4d171](https://github.com/anncwb/vue-vben-admin/commit/9f4d1719caa76de94e6362c16e4df3ac28df253c)), closes [#677](https://github.com/anncwb/vue-vben-admin/issues/677)
|
||||
- **table:** treeTable editable error ([4ae39c5](https://github.com/anncwb/vue-vben-admin/commit/4ae39c53b49532fc6c31086a31e30429d2e236ed)), closes [#811](https://github.com/anncwb/vue-vben-admin/issues/811)
|
||||
- **table:** try to get close to the form stuck ([d81481c](https://github.com/anncwb/vue-vben-admin/commit/d81481c52186145dac130aaa1594f0ba8db4d392))
|
||||
- **table:** useTable support onChange ([9f5085c](https://github.com/anncwb/vue-vben-admin/commit/9f5085c9f9f46b09391156b17091c1771bc13026))
|
||||
- **table-action:** fix the split line style is missing,fix [#674](https://github.com/anncwb/vue-vben-admin/issues/674) ([b1cb863](https://github.com/anncwb/vue-vben-admin/commit/b1cb86350253dc5be095466966d9469775f4395d))
|
||||
- **Tinymce:** Read only status upload button can also be used ([#718](https://github.com/anncwb/vue-vben-admin/issues/718)) ([966571b](https://github.com/anncwb/vue-vben-admin/commit/966571bdcb11c2729ab9ce212bd3e195f7bf3a59))
|
||||
- **upload:** ensure preview items valid ([4376928](https://github.com/anncwb/vue-vben-admin/commit/437692869a232ee65c300c65ee473557ae0913c7))
|
||||
- **upload:** make sure to carry custom parameters, fix [#802](https://github.com/anncwb/vue-vben-admin/issues/802) ([c4b22a2](https://github.com/anncwb/vue-vben-admin/commit/c4b22a225d0088d87be0c0068f543366312521db))
|
||||
- **use-message:** `content` not support vNode ([154ebc3](https://github.com/anncwb/vue-vben-admin/commit/154ebc3d96f73bb3ceab99ea0229a3619d585aba))
|
||||
- build error ([5212ea7](https://github.com/anncwb/vue-vben-admin/commit/5212ea79b43c832a5136354b549de8f89b6e2156))
|
||||
- ensure that roleList is not empty ([aebad61](https://github.com/anncwb/vue-vben-admin/commit/aebad61b3d3e11aaf720b37e762e53e2e6999d3c))
|
||||
- fix darkModeSwitch switch failure ([34a8054](https://github.com/anncwb/vue-vben-admin/commit/34a80542de670f0385dffaf5bf64bb9c3f6b90da))
|
||||
- fix if getDropdownList.length==0 show Dropdown component ([21c771b](https://github.com/anncwb/vue-vben-admin/commit/21c771b59cb45defbff37de21c5c1950370b8f92))
|
||||
- fix Login Page LocalePicker showLocale condition ([d683b0f](https://github.com/anncwb/vue-vben-admin/commit/d683b0f1e85b85b07090feba4ac7f741bd3bd482))
|
||||
- fix node12 version data mock error ([644dbe3](https://github.com/anncwb/vue-vben-admin/commit/644dbe315bb03ea1641a682359873237208a5303))
|
||||
- Fix the problem that the `lang` attribute of `HTML` will not be set when it is first loaded ([#682](https://github.com/anncwb/vue-vben-admin/issues/682)) ([eca8907](https://github.com/anncwb/vue-vben-admin/commit/eca8907a11c28d816c3da5a0667f45a38a499012))
|
||||
- login failed ([035f55a](https://github.com/anncwb/vue-vben-admin/commit/035f55af9778819d72adc1700d9de56a6569b58f))
|
||||
- session timeout login logic error ([#678](https://github.com/anncwb/vue-vben-admin/issues/678)) ([132c7fb](https://github.com/anncwb/vue-vben-admin/commit/132c7fb944df255c4d76a25d6d924439f91f9c54)), closes [#673](https://github.com/anncwb/vue-vben-admin/issues/673)
|
||||
- **tree:** support defaultExpandAll prop ([3ed2339](https://github.com/anncwb/vue-vben-admin/commit/3ed2339a6d75abbd6ccf723b6eaa762f9921409e))
|
||||
- **useViewHeight:** Fix the problem that useContentViewHeight does not calculate the footer ([#747](https://github.com/anncwb/vue-vben-admin/issues/747)) ([33cd8fe](https://github.com/anncwb/vue-vben-admin/commit/33cd8fe6533830176ab63ddfc4d74f75a384366c))
|
||||
- theme switching fails ([7e2ca79](https://github.com/anncwb/vue-vben-admin/commit/7e2ca79ece2f5209cb7ce4b0f5ee15012f9f51de))
|
||||
|
||||
### Features
|
||||
|
||||
- **demo:** add route multi tabs show ([0e414ba](https://github.com/anncwb/vue-vben-admin/commit/0e414ba3c10b4e47a85feb1a38cae66c815719d8)), closes [#817](https://github.com/anncwb/vue-vben-admin/issues/817)
|
||||
- add Tree LoadData demo ([9298b3c](https://github.com/anncwb/vue-vben-admin/commit/9298b3c988c10b81d83430ca31b9ce1d98a3fad9))
|
||||
- optimize error message for api failure ([ea6834a](https://github.com/anncwb/vue-vben-admin/commit/ea6834aeec3ef56d411b2c10a474f75d3d7bfdfc))
|
||||
- **api-select:** auto refetch after params changed ([50207ad](https://github.com/anncwb/vue-vben-admin/commit/50207ad702ef3faca1e27c873c89132ab92fae8e))
|
||||
- **app-search:** auto focus on show ([1ae6362](https://github.com/anncwb/vue-vben-admin/commit/1ae636296df2cf99e8a777f053c539c50e6ad49a))
|
||||
- **axios:** added authenticationScheme configuration,fix [#774](https://github.com/anncwb/vue-vben-admin/issues/774) ([b6d5b07](https://github.com/anncwb/vue-vben-admin/commit/b6d5b0796de4d0b66c0f33c335ec991d44f64ef2))
|
||||
- **demo:** `switch` use in table ([46899aa](https://github.com/anncwb/vue-vben-admin/commit/46899aa3cd6b1616c42ac263a28af75be839f6a0))
|
||||
- **demo:** added guide page example ([d196340](https://github.com/anncwb/vue-vben-admin/commit/d196340d270d2becbf2cc81b7d4f09273381bd09))
|
||||
- **echarts:** add getInstance for useECharts ([fb6c76d](https://github.com/anncwb/vue-vben-admin/commit/fb6c76db535bd0c6305d03c0cff876a1f079100b))
|
||||
- **modal:** add closeModal for useModal ([6d5f9aa](https://github.com/anncwb/vue-vben-admin/commit/6d5f9aa699c5da8af6bf5841baddc4a8bd603917))
|
||||
- **modal:** add redoModalHeight for useModalInner ([f732b56](https://github.com/anncwb/vue-vben-admin/commit/f732b569042f7fe77c85cb295538ddd85561f7e9))
|
||||
- **preview:** added createImgPreview picture preview function ([305630e](https://github.com/anncwb/vue-vben-admin/commit/305630e3fd886b3f690f890a934a8a6ba224fba1))
|
||||
- **project-setting:** added sessionTimeoutProcessing project configuration item,fix [#772](https://github.com/anncwb/vue-vben-admin/issues/772) ([0d07084](https://github.com/anncwb/vue-vben-admin/commit/0d0708409c4adbe7a0c5e33abf5307031147eaeb))
|
||||
- **table:** add editable DatePicker & TimePicker ([#654](https://github.com/anncwb/vue-vben-admin/issues/654)) ([93006c7](https://github.com/anncwb/vue-vben-admin/commit/93006c7dc7b5243b26637f444c8057c95935e622))
|
||||
- **table:** add updateTableDataRecord method ([8e4f486](https://github.com/anncwb/vue-vben-admin/commit/8e4f486fcf835f0b6f2a95676dba268ffdd0566e))
|
||||
- **table:** editable component text align ([8eaf575](https://github.com/anncwb/vue-vben-admin/commit/8eaf57562610a833c8083ae9957f458319d1cc93))
|
||||
- **table:** support columns-change event ([125a7d1](https://github.com/anncwb/vue-vben-admin/commit/125a7d14831642c9cbb2e4b3e75953c3b2e2cdef))
|
||||
- **table:** support custom update on row editing ([fe2bcfc](https://github.com/anncwb/vue-vben-admin/commit/fe2bcfc6f74159c355f3be153a316869fdb8b644)), closes [#646](https://github.com/anncwb/vue-vben-admin/issues/646)
|
||||
- **table:** updateTableDataRecord support functional rowKey ([448a4c2](https://github.com/anncwb/vue-vben-admin/commit/448a4c2809672480f8f635d7cc4661554112598a))
|
||||
- **table-action:** add stopButtonPropagation prop ([808012b](https://github.com/anncwb/vue-vben-admin/commit/808012b544b8c6f3cf467f42653c2783dbe8be6b)), closes [#699](https://github.com/anncwb/vue-vben-admin/issues/699)
|
||||
- **table-img:** support simple show mode and more props ([19d8e01](https://github.com/anncwb/vue-vben-admin/commit/19d8e01e11644c66222f137abd05940cbdec0bb6))
|
||||
- **test:** add jest test suite ([f6fe1dd](https://github.com/anncwb/vue-vben-admin/commit/f6fe1dd62df231ccbd063db0d32359b48aa5c76b))
|
||||
- **use-drawer:** add closeDrawer function ([639520a](https://github.com/anncwb/vue-vben-admin/commit/639520ad5ddf829875ab517067abf2b45ebc04c2))
|
||||
- add CropperAvatar component ([8e410fc](https://github.com/anncwb/vue-vben-admin/commit/8e410fc6401847d8e5545468b5ce6fd7ce9fc5cc))
|
||||
- **tabs:** add setTabTitle method ([#680](https://github.com/anncwb/vue-vben-admin/issues/680)) ([5ddccf6](https://github.com/anncwb/vue-vben-admin/commit/5ddccf6ba28453b9a35355d53d0db65f1a8876bc))
|
||||
- **tinymce:** support dark theme and I18n ([83c9cd7](https://github.com/anncwb/vue-vben-admin/commit/83c9cd77421e9c0888a41e2d8dcbca816da67488))
|
||||
- **Tinymce:** add dynamics to the read-only state of the rich text editor ([#725](https://github.com/anncwb/vue-vben-admin/issues/725)) ([efce482](https://github.com/anncwb/vue-vben-admin/commit/efce482b3215ddf9ed588f63a218d5f76939e947))
|
||||
- **tree:** add defaultExpandLevel prop ([6edca1c](https://github.com/anncwb/vue-vben-admin/commit/6edca1c19c3b0772f9ab82a7b09251a74fff2173)), closes [#672](https://github.com/anncwb/vue-vben-admin/issues/672)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- **component:** optimize tree and upload components ([3f6920f](https://github.com/anncwb/vue-vben-admin/commit/3f6920f7a9775fc06a34dead90b1724b23b7759c))
|
||||
- **cropper-avatar:** code optimization ([6dbbdba](https://github.com/anncwb/vue-vben-admin/commit/6dbbdbac76c2c3795e12dd346f6310d1b70f6a7d))
|
||||
- **i18n:** improve circular dependencies ([d677729](https://github.com/anncwb/vue-vben-admin/commit/d677729acbe2c024ab13cf490b205528507c4823))
|
||||
- **i18n:** improve warning prompt ([6ef62ba](https://github.com/anncwb/vue-vben-admin/commit/6ef62ba6ea7f5613a1fec982b30fe6b0f478bf59))
|
||||
- **locale:** reduce the number of multilingual files ([0acc4ab](https://github.com/anncwb/vue-vben-admin/commit/0acc4ab2dd70a239bd13929edede02b283feb7c2))
|
||||
- **pagewrapper:** 优化 PageWrapper 的高度自适应表现使用 getViewportOffset 替代 useContentViewHeight ([#792](https://github.com/anncwb/vue-vben-admin/issues/792)) ([4d8e398](https://github.com/anncwb/vue-vben-admin/commit/4d8e39857ea59fff99e69832b4a8cabf3a424c24))
|
||||
- **PageWrapper:** fix the height calculation problem when footer and global footer are opened at the same time ([#760](https://github.com/anncwb/vue-vben-admin/issues/760)) ([ab2c7ef](https://github.com/anncwb/vue-vben-admin/commit/ab2c7efe6994dacfe0ff407783f2c3b246427bfc))
|
||||
- **utils:** mitt default export is changed from Class to Function ([d3d620f](https://github.com/anncwb/vue-vben-admin/commit/d3d620f4fc75dd69270e4d090a71d426701272ef))
|
||||
- add createImgPreview func ([#713](https://github.com/anncwb/vue-vben-admin/issues/713)) ([b7c7c46](https://github.com/anncwb/vue-vben-admin/commit/b7c7c46853d332641d116d818e657447884784f3))
|
||||
- optimize components and add comments ([55e9d9f](https://github.com/anncwb/vue-vben-admin/commit/55e9d9fc2953643cec95c74b6ed34b0e68641fb6))
|
||||
|
||||
### Reverts
|
||||
|
||||
- **axios:** remove baseUrl config ([61d4efd](https://github.com/anncwb/vue-vben-admin/commit/61d4efd55a8b4f09990b5f1888e23ead43958164))
|
||||
|
||||
# [2.5.0](https://github.com/anncwb/vue-vben-admin/compare/v2.4.0...v2.5.0) (2021-06-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
@@ -1,3 +1,34 @@
|
||||
## 2.5.2(2021-06-27)
|
||||
|
||||
### ⚡ Performance Improvements
|
||||
|
||||
- **Icon** 移除 Icon 组件全局注册,防止特定情况下热更新问题
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **Menu** 新增 `permissionMode=PermissionModeEnum.ROUTE_MAPPING`模式
|
||||
- 项目默认改为该模式,删除原有菜单文件
|
||||
- 如果之前已经写好了菜单,可以更改为`PermissionModeEnum.ROLE`模式即可
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Drawer** 修复`visible`状态异常
|
||||
|
||||
## 2.5.1(2021-06-26)
|
||||
|
||||
### ⚡ Performance Improvements
|
||||
|
||||
- 升级`vue`与`ant-design-vue`版本,解决兼容问题
|
||||
- **Tree** 性能优化
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Table** 修复分页抖动问题
|
||||
- **Upload** 确保携带自定义参数
|
||||
- **Dropdown** 修复 popConfirm 的图标显示问题
|
||||
- **Table** 修复树形表格的编辑事件不正常的问题
|
||||
- **Table** 修复当表格数据为空时,getDataSource 返回的值不是表格所使用的数据源的问题
|
||||
|
||||
## 2.5.0(2021-06-20)
|
||||
|
||||
## (破坏性更新) Breaking changes
|
||||
|
50
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vben-admin",
|
||||
"version": "2.5.0",
|
||||
"version": "2.5.2",
|
||||
"author": {
|
||||
"name": "vben",
|
||||
"email": "anncwb@126.com",
|
||||
@@ -38,10 +38,10 @@
|
||||
"@logicflow/core": "^0.5.0",
|
||||
"@logicflow/extension": "^0.5.0",
|
||||
"@vueuse/core": "^5.0.3",
|
||||
"@zxcvbn-ts/core": "^0.3.0",
|
||||
"ant-design-vue": "2.1.6",
|
||||
"@zxcvbn-ts/core": "^1.0.0-beta.0",
|
||||
"ant-design-vue": "2.2.0-beta.6",
|
||||
"axios": "^0.21.1",
|
||||
"codemirror": "^5.61.1",
|
||||
"codemirror": "^5.62.0",
|
||||
"cropperjs": "^1.5.12",
|
||||
"crypto-js": "^4.0.0",
|
||||
"echarts": "^5.1.2",
|
||||
@@ -50,25 +50,25 @@
|
||||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"path-to-regexp": "^6.2.0",
|
||||
"pinia": "2.0.0-beta.3",
|
||||
"pinia": "^2.0.0-beta.3",
|
||||
"print-js": "^1.6.0",
|
||||
"qrcode": "^1.4.4",
|
||||
"sortablejs": "^1.13.0",
|
||||
"tinymce": "^5.8.1",
|
||||
"tinymce": "^5.8.2",
|
||||
"vditor": "^3.8.5",
|
||||
"vue": "3.0.11",
|
||||
"vue": "3.1.2",
|
||||
"vue-i18n": "9.1.6",
|
||||
"vue-json-pretty": "^2.0.2",
|
||||
"vue-router": "^4.0.9",
|
||||
"vue-types": "^3.0.2",
|
||||
"vue-router": "^4.0.10",
|
||||
"vue-types": "^4.0.0",
|
||||
"xlsx": "^0.17.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^12.1.4",
|
||||
"@commitlint/config-conventional": "^12.1.4",
|
||||
"@iconify/json": "^1.1.358",
|
||||
"@iconify/json": "^1.1.361",
|
||||
"@purge-icons/generated": "^0.7.0",
|
||||
"@types/codemirror": "^5.60.0",
|
||||
"@types/codemirror": "^5.60.1",
|
||||
"@types/crypto-js": "^4.0.1",
|
||||
"@types/fs-extra": "^9.0.11",
|
||||
"@types/inquirer": "^7.3.2",
|
||||
@@ -76,18 +76,18 @@
|
||||
"@types/jest": "^26.0.23",
|
||||
"@types/lodash-es": "^4.17.4",
|
||||
"@types/mockjs": "^1.0.3",
|
||||
"@types/node": "^15.12.4",
|
||||
"@types/node": "^15.12.5",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/qrcode": "^1.4.0",
|
||||
"@types/qs": "^6.9.6",
|
||||
"@types/sortablejs": "^1.10.6",
|
||||
"@typescript-eslint/eslint-plugin": "^4.27.0",
|
||||
"@typescript-eslint/parser": "^4.27.0",
|
||||
"@vitejs/plugin-legacy": "^1.4.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.28.0",
|
||||
"@typescript-eslint/parser": "^4.28.0",
|
||||
"@vitejs/plugin-legacy": "^1.4.2",
|
||||
"@vitejs/plugin-vue": "^1.2.3",
|
||||
"@vitejs/plugin-vue-jsx": "^1.1.5",
|
||||
"@vue/compiler-sfc": "3.0.11",
|
||||
"@vue/test-utils": "^2.0.0-rc.7",
|
||||
"@vue/compiler-sfc": "3.1.2",
|
||||
"@vue/test-utils": "^2.0.0-rc.9",
|
||||
"autoprefixer": "^10.2.6",
|
||||
"commitizen": "^4.2.4",
|
||||
"conventional-changelog-cli": "^2.1.1",
|
||||
@@ -98,19 +98,19 @@
|
||||
"eslint-define-config": "^1.0.8",
|
||||
"eslint-plugin-jest": "^24.3.6",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-vue": "^7.11.1",
|
||||
"eslint-plugin-vue": "^7.12.1",
|
||||
"esno": "^0.7.3",
|
||||
"fs-extra": "^10.0.0",
|
||||
"http-server": "^0.12.3",
|
||||
"husky": "^6.0.0",
|
||||
"inquirer": "^8.1.1",
|
||||
"is-ci": "^3.0.0",
|
||||
"jest": "^27.0.4",
|
||||
"jest": "^27.0.5",
|
||||
"less": "^4.1.1",
|
||||
"lint-staged": "^11.0.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.3.5",
|
||||
"prettier": "^2.3.1",
|
||||
"prettier": "^2.3.2",
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup-plugin-visualizer": "5.5.0",
|
||||
@@ -118,7 +118,7 @@
|
||||
"stylelint-config-prettier": "^8.0.2",
|
||||
"stylelint-config-standard": "^22.0.0",
|
||||
"stylelint-order": "^4.1.0",
|
||||
"tailwindcss": "^2.2.2",
|
||||
"tailwindcss": "^2.2.4",
|
||||
"ts-jest": "^27.0.3",
|
||||
"ts-node": "^10.0.0",
|
||||
"typescript": "4.3.4",
|
||||
@@ -129,16 +129,16 @@
|
||||
"vite-plugin-mock": "^2.8.0",
|
||||
"vite-plugin-purge-icons": "^0.7.0",
|
||||
"vite-plugin-pwa": "^0.8.1",
|
||||
"vite-plugin-style-import": "^1.0.0",
|
||||
"vite-plugin-svg-icons": "^0.7.1",
|
||||
"vite-plugin-style-import": "^1.0.1",
|
||||
"vite-plugin-svg-icons": "^1.0.0",
|
||||
"vite-plugin-theme": "^0.8.1",
|
||||
"vue-eslint-parser": "^7.6.0",
|
||||
"vue-tsc": "^0.1.7"
|
||||
"vue-tsc": "^0.2.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"//": "Used to install imagemin dependencies, because imagemin may not be installed in China. If it is abroad, you can delete it",
|
||||
"bin-wrapper": "npm:bin-wrapper-china",
|
||||
"rollup": "^2.52.1"
|
||||
"rollup": "^2.52.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@@ -10,7 +10,6 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import { ConfigProvider } from 'ant-design-vue';
|
||||
import { AppProvider } from '/@/components/Application';
|
||||
|
||||
import { useTitle } from '/@/hooks/web/useTitle';
|
||||
import { useLocale } from '/@/locales/useLocale';
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="6395" height="1079" viewBox="0 0 6395 1079">
|
||||
<defs>
|
||||
<clipPath id="clip-path">
|
||||
<rect id="Rectangle_73" data-name="Rectangle 73" width="6395" height="1079" transform="translate(-5391)" fill="#fff"/>
|
||||
<rect width="6395" height="1079" transform="translate(-5391)" fill="#fff"/>
|
||||
</clipPath>
|
||||
<linearGradient id="linear-gradient" x1="0.747" y1="0.222" x2="0.973" y2="0.807" gradientUnits="objectBoundingBox">
|
||||
<stop offset="0" stop-color="#2c41b4"/>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -37,7 +37,6 @@
|
||||
defineComponent,
|
||||
ref,
|
||||
computed,
|
||||
watchEffect,
|
||||
watch,
|
||||
unref,
|
||||
nextTick,
|
||||
@@ -135,9 +134,13 @@
|
||||
return !!unref(getProps)?.loading;
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
visibleRef.value = props.visible;
|
||||
});
|
||||
watch(
|
||||
() => props.visible,
|
||||
(newVal, oldVal) => {
|
||||
if (newVal !== oldVal) visibleRef.value = newVal;
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => visibleRef.value,
|
||||
|
@@ -11,9 +11,17 @@
|
||||
@click="handleClickMenu(item)"
|
||||
:disabled="item.disabled"
|
||||
>
|
||||
<Popconfirm v-if="popconfirm && item.popConfirm" v-bind="item">
|
||||
<Icon :icon="item.icon" v-if="item.icon" />
|
||||
<span class="ml-1">{{ item.text }}</span>
|
||||
<Popconfirm
|
||||
v-if="popconfirm && item.popConfirm"
|
||||
v-bind="getPopConfirmAttrs(item.popConfirm)"
|
||||
>
|
||||
<template #icon v-if="item.popConfirm.icon">
|
||||
<Icon :icon="item.popConfirm.icon" />
|
||||
</template>
|
||||
<div>
|
||||
<Icon :icon="item.icon" v-if="item.icon" />
|
||||
<span class="ml-1">{{ item.text }}</span>
|
||||
</div>
|
||||
</Popconfirm>
|
||||
<template v-else>
|
||||
<Icon :icon="item.icon" v-if="item.icon" />
|
||||
@@ -28,12 +36,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { PropType } from 'vue';
|
||||
import { computed, PropType } from 'vue';
|
||||
import type { DropMenu } from './typing';
|
||||
|
||||
import { defineComponent } from 'vue';
|
||||
import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { omit } from 'lodash-es';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BasicDropdown',
|
||||
@@ -76,8 +86,20 @@
|
||||
item.onClick?.();
|
||||
}
|
||||
|
||||
const getPopConfirmAttrs = computed(() => {
|
||||
return (attrs) => {
|
||||
const originAttrs = omit(attrs, ['confirm', 'cancel', 'icon']);
|
||||
if (!attrs.onConfirm && attrs.confirm && isFunction(attrs.confirm))
|
||||
originAttrs['onConfirm'] = attrs.confirm;
|
||||
if (!attrs.onCancel && attrs.cancel && isFunction(attrs.cancel))
|
||||
originAttrs['onCancel'] = attrs.cancel;
|
||||
return originAttrs;
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
handleClickMenu,
|
||||
getPopConfirmAttrs,
|
||||
getAttr: (key: string | number) => ({ key }),
|
||||
};
|
||||
},
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<Select
|
||||
@dropdownVisibleChange="handleFetch"
|
||||
v-bind="attrs"
|
||||
@change="handleChange"
|
||||
:options="getOptions"
|
||||
v-model:value="state"
|
||||
>
|
||||
@@ -67,11 +68,12 @@
|
||||
const options = ref<OptionsItem[]>([]);
|
||||
const loading = ref(false);
|
||||
const isFirstLoad = ref(true);
|
||||
const emitData = ref<any[]>([]);
|
||||
const attrs = useAttrs();
|
||||
const { t } = useI18n();
|
||||
|
||||
// Embedded in the form, just use the hook binding to perform form verification
|
||||
const [state] = useRuleFormItem(props);
|
||||
const [state] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
|
||||
const getOptions = computed(() => {
|
||||
const { labelField, valueField, numberToString } = props;
|
||||
@@ -135,7 +137,11 @@
|
||||
emit('options-change', unref(options));
|
||||
}
|
||||
|
||||
return { state, attrs, getOptions, loading, t, handleFetch };
|
||||
function handleChange(_, ...args) {
|
||||
emitData.value = args;
|
||||
}
|
||||
|
||||
return { state, attrs, getOptions, loading, t, handleFetch, handleChange };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@@ -19,25 +19,18 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { MenuState } from './types';
|
||||
|
||||
import { computed, defineComponent, unref, reactive, watch, toRefs, ref } from 'vue';
|
||||
import { Menu } from 'ant-design-vue';
|
||||
import BasicSubMenuItem from './components/BasicSubMenuItem.vue';
|
||||
|
||||
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
||||
|
||||
import { useOpenKeys } from './useOpenKeys';
|
||||
import { RouteLocationNormalizedLoaded, useRouter } from 'vue-router';
|
||||
|
||||
import { isFunction } from '/@/utils/is';
|
||||
|
||||
import { basicProps } from './props';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { REDIRECT_NAME } from '/@/router/constant';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
import { getCurrentParentPath } from '/@/router/menus';
|
||||
|
||||
import { listenerRouteChange } from '/@/logics/mitt/routeChange';
|
||||
import { getAllParentPath } from '/@/router/helper/menuHelper';
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MenuItem>
|
||||
<MenuItem :key="item.path">
|
||||
<!-- <MenuItem :class="getLevelClass"> -->
|
||||
<MenuItemContent v-bind="$props" :item="item" />
|
||||
</MenuItem>
|
||||
|
@@ -3,6 +3,7 @@
|
||||
<SubMenu
|
||||
v-if="menuHasChildren(item) && getShowMenu"
|
||||
:class="[theme]"
|
||||
:key="`submenu-${item.path}`"
|
||||
popupClassName="app-top-menu-popup"
|
||||
>
|
||||
<template #title>
|
||||
@@ -16,7 +17,6 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { Menu as MenuType } from '/@/router/types';
|
||||
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { Menu } from 'ant-design-vue';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<span :class="`${prefixCls}- flex items-center `">
|
||||
<Icon v-if="getIcon" :icon="getIcon" :size="18" :class="`${prefixCls}-wrapper__icon`" />
|
||||
<Icon v-if="getIcon" :icon="getIcon" :size="18" :class="`${prefixCls}-wrapper__icon mr-2`" />
|
||||
{{ getI18nName }}
|
||||
</span>
|
||||
</template>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div :class="getClass">
|
||||
<div :class="getClass" ref="wrapperRef">
|
||||
<PageHeader
|
||||
:ghost="ghost"
|
||||
:title="title"
|
||||
@@ -18,7 +18,7 @@
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<div class="overflow-hidden" :class="getContentClass" :style="getContentStyle">
|
||||
<div class="overflow-hidden" :class="getContentClass" :style="getContentStyle" ref="contentRef">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
@@ -35,16 +35,16 @@
|
||||
<script lang="ts">
|
||||
import type { CSSProperties, PropType } from 'vue';
|
||||
|
||||
import { defineComponent, computed, watch, nextTick, ref, unref } from 'vue';
|
||||
import { defineComponent, computed, watch, ref, unref } from 'vue';
|
||||
import PageFooter from './PageFooter.vue';
|
||||
import { usePageContext } from '/@/hooks/component/usePageContext';
|
||||
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { omit } from 'lodash-es';
|
||||
import { PageHeader } from 'ant-design-vue';
|
||||
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
|
||||
import { useLayoutHeight } from '/@/layouts/default/content/useContentViewHeight';
|
||||
import { useContentHeight } from './useContentHeight';
|
||||
import { WrapperProps } from './types';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PageWrapper',
|
||||
@@ -64,13 +64,26 @@
|
||||
fixedHeight: propTypes.bool,
|
||||
},
|
||||
setup(props, { slots }) {
|
||||
const wrapperRef = ref<ElRef>(null);
|
||||
const headerRef = ref<ComponentRef>(null);
|
||||
const contentRef = ref<ElRef>(null);
|
||||
const footerRef = ref<ComponentRef>(null);
|
||||
const footerHeight = ref(0);
|
||||
const { prefixCls, prefixVar } = useDesign('page-wrapper');
|
||||
const { contentHeight, setPageHeight, pageHeight } = usePageContext();
|
||||
const { prefixCls } = useDesign('page-wrapper');
|
||||
const { footerHeightRef } = useLayoutHeight();
|
||||
|
||||
const getProps = computed(() => {
|
||||
return props as WrapperProps;
|
||||
});
|
||||
|
||||
const { redoHeight, contentHeight } = useContentHeight(
|
||||
getProps,
|
||||
wrapperRef,
|
||||
headerRef,
|
||||
contentRef,
|
||||
footerRef,
|
||||
footerHeightRef
|
||||
);
|
||||
|
||||
const getClass = computed(() => {
|
||||
return [
|
||||
prefixCls,
|
||||
@@ -91,7 +104,8 @@
|
||||
if (!contentFullHeight) {
|
||||
return { ...contentStyle };
|
||||
}
|
||||
const height = `${unref(pageHeight)}px`;
|
||||
|
||||
const height = `${unref(contentHeight)}px`;
|
||||
return {
|
||||
...contentStyle,
|
||||
minHeight: height,
|
||||
@@ -111,9 +125,9 @@
|
||||
});
|
||||
|
||||
watch(
|
||||
() => [contentHeight?.value, getShowFooter.value, footerHeightRef.value],
|
||||
() => [getShowFooter.value, footerHeightRef.value],
|
||||
() => {
|
||||
calcContentHeight();
|
||||
redoHeight();
|
||||
},
|
||||
{
|
||||
flush: 'post',
|
||||
@@ -121,91 +135,16 @@
|
||||
}
|
||||
);
|
||||
|
||||
onMountedOrActivated(() => {
|
||||
nextTick(() => {
|
||||
calcContentHeight();
|
||||
});
|
||||
});
|
||||
|
||||
function calcContentHeight() {
|
||||
if (!props.contentFullHeight) {
|
||||
return;
|
||||
}
|
||||
//fix:in contentHeight mode: delay getting footer and header dom element to get the correct height
|
||||
const footer = unref(footerRef);
|
||||
const header = unref(headerRef);
|
||||
footerHeight.value = 0;
|
||||
const footerEl = footer?.$el;
|
||||
|
||||
if (footerEl) {
|
||||
footerHeight.value += footerEl?.offsetHeight ?? 0;
|
||||
}
|
||||
let headerHeight = 0;
|
||||
const headerEl = header?.$el;
|
||||
if (headerEl) {
|
||||
headerHeight += headerEl?.offsetHeight ?? 0;
|
||||
}
|
||||
// fix:subtract content's marginTop and marginBottom value
|
||||
let subtractHeight = 0;
|
||||
const ZERO_PX = '0px';
|
||||
let marginBottom = ZERO_PX;
|
||||
let marginTop = ZERO_PX;
|
||||
const classElments = document.querySelectorAll(`.${prefixVar}-page-wrapper-content`);
|
||||
if (classElments && classElments.length > 0) {
|
||||
const contentEl = classElments[0];
|
||||
const cssStyle = getComputedStyle(contentEl);
|
||||
marginBottom = cssStyle?.marginBottom ?? ZERO_PX;
|
||||
marginTop = cssStyle?.marginTop ?? ZERO_PX;
|
||||
}
|
||||
if (marginBottom) {
|
||||
const contentMarginBottom = Number(marginBottom.replace(/[^\d]/g, ''));
|
||||
subtractHeight += contentMarginBottom;
|
||||
}
|
||||
if (marginTop) {
|
||||
const contentMarginTop = Number(marginTop.replace(/[^\d]/g, ''));
|
||||
subtractHeight += contentMarginTop;
|
||||
}
|
||||
|
||||
// fix: wrapper marginTop and marginBottom value
|
||||
let wrapperSubtractHeight = 0;
|
||||
let wrapperMarginBottom = ZERO_PX;
|
||||
let wrapperMarginTop = ZERO_PX;
|
||||
const wrapperClassElments = document.querySelectorAll(`.${prefixVar}-page-wrapper`);
|
||||
if (wrapperClassElments && wrapperClassElments.length > 0) {
|
||||
const contentEl = wrapperClassElments[0];
|
||||
const cssStyle = getComputedStyle(contentEl);
|
||||
wrapperMarginBottom = cssStyle?.marginBottom ?? ZERO_PX;
|
||||
wrapperMarginTop = cssStyle?.marginTop ?? ZERO_PX;
|
||||
}
|
||||
if (wrapperMarginBottom) {
|
||||
const contentMarginBottom = Number(wrapperMarginBottom.replace(/[^\d]/g, ''));
|
||||
wrapperSubtractHeight += contentMarginBottom;
|
||||
}
|
||||
if (wrapperMarginTop) {
|
||||
const contentMarginTop = Number(wrapperMarginTop.replace(/[^\d]/g, ''));
|
||||
wrapperSubtractHeight += contentMarginTop;
|
||||
}
|
||||
let height =
|
||||
unref(contentHeight) -
|
||||
unref(footerHeight) -
|
||||
headerHeight -
|
||||
subtractHeight -
|
||||
wrapperSubtractHeight;
|
||||
if (unref(getShowFooter)) {
|
||||
height -= unref(footerHeightRef);
|
||||
}
|
||||
setPageHeight?.(height);
|
||||
}
|
||||
|
||||
return {
|
||||
getContentStyle,
|
||||
footerRef,
|
||||
wrapperRef,
|
||||
headerRef,
|
||||
contentRef,
|
||||
footerRef,
|
||||
getClass,
|
||||
getHeaderSlots,
|
||||
prefixCls,
|
||||
getShowFooter,
|
||||
pageHeight,
|
||||
omit,
|
||||
getContentClass,
|
||||
};
|
||||
|
13
src/components/Page/src/types.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { CSSProperties } from 'vue';
|
||||
|
||||
export interface WrapperProps {
|
||||
title?: string;
|
||||
dense: boolean;
|
||||
ghost: boolean;
|
||||
content: string;
|
||||
contentStyle?: CSSProperties;
|
||||
contentBackground: boolean;
|
||||
contentFullHeight: boolean;
|
||||
contentClass?: string;
|
||||
fixedHeight: boolean;
|
||||
}
|
93
src/components/Page/src/useContentHeight.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { ComputedRef, nextTick, Ref, ref, unref } from 'vue';
|
||||
import { WrapperProps } from './types';
|
||||
import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
|
||||
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
||||
import { getViewportOffset } from '/@/utils/domUtils';
|
||||
|
||||
export function useContentHeight(
|
||||
propsRef: ComputedRef<WrapperProps>,
|
||||
wrapperRef: Ref<ElRef>,
|
||||
headerRef?: Ref<ComponentRef>,
|
||||
contentRef?: Ref<ElRef>,
|
||||
footerRef?: Ref<ComponentRef>,
|
||||
layoutFooterHeightRef: Ref<number> = ref(0),
|
||||
offsetHeightRef: Ref<number> = ref(0)
|
||||
) {
|
||||
const contentHeight: Ref<Nullable<number>> = ref(null);
|
||||
|
||||
const redoHeight = () => {
|
||||
nextTick(() => {
|
||||
calcContentHeight();
|
||||
});
|
||||
};
|
||||
|
||||
const subtractMargin = (element: HTMLElement | null | undefined): number => {
|
||||
let subtractHeight = 0;
|
||||
const ZERO_PX = '0px';
|
||||
let marginBottom = ZERO_PX;
|
||||
let marginTop = ZERO_PX;
|
||||
if (element) {
|
||||
const cssStyle = getComputedStyle(element);
|
||||
marginBottom = cssStyle?.marginBottom ?? ZERO_PX;
|
||||
marginTop = cssStyle?.marginTop ?? ZERO_PX;
|
||||
}
|
||||
if (marginBottom) {
|
||||
const contentMarginBottom = Number(marginBottom.replace(/[^\d]/g, ''));
|
||||
subtractHeight += contentMarginBottom;
|
||||
}
|
||||
if (marginTop) {
|
||||
const contentMarginTop = Number(marginTop.replace(/[^\d]/g, ''));
|
||||
subtractHeight += contentMarginTop;
|
||||
}
|
||||
return subtractHeight;
|
||||
};
|
||||
|
||||
const calcContentHeight = async () => {
|
||||
const { contentFullHeight } = unref(propsRef);
|
||||
if (!contentFullHeight) {
|
||||
return;
|
||||
}
|
||||
// Add a delay to get the correct height
|
||||
await nextTick();
|
||||
|
||||
const wrapperEl = unref(wrapperRef);
|
||||
if (!wrapperEl) {
|
||||
return;
|
||||
}
|
||||
const { bottomIncludeBody } = getViewportOffset(wrapperEl);
|
||||
const headerHeight = unref(headerRef)?.$el.offsetHeight ?? 0;
|
||||
const footerHeight = unref(footerRef)?.$el.offsetHeight ?? 0;
|
||||
|
||||
// content's subtract
|
||||
const substractHeight = subtractMargin(unref(contentRef));
|
||||
let height =
|
||||
bottomIncludeBody -
|
||||
unref(layoutFooterHeightRef) -
|
||||
unref(offsetHeightRef) -
|
||||
headerHeight -
|
||||
footerHeight -
|
||||
substractHeight;
|
||||
|
||||
// fix: compensation height both layout's footer and page's footer was shown
|
||||
if (unref(layoutFooterHeightRef) > 0 && footerHeight > 0) {
|
||||
height += footerHeight;
|
||||
}
|
||||
|
||||
contentHeight.value = height;
|
||||
};
|
||||
|
||||
onMountedOrActivated(() => {
|
||||
nextTick(() => {
|
||||
calcContentHeight();
|
||||
});
|
||||
});
|
||||
useWindowSizeFn(
|
||||
() => {
|
||||
calcContentHeight();
|
||||
},
|
||||
50,
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
return { redoHeight, contentHeight };
|
||||
}
|
@@ -44,6 +44,7 @@
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { isString, isBoolean, isFunction, isNumber, isArray } from '/@/utils/is';
|
||||
import { createPlaceholderMessage } from './helper';
|
||||
import { set } from 'lodash-es';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'EditableCell',
|
||||
@@ -227,14 +228,16 @@
|
||||
if (!isPass) return false;
|
||||
}
|
||||
|
||||
const { column, index } = props;
|
||||
const { column, index, record } = props;
|
||||
if (!record) return false;
|
||||
const { key, dataIndex } = column;
|
||||
const value = unref(currentValueRef);
|
||||
if (!key || !dataIndex) return;
|
||||
|
||||
const dataKey = (dataIndex || key) as string;
|
||||
|
||||
const record = await table.updateTableData(index, dataKey, value);
|
||||
set(record, dataKey, value);
|
||||
//const record = await table.updateTableData(index, dataKey, value);
|
||||
needEmit && table.emit?.('edit-end', { record, index, key, value });
|
||||
isEdit.value = false;
|
||||
}
|
||||
@@ -249,7 +252,14 @@
|
||||
function handleCancel() {
|
||||
isEdit.value = false;
|
||||
currentValueRef.value = defaultValueRef.value;
|
||||
table.emit?.('edit-cancel', unref(currentValueRef));
|
||||
const { column, index, record } = props;
|
||||
const { key, dataIndex } = column;
|
||||
table.emit?.('edit-cancel', {
|
||||
record,
|
||||
index,
|
||||
key: dataIndex || key,
|
||||
value: unref(currentValueRef),
|
||||
});
|
||||
}
|
||||
|
||||
function onClickOutside() {
|
||||
|
@@ -113,7 +113,7 @@ export function useDataSource(
|
||||
const getDataSourceRef = computed(() => {
|
||||
const dataSource = unref(dataSourceRef);
|
||||
if (!dataSource || dataSource.length === 0) {
|
||||
return [];
|
||||
return unref(dataSourceRef);
|
||||
}
|
||||
if (unref(getAutoCreateKey)) {
|
||||
const firstItem = dataSource[0];
|
||||
|
@@ -31,6 +31,7 @@ export interface TreeActionType {
|
||||
getCheckedKeys: () => CheckKeys;
|
||||
filterByLevel: (level: number) => void;
|
||||
insertNodeByKey: (opt: InsertNodeParams) => void;
|
||||
insertNodesByKey: (opt: InsertNodeParams) => void;
|
||||
deleteNodeByKey: (key: string) => void;
|
||||
updateNodeByKey: (key: string, node: Omit<TreeDataItem, 'key'>) => void;
|
||||
}
|
||||
|
@@ -87,11 +87,39 @@ export function useTree(
|
||||
if (treeItem[keyField] === parentKey) {
|
||||
treeItem[childrenField] = treeItem[childrenField] || [];
|
||||
treeItem[childrenField][push](node);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
treeDataRef.value = treeData;
|
||||
}
|
||||
/**
|
||||
* 批量添加节点
|
||||
*/
|
||||
function insertNodesByKey({ parentKey = null, list, push = 'push' }: InsertNodeParams) {
|
||||
const treeData: any = cloneDeep(unref(treeDataRef));
|
||||
if (!list || list.length < 1) {
|
||||
return;
|
||||
}
|
||||
if (!parentKey) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
treeData[push](list[i]);
|
||||
}
|
||||
} else {
|
||||
const { key: keyField, children: childrenField } = unref(getReplaceFields);
|
||||
if (!childrenField || !keyField) return;
|
||||
|
||||
forEach(treeData, (treeItem) => {
|
||||
if (treeItem[keyField] === parentKey) {
|
||||
treeItem[childrenField] = treeItem[childrenField] || [];
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
treeItem[childrenField][push](list[i]);
|
||||
}
|
||||
treeDataRef.value = treeData;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Delete node
|
||||
function deleteNodeByKey(key: string, list?: TreeDataItem[]) {
|
||||
if (!key) return;
|
||||
@@ -111,5 +139,12 @@ export function useTree(
|
||||
}
|
||||
}
|
||||
}
|
||||
return { deleteNodeByKey, insertNodeByKey, filterByLevel, updateNodeByKey, getAllKeys };
|
||||
return {
|
||||
deleteNodeByKey,
|
||||
insertNodeByKey,
|
||||
insertNodesByKey,
|
||||
filterByLevel,
|
||||
updateNodeByKey,
|
||||
getAllKeys,
|
||||
};
|
||||
}
|
||||
|
@@ -1,18 +1,19 @@
|
||||
import type { App } from 'vue';
|
||||
import { Icon } from './Icon';
|
||||
// import { Icon } from './Icon';
|
||||
import { Button } from './Button';
|
||||
import {
|
||||
// Need
|
||||
Button as AntButton,
|
||||
Input,
|
||||
Layout,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
const compList = [Icon, AntButton.Group];
|
||||
const compList = [AntButton.Group];
|
||||
|
||||
export function registerGlobComp(app: App) {
|
||||
compList.forEach((comp) => {
|
||||
app.component(comp.name || comp.displayName, comp);
|
||||
});
|
||||
|
||||
app.use(Input).use(Button);
|
||||
app.use(Input).use(Button).use(Layout);
|
||||
}
|
||||
|
@@ -33,6 +33,8 @@ export enum PermissionModeEnum {
|
||||
ROLE = 'ROLE',
|
||||
// black
|
||||
BACK = 'BACK',
|
||||
// route mapping
|
||||
ROUTE_MAPPING = 'ROUTE_MAPPING',
|
||||
}
|
||||
|
||||
// Route switching animation
|
||||
|
@@ -1,12 +1,22 @@
|
||||
import type { UnwrapRef } from 'vue';
|
||||
import { reactive, readonly, computed, getCurrentInstance, watchEffect } from 'vue';
|
||||
import type { UnwrapRef, Ref } from 'vue';
|
||||
import {
|
||||
reactive,
|
||||
readonly,
|
||||
computed,
|
||||
getCurrentInstance,
|
||||
watchEffect,
|
||||
unref,
|
||||
nextTick,
|
||||
toRaw,
|
||||
} from 'vue';
|
||||
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
export function useRuleFormItem<T extends Recordable>(
|
||||
props: T,
|
||||
key: keyof T = 'value',
|
||||
changeEvent = 'change'
|
||||
changeEvent = 'change',
|
||||
emitData?: Ref<any[]>
|
||||
) {
|
||||
const instance = getCurrentInstance();
|
||||
const emit = instance?.emit;
|
||||
@@ -33,7 +43,9 @@ export function useRuleFormItem<T extends Recordable>(
|
||||
if (isEqual(value, defaultState.value)) return;
|
||||
|
||||
innerState.value = value as T[keyof T];
|
||||
emit?.(changeEvent, value);
|
||||
nextTick(() => {
|
||||
emit?.(changeEvent, value, ...(toRaw(unref(emitData)) || []));
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
@@ -31,7 +31,7 @@ export function usePermission() {
|
||||
appStore.setProjectConfig({
|
||||
permissionMode:
|
||||
projectSetting.permissionMode === PermissionModeEnum.BACK
|
||||
? PermissionModeEnum.ROLE
|
||||
? PermissionModeEnum.ROUTE_MAPPING
|
||||
: PermissionModeEnum.BACK,
|
||||
});
|
||||
location.reload();
|
||||
@@ -59,7 +59,7 @@ export function usePermission() {
|
||||
function hasPermission(value?: RoleEnum | RoleEnum[] | string | string[], def = true): boolean {
|
||||
const permMode = projectSetting.permissionMode;
|
||||
|
||||
if (PermissionModeEnum.ROLE === permMode) {
|
||||
if (PermissionModeEnum.ROUTE_MAPPING === permMode) {
|
||||
// Visible by default
|
||||
if (!value) {
|
||||
return def;
|
||||
@@ -75,9 +75,9 @@ export function usePermission() {
|
||||
if (!value) {
|
||||
return def;
|
||||
}
|
||||
const allCodeList = permissionStore.getPermCodeList;
|
||||
const allCodeList = permissionStore.getPermCodeList as string[];
|
||||
if (!isArray(value)) {
|
||||
return allCodeList.includes(value as string);
|
||||
return allCodeList.includes(value);
|
||||
}
|
||||
return (intersection(value, allCodeList) as string[]).length > 0;
|
||||
}
|
||||
@@ -89,9 +89,9 @@ export function usePermission() {
|
||||
* @param roles
|
||||
*/
|
||||
async function changeRole(roles: RoleEnum | RoleEnum[]): Promise<void> {
|
||||
if (projectSetting.permissionMode !== PermissionModeEnum.ROLE) {
|
||||
if (projectSetting.permissionMode !== PermissionModeEnum.ROUTE_MAPPING) {
|
||||
throw new Error(
|
||||
'Please switch PermissionModeEnum to ROLE mode in the configuration to operate!'
|
||||
'Please switch PermissionModeEnum to ROUTE_MAPPING mode in the configuration to operate!'
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,9 @@ import { getCurrentInstance, onBeforeUnmount, ref, Ref, unref } from 'vue';
|
||||
|
||||
const domSymbol = Symbol('watermark-dom');
|
||||
|
||||
export function useWatermark(appendEl: Ref<HTMLElement | null> = ref(document.body)) {
|
||||
export function useWatermark(
|
||||
appendEl: Ref<HTMLElement | null> = ref(document.body) as Ref<HTMLElement>
|
||||
) {
|
||||
let func: Fn = () => {};
|
||||
const id = domSymbol.toString();
|
||||
const clear = () => {
|
||||
|
@@ -19,7 +19,7 @@ export function useContentViewHeight() {
|
||||
const contentHeight = ref(window.innerHeight);
|
||||
const pageHeight = ref(window.innerHeight);
|
||||
const getViewHeight = computed(() => {
|
||||
return unref(contentHeight) - unref(headerHeightRef) || 0;
|
||||
return unref(contentHeight) - unref(headerHeightRef) - unref(footerHeightRef) || 0;
|
||||
});
|
||||
|
||||
useWindowSizeFn(
|
||||
|
@@ -5,7 +5,7 @@
|
||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useUserStoreWidthOut } from '/@/store/modules/user';
|
||||
import { useUserStoreWithOut } from '/@/store/modules/user';
|
||||
|
||||
import { SettingButtonPositionEnum } from '/@/enums/appEnum';
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
@@ -22,7 +22,7 @@
|
||||
setup() {
|
||||
const { getUseOpenBackTop, getShowSettingButton, getSettingButtonPosition, getFullContent } =
|
||||
useRootSetting();
|
||||
const userStore = useUserStoreWidthOut();
|
||||
const userStore = useUserStoreWithOut();
|
||||
const { prefixCls } = useDesign('setting-drawer-fearure');
|
||||
const { getShowHeader } = useHeaderSetting();
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MenuItem :key="key">
|
||||
<MenuItem :key="itemKey">
|
||||
<span class="flex items-center">
|
||||
<Icon :icon="icon" class="mr-1" />
|
||||
<span>{{ text }}</span>
|
||||
@@ -9,7 +9,7 @@
|
||||
<script lang="ts">
|
||||
import { Menu } from 'ant-design-vue';
|
||||
|
||||
import { defineComponent } from 'vue';
|
||||
import { computed, defineComponent, getCurrentInstance } from 'vue';
|
||||
|
||||
import Icon from '/@/components/Icon/index';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
@@ -22,5 +22,10 @@
|
||||
text: propTypes.string,
|
||||
icon: propTypes.string,
|
||||
},
|
||||
setup(props) {
|
||||
const instance = getCurrentInstance();
|
||||
const itemKey = computed(() => props.key || instance?.vnode?.props?.key);
|
||||
return { itemKey };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@@ -1,13 +1,10 @@
|
||||
import type { Menu } from '/@/router/types';
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import { watch, unref, ref, computed } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
import { useThrottleFn } from '@vueuse/core';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
|
||||
import { getChildrenMenus, getCurrentParentPath, getMenus, getShallowMenus } from '/@/router/menus';
|
||||
import { usePermissionStore } from '/@/store/modules/permission';
|
||||
import { useAppInject } from '/@/hooks/web/useAppInject';
|
||||
|
@@ -81,24 +81,19 @@
|
||||
import type { Menu } from '/@/router/types';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
import { defineComponent, onMounted, ref, computed, unref } from 'vue';
|
||||
|
||||
import { ScrollContainer } from '/@/components/Container';
|
||||
import { SimpleMenuTag } from '/@/components/SimpleMenu';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { AppLogo } from '/@/components/Application';
|
||||
import Trigger from '../trigger/HeaderTrigger.vue';
|
||||
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useDragLine } from './useLayoutSider';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
|
||||
import { SIDE_BAR_SHOW_TIT_MINI_WIDTH, SIDE_BAR_MINI_WIDTH } from '/@/enums/appEnum';
|
||||
|
||||
import clickOutside from '/@/directives/clickOutside';
|
||||
import { getShallowMenus, getChildrenMenus, getCurrentParentPath } from '/@/router/menus';
|
||||
import { listenerRouteChange } from '/@/logics/mitt/routeChange';
|
||||
|
@@ -163,7 +163,7 @@ export default {
|
||||
moduleName: 'System management',
|
||||
|
||||
account: 'Account management',
|
||||
|
||||
account_detail: 'Account detail',
|
||||
password: 'Change password',
|
||||
|
||||
dept: 'Department management',
|
||||
|
@@ -157,6 +157,7 @@ export default {
|
||||
system: {
|
||||
moduleName: '系统管理',
|
||||
account: '账号管理',
|
||||
account_detail: '账号详情',
|
||||
password: '修改密码',
|
||||
dept: '部门管理',
|
||||
menu: '菜单管理',
|
||||
|
@@ -1,9 +1,7 @@
|
||||
import '/@/design/index.less';
|
||||
import '/@/design/tailwind.css';
|
||||
|
||||
// Register icon sprite
|
||||
import 'virtual:svg-icons-register';
|
||||
|
||||
import App from './App.vue';
|
||||
import { createApp } from 'vue';
|
||||
import { initAppConfigStore } from '/@/logics/initAppConfig';
|
||||
@@ -42,7 +40,7 @@ async function bootstrap() {
|
||||
setupRouter(app);
|
||||
|
||||
// router-guard
|
||||
setupRouterGuard();
|
||||
setupRouterGuard(router);
|
||||
|
||||
// Register global directive
|
||||
setupGlobDirectives(app);
|
||||
|
@@ -1,20 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
|
||||
import projectSetting from '/@/settings/projectSetting';
|
||||
|
||||
/**
|
||||
* The interface used to close the current page to complete the request when the route is switched
|
||||
* @param router
|
||||
*/
|
||||
export function createHttpGuard(router: Router) {
|
||||
const { removeAllHttpPending } = projectSetting;
|
||||
let axiosCanceler: Nullable<AxiosCanceler>;
|
||||
if (removeAllHttpPending) {
|
||||
axiosCanceler = new AxiosCanceler();
|
||||
}
|
||||
router.beforeEach(async () => {
|
||||
// Switching the route will delete the previous request
|
||||
axiosCanceler?.removeAllPending();
|
||||
return true;
|
||||
});
|
||||
}
|
@@ -1,15 +1,19 @@
|
||||
import { router } from '/@/router';
|
||||
|
||||
import { createProgressGuard } from './progressGuard';
|
||||
import type { Router, RouteLocationNormalized } from 'vue-router';
|
||||
import { useAppStoreWithOut } from '/@/store/modules/app';
|
||||
import { useUserStoreWithOut } from '/@/store/modules/user';
|
||||
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
||||
import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel';
|
||||
import { Modal, notification } from 'ant-design-vue';
|
||||
import { warn } from '/@/utils/log';
|
||||
import { unref } from 'vue';
|
||||
import { setRouteChange } from '/@/logics/mitt/routeChange';
|
||||
import { createPermissionGuard } from './permissionGuard';
|
||||
import { createPageLoadingGuard } from './pageLoadingGuard';
|
||||
import { createMessageGuard } from './messageGuard';
|
||||
import { createScrollGuard } from './scrollGuard';
|
||||
import { createHttpGuard } from './httpGuard';
|
||||
import { createPageGuard } from './pageGuard';
|
||||
import { createStateGuard } from './stateGuard';
|
||||
import nProgress from 'nprogress';
|
||||
import projectSetting from '/@/settings/projectSetting';
|
||||
|
||||
export function setupRouterGuard() {
|
||||
// Don't change the order of creation
|
||||
export function setupRouterGuard(router: Router) {
|
||||
createPageGuard(router);
|
||||
createPageLoadingGuard(router);
|
||||
createHttpGuard(router);
|
||||
@@ -19,3 +23,123 @@ export function setupRouterGuard() {
|
||||
createPermissionGuard(router);
|
||||
createStateGuard(router);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks for handling page state
|
||||
*/
|
||||
function createPageGuard(router: Router) {
|
||||
const loadedPageMap = new Map<string, boolean>();
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
// The page has already been loaded, it will be faster to open it again, you don’t need to do loading and other processing
|
||||
to.meta.loaded = !!loadedPageMap.get(to.path);
|
||||
// Notify routing changes
|
||||
setRouteChange(to);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
router.afterEach((to) => {
|
||||
loadedPageMap.set(to.path, true);
|
||||
});
|
||||
}
|
||||
|
||||
// Used to handle page loading status
|
||||
function createPageLoadingGuard(router: Router) {
|
||||
const userStore = useUserStoreWithOut();
|
||||
const appStore = useAppStoreWithOut();
|
||||
const { getOpenPageLoading } = useTransitionSetting();
|
||||
router.beforeEach(async (to) => {
|
||||
if (!userStore.getToken) {
|
||||
return true;
|
||||
}
|
||||
if (to.meta.loaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (unref(getOpenPageLoading)) {
|
||||
appStore.setPageLoadingAction(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
router.afterEach(async () => {
|
||||
if (unref(getOpenPageLoading)) {
|
||||
// TODO Looking for a better way
|
||||
// The timer simulates the loading time to prevent flashing too fast,
|
||||
setTimeout(() => {
|
||||
appStore.setPageLoading(false);
|
||||
}, 220);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface used to close the current page to complete the request when the route is switched
|
||||
* @param router
|
||||
*/
|
||||
function createHttpGuard(router: Router) {
|
||||
const { removeAllHttpPending } = projectSetting;
|
||||
let axiosCanceler: Nullable<AxiosCanceler>;
|
||||
if (removeAllHttpPending) {
|
||||
axiosCanceler = new AxiosCanceler();
|
||||
}
|
||||
router.beforeEach(async () => {
|
||||
// Switching the route will delete the previous request
|
||||
axiosCanceler?.removeAllPending();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Routing switch back to the top
|
||||
function createScrollGuard(router: Router) {
|
||||
const isHash = (href: string) => {
|
||||
return /^#/.test(href);
|
||||
};
|
||||
|
||||
const body = document.body;
|
||||
|
||||
router.afterEach(async (to) => {
|
||||
// scroll top
|
||||
isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to close the message instance when the route is switched
|
||||
* @param router
|
||||
*/
|
||||
export function createMessageGuard(router: Router) {
|
||||
const { closeMessageOnSwitch } = projectSetting;
|
||||
|
||||
router.beforeEach(async () => {
|
||||
try {
|
||||
if (closeMessageOnSwitch) {
|
||||
Modal.destroyAll();
|
||||
notification.destroy();
|
||||
}
|
||||
} catch (error) {
|
||||
warn('message guard error:' + error);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function createProgressGuard(router: Router) {
|
||||
const { getOpenNProgress } = useTransitionSetting();
|
||||
router.beforeEach(async (to) => {
|
||||
if (to.meta.loaded) {
|
||||
return true;
|
||||
}
|
||||
unref(getOpenNProgress) && nProgress.start();
|
||||
return true;
|
||||
});
|
||||
|
||||
router.afterEach(async () => {
|
||||
unref(getOpenNProgress) && nProgress.done();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@@ -1,24 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { Modal, notification } from 'ant-design-vue';
|
||||
import projectSetting from '/@/settings/projectSetting';
|
||||
import { warn } from '/@/utils/log';
|
||||
|
||||
/**
|
||||
* Used to close the message instance when the route is switched
|
||||
* @param router
|
||||
*/
|
||||
export function createMessageGuard(router: Router) {
|
||||
const { closeMessageOnSwitch } = projectSetting;
|
||||
|
||||
router.beforeEach(async () => {
|
||||
try {
|
||||
if (closeMessageOnSwitch) {
|
||||
Modal.destroyAll();
|
||||
notification.destroy();
|
||||
}
|
||||
} catch (error) {
|
||||
warn('message guard error:' + error);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { setRouteChange } from '/@/logics/mitt/routeChange';
|
||||
|
||||
export function createPageGuard(router: Router) {
|
||||
const loadedPageMap = new Map<string, boolean>();
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
to.meta.loaded = !!loadedPageMap.get(to.path);
|
||||
// Notify routing changes
|
||||
setRouteChange(to);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
router.afterEach((to) => {
|
||||
loadedPageMap.set(to.path, true);
|
||||
});
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { useAppStoreWidthOut } from '/@/store/modules/app';
|
||||
import { useUserStoreWidthOut } from '/@/store/modules/user';
|
||||
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
||||
import { unref } from 'vue';
|
||||
|
||||
export function createPageLoadingGuard(router: Router) {
|
||||
const userStore = useUserStoreWidthOut();
|
||||
const appStore = useAppStoreWidthOut();
|
||||
const { getOpenPageLoading } = useTransitionSetting();
|
||||
router.beforeEach(async (to) => {
|
||||
if (!userStore.getToken) {
|
||||
return true;
|
||||
}
|
||||
if (to.meta.loaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (unref(getOpenPageLoading)) {
|
||||
appStore.setPageLoadingAction(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
router.afterEach(async () => {
|
||||
if (unref(getOpenPageLoading)) {
|
||||
setTimeout(() => {
|
||||
appStore.setPageLoading(false);
|
||||
}, 220);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
import type { Router, RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import { usePermissionStoreWidthOut } from '/@/store/modules/permission';
|
||||
import { usePermissionStoreWithOut } from '/@/store/modules/permission';
|
||||
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
import { useUserStoreWidthOut } from '/@/store/modules/user';
|
||||
import { useUserStoreWithOut } from '/@/store/modules/user';
|
||||
|
||||
import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
|
||||
|
||||
@@ -12,8 +12,8 @@ const LOGIN_PATH = PageEnum.BASE_LOGIN;
|
||||
const whitePathList: PageEnum[] = [LOGIN_PATH];
|
||||
|
||||
export function createPermissionGuard(router: Router) {
|
||||
const userStore = useUserStoreWidthOut();
|
||||
const permissionStore = usePermissionStoreWidthOut();
|
||||
const userStore = useUserStoreWithOut();
|
||||
const permissionStore = usePermissionStoreWithOut();
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
// Jump to the 404 page after processing the login
|
||||
if (from.path === LOGIN_PATH && to.name === PAGE_NOT_FOUND_ROUTE.name) {
|
||||
@@ -32,13 +32,11 @@ export function createPermissionGuard(router: Router) {
|
||||
// token does not exist
|
||||
if (!token) {
|
||||
// You can access without permission. You need to set the routing meta.ignoreAuth to true
|
||||
if (
|
||||
to.meta.ignoreAuth
|
||||
// || to.name === FULL_PAGE_NOT_FOUND_ROUTE.name
|
||||
) {
|
||||
if (to.meta.ignoreAuth) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// redirect login page
|
||||
const redirectData: { path: string; replace: boolean; query?: Recordable<string> } = {
|
||||
path: LOGIN_PATH,
|
||||
@@ -53,10 +51,12 @@ export function createPermissionGuard(router: Router) {
|
||||
next(redirectData);
|
||||
return;
|
||||
}
|
||||
|
||||
if (permissionStore.getIsDynamicAddedRoute) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
const routes = await permissionStore.buildRoutesAction();
|
||||
|
||||
routes.forEach((route) => {
|
||||
|
@@ -1,22 +0,0 @@
|
||||
import type { Router } from 'vue-router';
|
||||
|
||||
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
||||
|
||||
import nProgress from 'nprogress';
|
||||
|
||||
import { unref } from 'vue';
|
||||
|
||||
export function createProgressGuard(router: Router) {
|
||||
const { getOpenNProgress } = useTransitionSetting();
|
||||
router.beforeEach(async (to) => {
|
||||
if (to.meta.loaded) return true;
|
||||
unref(getOpenNProgress) && nProgress.start();
|
||||
return true;
|
||||
});
|
||||
|
||||
router.afterEach(async () => {
|
||||
// if (to.meta.loaded) return true;
|
||||
unref(getOpenNProgress) && nProgress.done();
|
||||
return true;
|
||||
});
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
import type { RouteLocationNormalized, Router } from 'vue-router';
|
||||
|
||||
const isHash = (href: string) => {
|
||||
return /^#/.test(href);
|
||||
};
|
||||
|
||||
export function createScrollGuard(router: Router) {
|
||||
const body = document.body;
|
||||
|
||||
router.afterEach(async (to) => {
|
||||
// scroll top
|
||||
isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0);
|
||||
return true;
|
||||
});
|
||||
}
|
@@ -9,7 +9,7 @@ import { createRouter, createWebHashHistory } from 'vue-router';
|
||||
export type LayoutMapKey = 'LAYOUT';
|
||||
const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue');
|
||||
|
||||
const LayoutMap = new Map<String, () => Promise<typeof import('*.vue')>>();
|
||||
const LayoutMap = new Map<string, () => Promise<typeof import('*.vue')>>();
|
||||
|
||||
LayoutMap.set('LAYOUT', LAYOUT);
|
||||
LayoutMap.set('IFRAME', IFRAME);
|
||||
@@ -27,7 +27,7 @@ function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
|
||||
const { component, name } = item;
|
||||
const { children } = item;
|
||||
if (component) {
|
||||
const layoutFound = LayoutMap.get(component);
|
||||
const layoutFound = LayoutMap.get(component as string);
|
||||
if (layoutFound) {
|
||||
item.component = layoutFound;
|
||||
} else {
|
||||
@@ -66,10 +66,10 @@ function dynamicImport(
|
||||
// Turn background objects into routing objects
|
||||
export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModule[]): T[] {
|
||||
routeList.forEach((route) => {
|
||||
if (route.component) {
|
||||
if ((route.component as string).toUpperCase() === 'LAYOUT') {
|
||||
//route.component = LayoutMap.get(route.component as LayoutMapKey);
|
||||
route.component = LayoutMap.get((route.component as string).toUpperCase() as LayoutMapKey);
|
||||
const component = route.component as string;
|
||||
if (component) {
|
||||
if (component.toUpperCase() === 'LAYOUT') {
|
||||
route.component = LayoutMap.get(component.toUpperCase());
|
||||
} else {
|
||||
route.children = [cloneDeep(route)];
|
||||
route.component = LAYOUT;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import type { Menu, MenuModule } from '/@/router/types';
|
||||
import type { RouteRecordNormalized } from 'vue-router';
|
||||
|
||||
import { useAppStoreWidthOut } from '/@/store/modules/app';
|
||||
import { useAppStoreWithOut } from '/@/store/modules/app';
|
||||
import { usePermissionStore } from '/@/store/modules/permission';
|
||||
import { transformMenuModule, getAllParentPath } from '/@/router/helper/menuHelper';
|
||||
import { filter } from '/@/utils/helper/treeHelper';
|
||||
@@ -23,9 +23,21 @@ Object.keys(modules).forEach((key) => {
|
||||
// ===========================
|
||||
// ==========Helper===========
|
||||
// ===========================
|
||||
|
||||
const getPermissionMode = () => {
|
||||
const appStore = useAppStoreWithOut();
|
||||
return appStore.getProjectConfig.permissionMode;
|
||||
};
|
||||
const isBackMode = () => {
|
||||
const appStore = useAppStoreWidthOut();
|
||||
return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK;
|
||||
return getPermissionMode() === PermissionModeEnum.BACK;
|
||||
};
|
||||
|
||||
const isRouteMappingMode = () => {
|
||||
return getPermissionMode() === PermissionModeEnum.ROUTE_MAPPING;
|
||||
};
|
||||
|
||||
const isRoleMode = () => {
|
||||
return getPermissionMode() === PermissionModeEnum.ROLE;
|
||||
};
|
||||
|
||||
const staticMenus: Menu[] = [];
|
||||
@@ -41,40 +53,53 @@ const staticMenus: Menu[] = [];
|
||||
|
||||
async function getAsyncMenus() {
|
||||
const permissionStore = usePermissionStore();
|
||||
return !isBackMode() ? staticMenus : permissionStore.getBackMenuList;
|
||||
if (isBackMode()) {
|
||||
return permissionStore.getBackMenuList;
|
||||
}
|
||||
if (isRouteMappingMode()) {
|
||||
return permissionStore.getFrontMenuList.filter((item) => !item.hideMenu);
|
||||
}
|
||||
return staticMenus;
|
||||
}
|
||||
|
||||
export const getMenus = async (): Promise<Menu[]> => {
|
||||
const menus = await getAsyncMenus();
|
||||
const routes = router.getRoutes();
|
||||
|
||||
return !isBackMode() ? filter(menus, basicFilter(routes)) : menus;
|
||||
if (isRoleMode()) {
|
||||
const routes = router.getRoutes();
|
||||
return filter(menus, basicFilter(routes));
|
||||
}
|
||||
return menus;
|
||||
};
|
||||
|
||||
export async function getCurrentParentPath(currentPath: string) {
|
||||
const menus = await getAsyncMenus();
|
||||
|
||||
const allParentPath = await getAllParentPath(menus, currentPath);
|
||||
|
||||
return allParentPath?.[0];
|
||||
}
|
||||
|
||||
// Get the level 1 menu, delete children
|
||||
export async function getShallowMenus(): Promise<Menu[]> {
|
||||
const menus = await getAsyncMenus();
|
||||
const routes = router.getRoutes();
|
||||
const shallowMenuList = menus.map((item) => ({ ...item, children: undefined }));
|
||||
return !isBackMode() ? shallowMenuList.filter(basicFilter(routes)) : shallowMenuList;
|
||||
if (isRoleMode()) {
|
||||
const routes = router.getRoutes();
|
||||
return shallowMenuList.filter(basicFilter(routes));
|
||||
}
|
||||
return shallowMenuList;
|
||||
}
|
||||
|
||||
// Get the children of the menu
|
||||
export async function getChildrenMenus(parentPath: string) {
|
||||
const menus = await getMenus();
|
||||
const parent = menus.find((item) => item.path === parentPath);
|
||||
if (!parent || !parent.children || !!parent?.meta?.hideChildrenInMenu) return [] as Menu[];
|
||||
const routes = router.getRoutes();
|
||||
|
||||
return !isBackMode() ? filter(parent.children, basicFilter(routes)) : parent.children;
|
||||
if (!parent || !parent.children || !!parent?.meta?.hideChildrenInMenu) {
|
||||
return [] as Menu[];
|
||||
}
|
||||
if (isRoleMode()) {
|
||||
const routes = router.getRoutes();
|
||||
return filter(parent.children, basicFilter(routes));
|
||||
}
|
||||
return parent.children;
|
||||
}
|
||||
|
||||
function basicFilter(routes: RouteRecordNormalized[]) {
|
||||
|
@@ -1,11 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const about: MenuModule = {
|
||||
orderNo: 100000,
|
||||
menu: {
|
||||
path: '/about/index',
|
||||
name: t('routes.dashboard.about'),
|
||||
},
|
||||
};
|
||||
export default about;
|
@@ -1,22 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 10,
|
||||
menu: {
|
||||
name: t('routes.dashboard.dashboard'),
|
||||
path: '/dashboard',
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'analysis',
|
||||
name: t('routes.dashboard.analysis'),
|
||||
},
|
||||
{
|
||||
path: 'workbench',
|
||||
name: t('routes.dashboard.workbench'),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,45 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 500,
|
||||
menu: {
|
||||
name: t('routes.demo.charts.charts'),
|
||||
path: '/charts',
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'aMap',
|
||||
name: t('routes.demo.charts.aMap'),
|
||||
},
|
||||
|
||||
{
|
||||
path: 'baiduMap',
|
||||
name: t('routes.demo.charts.baiduMap'),
|
||||
},
|
||||
{
|
||||
path: 'googleMap',
|
||||
name: t('routes.demo.charts.googleMap'),
|
||||
},
|
||||
{
|
||||
path: 'echarts',
|
||||
name: 'Echarts',
|
||||
children: [
|
||||
{
|
||||
path: 'map',
|
||||
name: t('routes.demo.charts.map'),
|
||||
},
|
||||
{
|
||||
path: 'line',
|
||||
name: t('routes.demo.charts.line'),
|
||||
},
|
||||
{
|
||||
path: 'pie',
|
||||
name: t('routes.demo.charts.pie'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,279 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 30,
|
||||
menu: {
|
||||
name: t('routes.demo.comp.comp'),
|
||||
path: '/comp',
|
||||
tag: { dot: true },
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: t('routes.demo.comp.basic'),
|
||||
},
|
||||
{
|
||||
path: 'form',
|
||||
name: t('routes.demo.form.form'),
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: t('routes.demo.form.basic'),
|
||||
},
|
||||
{
|
||||
path: 'useForm',
|
||||
name: t('routes.demo.form.useForm'),
|
||||
},
|
||||
{
|
||||
path: 'refForm',
|
||||
name: t('routes.demo.form.refForm'),
|
||||
},
|
||||
{
|
||||
path: 'advancedForm',
|
||||
name: t('routes.demo.form.advancedForm'),
|
||||
},
|
||||
{
|
||||
path: 'ruleForm',
|
||||
name: t('routes.demo.form.ruleForm'),
|
||||
},
|
||||
{
|
||||
path: 'dynamicForm',
|
||||
name: t('routes.demo.form.dynamicForm'),
|
||||
},
|
||||
{
|
||||
path: 'customerForm',
|
||||
name: t('routes.demo.form.customerForm'),
|
||||
},
|
||||
{
|
||||
path: 'appendForm',
|
||||
name: t('routes.demo.form.appendForm'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'table',
|
||||
name: t('routes.demo.table.table'),
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: t('routes.demo.table.basic'),
|
||||
},
|
||||
{
|
||||
path: 'treeTable',
|
||||
name: t('routes.demo.table.treeTable'),
|
||||
},
|
||||
{
|
||||
path: 'fetchTable',
|
||||
name: t('routes.demo.table.fetchTable'),
|
||||
},
|
||||
{
|
||||
path: 'fixedColumn',
|
||||
name: t('routes.demo.table.fixedColumn'),
|
||||
},
|
||||
{
|
||||
path: 'customerCell',
|
||||
name: t('routes.demo.table.customerCell'),
|
||||
},
|
||||
{
|
||||
path: 'formTable',
|
||||
name: t('routes.demo.table.formTable'),
|
||||
},
|
||||
{
|
||||
path: 'useTable',
|
||||
name: t('routes.demo.table.useTable'),
|
||||
},
|
||||
{
|
||||
path: 'refTable',
|
||||
name: t('routes.demo.table.refTable'),
|
||||
},
|
||||
{
|
||||
path: 'multipleHeader',
|
||||
name: t('routes.demo.table.multipleHeader'),
|
||||
},
|
||||
{
|
||||
path: 'mergeHeader',
|
||||
name: t('routes.demo.table.mergeHeader'),
|
||||
},
|
||||
{
|
||||
path: 'expandTable',
|
||||
name: t('routes.demo.table.expandTable'),
|
||||
},
|
||||
{
|
||||
path: 'fixedHeight',
|
||||
name: t('routes.demo.table.fixedHeight'),
|
||||
},
|
||||
{
|
||||
path: 'footerTable',
|
||||
name: t('routes.demo.table.footerTable'),
|
||||
},
|
||||
{
|
||||
path: 'editCellTable',
|
||||
name: t('routes.demo.table.editCellTable'),
|
||||
},
|
||||
{
|
||||
path: 'editRowTable',
|
||||
name: t('routes.demo.table.editRowTable'),
|
||||
},
|
||||
{
|
||||
path: 'authColumn',
|
||||
name: t('routes.demo.table.authColumn'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'cropper',
|
||||
name: t('routes.demo.comp.cropperImage'),
|
||||
tag: {
|
||||
content: 'new',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'countTo',
|
||||
name: t('routes.demo.comp.countTo'),
|
||||
},
|
||||
{
|
||||
path: 'timestamp',
|
||||
name: t('routes.demo.comp.time'),
|
||||
},
|
||||
{
|
||||
path: 'transition',
|
||||
name: t('routes.demo.comp.transition'),
|
||||
},
|
||||
|
||||
{
|
||||
path: 'modal',
|
||||
name: t('routes.demo.comp.modal'),
|
||||
},
|
||||
{
|
||||
path: 'drawer',
|
||||
name: t('routes.demo.comp.drawer'),
|
||||
},
|
||||
{
|
||||
path: 'desc',
|
||||
name: t('routes.demo.comp.desc'),
|
||||
},
|
||||
{
|
||||
path: 'qrcode',
|
||||
name: t('routes.demo.comp.qrcode'),
|
||||
},
|
||||
{
|
||||
path: 'strength-meter',
|
||||
name: t('routes.demo.comp.strength'),
|
||||
},
|
||||
{
|
||||
path: 'upload',
|
||||
name: t('routes.demo.comp.upload'),
|
||||
},
|
||||
{
|
||||
path: 'loading',
|
||||
name: t('routes.demo.comp.loading'),
|
||||
},
|
||||
{
|
||||
path: 'tree',
|
||||
name: t('routes.demo.comp.tree'),
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: t('routes.demo.comp.treeBasic'),
|
||||
},
|
||||
{
|
||||
path: 'editTree',
|
||||
name: t('routes.demo.comp.editTree'),
|
||||
},
|
||||
{
|
||||
path: 'actionTree',
|
||||
name: t('routes.demo.comp.actionTree'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: t('routes.demo.editor.editor'),
|
||||
path: 'editor',
|
||||
children: [
|
||||
{
|
||||
path: 'json',
|
||||
name: t('routes.demo.editor.jsonEditor'),
|
||||
},
|
||||
{
|
||||
path: 'markdown',
|
||||
name: t('routes.demo.editor.markdown'),
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: t('routes.demo.editor.tinymceBasic'),
|
||||
},
|
||||
{
|
||||
path: 'editor',
|
||||
name: t('routes.demo.editor.tinymceForm'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'tinymce',
|
||||
name: t('routes.demo.editor.tinymce'),
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: t('routes.demo.editor.tinymceBasic'),
|
||||
},
|
||||
{
|
||||
path: 'editor',
|
||||
name: t('routes.demo.editor.tinymceForm'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'scroll',
|
||||
name: t('routes.demo.comp.scroll'),
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: t('routes.demo.comp.scrollBasic'),
|
||||
},
|
||||
{
|
||||
path: 'action',
|
||||
name: t('routes.demo.comp.scrollAction'),
|
||||
},
|
||||
{
|
||||
path: 'virtualScroll',
|
||||
name: t('routes.demo.comp.virtualScroll'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'lazy',
|
||||
name: t('routes.demo.comp.lazy'),
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: t('routes.demo.comp.lazyBasic'),
|
||||
},
|
||||
{
|
||||
path: 'transition',
|
||||
name: t('routes.demo.comp.lazyTransition'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'verify',
|
||||
name: t('routes.demo.comp.verify'),
|
||||
children: [
|
||||
{
|
||||
path: 'drag',
|
||||
name: t('routes.demo.comp.verifyDrag'),
|
||||
},
|
||||
{
|
||||
path: 'rotate',
|
||||
name: t('routes.demo.comp.verifyRotate'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,29 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 500,
|
||||
menu: {
|
||||
name: t('routes.demo.excel.excel'),
|
||||
path: '/excel',
|
||||
children: [
|
||||
{
|
||||
path: 'customExport',
|
||||
name: t('routes.demo.excel.customExport'),
|
||||
},
|
||||
{
|
||||
path: 'jsonExport',
|
||||
name: t('routes.demo.excel.jsonExport'),
|
||||
},
|
||||
{
|
||||
path: 'arrayExport',
|
||||
name: t('routes.demo.excel.arrayExport'),
|
||||
},
|
||||
{
|
||||
path: 'importExcel',
|
||||
name: t('routes.demo.excel.importExcel'),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,130 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 19,
|
||||
menu: {
|
||||
name: t('routes.demo.feat.feat'),
|
||||
path: '/feat',
|
||||
children: [
|
||||
{
|
||||
path: 'icon',
|
||||
name: t('routes.demo.feat.icon'),
|
||||
},
|
||||
{
|
||||
path: 'ws',
|
||||
name: t('routes.demo.feat.ws'),
|
||||
},
|
||||
{
|
||||
name: t('routes.demo.feat.sessionTimeout'),
|
||||
path: 'session-timeout',
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
name: t('routes.demo.feat.tabs'),
|
||||
},
|
||||
|
||||
{
|
||||
path: 'context-menu',
|
||||
name: t('routes.demo.feat.contextMenu'),
|
||||
},
|
||||
{
|
||||
path: 'download',
|
||||
name: t('routes.demo.feat.download'),
|
||||
},
|
||||
{
|
||||
path: 'print',
|
||||
name: t('routes.demo.feat.print'),
|
||||
},
|
||||
{
|
||||
path: 'click-out-side',
|
||||
name: t('routes.demo.feat.clickOutSide'),
|
||||
},
|
||||
{
|
||||
path: 'img-preview',
|
||||
name: t('routes.demo.feat.imgPreview'),
|
||||
},
|
||||
{
|
||||
path: 'copy',
|
||||
name: t('routes.demo.feat.copy'),
|
||||
},
|
||||
{
|
||||
path: 'msg',
|
||||
name: t('routes.demo.feat.msg'),
|
||||
},
|
||||
{
|
||||
path: 'watermark',
|
||||
name: t('routes.demo.feat.watermark'),
|
||||
},
|
||||
{
|
||||
path: 'ripple',
|
||||
name: t('routes.demo.feat.ripple'),
|
||||
},
|
||||
{
|
||||
path: 'full-screen',
|
||||
name: t('routes.demo.feat.fullScreen'),
|
||||
},
|
||||
{
|
||||
path: 'error-log',
|
||||
name: t('routes.demo.feat.errorLog'),
|
||||
},
|
||||
|
||||
{
|
||||
name: t('routes.demo.excel.excel'),
|
||||
path: 'excel',
|
||||
children: [
|
||||
{
|
||||
path: 'customExport',
|
||||
name: t('routes.demo.excel.customExport'),
|
||||
},
|
||||
{
|
||||
path: 'jsonExport',
|
||||
name: t('routes.demo.excel.jsonExport'),
|
||||
},
|
||||
{
|
||||
path: 'arrayExport',
|
||||
name: t('routes.demo.excel.arrayExport'),
|
||||
},
|
||||
{
|
||||
path: 'importExcel',
|
||||
name: t('routes.demo.excel.importExcel'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: t('routes.demo.feat.breadcrumb'),
|
||||
path: 'breadcrumb',
|
||||
|
||||
children: [
|
||||
// {
|
||||
// path: 'flat',
|
||||
// name: t('routes.demo.feat.breadcrumbFlat'),
|
||||
// },
|
||||
// {
|
||||
// path: 'flatDetail',
|
||||
// name: t('routes.demo.feat.breadcrumbFlatDetail'),
|
||||
// },
|
||||
{
|
||||
path: 'children',
|
||||
name: t('routes.demo.feat.breadcrumbChildren'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'testTab',
|
||||
name: t('routes.demo.feat.tab'),
|
||||
children: [
|
||||
{
|
||||
path: 'id1',
|
||||
name: t('routes.demo.feat.tab1'),
|
||||
},
|
||||
{
|
||||
path: 'id2',
|
||||
name: t('routes.demo.feat.tab2'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,17 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 5000,
|
||||
menu: {
|
||||
name: t('routes.demo.flow.name'),
|
||||
path: '/flow',
|
||||
children: [
|
||||
{
|
||||
path: 'flowChart',
|
||||
name: t('routes.demo.flow.flowChart'),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,25 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 1000,
|
||||
menu: {
|
||||
name: t('routes.demo.iframe.frame'),
|
||||
path: '/frame',
|
||||
children: [
|
||||
{
|
||||
path: 'doc',
|
||||
name: t('routes.demo.iframe.doc'),
|
||||
},
|
||||
{
|
||||
path: 'antv',
|
||||
name: t('routes.demo.iframe.antv'),
|
||||
},
|
||||
{
|
||||
path: 'https://vvbin.cn/doc-next/',
|
||||
name: t('routes.demo.iframe.docExternal'),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,37 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 2000,
|
||||
menu: {
|
||||
name: t('routes.demo.level.level'),
|
||||
path: '/level',
|
||||
children: [
|
||||
{
|
||||
path: 'menu1',
|
||||
name: 'Menu1',
|
||||
children: [
|
||||
{
|
||||
path: 'menu1-1',
|
||||
name: 'Menu1-1',
|
||||
children: [
|
||||
{
|
||||
path: 'menu1-1-1',
|
||||
name: 'Menu1-1-1',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'menu1-2',
|
||||
name: 'Menu1-2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'menu2',
|
||||
name: 'Menu2',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,121 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 20,
|
||||
menu: {
|
||||
name: t('routes.demo.page.page'),
|
||||
path: '/page-demo',
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'form',
|
||||
name: t('routes.demo.page.form'),
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: t('routes.demo.page.formBasic'),
|
||||
},
|
||||
{
|
||||
path: 'step',
|
||||
name: t('routes.demo.page.formStep'),
|
||||
},
|
||||
{
|
||||
path: 'high',
|
||||
name: t('routes.demo.page.formHigh'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'desc',
|
||||
name: t('routes.demo.page.desc'),
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: t('routes.demo.page.descBasic'),
|
||||
},
|
||||
{
|
||||
path: 'high',
|
||||
name: t('routes.demo.page.descHigh'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'result',
|
||||
name: t('routes.demo.page.result'),
|
||||
|
||||
children: [
|
||||
{
|
||||
path: 'success',
|
||||
name: t('routes.demo.page.resultSuccess'),
|
||||
},
|
||||
{
|
||||
path: 'fail',
|
||||
name: t('routes.demo.page.resultFail'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'exception',
|
||||
name: t('routes.demo.page.exception'),
|
||||
children: [
|
||||
{
|
||||
path: '403',
|
||||
name: t('403'),
|
||||
},
|
||||
{
|
||||
path: '404',
|
||||
name: t('404'),
|
||||
},
|
||||
{
|
||||
path: '500',
|
||||
name: t('500'),
|
||||
},
|
||||
{
|
||||
path: 'net-work-error',
|
||||
name: t('routes.demo.page.netWorkError'),
|
||||
},
|
||||
{
|
||||
path: 'not-data',
|
||||
name: t('routes.demo.page.notData'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'account',
|
||||
name: t('routes.demo.page.account'),
|
||||
children: [
|
||||
{
|
||||
path: 'center',
|
||||
name: t('routes.demo.page.accountCenter'),
|
||||
},
|
||||
{
|
||||
path: 'setting',
|
||||
name: t('routes.demo.page.accountSetting'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'list',
|
||||
name: t('routes.demo.page.list'),
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: t('routes.demo.page.listBasic'),
|
||||
},
|
||||
{
|
||||
path: 'card',
|
||||
name: t('routes.demo.page.listCard'),
|
||||
},
|
||||
{
|
||||
path: 'search',
|
||||
name: t('routes.demo.page.listSearch'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,49 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 15,
|
||||
menu: {
|
||||
name: t('routes.demo.permission.permission'),
|
||||
path: '/permission',
|
||||
children: [
|
||||
{
|
||||
path: 'front',
|
||||
name: t('routes.demo.permission.front'),
|
||||
children: [
|
||||
{
|
||||
path: 'page',
|
||||
name: t('routes.demo.permission.frontPage'),
|
||||
},
|
||||
{
|
||||
path: 'btn',
|
||||
name: t('routes.demo.permission.frontBtn'),
|
||||
},
|
||||
{
|
||||
path: 'auth-pageA',
|
||||
name: t('routes.demo.permission.frontTestA'),
|
||||
},
|
||||
{
|
||||
path: 'auth-pageB',
|
||||
name: t('routes.demo.permission.frontTestB'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'back',
|
||||
name: t('routes.demo.permission.back'),
|
||||
children: [
|
||||
{
|
||||
path: 'page',
|
||||
name: t('routes.demo.permission.backPage'),
|
||||
},
|
||||
{
|
||||
path: 'btn',
|
||||
name: t('routes.demo.permission.backBtn'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -1,14 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const setup: MenuModule = {
|
||||
orderNo: 90000,
|
||||
menu: {
|
||||
path: '/setup/index',
|
||||
name: t('routes.demo.setup.page'),
|
||||
tag: {
|
||||
content: 'new',
|
||||
},
|
||||
},
|
||||
};
|
||||
export default setup;
|
@@ -1,34 +0,0 @@
|
||||
import type { MenuModule } from '/@/router/types';
|
||||
import { t } from '/@/hooks/web/useI18n';
|
||||
|
||||
const menu: MenuModule = {
|
||||
orderNo: 2000,
|
||||
menu: {
|
||||
name: t('routes.demo.system.moduleName'),
|
||||
path: '/system',
|
||||
children: [
|
||||
{
|
||||
path: 'account',
|
||||
name: t('routes.demo.system.account'),
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
name: t('routes.demo.system.role'),
|
||||
},
|
||||
{
|
||||
path: 'menu',
|
||||
name: t('routes.demo.system.menu'),
|
||||
},
|
||||
{
|
||||
path: 'dept',
|
||||
name: t('routes.demo.system.dept'),
|
||||
},
|
||||
|
||||
{
|
||||
path: 'changePassword',
|
||||
name: t('routes.demo.system.password'),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
export default menu;
|
@@ -10,6 +10,7 @@ export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = {
|
||||
meta: {
|
||||
title: 'ErrorPage',
|
||||
hideBreadcrumb: true,
|
||||
hideMenu: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
@@ -31,6 +32,7 @@ export const REDIRECT_ROUTE: AppRouteRecordRaw = {
|
||||
meta: {
|
||||
title: REDIRECT_NAME,
|
||||
hideBreadcrumb: true,
|
||||
hideMenu: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
|
@@ -9,8 +9,10 @@ const dashboard: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/about/index',
|
||||
meta: {
|
||||
hideChildrenInMenu: true,
|
||||
icon: 'simple-icons:about-dot-me',
|
||||
title: t('routes.dashboard.about'),
|
||||
orderNo: 100000,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
|
@@ -9,6 +9,7 @@ const dashboard: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/dashboard/analysis',
|
||||
meta: {
|
||||
orderNo: 10,
|
||||
icon: 'ion:grid-outline',
|
||||
title: t('routes.dashboard.dashboard'),
|
||||
},
|
||||
|
@@ -9,6 +9,7 @@ const charts: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/charts/echarts/map',
|
||||
meta: {
|
||||
orderNo: 500,
|
||||
icon: 'ion:bar-chart-outline',
|
||||
title: t('routes.demo.charts.charts'),
|
||||
},
|
||||
|
@@ -9,6 +9,7 @@ const comp: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/comp/basic',
|
||||
meta: {
|
||||
orderNo: 30,
|
||||
icon: 'ion:layers-outline',
|
||||
title: t('routes.demo.comp.comp'),
|
||||
},
|
||||
|
@@ -9,6 +9,7 @@ const feat: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/feat/icon',
|
||||
meta: {
|
||||
orderNo: 19,
|
||||
icon: 'ion:git-compare-outline',
|
||||
title: t('routes.demo.feat.feat'),
|
||||
},
|
||||
|
@@ -9,6 +9,7 @@ const charts: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/flow/flowChart',
|
||||
meta: {
|
||||
orderNo: 5000,
|
||||
icon: 'tabler:chart-dots',
|
||||
title: t('routes.demo.flow.name'),
|
||||
},
|
||||
|
@@ -10,6 +10,7 @@ const iframe: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/frame/doc',
|
||||
meta: {
|
||||
orderNo: 1000,
|
||||
icon: 'ion:tv-outline',
|
||||
title: t('routes.demo.iframe.frame'),
|
||||
},
|
||||
|
@@ -9,6 +9,7 @@ const permission: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/level/menu1/menu1-1/menu1-1-1',
|
||||
meta: {
|
||||
orderNo: 2000,
|
||||
icon: 'ion:menu-outline',
|
||||
title: t('routes.demo.level.level'),
|
||||
},
|
||||
|
@@ -12,6 +12,7 @@ const page: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/page-demo/form/basic',
|
||||
meta: {
|
||||
orderNo: 20,
|
||||
icon: 'ion:aperture-outline',
|
||||
title: t('routes.demo.page.page'),
|
||||
},
|
||||
|
@@ -10,6 +10,7 @@ const permission: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/permission/front/page',
|
||||
meta: {
|
||||
orderNo: 15,
|
||||
icon: 'ion:key-outline',
|
||||
title: t('routes.demo.permission.permission'),
|
||||
},
|
||||
|
@@ -9,6 +9,8 @@ const setup: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/setup/index',
|
||||
meta: {
|
||||
orderNo: 90000,
|
||||
hideChildrenInMenu: true,
|
||||
icon: 'simple-icons:about-dot-me',
|
||||
title: t('routes.demo.setup.page'),
|
||||
},
|
||||
|
@@ -9,6 +9,7 @@ const system: AppRouteModule = {
|
||||
component: LAYOUT,
|
||||
redirect: '/system/account',
|
||||
meta: {
|
||||
orderNo: 2000,
|
||||
icon: 'ion:settings-outline',
|
||||
title: t('routes.demo.system.moduleName'),
|
||||
},
|
||||
@@ -18,10 +19,22 @@ const system: AppRouteModule = {
|
||||
name: 'AccountManagement',
|
||||
meta: {
|
||||
title: t('routes.demo.system.account'),
|
||||
ignoreKeepAlive: true,
|
||||
ignoreKeepAlive: false,
|
||||
},
|
||||
component: () => import('/@/views/demo/system/account/index.vue'),
|
||||
},
|
||||
{
|
||||
path: 'account_detail/:id',
|
||||
name: 'AccountDetail',
|
||||
meta: {
|
||||
hideMenu: true,
|
||||
title: t('routes.demo.system.account_detail'),
|
||||
ignoreKeepAlive: true,
|
||||
showMenu: false,
|
||||
currentActiveMenu: '/system/account',
|
||||
},
|
||||
component: () => import('/@/views/demo/system/account/AccountDetail.vue'),
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
name: 'RoleManagement',
|
||||
|
@@ -24,7 +24,7 @@ const setting: ProjectConfig = {
|
||||
settingButtonPosition: SettingButtonPositionEnum.AUTO,
|
||||
|
||||
// Permission mode
|
||||
permissionMode: PermissionModeEnum.ROLE,
|
||||
permissionMode: PermissionModeEnum.ROUTE_MAPPING,
|
||||
|
||||
// Permission-related cache is stored in sessionStorage or localStorage
|
||||
permissionCacheType: CacheTypeEnum.LOCAL,
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import type { App } from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
|
||||
const store = createPinia();
|
||||
|
||||
export function setupStore(app: App<Element>) {
|
||||
|
@@ -103,6 +103,6 @@ export const useAppStore = defineStore({
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function useAppStoreWidthOut() {
|
||||
export function useAppStoreWithOut() {
|
||||
return useAppStore(store);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ import { defineStore } from 'pinia';
|
||||
import { store } from '/@/store';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useUserStore } from './user';
|
||||
import { useAppStoreWidthOut } from './app';
|
||||
import { useAppStoreWithOut } from './app';
|
||||
import { toRaw } from 'vue';
|
||||
import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper';
|
||||
import { transformRouteToMenu } from '/@/router/helper/menuHelper';
|
||||
@@ -32,6 +32,7 @@ interface PermissionState {
|
||||
lastBuildMenuTime: number;
|
||||
// Backstage menu list
|
||||
backMenuList: Menu[];
|
||||
frontMenuList: Menu[];
|
||||
}
|
||||
export const usePermissionStore = defineStore({
|
||||
id: 'app-permission',
|
||||
@@ -43,6 +44,8 @@ export const usePermissionStore = defineStore({
|
||||
lastBuildMenuTime: 0,
|
||||
// Backstage menu list
|
||||
backMenuList: [],
|
||||
// menu List
|
||||
frontMenuList: [],
|
||||
}),
|
||||
getters: {
|
||||
getPermCodeList(): string[] | number[] {
|
||||
@@ -51,6 +54,9 @@ export const usePermissionStore = defineStore({
|
||||
getBackMenuList(): Menu[] {
|
||||
return this.backMenuList;
|
||||
},
|
||||
getFrontMenuList(): Menu[] {
|
||||
return this.frontMenuList;
|
||||
},
|
||||
getLastBuildMenuTime(): number {
|
||||
return this.lastBuildMenuTime;
|
||||
},
|
||||
@@ -68,6 +74,10 @@ export const usePermissionStore = defineStore({
|
||||
list?.length > 0 && this.setLastBuildMenuTime();
|
||||
},
|
||||
|
||||
setFrontMenuList(list: Menu[]) {
|
||||
this.frontMenuList = list;
|
||||
},
|
||||
|
||||
setLastBuildMenuTime() {
|
||||
this.lastBuildMenuTime = new Date().getTime();
|
||||
},
|
||||
@@ -88,52 +98,70 @@ export const usePermissionStore = defineStore({
|
||||
async buildRoutesAction(): Promise<AppRouteRecordRaw[]> {
|
||||
const { t } = useI18n();
|
||||
const userStore = useUserStore();
|
||||
const appStore = useAppStoreWidthOut();
|
||||
const appStore = useAppStoreWithOut();
|
||||
|
||||
let routes: AppRouteRecordRaw[] = [];
|
||||
const roleList = toRaw(userStore.getRoleList) || [];
|
||||
const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig;
|
||||
// role permissions
|
||||
if (permissionMode === PermissionModeEnum.ROLE) {
|
||||
const routeFilter = (route: AppRouteRecordRaw) => {
|
||||
const { meta } = route;
|
||||
const { roles } = meta || {};
|
||||
if (!roles) return true;
|
||||
return roleList.some((role) => roles.includes(role));
|
||||
};
|
||||
routes = filter(asyncRoutes, routeFilter);
|
||||
routes = routes.filter(routeFilter);
|
||||
// Convert multi-level routing to level 2 routing
|
||||
routes = flatMultiLevelRoutes(routes);
|
||||
|
||||
const routeFilter = (route: AppRouteRecordRaw) => {
|
||||
const { meta } = route;
|
||||
const { roles } = meta || {};
|
||||
if (!roles) return true;
|
||||
return roleList.some((role) => roles.includes(role));
|
||||
};
|
||||
|
||||
switch (permissionMode) {
|
||||
case PermissionModeEnum.ROLE:
|
||||
routes = filter(asyncRoutes, routeFilter);
|
||||
routes = routes.filter(routeFilter);
|
||||
// Convert multi-level routing to level 2 routing
|
||||
routes = flatMultiLevelRoutes(routes);
|
||||
break;
|
||||
|
||||
case PermissionModeEnum.ROUTE_MAPPING:
|
||||
routes = filter(asyncRoutes, routeFilter);
|
||||
routes = routes.filter(routeFilter);
|
||||
const menuList = transformRouteToMenu(asyncRoutes);
|
||||
menuList.sort((a, b) => {
|
||||
return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0);
|
||||
});
|
||||
this.setFrontMenuList(menuList);
|
||||
// Convert multi-level routing to level 2 routing
|
||||
routes = flatMultiLevelRoutes(routes);
|
||||
break;
|
||||
|
||||
// If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below
|
||||
} else if (permissionMode === PermissionModeEnum.BACK) {
|
||||
const { createMessage } = useMessage();
|
||||
case PermissionModeEnum.BACK:
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
createMessage.loading({
|
||||
content: t('sys.app.menuLoading'),
|
||||
duration: 1,
|
||||
});
|
||||
createMessage.loading({
|
||||
content: t('sys.app.menuLoading'),
|
||||
duration: 1,
|
||||
});
|
||||
|
||||
// !Simulate to obtain permission codes from the background,
|
||||
// this function may only need to be executed once, and the actual project can be put at the right time by itself
|
||||
let routeList: AppRouteRecordRaw[] = [];
|
||||
try {
|
||||
this.changePermissionCode();
|
||||
routeList = (await getMenuList()) as AppRouteRecordRaw[];
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
// !Simulate to obtain permission codes from the background,
|
||||
// this function may only need to be executed once, and the actual project can be put at the right time by itself
|
||||
let routeList: AppRouteRecordRaw[] = [];
|
||||
try {
|
||||
this.changePermissionCode();
|
||||
routeList = (await getMenuList()) as AppRouteRecordRaw[];
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
// Dynamically introduce components
|
||||
routeList = transformObjToRoute(routeList);
|
||||
// Dynamically introduce components
|
||||
routeList = transformObjToRoute(routeList);
|
||||
|
||||
// Background routing to menu structure
|
||||
const backMenuList = transformRouteToMenu(routeList);
|
||||
this.setBackMenuList(backMenuList);
|
||||
// Background routing to menu structure
|
||||
const backMenuList = transformRouteToMenu(routeList);
|
||||
this.setBackMenuList(backMenuList);
|
||||
|
||||
routeList = flatMultiLevelRoutes(routeList);
|
||||
routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
|
||||
routeList = flatMultiLevelRoutes(routeList);
|
||||
routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
|
||||
break;
|
||||
}
|
||||
|
||||
routes.push(ERROR_LOG_ROUTE);
|
||||
return routes;
|
||||
},
|
||||
@@ -141,6 +169,6 @@ export const usePermissionStore = defineStore({
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function usePermissionStoreWidthOut() {
|
||||
export function usePermissionStoreWithOut() {
|
||||
return usePermissionStore(store);
|
||||
}
|
||||
|
@@ -128,6 +128,6 @@ export const useUserStore = defineStore({
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function useUserStoreWidthOut() {
|
||||
export function useUserStoreWithOut() {
|
||||
return useUserStore(store);
|
||||
}
|
||||
|
@@ -147,7 +147,10 @@ export function forEach<T = any>(
|
||||
const list: any[] = [...tree];
|
||||
const { children } = config;
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
func(list[i]);
|
||||
//func 返回true就终止遍历,避免大量节点场景下无意义循环,引起浏览器卡顿
|
||||
if (func(list[i])) {
|
||||
return;
|
||||
}
|
||||
children && list[i][children] && list.splice(i + 1, 0, ...list[i][children]);
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import axios from 'axios';
|
||||
import qs from 'qs';
|
||||
import { AxiosCanceler } from './axiosCancel';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { cloneDeep, omit } from 'lodash-es';
|
||||
import { ContentTypeEnum } from '/@/enums/httpEnum';
|
||||
import { RequestEnum } from '/@/enums/httpEnum';
|
||||
|
||||
@@ -136,8 +136,12 @@ export class VAxios {
|
||||
formData.append(key, params.data[key]);
|
||||
});
|
||||
}
|
||||
|
||||
formData.append(params.name || 'file', params.file, params.filename);
|
||||
const customParams = omit(params, 'file', 'filename', 'file');
|
||||
|
||||
Object.keys(customParams).forEach((key) => {
|
||||
formData.append(key, customParams[key]);
|
||||
});
|
||||
|
||||
return this.axiosInstance.request<T>({
|
||||
...config,
|
||||
|
@@ -3,7 +3,7 @@ import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
// import router from '/@/router';
|
||||
// import { PageEnum } from '/@/enums/pageEnum';
|
||||
import { useUserStoreWidthOut } from '/@/store/modules/user';
|
||||
import { useUserStoreWithOut } from '/@/store/modules/user';
|
||||
import projectSetting from '/@/settings/projectSetting';
|
||||
import { SessionTimeoutProcessingEnum } from '/@/enums/appEnum';
|
||||
|
||||
@@ -17,7 +17,7 @@ export function checkStatus(
|
||||
errorMessageMode: ErrorMessageMode = 'message'
|
||||
): void {
|
||||
const { t } = useI18n();
|
||||
const userStore = useUserStoreWidthOut();
|
||||
const userStore = useUserStoreWithOut();
|
||||
let errMessage = '';
|
||||
|
||||
switch (status) {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* https://github.com/developit/mitt
|
||||
* copy to https://github.com/developit/mitt
|
||||
* Expand clear method
|
||||
*/
|
||||
|
||||
export type EventType = string | symbol;
|
||||
|
@@ -96,6 +96,14 @@
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'fieldTime',
|
||||
component: 'RangePicker',
|
||||
label: '时间字段',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'field4',
|
||||
component: 'Select',
|
||||
@@ -171,6 +179,7 @@
|
||||
actionColOptions: {
|
||||
span: 24,
|
||||
},
|
||||
fieldMapToTime: [['fieldTime', ['startTime', 'endTime'], 'YYYY-MM']],
|
||||
});
|
||||
return {
|
||||
register,
|
||||
|
@@ -2,17 +2,15 @@
|
||||
<PageWrapper
|
||||
class="high-form"
|
||||
title="高级表单"
|
||||
contentBackground
|
||||
content=" 高级表单常见于一次性输入和提交大批量数据的场景。"
|
||||
contentClass="p-4"
|
||||
>
|
||||
<a-card title="仓库管理" :bordered="false">
|
||||
<BasicForm @register="register" />
|
||||
</a-card>
|
||||
<a-card title="任务管理" :bordered="false" class="mt-5">
|
||||
<a-card title="任务管理" :bordered="false" class="!mt-5">
|
||||
<BasicForm @register="registerTask" />
|
||||
</a-card>
|
||||
<a-card title="成员管理" :bordered="false" class="mt-5">
|
||||
<a-card title="成员管理" :bordered="false">
|
||||
<PersonTable ref="tableRef" />
|
||||
</a-card>
|
||||
|
||||
|
62
src/views/demo/system/account/AccountDetail.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<PageWrapper
|
||||
:title="`用户` + userId + `的资料`"
|
||||
content="这是用户资料详情页面。本页面仅用于演示相同路由在tab中打开多个页面并且显示不同的数据"
|
||||
contentBackground
|
||||
@back="goBack"
|
||||
>
|
||||
<template #extra>
|
||||
<a-button type="danger"> 禁用账号 </a-button>
|
||||
<a-button type="primary"> 修改密码 </a-button>
|
||||
</template>
|
||||
<template #footer>
|
||||
<a-tabs default-active-key="detail" v-model:activeKey="currentKey">
|
||||
<a-tab-pane key="detail" tab="用户资料" />
|
||||
<a-tab-pane key="logs" tab="操作日志" />
|
||||
</a-tabs>
|
||||
</template>
|
||||
<div class="pt-4 m-4 desc-wrap">
|
||||
<template v-if="currentKey == 'detail'">
|
||||
<div v-for="i in 10" :key="i">这是用户{{ userId }}资料Tab</div>
|
||||
</template>
|
||||
<template v-if="currentKey == 'logs'">
|
||||
<div v-for="i in 10" :key="i">这是用户{{ userId }}操作日志Tab</div>
|
||||
</template>
|
||||
</div>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { PageWrapper } from '/@/components/Page';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
import { useTabs } from '/@/hooks/web/useTabs';
|
||||
import { Tabs } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
name: 'AccountDetail',
|
||||
components: { PageWrapper, ATabs: Tabs, ATabPane: Tabs.TabPane },
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const go = useGo();
|
||||
// 此处可以得到用户ID
|
||||
const userId = ref(route.params?.id);
|
||||
const currentKey = ref('detail');
|
||||
const { setTitle } = useTabs();
|
||||
// TODO
|
||||
// 本页代码仅作演示,实际应当通过userId从接口获得用户的相关资料
|
||||
|
||||
// 设置Tab的标题(不会影响页面标题)
|
||||
setTitle('详情:用户' + userId.value);
|
||||
|
||||
// 页面左侧点击返回链接时的操作
|
||||
function goBack() {
|
||||
// 本例的效果时点击返回始终跳转到账号列表页,实际应用时可返回上一页
|
||||
go('/system/account');
|
||||
}
|
||||
return { userId, currentKey, goBack };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style></style>
|
@@ -8,13 +8,20 @@
|
||||
<template #action="{ record }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
icon: 'clarity:eye-show-solid',
|
||||
title: '查看用户详情',
|
||||
onClick: handleView.bind(null, record),
|
||||
},
|
||||
{
|
||||
icon: 'clarity:note-edit-line',
|
||||
title: '编辑用户资料',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
icon: 'ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: '删除此账号',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
@@ -39,11 +46,13 @@
|
||||
import AccountModal from './AccountModal.vue';
|
||||
|
||||
import { columns, searchFormSchema } from './account.data';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AccountManagement',
|
||||
components: { BasicTable, PageWrapper, DeptTree, AccountModal, TableAction },
|
||||
setup() {
|
||||
const go = useGo();
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const [registerTable, { reload, updateTableDataRecord }] = useTable({
|
||||
title: '账号列表',
|
||||
@@ -58,7 +67,7 @@
|
||||
showTableSetting: true,
|
||||
bordered: true,
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
width: 120,
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
@@ -98,6 +107,10 @@
|
||||
reload({ searchInfo: { deptId } });
|
||||
}
|
||||
|
||||
function handleView(record: Recordable) {
|
||||
go('/system/account_detail/' + record.id);
|
||||
}
|
||||
|
||||
return {
|
||||
registerTable,
|
||||
registerModal,
|
||||
@@ -106,6 +119,7 @@
|
||||
handleDelete,
|
||||
handleSuccess,
|
||||
handleSelect,
|
||||
handleView,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -26,10 +26,13 @@
|
||||
class="w-1/3"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<BasicTree title="异步树" :treeData="tree" class="w-1/3" :load-data="onLoadData" />
|
||||
</div>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { BasicTree } from '/@/components/Tree/index';
|
||||
import { treeData } from './data';
|
||||
import { PageWrapper } from '/@/components/Page';
|
||||
@@ -40,7 +43,34 @@
|
||||
function handleCheck(checkedKeys, e) {
|
||||
console.log('onChecked', checkedKeys, e);
|
||||
}
|
||||
return { treeData, handleCheck };
|
||||
const tree = ref([
|
||||
{
|
||||
title: 'parent ',
|
||||
key: '0-0',
|
||||
},
|
||||
]);
|
||||
|
||||
function onLoadData(treeNode) {
|
||||
return new Promise((resolve: (value?: unknown) => void) => {
|
||||
if (!treeNode.children) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
tree.value.forEach((v) => {
|
||||
if (v.key === treeNode.eventKey) {
|
||||
v.children = [
|
||||
{ title: 'Child Node', key: `${treeNode.eventKey}-0` },
|
||||
{ title: 'Child Node', key: `${treeNode.eventKey}-1` },
|
||||
];
|
||||
}
|
||||
});
|
||||
resolve();
|
||||
return;
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
return { treeData, handleCheck, tree, onLoadData };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div :class="prefixCls" class="relative w-full h-full px-4">
|
||||
<AppLocalePicker
|
||||
class="absolute top-4 right-4 enter-x text-white xl:text-gray-600"
|
||||
class="absolute text-white top-4 right-4 enter-x xl:text-gray-600"
|
||||
:showText="false"
|
||||
v-if="!sessionTimeout && showLocale"
|
||||
/>
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<div class="container relative h-full py-2 mx-auto sm:px-10">
|
||||
<div class="flex h-full">
|
||||
<div class="hidden xl:flex xl:flex-col xl:w-6/12 min-h-full mr-4 pl-4">
|
||||
<div class="hidden min-h-full pl-4 mr-4 xl:flex xl:flex-col xl:w-6/12">
|
||||
<AppLogo class="-enter-x" />
|
||||
<div class="my-auto">
|
||||
<img
|
||||
@@ -22,33 +22,32 @@
|
||||
class="w-1/2 -mt-16 -enter-x"
|
||||
/>
|
||||
<div class="mt-10 font-medium text-white -enter-x">
|
||||
<span class="mt-4 text-3xl inline-block"> {{ t('sys.login.signInTitle') }}</span>
|
||||
<span class="inline-block mt-4 text-3xl"> {{ t('sys.login.signInTitle') }}</span>
|
||||
</div>
|
||||
<div class="mt-5 text-md text-white font-normal dark:text-gray-500 -enter-x">
|
||||
<div class="mt-5 font-normal text-white text-md dark:text-gray-500 -enter-x">
|
||||
{{ t('sys.login.signInDesc') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-full xl:h-auto flex py-5 xl:py-0 xl:my-0 w-full xl:w-6/12">
|
||||
<div class="flex w-full h-full py-5 xl:h-auto xl:py-0 xl:my-0 xl:w-6/12">
|
||||
<div
|
||||
:class="`${prefixCls}-form`"
|
||||
class="
|
||||
my-auto
|
||||
mx-auto
|
||||
xl:ml-20 xl:bg-transparent
|
||||
relative
|
||||
w-full
|
||||
px-5
|
||||
py-8
|
||||
sm:px-8
|
||||
xl:p-4
|
||||
mx-auto
|
||||
my-auto
|
||||
rounded-md
|
||||
shadow-md
|
||||
xl:shadow-none
|
||||
w-full
|
||||
xl:ml-16 xl:bg-transparent
|
||||
sm:px-8
|
||||
xl:p-4 xl:shadow-none
|
||||
sm:w-3/4
|
||||
lg:w-2/4
|
||||
xl:w-auto
|
||||
enter-x
|
||||
relative
|
||||
"
|
||||
>
|
||||
<LoginForm />
|
||||
@@ -144,6 +143,7 @@
|
||||
}
|
||||
|
||||
.@{prefix-cls} {
|
||||
min-height: 100%;
|
||||
overflow: hidden;
|
||||
@media (max-width: @screen-xl) {
|
||||
background-color: #293146;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<h2 class="font-bold text-2xl xl:text-3xl enter-x text-center xl:text-left mb-6">
|
||||
<h2 class="mb-3 text-2xl font-bold text-center xl:text-3xl enter-x xl:text-left">
|
||||
{{ getFormTitle }}
|
||||
</h2>
|
||||
</template>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
const colors = require('tailwindcss/colors');
|
||||
const { sky: color_sky, ...colors } = require('tailwindcss/colors');
|
||||
|
||||
module.exports = {
|
||||
mode: 'jit',
|
||||
@@ -16,6 +16,7 @@ module.exports = {
|
||||
},
|
||||
colors: {
|
||||
...colors,
|
||||
sky: color_sky,
|
||||
primary: {
|
||||
DEFAULT: '#0960bd',
|
||||
// dark: primaryColorDark,
|
||||
|
Before Width: | Height: | Size: 215 KiB |
Before Width: | Height: | Size: 114 KiB |
Before Width: | Height: | Size: 405 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 2.1 KiB |
@@ -39,5 +39,5 @@
|
||||
"mock/**/*.ts",
|
||||
"vite.config.ts"
|
||||
],
|
||||
"exclude": ["node_modules", "dist", "**/*.js"]
|
||||
"exclude": ["node_modules", "tests/server/**/*.ts", "dist", "**/*.js"]
|
||||
}
|
||||
|
5
types/axios.d.ts
vendored
@@ -5,9 +5,10 @@ export interface RequestOptions {
|
||||
joinParamsToUrl?: boolean;
|
||||
// Format request parameter time
|
||||
formatDate?: boolean;
|
||||
// Whether to process the request result
|
||||
// Whether to process the request result
|
||||
isTransformResponse?: boolean;
|
||||
// 是否返回原生响应头 比如:需要获取响应头时使用该属性
|
||||
// Whether to return native response headers
|
||||
// For example: use this attribute when you need to get the response headers
|
||||
isReturnNativeResponse?: boolean;
|
||||
// Whether to join url
|
||||
joinPrefix?: boolean;
|
||||
|
1
types/vue-router.d.ts
vendored
@@ -2,6 +2,7 @@ export {};
|
||||
|
||||
declare module 'vue-router' {
|
||||
interface RouteMeta extends Record<string | number | symbol, unknown> {
|
||||
orderNo?: number;
|
||||
// title
|
||||
title: string;
|
||||
// Whether to ignore permissions
|
||||
|