mirror of
https://github.com/vbenjs/gf-vben-admin.git
synced 2025-02-03 03:32:59 +08:00
Merge remote-tracking branch 'vben/main' into Gf-Vben-Admin
# Conflicts: # .github/workflows/deploy.yml # .github/workflows/ftp-schedule.yml # src/views/sys/login/LoginForm.vue
This commit is contained in:
commit
c188d8398d
@ -25,6 +25,7 @@ module.exports = defineConfig({
|
|||||||
'plugin:jest/recommended',
|
'plugin:jest/recommended',
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
|
'vue/script-setup-uses-vars': 'error',
|
||||||
'@typescript-eslint/ban-ts-ignore': 'off',
|
'@typescript-eslint/ban-ts-ignore': 'off',
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
@ -61,7 +62,6 @@ module.exports = defineConfig({
|
|||||||
'vue/singleline-html-element-content-newline': 'off',
|
'vue/singleline-html-element-content-newline': 'off',
|
||||||
'vue/attribute-hyphenation': 'off',
|
'vue/attribute-hyphenation': 'off',
|
||||||
'vue/require-default-prop': 'off',
|
'vue/require-default-prop': 'off',
|
||||||
'vue/script-setup-uses-vars': 'off',
|
|
||||||
'vue/html-self-closing': [
|
'vue/html-self-closing': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
|
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -8,6 +8,6 @@
|
|||||||
"url": "http://localhost:3100",
|
"url": "http://localhost:3100",
|
||||||
"webRoot": "${workspaceFolder}/src",
|
"webRoot": "${workspaceFolder}/src",
|
||||||
"sourceMaps": true
|
"sourceMaps": true
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -117,6 +117,7 @@
|
|||||||
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
|
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
|
||||||
"i18n-ally.enabledParsers": ["ts"],
|
"i18n-ally.enabledParsers": ["ts"],
|
||||||
"i18n-ally.sourceLanguage": "en",
|
"i18n-ally.sourceLanguage": "en",
|
||||||
|
"i18n-ally.displayLanguage": "zh-CN",
|
||||||
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"vben",
|
"vben",
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
## 2.7.1(2021-08-16)
|
||||||
|
|
||||||
|
- Upgrade vue 3.2, if the operation fails, delete node_modules and reinstall it
|
||||||
|
|
||||||
|
### ✨ Features
|
||||||
|
|
||||||
|
- **BasicTree** Add search function related properties and methods
|
||||||
|
- **BasicForm** added `alwaysShowLines` to set the number of lines kept displayed when folding
|
||||||
|
|
||||||
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
|
- **Cropper** Fix the problem of failure to destroy in time
|
||||||
|
- **BasicTable**
|
||||||
|
- Fix the problem that `CellFormat` cannot use `Map` type data
|
||||||
|
- Fixed an issue where the editable cell failed to display the `0` value correctly
|
||||||
|
- Fixed the issue that selection-change event failed to trigger correctly when unchecked
|
||||||
|
- Fix the problem that the background color of the full screen state under the light theme is incorrect
|
||||||
|
- Fix the problem of obtaining complete data when `getSelectRows` does not support remote data cross-page selection
|
||||||
|
- Fix the issue that the `size` property provided for editing components in `editComponentProps` is invalid
|
||||||
|
- **Qrcode** Fixed the problem that the QR code component could not be drawn in time when it was created
|
||||||
|
- **BasicModal** Fix the problem that the `helpMessage` property does not work
|
||||||
|
- **BasicButton** Fix the problem that the button style performance is inconsistent with the official antd
|
||||||
|
- **Others** Fix the problem that `useRedo` (reload the current route) will lose route `params` data
|
||||||
|
|
||||||
## 2.7.0(2021-08-03)
|
## 2.7.0(2021-08-03)
|
||||||
|
|
||||||
## (Breaking changes) Breaking changes
|
## (Breaking changes) Breaking changes
|
||||||
|
87
CHANGELOG.md
87
CHANGELOG.md
@ -1,3 +1,90 @@
|
|||||||
|
## [2.7.1](https://github.com/anncwb/vue-vben-admin/compare/v2.6.1...v2.7.1) (2021-08-16)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- `slots` working in components ([b1f3176](https://github.com/anncwb/vue-vben-admin/commit/b1f31762e3c86a432a8d559ab957444eaf5525ad))
|
||||||
|
- add axios error info from response ([#1083](https://github.com/anncwb/vue-vben-admin/issues/1083)) ([72634ff](https://github.com/anncwb/vue-vben-admin/commit/72634ffe6e6649d36ee41f7633c8ee2ab80cf25e))
|
||||||
|
- auto remove script dom in `useScript` ([a544dd3](https://github.com/anncwb/vue-vben-admin/commit/a544dd3e589329339177dad3d5c1f75dd6e6f0ca))
|
||||||
|
- fixed `useRedo` may loss route params ([2dd3d85](https://github.com/anncwb/vue-vben-admin/commit/2dd3d8544866231895d23dba63785b683ae0062e)), closes [#1079](https://github.com/anncwb/vue-vben-admin/issues/1079)
|
||||||
|
- fixed basicButton ghost style ([3ba8a67](https://github.com/anncwb/vue-vben-admin/commit/3ba8a67647d35fb9639a5af66f33d43eff493d15))
|
||||||
|
- fixed basicButton primary style ([1b57792](https://github.com/anncwb/vue-vben-admin/commit/1b577922e752c02fe7c033c53be37ef81e4e9b8e))
|
||||||
|
- fixed basicButton style ([beb4ae9](https://github.com/anncwb/vue-vben-admin/commit/beb4ae92c190780bbd3bc6bc7547d52e2ccf8cf1))
|
||||||
|
- **cropper:** cropper not destroy in time ([3819430](https://github.com/anncwb/vue-vben-admin/commit/381943078fd55123fde3d5555e04f279d7f1c407)), closes [#1027](https://github.com/anncwb/vue-vben-admin/issues/1027)
|
||||||
|
- **demo:** fix form style in modal ([30c5fc6](https://github.com/anncwb/vue-vben-admin/commit/30c5fc63c8600cfb03f917d79e56c0a7e7ff64e0)), closes [#1076](https://github.com/anncwb/vue-vben-admin/issues/1076)
|
||||||
|
- **i18n:** add i18n translate data ([1f55c41](https://github.com/anncwb/vue-vben-admin/commit/1f55c4180f9c0cf48e3796a77d6f0bfd46107272))
|
||||||
|
- **locales:** fix that vscode extension i18n-Ally detect zh-CN as zh ([#1044](https://github.com/anncwb/vue-vben-admin/issues/1044)) ([b2d49cb](https://github.com/anncwb/vue-vben-admin/commit/b2d49cbbf81cb15e75905deb95bdf7ac4af4e599))
|
||||||
|
- **modal:** `helpMessage` doesn't work ([953bfc6](https://github.com/anncwb/vue-vben-admin/commit/953bfc6f1a559309ea2b1114b8ede911a3751cc7))
|
||||||
|
- **page-wrapper:** fix `class` not working ([8879ae8](https://github.com/anncwb/vue-vben-admin/commit/8879ae8d773e8dc4c252c4234eefeab9bc135a30))
|
||||||
|
- **qrcode:** qrcode not displayed properly ([26f251e](https://github.com/anncwb/vue-vben-admin/commit/26f251e1ed5bfd79c8615fb552ca302f917cc588)), closes [#1026](https://github.com/anncwb/vue-vben-admin/issues/1026)
|
||||||
|
- **route:** the whitelist should include basicRoutes ([#1048](https://github.com/anncwb/vue-vben-admin/issues/1048)) ([1bb5156](https://github.com/anncwb/vue-vben-admin/commit/1bb51569236fd9bcc55dd9f237f51f218956b258))
|
||||||
|
- **table:** `0` is not shown in editable cell ([33a335a](https://github.com/anncwb/vue-vben-admin/commit/33a335a3f52aead522b3fbee0d558e2e797580ff)), closes [#1039](https://github.com/anncwb/vue-vben-admin/issues/1039)
|
||||||
|
- **table:** `cellFormat` support `Map` ([1214b7c](https://github.com/anncwb/vue-vben-admin/commit/1214b7c32c425750a4d0202a9b235eb9e45a6f47)), closes [#1031](https://github.com/anncwb/vue-vben-admin/issues/1031)
|
||||||
|
- **table:** `getSelectRows` support multi-page ([4b6025c](https://github.com/anncwb/vue-vben-admin/commit/4b6025cb9a3ef067680201ec3052bc651e0a0c1b)), closes [#914](https://github.com/anncwb/vue-vben-admin/issues/914)
|
||||||
|
- **table:** `selection-change` not triggered in unchecking ([019555b](https://github.com/anncwb/vue-vben-admin/commit/019555be0c88edc673cae382023d647e78959b30)), closes [#1053](https://github.com/anncwb/vue-vben-admin/issues/1053)
|
||||||
|
- **table:** `size` not worked in `editComponentProps` ([7971896](https://github.com/anncwb/vue-vben-admin/commit/7971896383296c155b7ab16b5beb3544f34ee525)), closes [#1074](https://github.com/anncwb/vue-vben-admin/issues/1074)
|
||||||
|
- **table:** fix `getSelectRows` for treeTable ([f2b8bb4](https://github.com/anncwb/vue-vben-admin/commit/f2b8bb43a0b9172b9ef9ced8e83bf91143a091d9)), closes [#1003](https://github.com/anncwb/vue-vben-admin/issues/1003)
|
||||||
|
- **table:** fix `injection not found` warning ([53e79a2](https://github.com/anncwb/vue-vben-admin/commit/53e79a2d94df19c0e1aa7399d5ce4c27834e0350))
|
||||||
|
- **types:** fix some type errors ([9035fd1](https://github.com/anncwb/vue-vben-admin/commit/9035fd191e4e8d954f42b3a4cd1e80ec70b7cbb6))
|
||||||
|
- The Style of tableTitle slot ([#1023](https://github.com/anncwb/vue-vben-admin/issues/1023)) ([02e7756](https://github.com/anncwb/vue-vben-admin/commit/02e77560624cc4a95a5a20ffd5e0601f1f88c6f4))
|
||||||
|
- fix build handler & misc ([#1060](https://github.com/anncwb/vue-vben-admin/issues/1060)) ([66feb77](https://github.com/anncwb/vue-vben-admin/commit/66feb779a8645a93760c784c510512118c4c6efa))
|
||||||
|
- **table:** recursive updateTableDataRecord ([#1024](https://github.com/anncwb/vue-vben-admin/issues/1024)) ([72f953c](https://github.com/anncwb/vue-vben-admin/commit/72f953c8d3413a7f5482793258503017a81cc759))
|
||||||
|
- **table:** wrong bg-color in fullscreen mode ([2052eb5](https://github.com/anncwb/vue-vben-admin/commit/2052eb5a65be38c44165efecdb15266de4638667))
|
||||||
|
- **type:** fix ant-design-vue -> ([#1043](https://github.com/anncwb/vue-vben-admin/issues/1043)) ([6d5388a](https://github.com/anncwb/vue-vben-admin/commit/6d5388aaf143ac76bac0b68d56a3ab6b5993e807))
|
||||||
|
- fix iframe heigth error ([#1012](https://github.com/anncwb/vue-vben-admin/issues/1012)) ([d76cfd7](https://github.com/anncwb/vue-vben-admin/commit/d76cfd7f809ba48880c950a64cb43a5c9c44176c))
|
||||||
|
- Fix the invalid hot update of BasicButton when changing style outside ([#1016](https://github.com/anncwb/vue-vben-admin/issues/1016)) ([be2d11d](https://github.com/anncwb/vue-vben-admin/commit/be2d11d5d344a508e94abe3534726c80e1f1f271))
|
||||||
|
- the position of tinymce upload image is wrong ([#1015](https://github.com/anncwb/vue-vben-admin/issues/1015)) ([2fd0fd2](https://github.com/anncwb/vue-vben-admin/commit/2fd0fd281e65d6d2551478c5f19250347dc14062))
|
||||||
|
- **tree:** fix `checkAll` effects `disabled` node ([ddd1893](https://github.com/anncwb/vue-vben-admin/commit/ddd1893b113e13786037522341abb2e75f8f9d5b))
|
||||||
|
- style property of actionColOpt is invalid ([#997](https://github.com/anncwb/vue-vben-admin/issues/997)) ([225bd4c](https://github.com/anncwb/vue-vben-admin/commit/225bd4c39de377d93c605f33bfdf3d8fd565f12b))
|
||||||
|
- typo ([#980](https://github.com/anncwb/vue-vben-admin/issues/980)) ([7e6a89f](https://github.com/anncwb/vue-vben-admin/commit/7e6a89ffeb8c63467908d5807d3d7c4761620ee3))
|
||||||
|
- **api-tree-select:** auto reload while `params` changed ([c734f68](https://github.com/anncwb/vue-vben-admin/commit/c734f6858daea6d11cd517463b06fcce58744947))
|
||||||
|
- **dark-theme:** alert color in dark-theme ([9b7ede0](https://github.com/anncwb/vue-vben-admin/commit/9b7ede09b9efe4d5a15ab0cdeadac480a29c0f62))
|
||||||
|
- **dark-theme:** bgcolor of `selected tree node` in dark theme ([8cf004a](https://github.com/anncwb/vue-vben-admin/commit/8cf004a5f59895e2487c3a350c83000e585b897e)), closes [#949](https://github.com/anncwb/vue-vben-admin/issues/949)
|
||||||
|
- **dark-theme:** disabled link `button` color ([4281216](https://github.com/anncwb/vue-vben-admin/commit/42812162c46832ce4d3e332bd579c042309115bc))
|
||||||
|
- **dark-theme:** fixed `TreeSelect` & `DatePicker` theme ([d1e0e8b](https://github.com/anncwb/vue-vben-admin/commit/d1e0e8bcea1c168631222989969e14f7d0d1b6a4)), closes [#955](https://github.com/anncwb/vue-vben-admin/issues/955)
|
||||||
|
- **dark-theme:** style for checked tree nodes ([662b576](https://github.com/anncwb/vue-vben-admin/commit/662b576ac2088247cb58e295378f228462508a37))
|
||||||
|
- **demo:** account page form validation ([8702965](https://github.com/anncwb/vue-vben-admin/commit/87029650570e470431fb94d35a273c5d07a73135))
|
||||||
|
- **demo:** fix roles mock data ([c375e32](https://github.com/anncwb/vue-vben-admin/commit/c375e32305eae5128e09ad1bda39ce0cc6afd790))
|
||||||
|
- **form:** remove console error for `setFieldsValue` ([8d185bb](https://github.com/anncwb/vue-vben-admin/commit/8d185bb5841c83eb49c78e8342e65067aa6f9b80)), closes [#952](https://github.com/anncwb/vue-vben-admin/issues/952)
|
||||||
|
- **table:** fix `pagination` props working ([e327893](https://github.com/anncwb/vue-vben-admin/commit/e32789373eb5b1b531572b59692bf552dac365dc))
|
||||||
|
- expandIcon slot of BasicTable component is invalid ([#975](https://github.com/anncwb/vue-vben-admin/issues/975)) ([98c206d](https://github.com/anncwb/vue-vben-admin/commit/98c206d9c9661a18dde4ec7782cbe1eb6e62ebeb))
|
||||||
|
- **demo:** menu `error-log` link to 404 page ([341bd63](https://github.com/anncwb/vue-vben-admin/commit/341bd633d8ed38a5a357db8f97166c2eba2895d3))
|
||||||
|
- **demo:** multi-modal used with dynamic component ([e1c4723](https://github.com/anncwb/vue-vben-admin/commit/e1c47233edf7675aede6d5f023726945a510ddf7))
|
||||||
|
- **echarts:** fix graphic config cannot be used in echarts options ([#959](https://github.com/anncwb/vue-vben-admin/issues/959)) ([525484e](https://github.com/anncwb/vue-vben-admin/commit/525484e7a409b032d22231f90a92e700ef4290ae))
|
||||||
|
- **form:** fix `validate` promise catch ([571f281](https://github.com/anncwb/vue-vben-admin/commit/571f28138f782553eb39cda2d632e5ac1aa1e145))
|
||||||
|
- **img-rotate-drag-verify:** fix `resume` method support ([32d64db](https://github.com/anncwb/vue-vben-admin/commit/32d64dbe816a0afda6ee9e91863199afb3e7b48e)), closes [#946](https://github.com/anncwb/vue-vben-admin/issues/946)
|
||||||
|
- **login:** fix `auto fill` style in dark-theme ([cebc6a5](https://github.com/anncwb/vue-vben-admin/commit/cebc6a590e1a19af7380a55aed43b23af274df0a))
|
||||||
|
- **perm-guard:** Fix the problem that the routing query is lost after refreshing the page ([#941](https://github.com/anncwb/vue-vben-admin/issues/941)) ([9c4889f](https://github.com/anncwb/vue-vben-admin/commit/9c4889f0859bc60decf0ef40c383c1946de1d68a))
|
||||||
|
- **qrcode:** Fix the problem that the QR code cannot be dynamically generated ([#974](https://github.com/anncwb/vue-vben-admin/issues/974)) ([fe4eae3](https://github.com/anncwb/vue-vben-admin/commit/fe4eae37146068f01ba08f033e0c2e8bd03e48b5))
|
||||||
|
- **style:** fix checkbox-checked css in dark mode ([d3f08e3](https://github.com/anncwb/vue-vben-admin/commit/d3f08e37c5b6e46f33d525e9ef4b4c235d77a192))
|
||||||
|
- **table:** component shown in `fullscreen` mode ([a07ab6d](https://github.com/anncwb/vue-vben-admin/commit/a07ab6d7aa1060f856649a9bdbec9dfa50b14f26))
|
||||||
|
- **table:** editable cell display with validation ([202aa42](https://github.com/anncwb/vue-vben-admin/commit/202aa42b8d5a94e84ad386bcf7feab96926c70dd)), closes [#953](https://github.com/anncwb/vue-vben-admin/issues/953)
|
||||||
|
- **table:** fix `dataPicker` show in `fullscreen` mode ([a5a9b3f](https://github.com/anncwb/vue-vben-admin/commit/a5a9b3fb34c64b6ea9c9ab3d58045f6e5963952b))
|
||||||
|
- **table:** fix expand style ([14fb21d](https://github.com/anncwb/vue-vben-admin/commit/14fb21d0b7b9ac69c7b3c463de6d709bd5713d14)), closes [#969](https://github.com/anncwb/vue-vben-admin/issues/969)
|
||||||
|
- **table:** fix tableSettings popup in fullscreen mode ([dce3fb0](https://github.com/anncwb/vue-vben-admin/commit/dce3fb0f20516aaf4817281f5d08109e53a73ecb))
|
||||||
|
- **table-action:** stopButtonPropagation not working ([9b8f165](https://github.com/anncwb/vue-vben-admin/commit/9b8f165a365758d001e6d86ae7afe4ae3316d485))
|
||||||
|
- Fix vite profile hot update error reporting ([#968](https://github.com/anncwb/vue-vben-admin/issues/968)) ([956ed2e](https://github.com/anncwb/vue-vben-admin/commit/956ed2e3f770cc9cf822ce80f71b1e7f179792fb))
|
||||||
|
- **utils:** The date function gets a non-date when the parameter is null ([#954](https://github.com/anncwb/vue-vben-admin/issues/954)) ([350c85a](https://github.com/anncwb/vue-vben-admin/commit/350c85accf5033cc5a21b71bc36d5b7a74eb2573))
|
||||||
|
- fixed moment locale config ([27207a7](https://github.com/anncwb/vue-vben-admin/commit/27207a78caccb04372e0275c5cee526ec460de0e))
|
||||||
|
- typo for utils/env ([#1004](https://github.com/anncwb/vue-vben-admin/issues/1004)) ([e8eefd1](https://github.com/anncwb/vue-vben-admin/commit/e8eefd1bca41c181ec6395bf1d087d2018e2b1f1))
|
||||||
|
- **table:** fix editable cell not support `ellipsis` ([4bb506f](https://github.com/anncwb/vue-vben-admin/commit/4bb506fb1f6ac7d246f8792d29f337ec003ff426)), closes [#944](https://github.com/anncwb/vue-vben-admin/issues/944)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- add `updatePath` for `useTabs` ([bcfa338](https://github.com/anncwb/vue-vben-admin/commit/bcfa33822736b761757a2673d977f752cb5c4f7c)), closes [#1068](https://github.com/anncwb/vue-vben-admin/issues/1068)
|
||||||
|
- always refresh userinfo when page reload ([cc46935](https://github.com/anncwb/vue-vben-admin/commit/cc46935a8296dae62ecfc753a956338ba433927e))
|
||||||
|
- **demo:** add `async-validator` demo ([8b4b767](https://github.com/anncwb/vue-vben-admin/commit/8b4b767f4ca78f7c6f7586d8ba662552c2b7bb51))
|
||||||
|
- **form:** add `alwaysShowLines` prop ([93f9a19](https://github.com/anncwb/vue-vben-admin/commit/93f9a19aa16a3e9cb95338417c52d9a398e3f70b)), closes [#1051](https://github.com/anncwb/vue-vben-admin/issues/1051)
|
||||||
|
- **preview:** add more features ([e23bd26](https://github.com/anncwb/vue-vben-admin/commit/e23bd2696da945291a9b652f1af39ad1936f376b))
|
||||||
|
- **table:** add getRawDataSource() function ([#1029](https://github.com/anncwb/vue-vben-admin/issues/1029)) ([f3cf162](https://github.com/anncwb/vue-vben-admin/commit/f3cf162af1fa5634d4e562fa5239939af6f26093))
|
||||||
|
- **tree:** add searchable function ([60577d6](https://github.com/anncwb/vue-vben-admin/commit/60577d6720fd3f8d4d1a88b20ab902d6161a0eec)), closes [#1057](https://github.com/anncwb/vue-vben-admin/issues/1057)
|
||||||
|
- **use-loading:** add `setTip` method ([26d9476](https://github.com/anncwb/vue-vben-admin/commit/26d9476caff41cc355190604af42e0bd2ef0a353))
|
||||||
|
- Added support for tailwindcss night mode mechanism ([#998](https://github.com/anncwb/vue-vben-admin/issues/998)) ([189bc6f](https://github.com/anncwb/vue-vben-admin/commit/189bc6feb3f2860be8c531dd1ca996f3a2cff018))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
- **table:** fixed code style ([da12da9](https://github.com/anncwb/vue-vben-admin/commit/da12da9d8caeba0e7732551cfbad9b0da3baaac4)), closes [#1070](https://github.com/anncwb/vue-vben-admin/issues/1070)
|
||||||
|
- improve legacy compatibility ([e2664f6](https://github.com/anncwb/vue-vben-admin/commit/e2664f60029f03642f8b1a6afa9b1998705fce37))
|
||||||
|
|
||||||
# [2.7.0](https://github.com/anncwb/vue-vben-admin/compare/v2.5.9...v2.7.0) (2021-08-03)
|
# [2.7.0](https://github.com/anncwb/vue-vben-admin/compare/v2.5.9...v2.7.0) (2021-08-03)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
@ -1,8 +1,45 @@
|
|||||||
|
### ✨ Features
|
||||||
|
|
||||||
|
- **BasicForm** 表单组件新增`Divider`,用于较长表单的区域分割
|
||||||
|
- **BasicTable** 单元格编辑新增提交回调,将根据回调函数返回的结果来决定是否将数据提交到表格
|
||||||
|
|
||||||
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
|
- **CodeEditor** 修复 JSON 编辑器在格式化无效 JSON 文本时会抛出异常的问题
|
||||||
|
- **Tinymce** 修复 inline 模式在一些场景下会出现异常的问题
|
||||||
|
- **BasicTable**
|
||||||
|
- 修复可编辑单元格的内容为空时,不会显示编辑图标的问题
|
||||||
|
- 修复表尾合计行与表格主体部分的列有时候未能对齐的问题
|
||||||
|
- **其它**
|
||||||
|
- 修复部分封装组件在使用插槽时报错的问题
|
||||||
|
- 修复`useECharts`的`theme`参数不起作用的问题
|
||||||
|
- 修复`Token`失效时,按 F5 刷新页面可能会出现页面加载异常的问题
|
||||||
|
- 修复`useRedo`的不当调用可能会导致重定向`path`异常的问题
|
||||||
|
- 修复`vite`自定义模式名称不支持下划线的问题
|
||||||
|
|
||||||
|
## 2.7.1(2021-08-16)
|
||||||
|
|
||||||
|
- 升级 vue 3.2,如果运行失败,删除 node_modules 后重装即可
|
||||||
|
|
||||||
|
### ✨ Features
|
||||||
|
|
||||||
|
- **BasicTree** 添加搜索功能相关属性和方法
|
||||||
|
- **BasicForm** 新增`alwaysShowLines`用于设置折叠时保留显示的行数
|
||||||
|
|
||||||
### 🐛 Bug Fixes
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
- **Cropper** 修复未能及时销毁的问题
|
- **Cropper** 修复未能及时销毁的问题
|
||||||
- **BasicTable** 修复`CellFormat`无法使用`Map`类型数据的问题
|
- **BasicTable**
|
||||||
|
- 修复`CellFormat`无法使用`Map`类型数据的问题
|
||||||
|
- 修复可编辑单元格未能正确显示`0`值的问题
|
||||||
|
- 修复 selection-change 事件在取消勾选时未能正确触发的问题
|
||||||
|
- 修复浅色主题下的全屏状态背景颜色不正确的问题
|
||||||
|
- 修复`getSelectRows`不支持远程数据跨页选择时获取完整数据的问题
|
||||||
|
- 修复在`editComponentProps`中为编辑组件提供的`size`属性无效的问题
|
||||||
- **Qrcode** 修复二维码组件在创建时未能及时绘制的问题
|
- **Qrcode** 修复二维码组件在创建时未能及时绘制的问题
|
||||||
|
- **BasicModal** 修复`helpMessage`属性不起作用的问题
|
||||||
|
- **BasicButton** 修复按钮样式表现与 antd 官方不一致的问题
|
||||||
|
- **其它** 修复`useRedo`(重新加载当前路由)会丢失路由`params`数据的问题
|
||||||
|
|
||||||
## 2.7.0(2021-08-03)
|
## 2.7.0(2021-08-03)
|
||||||
|
|
||||||
|
@ -150,6 +150,7 @@ yarn build
|
|||||||
## 后台整合示例
|
## 后台整合示例
|
||||||
|
|
||||||
- [lamp-cloud](https://github.com/zuihou/lamp-cloud) - 基于 SpringCloud Alibaba 的微服务中后台快速开发平台
|
- [lamp-cloud](https://github.com/zuihou/lamp-cloud) - 基于 SpringCloud Alibaba 的微服务中后台快速开发平台
|
||||||
|
- [matecloud](https://github.com/matevip/matecloud) - MateCloud 微服务脚手架,基于 Spring Cloud 2020.0.3、SpringBoot 2.5.3 的全开源平台
|
||||||
|
|
||||||
## 维护者
|
## 维护者
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ export function generateModifyVars(dark = false) {
|
|||||||
'success-color': '#55D187', // Success color
|
'success-color': '#55D187', // Success color
|
||||||
'error-color': '#ED6F6F', // False color
|
'error-color': '#ED6F6F', // False color
|
||||||
'warning-color': '#EFBD47', // Warning color
|
'warning-color': '#EFBD47', // Warning color
|
||||||
'border-color-base': '#EEEEEE',
|
//'border-color-base': '#EEEEEE',
|
||||||
'font-size-base': '14px', // Main font size
|
'font-size-base': '14px', // Main font size
|
||||||
'border-radius-base': '2px', // Component/float fillet
|
'border-radius-base': '2px', // Component/float fillet
|
||||||
'link-color': primary, // Link color
|
'link-color': primary, // Link color
|
||||||
|
@ -52,19 +52,19 @@ async function generateIcon() {
|
|||||||
const { prefix } = data;
|
const { prefix } = data;
|
||||||
const isLocal = useType === 'local';
|
const isLocal = useType === 'local';
|
||||||
const icons = Object.keys(data.icons).map(
|
const icons = Object.keys(data.icons).map(
|
||||||
(item) => `${isLocal ? prefix + ':' : ''}${item}`
|
(item) => `${isLocal ? prefix + ':' : ''}${item}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await fs.writeFileSync(
|
await fs.writeFileSync(
|
||||||
path.join(output, `icons.data.ts`),
|
path.join(output, `icons.data.ts`),
|
||||||
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`
|
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`,
|
||||||
);
|
);
|
||||||
prefixSet.push(prefix);
|
prefixSet.push(prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite'));
|
fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite'));
|
||||||
console.log(
|
console.log(
|
||||||
`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`
|
`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ function createConfig(
|
|||||||
configName,
|
configName,
|
||||||
config,
|
config,
|
||||||
configFileName = GLOB_CONFIG_FILE_NAME,
|
configFileName = GLOB_CONFIG_FILE_NAME,
|
||||||
}: { configName: string; config: any; configFileName?: string } = { configName: '', config: {} }
|
}: { configName: string; config: any; configFileName?: string } = { configName: '', config: {} },
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const windowConf = `window.${configName}`;
|
const windowConf = `window.${configName}`;
|
||||||
|
@ -11,7 +11,7 @@ export const runBuild = async () => {
|
|||||||
|
|
||||||
// Generate configuration file
|
// Generate configuration file
|
||||||
if (!argvList.includes('disabled-config')) {
|
if (!argvList.includes('disabled-config')) {
|
||||||
await runBuildConfig();
|
runBuildConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - build successfully!');
|
console.log(`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - build successfully!');
|
||||||
|
@ -31,7 +31,9 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
|
|||||||
if (envName === 'VITE_PROXY') {
|
if (envName === 'VITE_PROXY') {
|
||||||
try {
|
try {
|
||||||
realName = JSON.parse(realName);
|
realName = JSON.parse(realName);
|
||||||
} catch (error) {}
|
} catch (error) {
|
||||||
|
realName = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret[envName] = realName;
|
ret[envName] = realName;
|
||||||
if (typeof realName === 'string') {
|
if (typeof realName === 'string') {
|
||||||
@ -48,7 +50,7 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
|
|||||||
*/
|
*/
|
||||||
function getConfFiles() {
|
function getConfFiles() {
|
||||||
const script = process.env.npm_lifecycle_script;
|
const script = process.env.npm_lifecycle_script;
|
||||||
const reg = new RegExp('--mode ([a-z]+)');
|
const reg = new RegExp('--mode ([a-z_\\d]+)');
|
||||||
const result = reg.exec(script as string) as any;
|
const result = reg.exec(script as string) as any;
|
||||||
if (result) {
|
if (result) {
|
||||||
const mode = result[1] as string;
|
const mode = result[1] as string;
|
||||||
|
@ -3,12 +3,11 @@
|
|||||||
* https://github.com/anncwb/vite-plugin-compression
|
* https://github.com/anncwb/vite-plugin-compression
|
||||||
*/
|
*/
|
||||||
import type { Plugin } from 'vite';
|
import type { Plugin } from 'vite';
|
||||||
|
|
||||||
import compressPlugin from 'vite-plugin-compression';
|
import compressPlugin from 'vite-plugin-compression';
|
||||||
|
|
||||||
export function configCompressPlugin(
|
export function configCompressPlugin(
|
||||||
compress: 'gzip' | 'brotli' | 'none',
|
compress: 'gzip' | 'brotli' | 'none',
|
||||||
deleteOriginFile = false
|
deleteOriginFile = false,
|
||||||
): Plugin | Plugin[] {
|
): Plugin | Plugin[] {
|
||||||
const compressList = compress.split(',');
|
const compressList = compress.split(',');
|
||||||
|
|
||||||
@ -19,16 +18,17 @@ export function configCompressPlugin(
|
|||||||
compressPlugin({
|
compressPlugin({
|
||||||
ext: '.gz',
|
ext: '.gz',
|
||||||
deleteOriginFile,
|
deleteOriginFile,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compressList.includes('brotli')) {
|
if (compressList.includes('brotli')) {
|
||||||
plugins.push(
|
plugins.push(
|
||||||
compressPlugin({
|
compressPlugin({
|
||||||
ext: '.br',
|
ext: '.br',
|
||||||
algorithm: 'brotliCompress',
|
algorithm: 'brotliCompress',
|
||||||
deleteOriginFile,
|
deleteOriginFile,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return plugins;
|
return plugins;
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
* https://github.com/anncwb/vite-plugin-html
|
* https://github.com/anncwb/vite-plugin-html
|
||||||
*/
|
*/
|
||||||
import type { Plugin } from 'vite';
|
import type { Plugin } from 'vite';
|
||||||
|
|
||||||
import html from 'vite-plugin-html';
|
import html from 'vite-plugin-html';
|
||||||
|
|
||||||
import pkg from '../../../package.json';
|
import pkg from '../../../package.json';
|
||||||
import { GLOB_CONFIG_FILE_NAME } from '../../constant';
|
import { GLOB_CONFIG_FILE_NAME } from '../../constant';
|
||||||
|
|
||||||
@ -22,7 +20,7 @@ export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) {
|
|||||||
minify: isBuild,
|
minify: isBuild,
|
||||||
inject: {
|
inject: {
|
||||||
// Inject data into ejs template
|
// Inject data into ejs template
|
||||||
injectData: {
|
data: {
|
||||||
title: VITE_GLOB_APP_TITLE,
|
title: VITE_GLOB_APP_TITLE,
|
||||||
},
|
},
|
||||||
// Embed the generated app.config.js file
|
// Embed the generated app.config.js file
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
// Image resource files used to compress the output of the production environment
|
// Image resource files used to compress the output of the production environment
|
||||||
// https://github.com/anncwb/vite-plugin-imagemin
|
// https://github.com/anncwb/vite-plugin-imagemin
|
||||||
|
|
||||||
import viteImagemin from 'vite-plugin-imagemin';
|
import viteImagemin from 'vite-plugin-imagemin';
|
||||||
|
|
||||||
export function configImageminPlugin() {
|
export function configImageminPlugin() {
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import type { Plugin } from 'vite';
|
import type { Plugin } from 'vite';
|
||||||
|
|
||||||
import vue from '@vitejs/plugin-vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||||
import legacy from '@vitejs/plugin-legacy';
|
import legacy from '@vitejs/plugin-legacy';
|
||||||
|
|
||||||
import purgeIcons from 'vite-plugin-purge-icons';
|
import purgeIcons from 'vite-plugin-purge-icons';
|
||||||
import windiCSS from 'vite-plugin-windicss';
|
import windiCSS from 'vite-plugin-windicss';
|
||||||
import { configHtmlPlugin } from './html';
|
import { configHtmlPlugin } from './html';
|
||||||
@ -70,7 +68,7 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
|||||||
|
|
||||||
// rollup-plugin-gzip
|
// rollup-plugin-gzip
|
||||||
vitePlugins.push(
|
vitePlugins.push(
|
||||||
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE)
|
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE),
|
||||||
);
|
);
|
||||||
|
|
||||||
// vite-plugin-pwa
|
// vite-plugin-pwa
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
* Zero-config PWA for Vite
|
* Zero-config PWA for Vite
|
||||||
* https://github.com/antfu/vite-plugin-pwa
|
* https://github.com/antfu/vite-plugin-pwa
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { VitePWA } from 'vite-plugin-pwa';
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
|
|
||||||
export function configPwaConfig(env: ViteEnv) {
|
export function configPwaConfig(env: ViteEnv) {
|
||||||
|
@ -2,11 +2,12 @@
|
|||||||
* Introduces component library styles on demand.
|
* Introduces component library styles on demand.
|
||||||
* https://github.com/anncwb/vite-plugin-style-import
|
* https://github.com/anncwb/vite-plugin-style-import
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import styleImport from 'vite-plugin-style-import';
|
import styleImport from 'vite-plugin-style-import';
|
||||||
|
|
||||||
export function configStyleImportPlugin(isBuild: boolean) {
|
export function configStyleImportPlugin(isBuild: boolean) {
|
||||||
if (!isBuild) return [];
|
if (!isBuild) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
const styleImportPlugin = styleImport({
|
const styleImportPlugin = styleImport({
|
||||||
libs: [
|
libs: [
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,11 @@ export function configThemePlugin(isBuild: boolean): Plugin[] {
|
|||||||
return s;
|
return s;
|
||||||
case '.ant-select-item-option-selected:not(.ant-select-item-option-disabled)':
|
case '.ant-select-item-option-selected:not(.ant-select-item-option-disabled)':
|
||||||
return s;
|
return s;
|
||||||
|
default:
|
||||||
|
if (s.indexOf('.ant-btn') >= -1) {
|
||||||
|
// 按钮被重新定制过,需要过滤掉class防止覆盖
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return s.startsWith('[data-theme') ? s : `[data-theme] ${s}`;
|
return s.startsWith('[data-theme') ? s : `[data-theme] ${s}`;
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,7 @@ export function resultPageSuccess<T = any>(
|
|||||||
page: number,
|
page: number,
|
||||||
pageSize: number,
|
pageSize: number,
|
||||||
list: T[],
|
list: T[],
|
||||||
{ message = 'ok' } = {}
|
{ message = 'ok' } = {},
|
||||||
) {
|
) {
|
||||||
const pageData = pagination(page, pageSize, list);
|
const pageData = pagination(page, pageSize, list);
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ export default [
|
|||||||
response: ({ body }) => {
|
response: ({ body }) => {
|
||||||
const { username, password } = body;
|
const { username, password } = body;
|
||||||
const checkUser = createFakeUserList().find(
|
const checkUser = createFakeUserList().find(
|
||||||
(item) => item.username === username && password === item.password
|
(item) => item.username === username && password === item.password,
|
||||||
);
|
);
|
||||||
if (!checkUser) {
|
if (!checkUser) {
|
||||||
return resultError('Incorrect account or password!');
|
return resultError('Incorrect account or password!');
|
||||||
|
80
package.json
80
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vben-admin",
|
"name": "vben-admin",
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "vben",
|
"name": "vben",
|
||||||
"email": "anncwb@126.com",
|
"email": "anncwb@126.com",
|
||||||
@ -34,14 +34,14 @@
|
|||||||
"gen:icon": "esno ./build/generate/icon/index.ts"
|
"gen:icon": "esno ./build/generate/icon/index.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify/iconify": "^2.0.3",
|
"@iconify/iconify": "^2.0.4",
|
||||||
"@logicflow/core": "^0.6.6",
|
"@logicflow/core": "^0.6.15",
|
||||||
"@logicflow/extension": "^0.6.6",
|
"@logicflow/extension": "^0.6.15",
|
||||||
"@vueuse/core": "^5.2.0",
|
"@vueuse/core": "^6.0.0",
|
||||||
"@zxcvbn-ts/core": "^1.0.0-beta.0",
|
"@zxcvbn-ts/core": "^1.0.0-beta.0",
|
||||||
"ant-design-vue": "2.2.2",
|
"ant-design-vue": "2.2.6",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"codemirror": "^5.62.2",
|
"codemirror": "^5.62.3",
|
||||||
"cropperjs": "^1.5.12",
|
"cropperjs": "^1.5.12",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"echarts": "^5.1.2",
|
"echarts": "^5.1.2",
|
||||||
@ -50,46 +50,46 @@
|
|||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"path-to-regexp": "^6.2.0",
|
"path-to-regexp": "^6.2.0",
|
||||||
"pinia": "2.0.0-beta.5",
|
"pinia": "2.0.0-rc.6",
|
||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"qrcode": "^1.4.4",
|
"qrcode": "^1.4.4",
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
"sortablejs": "^1.14.0",
|
"sortablejs": "^1.14.0",
|
||||||
"tinymce": "^5.8.2",
|
"tinymce": "^5.8.2",
|
||||||
"vditor": "^3.8.6",
|
"vditor": "^3.8.6",
|
||||||
"vue": "3.1.5",
|
"vue": "3.2.4",
|
||||||
"vue-i18n": "9.1.7",
|
"vue-i18n": "9.1.7",
|
||||||
"vue-json-pretty": "^2.0.2",
|
"vue-router": "^4.0.11",
|
||||||
"vue-router": "^4.0.10",
|
"vue-types": "^4.0.3",
|
||||||
"vue-types": "^4.0.1",
|
"xlsx": "^0.17.1",
|
||||||
"xlsx": "^0.17.0"
|
"vue-json-pretty": "1.8.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^13.1.0",
|
"@commitlint/cli": "^13.1.0",
|
||||||
"@commitlint/config-conventional": "^13.1.0",
|
"@commitlint/config-conventional": "^13.1.0",
|
||||||
"@iconify/json": "^1.1.382",
|
"@iconify/json": "^1.1.392",
|
||||||
"@purge-icons/generated": "^0.7.0",
|
"@purge-icons/generated": "^0.7.0",
|
||||||
"@types/codemirror": "^5.60.2",
|
"@types/codemirror": "^5.60.2",
|
||||||
"@types/crypto-js": "^4.0.2",
|
"@types/crypto-js": "^4.0.2",
|
||||||
"@types/fs-extra": "^9.0.12",
|
"@types/fs-extra": "^9.0.12",
|
||||||
"@types/inquirer": "^7.3.3",
|
"@types/inquirer": "^7.3.3",
|
||||||
"@types/intro.js": "^3.0.2",
|
"@types/intro.js": "^3.0.2",
|
||||||
"@types/jest": "^26.0.24",
|
"@types/jest": "^27.0.1",
|
||||||
"@types/lodash-es": "^4.17.4",
|
"@types/lodash-es": "^4.17.4",
|
||||||
"@types/mockjs": "^1.0.4",
|
"@types/mockjs": "^1.0.4",
|
||||||
"@types/node": "^16.4.10",
|
"@types/node": "^16.7.1",
|
||||||
"@types/nprogress": "^0.2.0",
|
"@types/nprogress": "^0.2.0",
|
||||||
"@types/qrcode": "^1.4.1",
|
"@types/qrcode": "^1.4.1",
|
||||||
"@types/qs": "^6.9.7",
|
"@types/qs": "^6.9.7",
|
||||||
"@types/sortablejs": "^1.10.7",
|
"@types/sortablejs": "^1.10.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.29.0",
|
"@typescript-eslint/eslint-plugin": "^4.29.3",
|
||||||
"@typescript-eslint/parser": "^4.29.0",
|
"@typescript-eslint/parser": "^4.29.3",
|
||||||
"@vitejs/plugin-legacy": "^1.5.0",
|
"@vitejs/plugin-legacy": "^1.5.1",
|
||||||
"@vitejs/plugin-vue": "^1.3.0",
|
"@vitejs/plugin-vue": "^1.4.0",
|
||||||
"@vitejs/plugin-vue-jsx": "^1.1.7",
|
"@vitejs/plugin-vue-jsx": "^1.1.7",
|
||||||
"@vue/compiler-sfc": "3.1.5",
|
"@vue/compiler-sfc": "3.2.4",
|
||||||
"@vue/test-utils": "^2.0.0-rc.12",
|
"@vue/test-utils": "^2.0.0-rc.12",
|
||||||
"autoprefixer": "^10.3.1",
|
"autoprefixer": "^10.3.2",
|
||||||
"commitizen": "^4.2.4",
|
"commitizen": "^4.2.4",
|
||||||
"conventional-changelog-cli": "^2.1.1",
|
"conventional-changelog-cli": "^2.1.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
@ -98,17 +98,17 @@
|
|||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-define-config": "^1.0.9",
|
"eslint-define-config": "^1.0.9",
|
||||||
"eslint-plugin-jest": "^24.4.0",
|
"eslint-plugin-jest": "^24.4.0",
|
||||||
"eslint-plugin-prettier": "^3.4.0",
|
"eslint-plugin-prettier": "^3.4.1",
|
||||||
"eslint-plugin-vue": "^7.15.0",
|
"eslint-plugin-vue": "^7.16.0",
|
||||||
"esno": "^0.8.0",
|
"esno": "^0.9.1",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"http-server": "^0.12.3",
|
"http-server": "^13.0.1",
|
||||||
"husky": "^7.0.1",
|
"husky": "^7.0.1",
|
||||||
"inquirer": "^8.1.2",
|
"inquirer": "^8.1.2",
|
||||||
"is-ci": "^3.0.0",
|
"is-ci": "^3.0.0",
|
||||||
"jest": "^27.0.6",
|
"jest": "^27.0.6",
|
||||||
"less": "^4.1.1",
|
"less": "^4.1.1",
|
||||||
"lint-staged": "^11.1.1",
|
"lint-staged": "^11.1.2",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"postcss": "^8.3.6",
|
"postcss": "^8.3.6",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.3.2",
|
||||||
@ -119,27 +119,27 @@
|
|||||||
"stylelint-config-prettier": "^8.0.2",
|
"stylelint-config-prettier": "^8.0.2",
|
||||||
"stylelint-config-standard": "^22.0.0",
|
"stylelint-config-standard": "^22.0.0",
|
||||||
"stylelint-order": "^4.1.0",
|
"stylelint-order": "^4.1.0",
|
||||||
"ts-jest": "^27.0.4",
|
"ts-jest": "^27.0.5",
|
||||||
"ts-node": "^10.1.0",
|
"ts-node": "^10.2.1",
|
||||||
"typescript": "4.3.5",
|
"typescript": "4.3.5",
|
||||||
"vite": "2.4.4",
|
"vite": "2.5.0",
|
||||||
"vite-plugin-compression": "^0.3.3",
|
"vite-plugin-compression": "^0.3.5",
|
||||||
"vite-plugin-html": "^2.0.7",
|
"vite-plugin-html": "^2.1.0",
|
||||||
"vite-plugin-imagemin": "^0.4.3",
|
"vite-plugin-imagemin": "^0.4.5",
|
||||||
"vite-plugin-mock": "^2.9.4",
|
"vite-plugin-mock": "^2.9.6",
|
||||||
"vite-plugin-purge-icons": "^0.7.0",
|
"vite-plugin-purge-icons": "^0.7.0",
|
||||||
"vite-plugin-pwa": "^0.9.3",
|
"vite-plugin-pwa": "^0.11.0",
|
||||||
"vite-plugin-style-import": "^1.1.0",
|
"vite-plugin-style-import": "^1.2.1",
|
||||||
"vite-plugin-svg-icons": "^1.0.3",
|
"vite-plugin-svg-icons": "^1.0.4",
|
||||||
"vite-plugin-theme": "^0.8.1",
|
"vite-plugin-theme": "^0.8.1",
|
||||||
"vite-plugin-windicss": "^1.2.7",
|
"vite-plugin-windicss": "^1.2.8",
|
||||||
"vue-eslint-parser": "^7.10.0",
|
"vue-eslint-parser": "^7.10.0",
|
||||||
"vue-tsc": "^0.2.2"
|
"vue-tsc": "^0.3.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"//": "Used to install imagemin dependencies, because imagemin may not be installed in China. If it is abroad, you can delete it",
|
"//": "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",
|
"bin-wrapper": "npm:bin-wrapper-china",
|
||||||
"rollup": "^2.55.1"
|
"rollup": "^2.56.3"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -7,7 +7,7 @@ module.exports = {
|
|||||||
singleQuote: true,
|
singleQuote: true,
|
||||||
quoteProps: 'as-needed',
|
quoteProps: 'as-needed',
|
||||||
bracketSpacing: true,
|
bracketSpacing: true,
|
||||||
trailingComma: 'es5',
|
trailingComma: 'all',
|
||||||
jsxBracketSameLine: false,
|
jsxBracketSameLine: false,
|
||||||
jsxSingleQuote: false,
|
jsxSingleQuote: false,
|
||||||
arrowParens: 'always',
|
arrowParens: 'always',
|
||||||
@ -16,5 +16,4 @@ module.exports = {
|
|||||||
proseWrap: 'never',
|
proseWrap: 'never',
|
||||||
htmlWhitespaceSensitivity: 'strict',
|
htmlWhitespaceSensitivity: 'strict',
|
||||||
endOfLine: 'auto',
|
endOfLine: 'auto',
|
||||||
rangeStart: 0,
|
|
||||||
};
|
};
|
||||||
|
18
src/App.vue
18
src/App.vue
@ -6,23 +6,15 @@
|
|||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
import { ConfigProvider } from 'ant-design-vue';
|
import { ConfigProvider } from 'ant-design-vue';
|
||||||
import { AppProvider } from '/@/components/Application';
|
import { AppProvider } from '/@/components/Application';
|
||||||
import { useTitle } from '/@/hooks/web/useTitle';
|
import { useTitle } from '/@/hooks/web/useTitle';
|
||||||
import { useLocale } from '/@/locales/useLocale';
|
import { useLocale } from '/@/locales/useLocale';
|
||||||
|
|
||||||
export default defineComponent({
|
// support Multi-language
|
||||||
name: 'App',
|
const { getAntdLocale } = useLocale();
|
||||||
components: { ConfigProvider, AppProvider },
|
|
||||||
setup() {
|
|
||||||
useTitle();
|
|
||||||
|
|
||||||
// support Multi-language
|
// Listening to page changes and dynamically changing site titles
|
||||||
const { getAntdLocale } = useLocale();
|
useTitle();
|
||||||
|
|
||||||
return { getAntdLocale };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -10,13 +10,13 @@ const { uploadUrl = '' } = useGlobSetting();
|
|||||||
*/
|
*/
|
||||||
export function uploadApi(
|
export function uploadApi(
|
||||||
params: UploadFileParams,
|
params: UploadFileParams,
|
||||||
onUploadProgress: (progressEvent: ProgressEvent) => void
|
onUploadProgress: (progressEvent: ProgressEvent) => void,
|
||||||
) {
|
) {
|
||||||
return defHttp.uploadFile<UploadApiResult>(
|
return defHttp.uploadFile<UploadApiResult>(
|
||||||
{
|
{
|
||||||
url: uploadUrl,
|
url: uploadUrl,
|
||||||
onUploadProgress,
|
onUploadProgress,
|
||||||
},
|
},
|
||||||
params
|
params,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal')
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
errorMessageMode: mode,
|
errorMessageMode: mode,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="getShowDarkModeToggle" :class="getClass" @click="toggleDarkMode">
|
<div v-if="getShowDarkModeToggle" :class="getClass" @click="toggleDarkMode">
|
||||||
<div :class="`${prefixCls}-inner`"> </div>
|
<div :class="`${prefixCls}-inner`"></div>
|
||||||
<SvgIcon size="14" name="sun" />
|
<SvgIcon size="14" name="sun" />
|
||||||
<SvgIcon size="14" name="moon" />
|
<SvgIcon size="14" name="moon" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent, computed, unref } from 'vue';
|
import { computed, unref } from 'vue';
|
||||||
import { SvgIcon } from '/@/components/Icon';
|
import { SvgIcon } from '/@/components/Icon';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||||
@ -14,39 +14,25 @@
|
|||||||
import { updateDarkTheme } from '/@/logics/theme/dark';
|
import { updateDarkTheme } from '/@/logics/theme/dark';
|
||||||
import { ThemeEnum } from '/@/enums/appEnum';
|
import { ThemeEnum } from '/@/enums/appEnum';
|
||||||
|
|
||||||
export default defineComponent({
|
const { prefixCls } = useDesign('dark-switch');
|
||||||
name: 'DarkModeToggle',
|
const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();
|
||||||
components: { SvgIcon },
|
|
||||||
setup() {
|
|
||||||
const { prefixCls } = useDesign('dark-switch');
|
|
||||||
const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();
|
|
||||||
|
|
||||||
const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK);
|
const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK);
|
||||||
|
|
||||||
const getClass = computed(() => [
|
const getClass = computed(() => [
|
||||||
prefixCls,
|
prefixCls,
|
||||||
{
|
{
|
||||||
[`${prefixCls}--dark`]: unref(isDark),
|
[`${prefixCls}--dark`]: unref(isDark),
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
function toggleDarkMode() {
|
|
||||||
const darkMode = getDarkMode.value === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
|
|
||||||
setDarkMode(darkMode);
|
|
||||||
updateDarkTheme(darkMode);
|
|
||||||
updateHeaderBgColor();
|
|
||||||
updateSidebarBgColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
getClass,
|
|
||||||
isDark,
|
|
||||||
prefixCls,
|
|
||||||
toggleDarkMode,
|
|
||||||
getShowDarkModeToggle,
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
});
|
]);
|
||||||
|
|
||||||
|
function toggleDarkMode() {
|
||||||
|
const darkMode = getDarkMode.value === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
|
||||||
|
setDarkMode(darkMode);
|
||||||
|
updateDarkTheme(darkMode);
|
||||||
|
updateHeaderBgColor();
|
||||||
|
updateSidebarBgColor();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@prefix-cls: ~'@{namespace}-dark-switch';
|
@prefix-cls: ~'@{namespace}-dark-switch';
|
||||||
|
@ -17,16 +17,16 @@
|
|||||||
</span>
|
</span>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import type { LocaleType } from '/#/config';
|
import type { LocaleType } from '/#/config';
|
||||||
import type { DropMenu } from '/@/components/Dropdown';
|
import type { DropMenu } from '/@/components/Dropdown';
|
||||||
import { defineComponent, ref, watchEffect, unref, computed } from 'vue';
|
import { ref, watchEffect, unref, computed } from 'vue';
|
||||||
import { Dropdown } from '/@/components/Dropdown';
|
import { Dropdown } from '/@/components/Dropdown';
|
||||||
import { Icon } from '/@/components/Icon';
|
import { Icon } from '/@/components/Icon';
|
||||||
import { useLocale } from '/@/locales/useLocale';
|
import { useLocale } from '/@/locales/useLocale';
|
||||||
import { localeList } from '/@/settings/localeSetting';
|
import { localeList } from '/@/settings/localeSetting';
|
||||||
|
|
||||||
const props = {
|
const props = defineProps({
|
||||||
/**
|
/**
|
||||||
* Whether to display text
|
* Whether to display text
|
||||||
*/
|
*/
|
||||||
@ -35,45 +35,36 @@
|
|||||||
* Whether to refresh the interface when changing
|
* Whether to refresh the interface when changing
|
||||||
*/
|
*/
|
||||||
reload: { type: Boolean },
|
reload: { type: Boolean },
|
||||||
};
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'AppLocalPicker',
|
|
||||||
components: { Dropdown, Icon },
|
|
||||||
props,
|
|
||||||
setup(props) {
|
|
||||||
const selectedKeys = ref<string[]>([]);
|
|
||||||
|
|
||||||
const { changeLocale, getLocale } = useLocale();
|
|
||||||
|
|
||||||
const getLocaleText = computed(() => {
|
|
||||||
const key = selectedKeys.value[0];
|
|
||||||
if (!key) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return localeList.find((item) => item.event === key)?.text;
|
|
||||||
});
|
|
||||||
|
|
||||||
watchEffect(() => {
|
|
||||||
selectedKeys.value = [unref(getLocale)];
|
|
||||||
});
|
|
||||||
|
|
||||||
async function toggleLocale(lang: LocaleType | string) {
|
|
||||||
await changeLocale(lang as LocaleType);
|
|
||||||
selectedKeys.value = [lang as string];
|
|
||||||
props.reload && location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMenuEvent(menu: DropMenu) {
|
|
||||||
if (unref(getLocale) === menu.event) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
toggleLocale(menu.event as string);
|
|
||||||
}
|
|
||||||
|
|
||||||
return { localeList, handleMenuEvent, selectedKeys, getLocaleText };
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const selectedKeys = ref<string[]>([]);
|
||||||
|
|
||||||
|
const { changeLocale, getLocale } = useLocale();
|
||||||
|
|
||||||
|
const getLocaleText = computed(() => {
|
||||||
|
const key = selectedKeys.value[0];
|
||||||
|
if (!key) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return localeList.find((item) => item.event === key)?.text;
|
||||||
|
});
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
selectedKeys.value = [unref(getLocale)];
|
||||||
|
});
|
||||||
|
|
||||||
|
async function toggleLocale(lang: LocaleType | string) {
|
||||||
|
await changeLocale(lang as LocaleType);
|
||||||
|
selectedKeys.value = [lang as string];
|
||||||
|
props.reload && location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMenuEvent(menu: DropMenu) {
|
||||||
|
if (unref(getLocale) === menu.event) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toggleLocale(menu.event as string);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent, computed, unref } from 'vue';
|
import { computed, unref } from 'vue';
|
||||||
import { useGlobSetting } from '/@/hooks/setting';
|
import { useGlobSetting } from '/@/hooks/setting';
|
||||||
import { useGo } from '/@/hooks/web/usePage';
|
import { useGo } from '/@/hooks/web/usePage';
|
||||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||||
@ -19,11 +19,11 @@
|
|||||||
import { PageEnum } from '/@/enums/pageEnum';
|
import { PageEnum } from '/@/enums/pageEnum';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
|
|
||||||
const props = {
|
const props = defineProps({
|
||||||
/**
|
/**
|
||||||
* The theme of the current parent component
|
* The theme of the current parent component
|
||||||
*/
|
*/
|
||||||
theme: { type: String, validator: (v) => ['light', 'dark'].includes(v) },
|
theme: { type: String, validator: (v: string) => ['light', 'dark'].includes(v) },
|
||||||
/**
|
/**
|
||||||
* Whether to show title
|
* Whether to show title
|
||||||
*/
|
*/
|
||||||
@ -32,45 +32,30 @@
|
|||||||
* The title is also displayed when the menu is collapsed
|
* The title is also displayed when the menu is collapsed
|
||||||
*/
|
*/
|
||||||
alwaysShowTitle: { type: Boolean },
|
alwaysShowTitle: { type: Boolean },
|
||||||
};
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'AppLogo',
|
|
||||||
props: props,
|
|
||||||
setup(props) {
|
|
||||||
const { prefixCls } = useDesign('app-logo');
|
|
||||||
const { getCollapsedShowTitle } = useMenuSetting();
|
|
||||||
const userStore = useUserStore();
|
|
||||||
const { title } = useGlobSetting();
|
|
||||||
const go = useGo();
|
|
||||||
|
|
||||||
const getAppLogoClass = computed(() => [
|
|
||||||
prefixCls,
|
|
||||||
props.theme,
|
|
||||||
{ 'collapsed-show-title': unref(getCollapsedShowTitle) },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const getTitleClass = computed(() => [
|
|
||||||
`${prefixCls}__title`,
|
|
||||||
{
|
|
||||||
'xs:opacity-0': !props.alwaysShowTitle,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
function goHome() {
|
|
||||||
go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
getAppLogoClass,
|
|
||||||
getTitleClass,
|
|
||||||
getCollapsedShowTitle,
|
|
||||||
goHome,
|
|
||||||
title,
|
|
||||||
prefixCls,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { prefixCls } = useDesign('app-logo');
|
||||||
|
const { getCollapsedShowTitle } = useMenuSetting();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const { title } = useGlobSetting();
|
||||||
|
const go = useGo();
|
||||||
|
|
||||||
|
const getAppLogoClass = computed(() => [
|
||||||
|
prefixCls,
|
||||||
|
props.theme,
|
||||||
|
{ 'collapsed-show-title': unref(getCollapsedShowTitle) },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const getTitleClass = computed(() => [
|
||||||
|
`${prefixCls}__title`,
|
||||||
|
{
|
||||||
|
'xs:opacity-0': !props.alwaysShowTitle,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
function goHome() {
|
||||||
|
go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@prefix-cls: ~'@{namespace}-app-logo';
|
@prefix-cls: ~'@{namespace}-app-logo';
|
||||||
|
@ -10,20 +10,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
import AppSearchKeyItem from './AppSearchKeyItem.vue';
|
import AppSearchKeyItem from './AppSearchKeyItem.vue';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
export default defineComponent({
|
const { prefixCls } = useDesign('app-search-footer');
|
||||||
name: 'AppSearchFooter',
|
const { t } = useI18n();
|
||||||
components: { AppSearchKeyItem },
|
|
||||||
setup() {
|
|
||||||
const { prefixCls } = useDesign('app-search-footer');
|
|
||||||
const { t } = useI18n();
|
|
||||||
return { prefixCls, t };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@prefix-cls: ~'@{namespace}-app-search-footer';
|
@prefix-cls: ~'@{namespace}-app-search-footer';
|
||||||
|
@ -3,11 +3,9 @@
|
|||||||
<Icon :icon="icon" />
|
<Icon :icon="icon" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
import { Icon } from '/@/components/Icon';
|
import { Icon } from '/@/components/Icon';
|
||||||
export default defineComponent({
|
defineProps({
|
||||||
components: { Icon },
|
icon: String,
|
||||||
props: { icon: String },
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -56,85 +56,62 @@
|
|||||||
</transition>
|
</transition>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent, computed, unref, ref, watch, nextTick } from 'vue';
|
<script lang="ts" setup>
|
||||||
|
import { computed, unref, ref, watch, nextTick } from 'vue';
|
||||||
import { SearchOutlined } from '@ant-design/icons-vue';
|
import { SearchOutlined } from '@ant-design/icons-vue';
|
||||||
import AppSearchFooter from './AppSearchFooter.vue';
|
import AppSearchFooter from './AppSearchFooter.vue';
|
||||||
import Icon from '/@/components/Icon';
|
import Icon from '/@/components/Icon';
|
||||||
import clickOutside from '/@/directives/clickOutside';
|
// @ts-ignore
|
||||||
|
import vClickOutside from '/@/directives/clickOutside';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { useRefs } from '/@/hooks/core/useRefs';
|
import { useRefs } from '/@/hooks/core/useRefs';
|
||||||
import { useMenuSearch } from './useMenuSearch';
|
import { useMenuSearch } from './useMenuSearch';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { useAppInject } from '/@/hooks/web/useAppInject';
|
import { useAppInject } from '/@/hooks/web/useAppInject';
|
||||||
|
|
||||||
const props = {
|
const props = defineProps({
|
||||||
visible: { type: Boolean },
|
visible: { type: Boolean },
|
||||||
};
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'AppSearchModal',
|
|
||||||
components: { Icon, SearchOutlined, AppSearchFooter },
|
|
||||||
directives: {
|
|
||||||
clickOutside,
|
|
||||||
},
|
|
||||||
props,
|
|
||||||
emits: ['close'],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const scrollWrap = ref<ElRef>(null);
|
|
||||||
const inputRef = ref<Nullable<HTMLElement>>(null);
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const { prefixCls } = useDesign('app-search-modal');
|
|
||||||
const [refs, setRefs] = useRefs();
|
|
||||||
const { getIsMobile } = useAppInject();
|
|
||||||
|
|
||||||
const { handleSearch, searchResult, keyword, activeIndex, handleEnter, handleMouseenter } =
|
|
||||||
useMenuSearch(refs, scrollWrap, emit);
|
|
||||||
|
|
||||||
const getIsNotData = computed(() => !keyword || unref(searchResult).length === 0);
|
|
||||||
|
|
||||||
const getClass = computed(() => {
|
|
||||||
return [
|
|
||||||
prefixCls,
|
|
||||||
{
|
|
||||||
[`${prefixCls}--mobile`]: unref(getIsMobile),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.visible,
|
|
||||||
(visible: boolean) => {
|
|
||||||
visible &&
|
|
||||||
nextTick(() => {
|
|
||||||
unref(inputRef)?.focus();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function handleClose() {
|
|
||||||
searchResult.value = [];
|
|
||||||
emit('close');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
t,
|
|
||||||
prefixCls,
|
|
||||||
getClass,
|
|
||||||
handleSearch,
|
|
||||||
searchResult,
|
|
||||||
activeIndex,
|
|
||||||
getIsNotData,
|
|
||||||
handleEnter,
|
|
||||||
setRefs,
|
|
||||||
scrollWrap,
|
|
||||||
handleMouseenter,
|
|
||||||
handleClose,
|
|
||||||
inputRef,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['close']);
|
||||||
|
|
||||||
|
const scrollWrap = ref(null);
|
||||||
|
const inputRef = ref<Nullable<HTMLElement>>(null);
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const { prefixCls } = useDesign('app-search-modal');
|
||||||
|
const [refs, setRefs] = useRefs();
|
||||||
|
const { getIsMobile } = useAppInject();
|
||||||
|
|
||||||
|
const { handleSearch, searchResult, keyword, activeIndex, handleEnter, handleMouseenter } =
|
||||||
|
useMenuSearch(refs, scrollWrap, emit);
|
||||||
|
|
||||||
|
const getIsNotData = computed(() => !keyword || unref(searchResult).length === 0);
|
||||||
|
|
||||||
|
const getClass = computed(() => {
|
||||||
|
return [
|
||||||
|
prefixCls,
|
||||||
|
{
|
||||||
|
[`${prefixCls}--mobile`]: unref(getIsMobile),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.visible,
|
||||||
|
(visible: boolean) => {
|
||||||
|
visible &&
|
||||||
|
nextTick(() => {
|
||||||
|
unref(inputRef)?.focus();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
function handleClose() {
|
||||||
|
searchResult.value = [];
|
||||||
|
emit('close');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@prefix-cls: ~'@{namespace}-app-search-modal';
|
@prefix-cls: ~'@{namespace}-app-search-modal';
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
<Icon icon="ion:chevron-forward" :style="$attrs.iconStyle" />
|
<Icon icon="ion:chevron-forward" :style="$attrs.iconStyle" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent, computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { Icon } from '/@/components/Icon';
|
import { Icon } from '/@/components/Icon';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
|
|
||||||
const props = {
|
const props = defineProps({
|
||||||
/**
|
/**
|
||||||
* Arrow expand state
|
* Arrow expand state
|
||||||
*/
|
*/
|
||||||
@ -29,31 +29,22 @@
|
|||||||
* Cancel padding/margin for inline
|
* Cancel padding/margin for inline
|
||||||
*/
|
*/
|
||||||
inset: { type: Boolean },
|
inset: { type: Boolean },
|
||||||
};
|
});
|
||||||
|
|
||||||
export default defineComponent({
|
const { prefixCls } = useDesign('basic-arrow');
|
||||||
name: 'BasicArrow',
|
|
||||||
components: { Icon },
|
|
||||||
props,
|
|
||||||
setup(props) {
|
|
||||||
const { prefixCls } = useDesign('basic-arrow');
|
|
||||||
|
|
||||||
// get component class
|
// get component class
|
||||||
const getClass = computed(() => {
|
const getClass = computed(() => {
|
||||||
const { expand, up, down, inset } = props;
|
const { expand, up, down, inset } = props;
|
||||||
return [
|
return [
|
||||||
prefixCls,
|
prefixCls,
|
||||||
{
|
{
|
||||||
[`${prefixCls}--active`]: expand,
|
[`${prefixCls}--active`]: expand,
|
||||||
up,
|
up,
|
||||||
inset,
|
inset,
|
||||||
down,
|
down,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
|
||||||
|
|
||||||
return { getClass };
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
const { prefixCls } = useDesign('basic-help');
|
const { prefixCls } = useDesign('basic-help');
|
||||||
|
|
||||||
const getTooltipStyle = computed(
|
const getTooltipStyle = computed(
|
||||||
(): CSSProperties => ({ color: props.color, fontSize: props.fontSize })
|
(): CSSProperties => ({ color: props.color, fontSize: props.fontSize }),
|
||||||
);
|
);
|
||||||
|
|
||||||
const getOverlayStyle = computed((): CSSProperties => ({ maxWidth: props.maxWidth }));
|
const getOverlayStyle = computed((): CSSProperties => ({ maxWidth: props.maxWidth }));
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
<BasicHelp :class="`${prefixCls}-help`" v-if="helpMessage" :text="helpMessage" />
|
<BasicHelp :class="`${prefixCls}-help`" v-if="helpMessage" :text="helpMessage" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import { defineComponent, computed } from 'vue';
|
import { useSlots, computed } from 'vue';
|
||||||
import BasicHelp from './BasicHelp.vue';
|
import BasicHelp from './BasicHelp.vue';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
|
|
||||||
const props = {
|
const props = defineProps({
|
||||||
/**
|
/**
|
||||||
* Help text list or string
|
* Help text list or string
|
||||||
* @default: ''
|
* @default: ''
|
||||||
@ -29,24 +29,15 @@
|
|||||||
* @default: false
|
* @default: false
|
||||||
*/
|
*/
|
||||||
normal: { type: Boolean },
|
normal: { type: Boolean },
|
||||||
};
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'BasicTitle',
|
|
||||||
components: { BasicHelp },
|
|
||||||
props,
|
|
||||||
setup(props, { slots }) {
|
|
||||||
const { prefixCls } = useDesign('basic-title');
|
|
||||||
|
|
||||||
const getClass = computed(() => [
|
|
||||||
prefixCls,
|
|
||||||
{ [`${prefixCls}-show-span`]: props.span && slots.default },
|
|
||||||
{ [`${prefixCls}-normal`]: props.normal },
|
|
||||||
]);
|
|
||||||
|
|
||||||
return { prefixCls, getClass };
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { prefixCls } = useDesign('basic-title');
|
||||||
|
const slots = useSlots();
|
||||||
|
const getClass = computed(() => [
|
||||||
|
prefixCls,
|
||||||
|
{ [`${prefixCls}-show-span`]: props.span && slots.default },
|
||||||
|
{ [`${prefixCls}-normal`]: props.normal },
|
||||||
|
]);
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@prefix-cls: ~'@{namespace}-basic-title';
|
@prefix-cls: ~'@{namespace}-basic-title';
|
||||||
|
@ -2,40 +2,39 @@
|
|||||||
<Button v-bind="getBindValue" :class="getButtonClass" @click="onClick">
|
<Button v-bind="getBindValue" :class="getButtonClass" @click="onClick">
|
||||||
<template #default="data">
|
<template #default="data">
|
||||||
<Icon :icon="preIcon" v-if="preIcon" :size="iconSize" />
|
<Icon :icon="preIcon" v-if="preIcon" :size="iconSize" />
|
||||||
<slot v-bind="data"></slot>
|
<slot v-bind="data || {}"></slot>
|
||||||
<Icon :icon="postIcon" v-if="postIcon" :size="iconSize" />
|
<Icon :icon="postIcon" v-if="postIcon" :size="iconSize" />
|
||||||
</template>
|
</template>
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, computed, unref } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'AButton',
|
||||||
|
inheritAttrs: false,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, unref } from 'vue';
|
||||||
import { Button } from 'ant-design-vue';
|
import { Button } from 'ant-design-vue';
|
||||||
import Icon from '/@/components/Icon/src/Icon.vue';
|
import Icon from '/@/components/Icon/src/Icon.vue';
|
||||||
import { buttonProps } from './props';
|
import { buttonProps } from './props';
|
||||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps(buttonProps);
|
||||||
name: 'AButton',
|
// get component class
|
||||||
components: { Button, Icon },
|
const attrs = useAttrs({ excludeDefaultKeys: false });
|
||||||
inheritAttrs: false,
|
const getButtonClass = computed(() => {
|
||||||
props: buttonProps,
|
const { color, disabled } = props;
|
||||||
setup(props) {
|
return [
|
||||||
// get component class
|
{
|
||||||
const attrs = useAttrs({ excludeDefaultKeys: false });
|
[`ant-btn-${color}`]: !!color,
|
||||||
const getButtonClass = computed(() => {
|
[`is-disabled`]: disabled,
|
||||||
const { color, disabled } = props;
|
},
|
||||||
return [
|
];
|
||||||
{
|
|
||||||
[`ant-btn-${color}`]: !!color,
|
|
||||||
[`is-disabled`]: disabled,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
// get inherit binding value
|
|
||||||
const getBindValue = computed(() => ({ ...unref(attrs), ...props }));
|
|
||||||
|
|
||||||
return { getBindValue, getButtonClass };
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// get inherit binding value
|
||||||
|
const getBindValue = computed(() => ({ ...unref(attrs), ...props }));
|
||||||
</script>
|
</script>
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'PopButton',
|
name: 'PopButton',
|
||||||
components: { Popconfirm, BasicButton },
|
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props,
|
props,
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
@ -34,13 +33,13 @@
|
|||||||
okText: t('common.okText'),
|
okText: t('common.okText'),
|
||||||
cancelText: t('common.cancelText'),
|
cancelText: t('common.cancelText'),
|
||||||
},
|
},
|
||||||
{ ...props, ...unref(attrs) }
|
{ ...props, ...unref(attrs) },
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const bindValues = omit(unref(getBindValues), 'icon');
|
const bindValues = omit(unref(getBindValues), 'icon');
|
||||||
const btnBind = omit(bindValues, 'title');
|
const btnBind = omit(bindValues, 'title') as Recordable;
|
||||||
if (btnBind.disabled) btnBind.color = '';
|
if (btnBind.disabled) btnBind.color = '';
|
||||||
const Button = h(BasicButton, btnBind, extendSlots(slots));
|
const Button = h(BasicButton, btnBind, extendSlots(slots));
|
||||||
|
|
||||||
|
@ -3,24 +3,17 @@
|
|||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent, ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { onClickOutside } from '@vueuse/core';
|
import { onClickOutside } from '@vueuse/core';
|
||||||
export default defineComponent({
|
const emit = defineEmits(['mounted', 'clickOutside']);
|
||||||
name: 'ClickOutSide',
|
const wrap = ref<ElRef>(null);
|
||||||
emits: ['mounted', 'clickOutside'],
|
|
||||||
setup(_, { emit }) {
|
|
||||||
const wrap = ref<ElRef>(null);
|
|
||||||
|
|
||||||
onClickOutside(wrap, () => {
|
onClickOutside(wrap, () => {
|
||||||
emit('clickOutside');
|
emit('clickOutside');
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
emit('mounted');
|
emit('mounted');
|
||||||
});
|
|
||||||
|
|
||||||
return { wrap };
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -8,45 +8,47 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent, computed } from 'vue';
|
|
||||||
import CodeMirrorEditor from './codemirror/CodeMirror.vue';
|
|
||||||
import { isString } from '/@/utils/is';
|
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
const MODE = {
|
const MODE = {
|
||||||
JSON: 'application/json',
|
JSON: 'application/json',
|
||||||
html: 'htmlmixed',
|
html: 'htmlmixed',
|
||||||
js: 'javascript',
|
js: 'javascript',
|
||||||
};
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import CodeMirrorEditor from './codemirror/CodeMirror.vue';
|
||||||
|
import { isString } from '/@/utils/is';
|
||||||
|
|
||||||
const props = {
|
const props = defineProps({
|
||||||
value: { type: [Object, String] as PropType<Record<string, any> | string> },
|
value: { type: [Object, String] as PropType<Record<string, any> | string> },
|
||||||
mode: { type: String, default: MODE.JSON },
|
mode: { type: String, default: MODE.JSON },
|
||||||
readonly: { type: Boolean },
|
readonly: { type: Boolean },
|
||||||
};
|
autoFormat: { type: Boolean, default: true },
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'CodeEditor',
|
|
||||||
components: { CodeMirrorEditor },
|
|
||||||
props,
|
|
||||||
emits: ['change', 'update:value'],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const getValue = computed(() => {
|
|
||||||
const { value, mode } = props;
|
|
||||||
if (mode !== MODE.JSON) {
|
|
||||||
return value as string;
|
|
||||||
}
|
|
||||||
return isString(value)
|
|
||||||
? JSON.stringify(JSON.parse(value), null, 2)
|
|
||||||
: JSON.stringify(value, null, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleValueChange(v) {
|
|
||||||
emit('update:value', v);
|
|
||||||
emit('change', v);
|
|
||||||
}
|
|
||||||
|
|
||||||
return { handleValueChange, getValue };
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['change', 'update:value', 'format-error']);
|
||||||
|
|
||||||
|
const getValue = computed(() => {
|
||||||
|
const { value, mode, autoFormat } = props;
|
||||||
|
if (!autoFormat || mode !== MODE.JSON) {
|
||||||
|
return value as string;
|
||||||
|
}
|
||||||
|
let result = value;
|
||||||
|
if (isString(value)) {
|
||||||
|
try {
|
||||||
|
result = JSON.parse(value);
|
||||||
|
} catch (e) {
|
||||||
|
emit('format-error', value);
|
||||||
|
return value as string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return JSON.stringify(result, null, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleValueChange(v) {
|
||||||
|
emit('update:value', v);
|
||||||
|
emit('change', v);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,18 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative !h-full w-full overflow-hidden" ref="el"> </div>
|
<div class="relative !h-full w-full overflow-hidden" ref="el"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import {
|
import { ref, onMounted, onUnmounted, watchEffect, watch, unref, nextTick } from 'vue';
|
||||||
ref,
|
|
||||||
onMounted,
|
|
||||||
onUnmounted,
|
|
||||||
watchEffect,
|
|
||||||
watch,
|
|
||||||
defineComponent,
|
|
||||||
unref,
|
|
||||||
nextTick,
|
|
||||||
} from 'vue';
|
|
||||||
import { useDebounceFn } from '@vueuse/core';
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
import { useAppStore } from '/@/store/modules/app';
|
import { useAppStore } from '/@/store/modules/app';
|
||||||
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
||||||
@ -26,95 +17,89 @@
|
|||||||
import 'codemirror/mode/css/css';
|
import 'codemirror/mode/css/css';
|
||||||
import 'codemirror/mode/htmlmixed/htmlmixed';
|
import 'codemirror/mode/htmlmixed/htmlmixed';
|
||||||
|
|
||||||
const props = {
|
const props = defineProps({
|
||||||
mode: { type: String, default: 'application/json' },
|
mode: { type: String, default: 'application/json' },
|
||||||
value: { type: String, default: '' },
|
value: { type: String, default: '' },
|
||||||
readonly: { type: Boolean, default: false },
|
readonly: { type: Boolean, default: false },
|
||||||
};
|
});
|
||||||
|
|
||||||
export default defineComponent({
|
const emit = defineEmits(['change']);
|
||||||
props,
|
|
||||||
emits: ['change'],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const el = ref();
|
|
||||||
let editor: Nullable<CodeMirror.Editor>;
|
|
||||||
|
|
||||||
const debounceRefresh = useDebounceFn(refresh, 100);
|
const el = ref();
|
||||||
const appStore = useAppStore();
|
let editor: Nullable<CodeMirror.Editor>;
|
||||||
|
|
||||||
watch(
|
const debounceRefresh = useDebounceFn(refresh, 100);
|
||||||
() => props.value,
|
const appStore = useAppStore();
|
||||||
async (value) => {
|
|
||||||
await nextTick();
|
|
||||||
const oldValue = editor?.getValue();
|
|
||||||
if (value !== oldValue) {
|
|
||||||
editor?.setValue(value ? value : '');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ flush: 'post' }
|
|
||||||
);
|
|
||||||
|
|
||||||
watchEffect(() => {
|
watch(
|
||||||
editor?.setOption('mode', props.mode);
|
() => props.value,
|
||||||
});
|
async (value) => {
|
||||||
|
await nextTick();
|
||||||
watch(
|
const oldValue = editor?.getValue();
|
||||||
() => appStore.getDarkMode,
|
if (value !== oldValue) {
|
||||||
async () => {
|
editor?.setValue(value ? value : '');
|
||||||
setTheme();
|
|
||||||
},
|
|
||||||
{
|
|
||||||
immediate: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function setTheme() {
|
|
||||||
unref(editor)?.setOption(
|
|
||||||
'theme',
|
|
||||||
appStore.getDarkMode === 'light' ? 'idea' : 'material-palenight'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function refresh() {
|
|
||||||
editor?.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
const addonOptions = {
|
|
||||||
autoCloseBrackets: true,
|
|
||||||
autoCloseTags: true,
|
|
||||||
foldGutter: true,
|
|
||||||
gutters: ['CodeMirror-linenumbers'],
|
|
||||||
};
|
|
||||||
|
|
||||||
editor = CodeMirror(el.value!, {
|
|
||||||
value: '',
|
|
||||||
mode: props.mode,
|
|
||||||
readOnly: props.readonly,
|
|
||||||
tabSize: 2,
|
|
||||||
theme: 'material-palenight',
|
|
||||||
lineWrapping: true,
|
|
||||||
lineNumbers: true,
|
|
||||||
...addonOptions,
|
|
||||||
});
|
|
||||||
editor?.setValue(props.value);
|
|
||||||
setTheme();
|
|
||||||
editor?.on('change', () => {
|
|
||||||
emit('change', editor?.getValue());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
await nextTick();
|
|
||||||
init();
|
|
||||||
useWindowSizeFn(debounceRefresh);
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
editor = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
return { el };
|
|
||||||
},
|
},
|
||||||
|
{ flush: 'post' },
|
||||||
|
);
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
editor?.setOption('mode', props.mode);
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => appStore.getDarkMode,
|
||||||
|
async () => {
|
||||||
|
setTheme();
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
function setTheme() {
|
||||||
|
unref(editor)?.setOption(
|
||||||
|
'theme',
|
||||||
|
appStore.getDarkMode === 'light' ? 'idea' : 'material-palenight',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
editor?.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
const addonOptions = {
|
||||||
|
autoCloseBrackets: true,
|
||||||
|
autoCloseTags: true,
|
||||||
|
foldGutter: true,
|
||||||
|
gutters: ['CodeMirror-linenumbers'],
|
||||||
|
};
|
||||||
|
|
||||||
|
editor = CodeMirror(el.value!, {
|
||||||
|
value: '',
|
||||||
|
mode: props.mode,
|
||||||
|
readOnly: props.readonly,
|
||||||
|
tabSize: 2,
|
||||||
|
theme: 'material-palenight',
|
||||||
|
lineWrapping: true,
|
||||||
|
lineNumbers: true,
|
||||||
|
...addonOptions,
|
||||||
|
});
|
||||||
|
editor?.setValue(props.value);
|
||||||
|
setTheme();
|
||||||
|
editor?.on('change', () => {
|
||||||
|
emit('change', editor?.getValue());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await nextTick();
|
||||||
|
init();
|
||||||
|
useWindowSizeFn(debounceRefresh);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
editor = null;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,13 +2,11 @@
|
|||||||
<vue-json-pretty :path="'res'" :deep="3" :showLength="true" :data="data" />
|
<vue-json-pretty :path="'res'" :deep="3" :showLength="true" :data="data" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import VueJsonPretty from 'vue-json-pretty';
|
import VueJsonPretty from 'vue-json-pretty';
|
||||||
import 'vue-json-pretty/lib/styles.css';
|
import 'vue-json-pretty/lib/styles.css';
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
export default defineComponent({
|
defineProps({
|
||||||
name: 'JsonPreview',
|
data: Object,
|
||||||
components: { VueJsonPretty },
|
|
||||||
props: { data: Object },
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const wrap = unref(scrollbar.wrap);
|
const wrap = unref(scrollbar.wrap) as any;
|
||||||
if (!wrap) {
|
if (!wrap) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import { defineComponent, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
// component
|
// component
|
||||||
import { Skeleton } from 'ant-design-vue';
|
import { Skeleton } from 'ant-design-vue';
|
||||||
import { CollapseTransition } from '/@/components/Transition';
|
import { CollapseTransition } from '/@/components/Transition';
|
||||||
@ -34,7 +34,7 @@
|
|||||||
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
import { useTimeoutFn } from '/@/hooks/core/useTimeout';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
|
|
||||||
const props = {
|
const props = defineProps({
|
||||||
title: { type: String, default: '' },
|
title: { type: String, default: '' },
|
||||||
loading: { type: Boolean },
|
loading: { type: Boolean },
|
||||||
/**
|
/**
|
||||||
@ -57,39 +57,22 @@
|
|||||||
* Delayed loading time
|
* Delayed loading time
|
||||||
*/
|
*/
|
||||||
lazyTime: { type: Number, default: 0 },
|
lazyTime: { type: Number, default: 0 },
|
||||||
};
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'CollapseContainer',
|
|
||||||
components: {
|
|
||||||
Skeleton,
|
|
||||||
CollapseHeader,
|
|
||||||
CollapseTransition,
|
|
||||||
},
|
|
||||||
props,
|
|
||||||
setup(props) {
|
|
||||||
const show = ref(true);
|
|
||||||
|
|
||||||
const { prefixCls } = useDesign('collapse-container');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: Handling development events
|
|
||||||
*/
|
|
||||||
function handleExpand() {
|
|
||||||
show.value = !show.value;
|
|
||||||
if (props.triggerWindowResize) {
|
|
||||||
// 200 milliseconds here is because the expansion has animation,
|
|
||||||
useTimeoutFn(triggerWindowResize, 200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
show,
|
|
||||||
handleExpand,
|
|
||||||
prefixCls,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const show = ref(true);
|
||||||
|
|
||||||
|
const { prefixCls } = useDesign('collapse-container');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Handling development events
|
||||||
|
*/
|
||||||
|
function handleExpand() {
|
||||||
|
show.value = !show.value;
|
||||||
|
if (props.triggerWindowResize) {
|
||||||
|
// 200 milliseconds here is because the expansion has animation,
|
||||||
|
useTimeoutFn(triggerWindowResize, 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@prefix-cls: ~'@{namespace}-collapse-container';
|
@prefix-cls: ~'@{namespace}-collapse-container';
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
name: 'ContextMenu',
|
name: 'ContextMenu',
|
||||||
props,
|
props,
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const wrapRef = ref<ElRef>(null);
|
const wrapRef = ref(null);
|
||||||
const showRef = ref(false);
|
const showRef = ref(false);
|
||||||
|
|
||||||
const getStyle = computed((): CSSProperties => {
|
const getStyle = computed((): CSSProperties => {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<CountButton :size="size" :count="count" :value="state" :beforeStartFunc="sendCodeApi" />
|
<CountButton :size="size" :count="count" :value="state" :beforeStartFunc="sendCodeApi" />
|
||||||
</template>
|
</template>
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots).filter((k) => k !== 'addonAfter')">
|
<template #[item]="data" v-for="item in Object.keys($slots).filter((k) => k !== 'addonAfter')">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
</a-input>
|
</a-input>
|
||||||
</template>
|
</template>
|
||||||
|
@ -122,10 +122,12 @@
|
|||||||
import { isFunction } from '/@/utils/is';
|
import { isFunction } from '/@/utils/is';
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
|
|
||||||
|
type apiFunParams = { file: Blob; name: string; filename: string };
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
circled: { type: Boolean, default: true },
|
circled: { type: Boolean, default: true },
|
||||||
uploadApi: {
|
uploadApi: {
|
||||||
type: Function as PropType<({ file: Blob, name: string, filename: string }) => Promise<any>>,
|
type: Function as PropType<(params: apiFunParams) => Promise<any>>,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
const getStyle = computed((): CSSProperties => ({ width: unref(getWidth) }));
|
const getStyle = computed((): CSSProperties => ({ width: unref(getWidth) }));
|
||||||
|
|
||||||
const getImageWrapperStyle = computed(
|
const getImageWrapperStyle = computed(
|
||||||
(): CSSProperties => ({ width: unref(getWidth), height: unref(getWidth) })
|
(): CSSProperties => ({ width: unref(getWidth), height: unref(getWidth) }),
|
||||||
);
|
);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
@ -88,7 +88,7 @@
|
|||||||
() => sourceValue.value,
|
() => sourceValue.value,
|
||||||
(v: string) => {
|
(v: string) => {
|
||||||
emit('update:value', v);
|
emit('update:value', v);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleUploadSuccess({ source }) {
|
function handleUploadSuccess({ source }) {
|
||||||
@ -103,7 +103,7 @@
|
|||||||
t,
|
t,
|
||||||
prefixCls,
|
prefixCls,
|
||||||
register,
|
register,
|
||||||
openModal,
|
openModal: openModal as any,
|
||||||
getIconWidth,
|
getIconWidth,
|
||||||
sourceValue,
|
sourceValue,
|
||||||
getClass,
|
getClass,
|
||||||
|
@ -14,7 +14,7 @@ export interface DescItem {
|
|||||||
// render
|
// render
|
||||||
render?: (
|
render?: (
|
||||||
val: any,
|
val: any,
|
||||||
data: Recordable
|
data: Recordable,
|
||||||
) => VNode | undefined | JSX.Element | Element | string | number;
|
) => VNode | undefined | JSX.Element | Element | string | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
<DrawerFooter v-bind="getProps" @close="onClose" @ok="handleOk" :height="getFooterHeight">
|
<DrawerFooter v-bind="getProps" @close="onClose" @ok="handleOk" :height="getFooterHeight">
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
</DrawerFooter>
|
</DrawerFooter>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
@ -139,7 +139,7 @@
|
|||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
if (newVal !== oldVal) visibleRef.value = newVal;
|
if (newVal !== oldVal) visibleRef.value = newVal;
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -149,7 +149,7 @@
|
|||||||
emit('visible-change', visible);
|
emit('visible-change', visible);
|
||||||
instance && drawerInstance.emitVisible?.(visible, instance.uid);
|
instance && drawerInstance.emitVisible?.(visible, instance.uid);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// Cancel event
|
// Cancel event
|
||||||
@ -181,9 +181,9 @@
|
|||||||
onClose,
|
onClose,
|
||||||
t,
|
t,
|
||||||
prefixCls,
|
prefixCls,
|
||||||
getMergeProps,
|
getMergeProps: getMergeProps as any,
|
||||||
getScrollContentStyle,
|
getScrollContentStyle,
|
||||||
getProps,
|
getProps: getProps as any,
|
||||||
getLoading,
|
getLoading,
|
||||||
getBindValues,
|
getBindValues,
|
||||||
getFooterHeight,
|
getFooterHeight,
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Ref } from 'vue';
|
||||||
import type { Definition } from '@logicflow/core';
|
import type { Definition } from '@logicflow/core';
|
||||||
import { defineComponent, ref, onMounted, unref, nextTick, computed, watch } from 'vue';
|
import { defineComponent, ref, onMounted, unref, nextTick, computed, watch } from 'vue';
|
||||||
import FlowChartToolbar from './FlowChartToolbar.vue';
|
import FlowChartToolbar from './FlowChartToolbar.vue';
|
||||||
@ -46,10 +47,10 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const lfElRef = ref<ElRef>(null);
|
const lfElRef = ref(null);
|
||||||
const graphData = ref<Recordable>({});
|
const graphData = ref({});
|
||||||
|
|
||||||
const lfInstance = ref<Nullable<LogicFlow>>(null);
|
const lfInstance = ref(null) as Ref<LogicFlow | null>;
|
||||||
|
|
||||||
const { prefixCls } = useDesign('flow-chart');
|
const { prefixCls } = useDesign('flow-chart');
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
@ -78,7 +79,7 @@
|
|||||||
() => props.data,
|
() => props.data,
|
||||||
() => {
|
() => {
|
||||||
onRender();
|
onRender();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
@ -93,7 +94,7 @@
|
|||||||
() => unref(getFlowOptions),
|
() => unref(getFlowOptions),
|
||||||
(options) => {
|
(options) => {
|
||||||
unref(lfInstance)?.updateEditConfig(options);
|
unref(lfInstance)?.updateEditConfig(options);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// init logicFlow
|
// init logicFlow
|
||||||
|
@ -19,17 +19,17 @@
|
|||||||
:setFormModel="setFormModel"
|
:setFormModel="setFormModel"
|
||||||
>
|
>
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<FormAction v-bind="{ ...getProps, ...advanceState }" @toggle-advanced="handleToggleAdvanced">
|
<FormAction v-bind="getFormActionBindProps" @toggle-advanced="handleToggleAdvanced">
|
||||||
<template
|
<template
|
||||||
#[item]="data"
|
#[item]="data"
|
||||||
v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']"
|
v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']"
|
||||||
>
|
>
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
</FormAction>
|
</FormAction>
|
||||||
<slot name="formFooter"></slot>
|
<slot name="formFooter"></slot>
|
||||||
@ -62,8 +62,6 @@
|
|||||||
import { basicProps } from './props';
|
import { basicProps } from './props';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
|
|
||||||
import type { RowProps } from 'ant-design-vue/lib/grid/Row';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'BasicForm',
|
name: 'BasicForm',
|
||||||
components: { FormItem, Form, Row, FormAction },
|
components: { FormItem, Form, Row, FormAction },
|
||||||
@ -103,7 +101,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get uniform row style and Row configuration for the entire form
|
// Get uniform row style and Row configuration for the entire form
|
||||||
const getRow = computed((): RowProps => {
|
const getRow = computed((): Recordable => {
|
||||||
const { baseRowStyle = {}, rowProps } = unref(getProps);
|
const { baseRowStyle = {}, rowProps } = unref(getProps);
|
||||||
return {
|
return {
|
||||||
style: baseRowStyle,
|
style: baseRowStyle,
|
||||||
@ -112,7 +110,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const getBindValue = computed(
|
const getBindValue = computed(
|
||||||
() => ({ ...attrs, ...props, ...unref(getProps) } as Recordable)
|
() => ({ ...attrs, ...props, ...unref(getProps) } as Recordable),
|
||||||
);
|
);
|
||||||
|
|
||||||
const getSchema = computed((): FormSchema[] => {
|
const getSchema = computed((): FormSchema[] => {
|
||||||
@ -132,7 +130,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return schemas as FormSchema[];
|
if (unref(getProps).showAdvancedButton) {
|
||||||
|
return schemas.filter((schema) => schema.component !== 'Divider') as FormSchema[];
|
||||||
|
} else {
|
||||||
|
return schemas as FormSchema[];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleToggleAdvanced } = useAdvanced({
|
const { handleToggleAdvanced } = useAdvanced({
|
||||||
@ -196,14 +198,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => unref(getProps).schemas,
|
() => unref(getProps).schemas,
|
||||||
(schemas) => {
|
(schemas) => {
|
||||||
resetSchema(schemas ?? []);
|
resetSchema(schemas ?? []);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -220,7 +222,7 @@
|
|||||||
initDefault();
|
initDefault();
|
||||||
isInitedDefaultRef.value = true;
|
isInitedDefaultRef.value = true;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
async function setProps(formProps: Partial<FormProps>): Promise<void> {
|
async function setProps(formProps: Partial<FormProps>): Promise<void> {
|
||||||
@ -278,10 +280,12 @@
|
|||||||
getProps,
|
getProps,
|
||||||
formElRef,
|
formElRef,
|
||||||
getSchema,
|
getSchema,
|
||||||
formActionType,
|
formActionType: formActionType as any,
|
||||||
setFormModel,
|
setFormModel,
|
||||||
prefixCls,
|
|
||||||
getFormClass,
|
getFormClass,
|
||||||
|
getFormActionBindProps: computed(
|
||||||
|
(): Recordable => ({ ...getProps.value, ...advanceState }),
|
||||||
|
),
|
||||||
...formActionType,
|
...formActionType,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
TreeSelect,
|
TreeSelect,
|
||||||
Slider,
|
Slider,
|
||||||
Rate,
|
Rate,
|
||||||
|
Divider,
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
|
|
||||||
import RadioButtonGroup from './components/RadioButtonGroup.vue';
|
import RadioButtonGroup from './components/RadioButtonGroup.vue';
|
||||||
@ -61,6 +62,7 @@ componentMap.set('IconPicker', IconPicker);
|
|||||||
componentMap.set('InputCountDown', CountdownInput);
|
componentMap.set('InputCountDown', CountdownInput);
|
||||||
|
|
||||||
componentMap.set('Upload', BasicUpload);
|
componentMap.set('Upload', BasicUpload);
|
||||||
|
componentMap.set('Divider', Divider);
|
||||||
|
|
||||||
export function add(compName: ComponentType, component: Component) {
|
export function add(compName: ComponentType, component: Component) {
|
||||||
componentMap.set(compName, component);
|
componentMap.set(compName, component);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
v-model:value="state"
|
v-model:value="state"
|
||||||
>
|
>
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
<template #suffixIcon v-if="loading">
|
<template #suffixIcon v-if="loading">
|
||||||
<LoadingOutlined spin />
|
<LoadingOutlined spin />
|
||||||
@ -100,7 +100,7 @@
|
|||||||
() => {
|
() => {
|
||||||
!unref(isFirstLoad) && fetch();
|
!unref(isFirstLoad) && fetch();
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
async function fetch() {
|
async function fetch() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-tree-select v-bind="getAttrs" @change="handleChange">
|
<a-tree-select v-bind="getAttrs" @change="handleChange">
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
<template #suffixIcon v-if="loading">
|
<template #suffixIcon v-if="loading">
|
||||||
<LoadingOutlined spin />
|
<LoadingOutlined spin />
|
||||||
@ -46,14 +46,14 @@
|
|||||||
() => {
|
() => {
|
||||||
isFirstLoaded.value && fetch();
|
isFirstLoaded.value && fetch();
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.immediate,
|
() => props.immediate,
|
||||||
(v) => {
|
(v) => {
|
||||||
v && !isFirstLoaded.value && fetch();
|
v && !isFirstLoaded.value && fetch();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -105,7 +105,7 @@
|
|||||||
{
|
{
|
||||||
text: t('common.resetText'),
|
text: t('common.resetText'),
|
||||||
},
|
},
|
||||||
props.resetButtonOptions
|
props.resetButtonOptions,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -114,7 +114,7 @@
|
|||||||
{
|
{
|
||||||
text: t('common.queryText'),
|
text: t('common.queryText'),
|
||||||
},
|
},
|
||||||
props.submitButtonOptions
|
props.submitButtonOptions,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import type { ValidationRule } from 'ant-design-vue/lib/form/Form';
|
import type { ValidationRule } from 'ant-design-vue/lib/form/Form';
|
||||||
import type { TableActionType } from '/@/components/Table';
|
import type { TableActionType } from '/@/components/Table';
|
||||||
import { defineComponent, computed, unref, toRefs } from 'vue';
|
import { defineComponent, computed, unref, toRefs } from 'vue';
|
||||||
import { Form, Col } from 'ant-design-vue';
|
import { Form, Col, Divider } from 'ant-design-vue';
|
||||||
import { componentMap } from '../componentMap';
|
import { componentMap } from '../componentMap';
|
||||||
import { BasicHelp } from '/@/components/Basic';
|
import { BasicHelp } from '/@/components/Basic';
|
||||||
import { isBoolean, isFunction, isNull } from '/@/utils/is';
|
import { isBoolean, isFunction, isNull } from '/@/utils/is';
|
||||||
@ -73,11 +73,17 @@
|
|||||||
|
|
||||||
const getComponentsProps = computed(() => {
|
const getComponentsProps = computed(() => {
|
||||||
const { schema, tableAction, formModel, formActionType } = props;
|
const { schema, tableAction, formModel, formActionType } = props;
|
||||||
const { componentProps = {} } = schema;
|
let { componentProps = {} } = schema;
|
||||||
if (!isFunction(componentProps)) {
|
if (isFunction(componentProps)) {
|
||||||
return componentProps;
|
componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
|
||||||
}
|
}
|
||||||
return componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
|
if (schema.component === 'Divider') {
|
||||||
|
componentProps = Object.assign({ type: 'horizontal' }, componentProps, {
|
||||||
|
orientation: 'left',
|
||||||
|
plain: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return componentProps as Recordable;
|
||||||
});
|
});
|
||||||
|
|
||||||
const getDisable = computed(() => {
|
const getDisable = computed(() => {
|
||||||
@ -177,7 +183,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const requiredRuleIndex: number = rules.findIndex(
|
const requiredRuleIndex: number = rules.findIndex(
|
||||||
(rule) => Reflect.has(rule, 'required') && !Reflect.has(rule, 'validator')
|
(rule) => Reflect.has(rule, 'required') && !Reflect.has(rule, 'validator'),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (requiredRuleIndex !== -1) {
|
if (requiredRuleIndex !== -1) {
|
||||||
@ -300,38 +306,46 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderItem() {
|
function renderItem() {
|
||||||
const { itemProps, slot, render, field, suffix } = props.schema;
|
const { itemProps, slot, render, field, suffix, component } = props.schema;
|
||||||
const { labelCol, wrapperCol } = unref(itemLabelWidthProp);
|
const { labelCol, wrapperCol } = unref(itemLabelWidthProp);
|
||||||
const { colon } = props.formProps;
|
const { colon } = props.formProps;
|
||||||
|
|
||||||
const getContent = () => {
|
if (component === 'Divider') {
|
||||||
return slot
|
return (
|
||||||
? getSlot(slots, slot, unref(getValues))
|
<Col span={24}>
|
||||||
: render
|
<Divider {...unref(getComponentsProps)}>{renderLabelHelpMessage()}</Divider>
|
||||||
? render(unref(getValues))
|
</Col>
|
||||||
: renderComponent();
|
);
|
||||||
};
|
} else {
|
||||||
|
const getContent = () => {
|
||||||
|
return slot
|
||||||
|
? getSlot(slots, slot, unref(getValues))
|
||||||
|
: render
|
||||||
|
? render(unref(getValues))
|
||||||
|
: renderComponent();
|
||||||
|
};
|
||||||
|
|
||||||
const showSuffix = !!suffix;
|
const showSuffix = !!suffix;
|
||||||
const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
|
const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={field}
|
name={field}
|
||||||
colon={colon}
|
colon={colon}
|
||||||
class={{ 'suffix-item': showSuffix }}
|
class={{ 'suffix-item': showSuffix }}
|
||||||
{...(itemProps as Recordable)}
|
{...(itemProps as Recordable)}
|
||||||
label={renderLabelHelpMessage()}
|
label={renderLabelHelpMessage()}
|
||||||
rules={handleRules()}
|
rules={handleRules()}
|
||||||
labelCol={labelCol}
|
labelCol={labelCol}
|
||||||
wrapperCol={wrapperCol}
|
wrapperCol={wrapperCol}
|
||||||
>
|
>
|
||||||
<div style="display:flex">
|
<div style="display:flex">
|
||||||
<div style="flex:1">{getContent()}</div>
|
<div style="flex:1">{getContent()}</div>
|
||||||
{showSuffix && <span class="suffix">{getSuffix}</span>}
|
{showSuffix && <span class="suffix">{getSuffix}</span>}
|
||||||
</div>
|
</div>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
@ -38,7 +38,7 @@ function genType() {
|
|||||||
export function setComponentRuleType(
|
export function setComponentRuleType(
|
||||||
rule: ValidationRule,
|
rule: ValidationRule,
|
||||||
component: ComponentType,
|
component: ComponentType,
|
||||||
valueFormat: string
|
valueFormat: string,
|
||||||
) {
|
) {
|
||||||
if (['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'].includes(component)) {
|
if (['DatePicker', 'MonthPicker', 'WeekPicker', 'TimePicker'].includes(component)) {
|
||||||
rule.type = valueFormat ? 'string' : 'object';
|
rule.type = valueFormat ? 'string' : 'object';
|
||||||
|
@ -58,7 +58,7 @@ export default function ({
|
|||||||
debounceUpdateAdvanced();
|
debounceUpdateAdvanced();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
function getAdvanced(itemCol: Partial<ColEx>, itemColSum = 0, isLastAction = false) {
|
function getAdvanced(itemCol: Partial<ColEx>, itemColSum = 0, isLastAction = false) {
|
||||||
@ -103,7 +103,7 @@ export default function ({
|
|||||||
}
|
}
|
||||||
return { isAdvanced: advanceState.isAdvanced, itemColSum };
|
return { isAdvanced: advanceState.isAdvanced, itemColSum };
|
||||||
}
|
}
|
||||||
if (itemColSum > BASIC_COL_LEN) {
|
if (itemColSum > BASIC_COL_LEN * (unref(getProps).alwaysShowLines || 1)) {
|
||||||
return { isAdvanced: advanceState.isAdvanced, itemColSum };
|
return { isAdvanced: advanceState.isAdvanced, itemColSum };
|
||||||
} else {
|
} else {
|
||||||
// The first line is always displayed
|
// The first line is always displayed
|
||||||
@ -139,7 +139,7 @@ export default function ({
|
|||||||
if (isShow && (colProps || baseColProps)) {
|
if (isShow && (colProps || baseColProps)) {
|
||||||
const { itemColSum: sum, isAdvanced } = getAdvanced(
|
const { itemColSum: sum, isAdvanced } = getAdvanced(
|
||||||
{ ...baseColProps, ...colProps },
|
{ ...baseColProps, ...colProps },
|
||||||
itemColSum
|
itemColSum,
|
||||||
);
|
);
|
||||||
|
|
||||||
itemColSum = sum || 0;
|
itemColSum = sum || 0;
|
||||||
|
@ -18,7 +18,7 @@ export function useForm(props?: Props): UseFormReturnType {
|
|||||||
const form = unref(formRef);
|
const form = unref(formRef);
|
||||||
if (!form) {
|
if (!form) {
|
||||||
error(
|
error(
|
||||||
'The form instance has not been obtained, please make sure that the form has been rendered when performing the form operation!'
|
'The form instance has not been obtained, please make sure that the form has been rendered when performing the form operation!',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await nextTick();
|
await nextTick();
|
||||||
@ -44,7 +44,7 @@ export function useForm(props?: Props): UseFormReturnType {
|
|||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true,
|
deep: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ export function useForm(props?: Props): UseFormReturnType {
|
|||||||
appendSchemaByField: async (
|
appendSchemaByField: async (
|
||||||
schema: FormSchema,
|
schema: FormSchema,
|
||||||
prefixField: string | undefined,
|
prefixField: string | undefined,
|
||||||
first: boolean
|
first: boolean,
|
||||||
) => {
|
) => {
|
||||||
const form = await getForm();
|
const form = await getForm();
|
||||||
form.appendSchemaByField(schema, prefixField, first);
|
form.appendSchemaByField(schema, prefixField, first);
|
||||||
|
@ -149,11 +149,13 @@ export function useFormEvents({
|
|||||||
updateData = [...data];
|
updateData = [...data];
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field);
|
const hasField = updateData.every(
|
||||||
|
(item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field),
|
||||||
|
);
|
||||||
|
|
||||||
if (!hasField) {
|
if (!hasField) {
|
||||||
error(
|
error(
|
||||||
'All children of the form Schema array that need to be updated must contain the `field` field'
|
'All children of the form Schema array that need to be updated must contain the `field` field',
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -169,11 +171,13 @@ export function useFormEvents({
|
|||||||
updateData = [...data];
|
updateData = [...data];
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasField = updateData.every((item) => Reflect.has(item, 'field') && item.field);
|
const hasField = updateData.every(
|
||||||
|
(item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field),
|
||||||
|
);
|
||||||
|
|
||||||
if (!hasField) {
|
if (!hasField) {
|
||||||
error(
|
error(
|
||||||
'All children of the form Schema array that need to be updated must contain the `field` field'
|
'All children of the form Schema array that need to be updated must contain the `field` field',
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,8 @@ export const basicProps = {
|
|||||||
rulesMessageJoinLabel: propTypes.bool.def(true),
|
rulesMessageJoinLabel: propTypes.bool.def(true),
|
||||||
// 超过3行自动折叠
|
// 超过3行自动折叠
|
||||||
autoAdvancedLine: propTypes.number.def(3),
|
autoAdvancedLine: propTypes.number.def(3),
|
||||||
|
// 不受折叠影响的行数
|
||||||
|
alwaysShowLines: propTypes.number.def(1),
|
||||||
|
|
||||||
// 是否显示操作按钮
|
// 是否显示操作按钮
|
||||||
showActionButtonGroup: propTypes.bool.def(true),
|
showActionButtonGroup: propTypes.bool.def(true),
|
||||||
|
@ -37,7 +37,7 @@ export interface FormActionType {
|
|||||||
appendSchemaByField: (
|
appendSchemaByField: (
|
||||||
schema: FormSchema,
|
schema: FormSchema,
|
||||||
prefixField: string | undefined,
|
prefixField: string | undefined,
|
||||||
first?: boolean | undefined
|
first?: boolean | undefined,
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
validateFields: (nameList?: NamePath[]) => Promise<any>;
|
validateFields: (nameList?: NamePath[]) => Promise<any>;
|
||||||
validate: (nameList?: NamePath[]) => Promise<any>;
|
validate: (nameList?: NamePath[]) => Promise<any>;
|
||||||
@ -97,6 +97,8 @@ export interface FormProps {
|
|||||||
autoFocusFirstItem?: boolean;
|
autoFocusFirstItem?: boolean;
|
||||||
// Automatically collapse over the specified number of rows
|
// Automatically collapse over the specified number of rows
|
||||||
autoAdvancedLine?: number;
|
autoAdvancedLine?: number;
|
||||||
|
// Always show lines
|
||||||
|
alwaysShowLines?: number;
|
||||||
// Whether to show the operation button
|
// Whether to show the operation button
|
||||||
showActionButtonGroup?: boolean;
|
showActionButtonGroup?: boolean;
|
||||||
|
|
||||||
|
@ -109,4 +109,5 @@ export type ComponentType =
|
|||||||
| 'IconPicker'
|
| 'IconPicker'
|
||||||
| 'Render'
|
| 'Render'
|
||||||
| 'Slider'
|
| 'Slider'
|
||||||
| 'Rate';
|
| 'Rate'
|
||||||
|
| 'Divider';
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-else
|
<template v-else
|
||||||
><div class="p-5"> <Empty /></div>
|
><div class="p-5"><Empty /></div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -121,7 +121,7 @@
|
|||||||
copy: propTypes.bool.def(false),
|
copy: propTypes.bool.def(false),
|
||||||
mode: propTypes.oneOf<('svg' | 'iconify')[]>(['svg', 'iconify']).def('iconify'),
|
mode: propTypes.oneOf<('svg' | 'iconify')[]>(['svg', 'iconify']).def('iconify'),
|
||||||
},
|
},
|
||||||
emits: ['change'],
|
emits: ['change', 'update:value'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const isSvgMode = props.mode === 'svg';
|
const isSvgMode = props.mode === 'svg';
|
||||||
const icons = isSvgMode ? getSvgIcons() : getIcons();
|
const icons = isSvgMode ? getSvgIcons() : getIcons();
|
||||||
@ -139,7 +139,7 @@
|
|||||||
|
|
||||||
const { getPaginationList, getTotal, setCurrentPage } = usePagination(
|
const { getPaginationList, getTotal, setCurrentPage } = usePagination(
|
||||||
currentList,
|
currentList,
|
||||||
props.pageSize
|
props.pageSize,
|
||||||
);
|
);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
@ -148,7 +148,10 @@
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => currentSelect.value,
|
() => currentSelect.value,
|
||||||
(v) => emit('change', v)
|
(v) => {
|
||||||
|
emit('update:value', v);
|
||||||
|
return emit('change', v);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
function handlePageChange(page: number) {
|
function handlePageChange(page: number) {
|
||||||
|
@ -4,7 +4,7 @@ import type { LoadingProps } from './typing';
|
|||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
|
|
||||||
export interface UseLoadingOptions {
|
export interface UseLoadingOptions {
|
||||||
target?: HTMLElement | Ref<ElRef>;
|
target?: any;
|
||||||
props?: Partial<LoadingProps>;
|
props?: Partial<LoadingProps>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ export function useLoading(props: Partial<LoadingProps>): [Fn, Fn, (string) => v
|
|||||||
export function useLoading(opt: Partial<UseLoadingOptions>): [Fn, Fn, (string) => void];
|
export function useLoading(opt: Partial<UseLoadingOptions>): [Fn, Fn, (string) => void];
|
||||||
|
|
||||||
export function useLoading(
|
export function useLoading(
|
||||||
opt: Partial<LoadingProps> | Partial<UseLoadingOptions>
|
opt: Partial<LoadingProps> | Partial<UseLoadingOptions>,
|
||||||
): [Fn, Fn, (string) => void] {
|
): [Fn, Fn, (string) => void] {
|
||||||
let props: Partial<LoadingProps>;
|
let props: Partial<LoadingProps>;
|
||||||
let target: HTMLElement | Ref<ElRef> = document.body;
|
let target: HTMLElement | Ref<ElRef> = document.body;
|
||||||
@ -32,7 +32,7 @@ export function useLoading(
|
|||||||
const instance = createLoading(props, undefined, true);
|
const instance = createLoading(props, undefined, true);
|
||||||
|
|
||||||
const open = (): void => {
|
const open = (): void => {
|
||||||
const t = unref(target);
|
const t = unref(target as Ref<ElRef>);
|
||||||
if (!t) return;
|
if (!t) return;
|
||||||
instance.open(t);
|
instance.open(t);
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<div ref="wrapRef"></div>
|
<div ref="wrapRef"></div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Ref } from 'vue';
|
||||||
import {
|
import {
|
||||||
defineComponent,
|
defineComponent,
|
||||||
ref,
|
ref,
|
||||||
@ -30,7 +31,7 @@
|
|||||||
emits: ['change', 'get', 'update:value'],
|
emits: ['change', 'get', 'update:value'],
|
||||||
setup(props, { attrs, emit }) {
|
setup(props, { attrs, emit }) {
|
||||||
const wrapRef = ref<ElRef>(null);
|
const wrapRef = ref<ElRef>(null);
|
||||||
const vditorRef = ref<Nullable<Vditor>>(null);
|
const vditorRef = ref(null) as Ref<Nullable<Vditor>>;
|
||||||
const initedRef = ref(false);
|
const initedRef = ref(false);
|
||||||
|
|
||||||
const modalFn = useModalContext();
|
const modalFn = useModalContext();
|
||||||
@ -51,7 +52,7 @@
|
|||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
flush: 'post',
|
flush: 'post',
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -61,7 +62,7 @@
|
|||||||
instance.getVditor()?.setValue(v);
|
instance.getVditor()?.setValue(v);
|
||||||
}
|
}
|
||||||
valueRef.value = v;
|
valueRef.value = v;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => {
|
const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => {
|
||||||
|
@ -56,15 +56,15 @@
|
|||||||
const { prefixCls } = useDesign('basic-menu');
|
const { prefixCls } = useDesign('basic-menu');
|
||||||
const { items, mode, accordion } = toRefs(props);
|
const { items, mode, accordion } = toRefs(props);
|
||||||
|
|
||||||
const { getCollapsed, getIsHorizontal, getTopMenuAlign, getSplit } = useMenuSetting();
|
const { getCollapsed, getTopMenuAlign, getSplit } = useMenuSetting();
|
||||||
|
|
||||||
const { currentRoute } = useRouter();
|
const { currentRoute } = useRouter();
|
||||||
|
|
||||||
const { handleOpenChange, setOpenKeys, getOpenKeys } = useOpenKeys(
|
const { handleOpenChange, setOpenKeys, getOpenKeys } = useOpenKeys(
|
||||||
menuState,
|
menuState,
|
||||||
items,
|
items,
|
||||||
mode,
|
mode as any,
|
||||||
accordion
|
accordion,
|
||||||
);
|
);
|
||||||
|
|
||||||
const getIsTopMenu = computed(() => {
|
const getIsTopMenu = computed(() => {
|
||||||
@ -114,7 +114,7 @@
|
|||||||
() => props.items,
|
() => props.items,
|
||||||
() => {
|
() => {
|
||||||
handleMenuChange();
|
handleMenuChange();
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
async function handleMenuClick({ key }: { key: string; keyPath: string[] }) {
|
async function handleMenuClick({ key }: { key: string; keyPath: string[] }) {
|
||||||
@ -150,8 +150,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
prefixCls,
|
|
||||||
getIsHorizontal,
|
|
||||||
handleMenuClick,
|
handleMenuClick,
|
||||||
getInlineCollapseOptions,
|
getInlineCollapseOptions,
|
||||||
getMenuClass,
|
getMenuClass,
|
||||||
|
@ -4,6 +4,8 @@ import type { PropType } from 'vue';
|
|||||||
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
|
||||||
import { ThemeEnum } from '/@/enums/appEnum';
|
import { ThemeEnum } from '/@/enums/appEnum';
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
|
import type { MenuTheme } from 'ant-design-vue';
|
||||||
|
import type { MenuMode } from 'ant-design-vue/lib/menu/src/interface';
|
||||||
export const basicProps = {
|
export const basicProps = {
|
||||||
items: {
|
items: {
|
||||||
type: Array as PropType<Menu[]>,
|
type: Array as PropType<Menu[]>,
|
||||||
@ -14,7 +16,7 @@ export const basicProps = {
|
|||||||
inlineIndent: propTypes.number.def(20),
|
inlineIndent: propTypes.number.def(20),
|
||||||
// 菜单组件的mode属性
|
// 菜单组件的mode属性
|
||||||
mode: {
|
mode: {
|
||||||
type: String as PropType<MenuModeEnum>,
|
type: String as PropType<MenuMode>,
|
||||||
default: MenuModeEnum.INLINE,
|
default: MenuModeEnum.INLINE,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -22,7 +24,10 @@ export const basicProps = {
|
|||||||
type: String as PropType<MenuTypeEnum>,
|
type: String as PropType<MenuTypeEnum>,
|
||||||
default: MenuTypeEnum.MIX,
|
default: MenuTypeEnum.MIX,
|
||||||
},
|
},
|
||||||
theme: propTypes.string.def(ThemeEnum.DARK),
|
theme: {
|
||||||
|
type: String as PropType<MenuTheme>,
|
||||||
|
default: ThemeEnum.DARK,
|
||||||
|
},
|
||||||
inlineCollapsed: propTypes.bool,
|
inlineCollapsed: propTypes.bool,
|
||||||
mixSider: propTypes.bool,
|
mixSider: propTypes.bool,
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ export function useOpenKeys(
|
|||||||
menuState: MenuState,
|
menuState: MenuState,
|
||||||
menus: Ref<MenuType[]>,
|
menus: Ref<MenuType[]>,
|
||||||
mode: Ref<MenuModeEnum>,
|
mode: Ref<MenuModeEnum>,
|
||||||
accordion: Ref<boolean>
|
accordion: Ref<boolean>,
|
||||||
) {
|
) {
|
||||||
const { getCollapsed, getIsMixSidebar } = useMenuSetting();
|
const { getCollapsed, getIsMixSidebar } = useMenuSetting();
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ export function useOpenKeys(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
16,
|
16,
|
||||||
!native
|
!native,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<template #footer v-if="!$slots.footer">
|
<template #footer v-if="!$slots.footer">
|
||||||
<ModalFooter v-bind="getBindValue" @ok="handleOk" @cancel="handleCancel">
|
<ModalFooter v-bind="getBindValue" @ok="handleOk" @cancel="handleCancel">
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</template>
|
</template>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
</ModalWrapper>
|
</ModalWrapper>
|
||||||
|
|
||||||
<template #[item]="data" v-for="item in Object.keys(omit($slots, 'default'))">
|
<template #[item]="data" v-for="item in Object.keys(omit($slots, 'default'))">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
@ -104,7 +104,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Custom title component: get title
|
// Custom title component: get title
|
||||||
const getMergeProps = computed((): ModalProps => {
|
const getMergeProps = computed((): Recordable => {
|
||||||
return {
|
return {
|
||||||
...props,
|
...props,
|
||||||
...(unref(propsRef) as any),
|
...(unref(propsRef) as any),
|
||||||
@ -118,7 +118,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// modal component does not need title and origin buttons
|
// modal component does not need title and origin buttons
|
||||||
const getProps = computed((): ModalProps => {
|
const getProps = computed((): Recordable => {
|
||||||
const opt = {
|
const opt = {
|
||||||
...unref(getMergeProps),
|
...unref(getMergeProps),
|
||||||
visible: unref(visibleRef),
|
visible: unref(visibleRef),
|
||||||
@ -140,9 +140,9 @@
|
|||||||
wrapClassName: unref(getWrapClassName),
|
wrapClassName: unref(getWrapClassName),
|
||||||
};
|
};
|
||||||
if (unref(fullScreenRef)) {
|
if (unref(fullScreenRef)) {
|
||||||
return omit(attr, 'height');
|
return omit(attr, ['height', 'title']);
|
||||||
}
|
}
|
||||||
return attr;
|
return omit(attr, 'title');
|
||||||
});
|
});
|
||||||
|
|
||||||
const getWrapperHeight = computed(() => {
|
const getWrapperHeight = computed(() => {
|
||||||
@ -169,7 +169,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: false,
|
immediate: false,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// 取消事件
|
// 取消事件
|
||||||
@ -212,7 +212,7 @@
|
|||||||
extHeightRef.value = height;
|
extHeightRef.value = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTitleDbClick(e: ChangeEvent) {
|
function handleTitleDbClick(e) {
|
||||||
if (!props.canFullscreen) return;
|
if (!props.canFullscreen) return;
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleFullScreen(e);
|
handleFullScreen(e);
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
{
|
{
|
||||||
attributes: true,
|
attributes: true,
|
||||||
subtree: true,
|
subtree: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
createModalContext({
|
createModalContext({
|
||||||
@ -89,7 +89,7 @@
|
|||||||
} else {
|
} else {
|
||||||
minRealHeightRef.value = realHeightRef.value;
|
minRealHeightRef.value = realHeightRef.value;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -125,7 +125,7 @@
|
|||||||
const modalDom = bodyDom.parentElement && bodyDom.parentElement.parentElement;
|
const modalDom = bodyDom.parentElement && bodyDom.parentElement.parentElement;
|
||||||
if (!modalDom) return;
|
if (!modalDom) return;
|
||||||
|
|
||||||
const modalRect = getComputedStyle(modalDom).top;
|
const modalRect = getComputedStyle(modalDom as Element).top;
|
||||||
const modalTop = Number.parseInt(modalRect);
|
const modalTop = Number.parseInt(modalRect);
|
||||||
let maxHeight =
|
let maxHeight =
|
||||||
window.innerHeight -
|
window.innerHeight -
|
||||||
|
@ -5,3 +5,5 @@ import pageWrapper from './src/PageWrapper.vue';
|
|||||||
|
|
||||||
export const PageFooter = withInstall(pageFooter);
|
export const PageFooter = withInstall(pageFooter);
|
||||||
export const PageWrapper = withInstall(pageWrapper);
|
export const PageWrapper = withInstall(pageWrapper);
|
||||||
|
|
||||||
|
export const PageWrapperFixedHeightKey = 'PageWrapperFixedHeight';
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<slot name="headerContent" v-else></slot>
|
<slot name="headerContent" v-else></slot>
|
||||||
</template>
|
</template>
|
||||||
<template #[item]="data" v-for="item in getHeaderSlots">
|
<template #[item]="data" v-for="item in getHeaderSlots">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
|
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { CSSProperties, PropType } from 'vue';
|
import { CSSProperties, PropType, provide } from 'vue';
|
||||||
|
|
||||||
import { defineComponent, computed, watch, ref, unref } from 'vue';
|
import { defineComponent, computed, watch, ref, unref } from 'vue';
|
||||||
import PageFooter from './PageFooter.vue';
|
import PageFooter from './PageFooter.vue';
|
||||||
@ -43,6 +43,7 @@
|
|||||||
import { omit } from 'lodash-es';
|
import { omit } from 'lodash-es';
|
||||||
import { PageHeader } from 'ant-design-vue';
|
import { PageHeader } from 'ant-design-vue';
|
||||||
import { useContentHeight } from '/@/hooks/web/useContentHeight';
|
import { useContentHeight } from '/@/hooks/web/useContentHeight';
|
||||||
|
import { PageWrapperFixedHeightKey } from '..';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'PageWrapper',
|
name: 'PageWrapper',
|
||||||
@ -68,6 +69,11 @@
|
|||||||
const footerRef = ref(null);
|
const footerRef = ref(null);
|
||||||
const { prefixCls } = useDesign('page-wrapper');
|
const { prefixCls } = useDesign('page-wrapper');
|
||||||
|
|
||||||
|
provide(
|
||||||
|
PageWrapperFixedHeightKey,
|
||||||
|
computed(() => props.fixedHeight),
|
||||||
|
);
|
||||||
|
|
||||||
const getIsContentFullHeight = computed(() => {
|
const getIsContentFullHeight = computed(() => {
|
||||||
return props.contentFullHeight;
|
return props.contentFullHeight;
|
||||||
});
|
});
|
||||||
@ -76,7 +82,7 @@
|
|||||||
getIsContentFullHeight,
|
getIsContentFullHeight,
|
||||||
wrapperRef,
|
wrapperRef,
|
||||||
[headerRef, footerRef],
|
[headerRef, footerRef],
|
||||||
[contentRef]
|
[contentRef],
|
||||||
);
|
);
|
||||||
setCompensation({ useLayoutFooter: true, elements: [footerRef] });
|
setCompensation({ useLayoutFooter: true, elements: [footerRef] });
|
||||||
|
|
||||||
@ -129,7 +135,7 @@
|
|||||||
{
|
{
|
||||||
flush: 'post',
|
flush: 'post',
|
||||||
immediate: true,
|
immediate: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { defineComponent, ref, unref, computed, reactive, watchEffect } from 'vue';
|
import { defineComponent, ref, unref, computed, reactive, watchEffect } from 'vue';
|
||||||
import { Props } from './typing';
|
|
||||||
import { CloseOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
import { CloseOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
||||||
import resumeSvg from '/@/assets/svg/preview/resume.svg';
|
import resumeSvg from '/@/assets/svg/preview/resume.svg';
|
||||||
import rotateSvg from '/@/assets/svg/preview/p-rotate.svg';
|
import rotateSvg from '/@/assets/svg/preview/p-rotate.svg';
|
||||||
@ -57,7 +56,7 @@
|
|||||||
name: 'ImagePreview',
|
name: 'ImagePreview',
|
||||||
props,
|
props,
|
||||||
emits: ['img-load', 'img-error'],
|
emits: ['img-load', 'img-error'],
|
||||||
setup(props: Props, { expose, emit }) {
|
setup(props, { expose, emit }) {
|
||||||
interface stateInfo {
|
interface stateInfo {
|
||||||
scale: number;
|
scale: number;
|
||||||
rotate: number;
|
rotate: number;
|
||||||
@ -117,8 +116,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getScaleStep = computed(() => {
|
const getScaleStep = computed(() => {
|
||||||
if (props.scaleStep > 0 && props.scaleStep < 100) {
|
const scaleStep = props?.scaleStep ?? 0;
|
||||||
return props.scaleStep / 100;
|
if (scaleStep ?? (0 > 0 && scaleStep < 100)) {
|
||||||
|
return scaleStep / 100;
|
||||||
} else {
|
} else {
|
||||||
return imgState.imgScale / 10;
|
return imgState.imgScale / 10;
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@
|
|||||||
img.src = url;
|
img.src = url;
|
||||||
img.onload = (e: Event) => {
|
img.onload = (e: Event) => {
|
||||||
if (imgState.currentUrl !== url) {
|
if (imgState.currentUrl !== url) {
|
||||||
const ele: HTMLElement[] = e.composedPath();
|
const ele: any[] = e.composedPath();
|
||||||
if (props.rememberState) {
|
if (props.rememberState) {
|
||||||
// 保存当前图片的缩放信息
|
// 保存当前图片的缩放信息
|
||||||
stateMap.set(imgState.currentUrl, {
|
stateMap.set(imgState.currentUrl, {
|
||||||
@ -244,7 +244,7 @@
|
|||||||
setRotate: (rotate: number) => {
|
setRotate: (rotate: number) => {
|
||||||
imgState.imgRotate = rotate;
|
imgState.imgRotate = rotate;
|
||||||
},
|
},
|
||||||
} as PreviewActions);
|
});
|
||||||
|
|
||||||
// 上一页下一页
|
// 上一页下一页
|
||||||
function handleChange(direction: 'left' | 'right') {
|
function handleChange(direction: 'left' | 'right') {
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
setup(props) {
|
setup(props) {
|
||||||
const { prefixCls } = useDesign('image-preview');
|
const { prefixCls } = useDesign('image-preview');
|
||||||
|
|
||||||
const getImageList = computed(() => {
|
const getImageList = computed((): any[] => {
|
||||||
const { imageList } = props;
|
const { imageList } = props;
|
||||||
if (!imageList) {
|
if (!imageList) {
|
||||||
return [];
|
return [];
|
||||||
|
@ -103,7 +103,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true,
|
deep: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return { wrapRef, download };
|
return { wrapRef, download };
|
||||||
|
@ -7,9 +7,9 @@ export const renderQrCode = ({
|
|||||||
canvas,
|
canvas,
|
||||||
content,
|
content,
|
||||||
width = 0,
|
width = 0,
|
||||||
options: params = {}
|
options: params = {},
|
||||||
}: RenderQrCodeParams) => {
|
}: RenderQrCodeParams) => {
|
||||||
const options = cloneDeep(params)
|
const options = cloneDeep(params);
|
||||||
// 容错率,默认对内容少的二维码采用高容错率,内容多的二维码采用低容错率
|
// 容错率,默认对内容少的二维码采用高容错率,内容多的二维码采用低容错率
|
||||||
options.errorCorrectionLevel = options.errorCorrectionLevel || getErrorCorrectionLevel(content);
|
options.errorCorrectionLevel = options.errorCorrectionLevel || getErrorCorrectionLevel(content);
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const clickTrackHandler = (e: any) => {
|
const clickTrackHandler = (e: any) => {
|
||||||
const offset = Math.abs(
|
const offset = Math.abs(
|
||||||
e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]
|
e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client],
|
||||||
);
|
);
|
||||||
const thumbHalf = thumb.value[bar.value.offset] / 2;
|
const thumbHalf = thumb.value[bar.value.offset] / 2;
|
||||||
const thumbPositionPercentage =
|
const thumbPositionPercentage =
|
||||||
@ -104,7 +104,7 @@ export default defineComponent({
|
|||||||
move: props.move,
|
move: props.move,
|
||||||
bar: bar.value,
|
bar: bar.value,
|
||||||
}),
|
}),
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -75,7 +75,7 @@
|
|||||||
items,
|
items,
|
||||||
accordion,
|
accordion,
|
||||||
mixSider,
|
mixSider,
|
||||||
collapse
|
collapse,
|
||||||
);
|
);
|
||||||
|
|
||||||
const getBindValues = computed(() => ({ ...attrs, ...props }));
|
const getBindValues = computed(() => ({ ...attrs, ...props }));
|
||||||
@ -89,7 +89,7 @@
|
|||||||
setOpenKeys(currentRoute.value.path);
|
setOpenKeys(currentRoute.value.path);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -100,7 +100,7 @@
|
|||||||
}
|
}
|
||||||
setOpenKeys(currentRoute.value.path);
|
setOpenKeys(currentRoute.value.path);
|
||||||
},
|
},
|
||||||
{ flush: 'post' }
|
{ flush: 'post' },
|
||||||
);
|
);
|
||||||
|
|
||||||
listenerRouteChange((route) => {
|
listenerRouteChange((route) => {
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
updateOpened();
|
updateOpened();
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
function updateOpened() {
|
function updateOpened() {
|
||||||
@ -124,7 +124,7 @@
|
|||||||
isRemoveAllPopup,
|
isRemoveAllPopup,
|
||||||
sliceIndex,
|
sliceIndex,
|
||||||
level: 0,
|
level: 0,
|
||||||
props,
|
props: props as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
active.value = false;
|
active.value = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
return { getClass, prefixCls, getItemStyle, getCollapse, handleClickItem, showTooptip };
|
return { getClass, prefixCls, getItemStyle, getCollapse, handleClickItem, showTooptip };
|
||||||
|
@ -286,7 +286,7 @@
|
|||||||
if (props.name && Array.isArray(data)) {
|
if (props.name && Array.isArray(data)) {
|
||||||
state.opened = (data as (string | number)[]).includes(props.name);
|
state.opened = (data as (string | number)[]).includes(props.name);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
rootMenuEmitter.on('on-update-active-name:submenu', (data: number[]) => {
|
rootMenuEmitter.on('on-update-active-name:submenu', (data: number[]) => {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import type { InjectionKey, Ref } from 'vue';
|
import type { InjectionKey, Ref } from 'vue';
|
||||||
|
import type { Emitter } from '/@/utils/mitt';
|
||||||
import { createContext, useContext } from '/@/hooks/core/useContext';
|
import { createContext, useContext } from '/@/hooks/core/useContext';
|
||||||
import mitt from '/@/utils/mitt';
|
|
||||||
|
|
||||||
export interface SimpleRootMenuContextProps {
|
export interface SimpleRootMenuContextProps {
|
||||||
rootMenuEmitter: typeof mitt;
|
rootMenuEmitter: Emitter;
|
||||||
activeName: Ref<string | number>;
|
activeName: Ref<string | number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ export function useOpenKeys(
|
|||||||
menus: Ref<MenuType[]>,
|
menus: Ref<MenuType[]>,
|
||||||
accordion: Ref<boolean>,
|
accordion: Ref<boolean>,
|
||||||
mixSider: Ref<boolean>,
|
mixSider: Ref<boolean>,
|
||||||
collapse: Ref<boolean>
|
collapse: Ref<boolean>,
|
||||||
) {
|
) {
|
||||||
const debounceSetOpenKeys = useDebounceFn(setOpenKeys, 50);
|
const debounceSetOpenKeys = useDebounceFn(setOpenKeys, 50);
|
||||||
async function setOpenKeys(path: string) {
|
async function setOpenKeys(path: string) {
|
||||||
@ -38,7 +38,7 @@ export function useOpenKeys(
|
|||||||
menuState.activeSubMenuNames = menuState.openNames;
|
menuState.activeSubMenuNames = menuState.openNames;
|
||||||
},
|
},
|
||||||
30,
|
30,
|
||||||
native
|
native,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
>
|
>
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
</InputPassword>
|
</InputPassword>
|
||||||
<div :class="`${prefixCls}-bar`">
|
<div :class="`${prefixCls}-bar`">
|
||||||
@ -59,7 +59,7 @@
|
|||||||
() => unref(innerValueRef),
|
() => unref(innerValueRef),
|
||||||
(val) => {
|
(val) => {
|
||||||
emit('change', val);
|
emit('change', val);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
@advanced-change="redoHeight"
|
@advanced-change="redoHeight"
|
||||||
>
|
>
|
||||||
<template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
|
<template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
</BasicForm>
|
</BasicForm>
|
||||||
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
@change="handleTableChange"
|
@change="handleTableChange"
|
||||||
>
|
>
|
||||||
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
|
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
|
||||||
<slot :name="item" v-bind="data"></slot>
|
<slot :name="item" v-bind="data || {}"></slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #[`header-${column.dataIndex}`] v-for="column in columns" :key="column.dataIndex">
|
<template #[`header-${column.dataIndex}`] v-for="column in columns" :key="column.dataIndex">
|
||||||
@ -39,9 +39,10 @@
|
|||||||
ColumnChangeParam,
|
ColumnChangeParam,
|
||||||
} from './types/table';
|
} from './types/table';
|
||||||
|
|
||||||
import { defineComponent, ref, computed, unref, toRaw } from 'vue';
|
import { defineComponent, ref, computed, unref, toRaw, inject, watchEffect } from 'vue';
|
||||||
import { Table } from 'ant-design-vue';
|
import { Table } from 'ant-design-vue';
|
||||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
|
import { PageWrapperFixedHeightKey } from '/@/components/Page';
|
||||||
import expandIcon from './components/ExpandIcon';
|
import expandIcon from './components/ExpandIcon';
|
||||||
import HeaderCell from './components/HeaderCell.vue';
|
import HeaderCell from './components/HeaderCell.vue';
|
||||||
import { InnerHandlers } from './types/table';
|
import { InnerHandlers } from './types/table';
|
||||||
@ -64,6 +65,7 @@
|
|||||||
import { omit } from 'lodash-es';
|
import { omit } from 'lodash-es';
|
||||||
import { basicProps } from './props';
|
import { basicProps } from './props';
|
||||||
import { isFunction } from '/@/utils/is';
|
import { isFunction } from '/@/utils/is';
|
||||||
|
import { warn } from '/@/utils/log';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@ -91,10 +93,10 @@
|
|||||||
'columns-change',
|
'columns-change',
|
||||||
],
|
],
|
||||||
setup(props, { attrs, emit, slots, expose }) {
|
setup(props, { attrs, emit, slots, expose }) {
|
||||||
const tableElRef = ref<ComponentRef>(null);
|
const tableElRef = ref(null);
|
||||||
const tableData = ref<Recordable[]>([]);
|
const tableData = ref<Recordable[]>([]);
|
||||||
|
|
||||||
const wrapRef = ref<Nullable<HTMLDivElement>>(null);
|
const wrapRef = ref(null);
|
||||||
const innerPropsRef = ref<Partial<BasicTableProps>>();
|
const innerPropsRef = ref<Partial<BasicTableProps>>();
|
||||||
|
|
||||||
const { prefixCls } = useDesign('basic-table');
|
const { prefixCls } = useDesign('basic-table');
|
||||||
@ -104,6 +106,15 @@
|
|||||||
return { ...props, ...unref(innerPropsRef) } as BasicTableProps;
|
return { ...props, ...unref(innerPropsRef) } as BasicTableProps;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isFixedHeightPage = inject(PageWrapperFixedHeightKey, false);
|
||||||
|
watchEffect(() => {
|
||||||
|
unref(isFixedHeightPage) &&
|
||||||
|
props.canResize &&
|
||||||
|
warn(
|
||||||
|
"'canResize' of BasicTable may not work in PageWrapper with 'fixedHeight' (especially in hot updates)",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const { getLoading, setLoading } = useLoading(getProps);
|
const { getLoading, setLoading } = useLoading(getProps);
|
||||||
const {
|
const {
|
||||||
getPaginationInfo,
|
getPaginationInfo,
|
||||||
@ -127,6 +138,7 @@
|
|||||||
handleTableChange: onTableChange,
|
handleTableChange: onTableChange,
|
||||||
getDataSourceRef,
|
getDataSourceRef,
|
||||||
getDataSource,
|
getDataSource,
|
||||||
|
getRawDataSource,
|
||||||
setTableData,
|
setTableData,
|
||||||
updateTableDataRecord,
|
updateTableDataRecord,
|
||||||
findTableDataRecord,
|
findTableDataRecord,
|
||||||
@ -145,7 +157,7 @@
|
|||||||
getFieldsValue: formActions.getFieldsValue,
|
getFieldsValue: formActions.getFieldsValue,
|
||||||
clearSelectedRowKeys,
|
clearSelectedRowKeys,
|
||||||
},
|
},
|
||||||
emit
|
emit,
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleTableChange(...args) {
|
function handleTableChange(...args) {
|
||||||
@ -170,7 +182,7 @@
|
|||||||
tableElRef,
|
tableElRef,
|
||||||
getColumnsRef,
|
getColumnsRef,
|
||||||
getRowSelectionRef,
|
getRowSelectionRef,
|
||||||
getDataSourceRef
|
getDataSourceRef,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { customRow } = useCustomRow(getProps, {
|
const { customRow } = useCustomRow(getProps, {
|
||||||
@ -199,7 +211,7 @@
|
|||||||
getProps,
|
getProps,
|
||||||
getScrollRef,
|
getScrollRef,
|
||||||
tableElRef,
|
tableElRef,
|
||||||
getDataSourceRef
|
getDataSourceRef,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { getFormProps, replaceFormSlotKey, getFormSlotKeys, handleSearchInfoChange } =
|
const { getFormProps, replaceFormSlotKey, getFormSlotKeys, handleSearchInfoChange } =
|
||||||
@ -273,6 +285,7 @@
|
|||||||
setColumns,
|
setColumns,
|
||||||
setLoading,
|
setLoading,
|
||||||
getDataSource,
|
getDataSource,
|
||||||
|
getRawDataSource,
|
||||||
setProps,
|
setProps,
|
||||||
getRowSelection,
|
getRowSelection,
|
||||||
getPaginationRef: getPagination,
|
getPaginationRef: getPagination,
|
||||||
@ -307,7 +320,7 @@
|
|||||||
wrapRef,
|
wrapRef,
|
||||||
tableAction,
|
tableAction,
|
||||||
redoHeight,
|
redoHeight,
|
||||||
getFormProps,
|
getFormProps: getFormProps as any,
|
||||||
replaceFormSlotKey,
|
replaceFormSlotKey,
|
||||||
getFormSlotKeys,
|
getFormSlotKeys,
|
||||||
getWrapperClass,
|
getWrapperClass,
|
||||||
@ -378,9 +391,9 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-table-tbody > tr.ant-table-row-selected td {
|
//.ant-table-tbody > tr.ant-table-row-selected td {
|
||||||
background-color: fade(@primary-color, 8%) !important;
|
//background-color: fade(@primary-color, 8%) !important;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-pagination {
|
.ant-pagination {
|
||||||
@ -400,7 +413,7 @@
|
|||||||
|
|
||||||
.ant-table-body {
|
.ant-table-body {
|
||||||
overflow-x: hidden !important;
|
overflow-x: hidden !important;
|
||||||
overflow-y: scroll !important;
|
// overflow-y: scroll !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
.map((action) => {
|
.map((action) => {
|
||||||
const { popConfirm } = action;
|
const { popConfirm } = action;
|
||||||
return {
|
return {
|
||||||
getPopupContainer: () => unref(table?.wrapRef.value) ?? document.body,
|
getPopupContainer: () => unref((table as any)?.wrapRef.value) ?? document.body,
|
||||||
type: 'link',
|
type: 'link',
|
||||||
size: 'small',
|
size: 'small',
|
||||||
...action,
|
...action,
|
||||||
@ -107,7 +107,7 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const getDropdownList = computed(() => {
|
const getDropdownList = computed((): any[] => {
|
||||||
return (toRaw(props.dropDownActions) || [])
|
return (toRaw(props.dropDownActions) || [])
|
||||||
.filter((action) => {
|
.filter((action) => {
|
||||||
return hasPermission(action.auth) && isIfShow(action);
|
return hasPermission(action.auth) && isIfShow(action);
|
||||||
@ -133,7 +133,7 @@
|
|||||||
|
|
||||||
function getTooltip(data: string | TooltipProps): TooltipProps {
|
function getTooltip(data: string | TooltipProps): TooltipProps {
|
||||||
return {
|
return {
|
||||||
getPopupContainer: () => unref(table?.wrapRef.value) ?? document.body,
|
getPopupContainer: () => unref((table as any)?.wrapRef.value) ?? document.body,
|
||||||
placement: 'bottom',
|
placement: 'bottom',
|
||||||
...(isString(data) ? { title: data } : data),
|
...(isString(data) ? { title: data } : data),
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<template v-for="(img, index) in imgList" :key="img">
|
<template v-for="(img, index) in imgList" :key="img">
|
||||||
<Image
|
<Image
|
||||||
:width="size"
|
:width="size"
|
||||||
:style="{ 'margin-left': index === 0 ? 0 : margin }"
|
:style="{ marginLeft: index === 0 ? 0 : margin }"
|
||||||
:src="srcPrefix + img"
|
:src="srcPrefix + img"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -21,7 +21,7 @@ export const CellComponent: FunctionalComponent = (
|
|||||||
popoverVisible,
|
popoverVisible,
|
||||||
getPopupContainer,
|
getPopupContainer,
|
||||||
}: ComponentProps,
|
}: ComponentProps,
|
||||||
{ attrs }
|
{ attrs },
|
||||||
) => {
|
) => {
|
||||||
const Comp = componentMap.get(component) as typeof defineComponent;
|
const Comp = componentMap.get(component) as typeof defineComponent;
|
||||||
|
|
||||||
@ -39,6 +39,6 @@ export const CellComponent: FunctionalComponent = (
|
|||||||
{
|
{
|
||||||
default: () => DefaultComp,
|
default: () => DefaultComp,
|
||||||
content: () => ruleMessage,
|
content: () => ruleMessage,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -5,41 +5,41 @@
|
|||||||
:class="{ [`${prefixCls}__normal`]: true, 'ellipsis-cell': column.ellipsis }"
|
:class="{ [`${prefixCls}__normal`]: true, 'ellipsis-cell': column.ellipsis }"
|
||||||
@click="handleEdit"
|
@click="handleEdit"
|
||||||
>
|
>
|
||||||
<div class="cell-content" :title="column.ellipsis ? getValues || '' : ''">{{
|
<div class="cell-content" :title="column.ellipsis ? getValues ?? '' : ''">
|
||||||
getValues || ' '
|
{{ getValues ? getValues : ' ' }}
|
||||||
}}</div>
|
</div>
|
||||||
<FormOutlined :class="`${prefixCls}__normal-icon`" v-if="!column.editRow" />
|
<FormOutlined :class="`${prefixCls}__normal-icon`" v-if="!column.editRow" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isEdit" :class="`${prefixCls}__wrapper`" v-click-outside="onClickOutside">
|
<a-spin v-if="isEdit" :spinning="spinning">
|
||||||
<CellComponent
|
<div :class="`${prefixCls}__wrapper`" v-click-outside="onClickOutside">
|
||||||
v-bind="getComponentProps"
|
<CellComponent
|
||||||
:component="getComponent"
|
v-bind="getComponentProps"
|
||||||
:style="getWrapperStyle"
|
:component="getComponent"
|
||||||
:popoverVisible="getRuleVisible"
|
:style="getWrapperStyle"
|
||||||
:rule="getRule"
|
:popoverVisible="getRuleVisible"
|
||||||
:ruleMessage="ruleMessage"
|
:rule="getRule"
|
||||||
:class="getWrapperClass"
|
:ruleMessage="ruleMessage"
|
||||||
size="small"
|
:class="getWrapperClass"
|
||||||
ref="elRef"
|
ref="elRef"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
@options-change="handleOptionsChange"
|
@options-change="handleOptionsChange"
|
||||||
@pressEnter="handleEnter"
|
@pressEnter="handleEnter"
|
||||||
/>
|
/>
|
||||||
<div :class="`${prefixCls}__action`" v-if="!getRowEditable">
|
<div :class="`${prefixCls}__action`" v-if="!getRowEditable">
|
||||||
<CheckOutlined :class="[`${prefixCls}__icon`, 'mx-2']" @click="handleSubmit" />
|
<CheckOutlined :class="[`${prefixCls}__icon`, 'mx-2']" @click="handleSubmitClick" />
|
||||||
<CloseOutlined :class="`${prefixCls}__icon `" @click="handleCancel" />
|
<CloseOutlined :class="`${prefixCls}__icon `" @click="handleCancel" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</a-spin>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { CSSProperties, PropType } from 'vue';
|
import type { CSSProperties, PropType } from 'vue';
|
||||||
|
import { computed, defineComponent, nextTick, ref, toRaw, unref, watchEffect } from 'vue';
|
||||||
import type { BasicColumn } from '../../types/table';
|
import type { BasicColumn } from '../../types/table';
|
||||||
import type { EditRecordRow } from './index';
|
import type { EditRecordRow } from './index';
|
||||||
|
import { CheckOutlined, CloseOutlined, FormOutlined } from '@ant-design/icons-vue';
|
||||||
import { defineComponent, ref, unref, nextTick, computed, watchEffect, toRaw } from 'vue';
|
|
||||||
import { FormOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons-vue';
|
|
||||||
import { CellComponent } from './CellComponent';
|
import { CellComponent } from './CellComponent';
|
||||||
|
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
@ -48,14 +48,15 @@
|
|||||||
import clickOutside from '/@/directives/clickOutside';
|
import clickOutside from '/@/directives/clickOutside';
|
||||||
|
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
import { isString, isBoolean, isFunction, isNumber, isArray } from '/@/utils/is';
|
import { isArray, isBoolean, isFunction, isNumber, isString } from '/@/utils/is';
|
||||||
import { createPlaceholderMessage } from './helper';
|
import { createPlaceholderMessage } from './helper';
|
||||||
import { set, omit } from 'lodash-es';
|
import { omit, pick, set } from 'lodash-es';
|
||||||
import { treeToList } from '/@/utils/helper/treeHelper';
|
import { treeToList } from '/@/utils/helper/treeHelper';
|
||||||
|
import { Spin } from 'ant-design-vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'EditableCell',
|
name: 'EditableCell',
|
||||||
components: { FormOutlined, CloseOutlined, CheckOutlined, CellComponent },
|
components: { FormOutlined, CloseOutlined, CheckOutlined, CellComponent, ASpin: Spin },
|
||||||
directives: {
|
directives: {
|
||||||
clickOutside,
|
clickOutside,
|
||||||
},
|
},
|
||||||
@ -82,6 +83,7 @@
|
|||||||
const optionsRef = ref<LabelValueOptions>([]);
|
const optionsRef = ref<LabelValueOptions>([]);
|
||||||
const currentValueRef = ref<any>(props.value);
|
const currentValueRef = ref<any>(props.value);
|
||||||
const defaultValueRef = ref<any>(props.value);
|
const defaultValueRef = ref<any>(props.value);
|
||||||
|
const spinning = ref<boolean>(false);
|
||||||
|
|
||||||
const { prefixCls } = useDesign('editable-cell');
|
const { prefixCls } = useDesign('editable-cell');
|
||||||
|
|
||||||
@ -113,6 +115,7 @@
|
|||||||
const value = isCheckValue ? (isNumber(val) && isBoolean(val) ? val : !!val) : val;
|
const value = isCheckValue ? (isNumber(val) && isBoolean(val) ? val : !!val) : val;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
size: 'small',
|
||||||
getPopupContainer: () => unref(table?.wrapRef.value) ?? document.body,
|
getPopupContainer: () => unref(table?.wrapRef.value) ?? document.body,
|
||||||
getCalendarContainer: () => unref(table?.wrapRef.value) ?? document.body,
|
getCalendarContainer: () => unref(table?.wrapRef.value) ?? document.body,
|
||||||
placeholder: createPlaceholderMessage(unref(getComponent)),
|
placeholder: createPlaceholderMessage(unref(getComponent)),
|
||||||
@ -214,8 +217,7 @@
|
|||||||
if (isBoolean(editRule) && !currentValue && !isNumber(currentValue)) {
|
if (isBoolean(editRule) && !currentValue && !isNumber(currentValue)) {
|
||||||
ruleVisible.value = true;
|
ruleVisible.value = true;
|
||||||
const component = unref(getComponent);
|
const component = unref(getComponent);
|
||||||
const message = createPlaceholderMessage(component);
|
ruleMessage.value = createPlaceholderMessage(component);
|
||||||
ruleMessage.value = message;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isFunction(editRule)) {
|
if (isFunction(editRule)) {
|
||||||
@ -248,6 +250,35 @@
|
|||||||
|
|
||||||
const dataKey = (dataIndex || key) as string;
|
const dataKey = (dataIndex || key) as string;
|
||||||
|
|
||||||
|
if (!record.editable) {
|
||||||
|
const { getBindValues } = table;
|
||||||
|
|
||||||
|
const { beforeEditSubmit, columns } = unref(getBindValues);
|
||||||
|
|
||||||
|
if (beforeEditSubmit && isFunction(beforeEditSubmit)) {
|
||||||
|
spinning.value = true;
|
||||||
|
const keys: string[] = columns
|
||||||
|
.map((_column) => _column.dataIndex)
|
||||||
|
.filter((field) => !!field) as string[];
|
||||||
|
let result: any = true;
|
||||||
|
try {
|
||||||
|
result = await beforeEditSubmit({
|
||||||
|
record: pick(record, keys),
|
||||||
|
index,
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
result = false;
|
||||||
|
} finally {
|
||||||
|
spinning.value = false;
|
||||||
|
}
|
||||||
|
if (result === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set(record, dataKey, value);
|
set(record, dataKey, value);
|
||||||
//const record = await table.updateTableData(index, dataKey, value);
|
//const record = await table.updateTableData(index, dataKey, value);
|
||||||
needEmit && table.emit?.('edit-end', { record, index, key, value });
|
needEmit && table.emit?.('edit-end', { record, index, key, value });
|
||||||
@ -261,6 +292,10 @@
|
|||||||
handleSubmit();
|
handleSubmit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSubmitClick() {
|
||||||
|
handleSubmit();
|
||||||
|
}
|
||||||
|
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
isEdit.value = false;
|
isEdit.value = false;
|
||||||
currentValueRef.value = defaultValueRef.value;
|
currentValueRef.value = defaultValueRef.value;
|
||||||
@ -365,7 +400,8 @@
|
|||||||
getRowEditable,
|
getRowEditable,
|
||||||
getValues,
|
getValues,
|
||||||
handleEnter,
|
handleEnter,
|
||||||
// getSize,
|
handleSubmitClick,
|
||||||
|
spinning,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -282,7 +282,7 @@
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const columnListEl = unref(columnListRef);
|
const columnListEl = unref(columnListRef);
|
||||||
if (!columnListEl) return;
|
if (!columnListEl) return;
|
||||||
const el = columnListEl.$el;
|
const el = columnListEl.$el as any;
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
// Drag and drop sort
|
// Drag and drop sort
|
||||||
const { initSortable } = useSortable(el, {
|
const { initSortable } = useSortable(el, {
|
||||||
@ -351,7 +351,7 @@
|
|||||||
const visible =
|
const visible =
|
||||||
columns.findIndex(
|
columns.findIndex(
|
||||||
(c: BasicColumn | string) =>
|
(c: BasicColumn | string) =>
|
||||||
c === col.value || (typeof c !== 'string' && c.dataIndex === col.value)
|
c === col.value || (typeof c !== 'string' && c.dataIndex === col.value),
|
||||||
) !== -1;
|
) !== -1;
|
||||||
return { dataIndex: col.value, fixed: col.fixed, visible };
|
return { dataIndex: col.value, fixed: col.fixed, visible };
|
||||||
});
|
});
|
||||||
|
@ -40,7 +40,7 @@ function handleChildren(children: BasicColumn[] | undefined, ellipsis: boolean)
|
|||||||
function handleIndexColumn(
|
function handleIndexColumn(
|
||||||
propsRef: ComputedRef<BasicTableProps>,
|
propsRef: ComputedRef<BasicTableProps>,
|
||||||
getPaginationRef: ComputedRef<boolean | PaginationProps>,
|
getPaginationRef: ComputedRef<boolean | PaginationProps>,
|
||||||
columns: BasicColumn[]
|
columns: BasicColumn[],
|
||||||
) {
|
) {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ function handleActionColumn(propsRef: ComputedRef<BasicTableProps>, columns: Bas
|
|||||||
|
|
||||||
export function useColumns(
|
export function useColumns(
|
||||||
propsRef: ComputedRef<BasicTableProps>,
|
propsRef: ComputedRef<BasicTableProps>,
|
||||||
getPaginationRef: ComputedRef<boolean | PaginationProps>
|
getPaginationRef: ComputedRef<boolean | PaginationProps>,
|
||||||
) {
|
) {
|
||||||
const columnsRef = ref(unref(propsRef).columns) as unknown as Ref<BasicColumn[]>;
|
const columnsRef = ref(unref(propsRef).columns) as unknown as Ref<BasicColumn[]>;
|
||||||
let cacheColumns = unref(propsRef).columns;
|
let cacheColumns = unref(propsRef).columns;
|
||||||
@ -122,7 +122,7 @@ export function useColumns(
|
|||||||
|
|
||||||
handleItem(
|
handleItem(
|
||||||
item,
|
item,
|
||||||
Reflect.has(item, 'ellipsis') ? !!item.ellipsis : !!ellipsis && !customRender && !slots
|
Reflect.has(item, 'ellipsis') ? !!item.ellipsis : !!ellipsis && !customRender && !slots,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
return columns;
|
return columns;
|
||||||
@ -179,7 +179,7 @@ export function useColumns(
|
|||||||
(columns) => {
|
(columns) => {
|
||||||
columnsRef.value = columns;
|
columnsRef.value = columns;
|
||||||
cacheColumns = columns?.filter((item) => !item.flag) ?? [];
|
cacheColumns = columns?.filter((item) => !item.flag) ?? [];
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
function setCacheColumnsByField(dataIndex: string | undefined, value: Partial<BasicColumn>) {
|
function setCacheColumnsByField(dataIndex: string | undefined, value: Partial<BasicColumn>) {
|
||||||
@ -288,7 +288,7 @@ function sortFixedColumn(columns: BasicColumn[]) {
|
|||||||
defColumns.push(column);
|
defColumns.push(column);
|
||||||
}
|
}
|
||||||
return [...fixedLeftColumns, ...defColumns, ...fixedRightColumns].filter(
|
return [...fixedLeftColumns, ...defColumns, ...fixedRightColumns].filter(
|
||||||
(item) => !item.defaultHidden
|
(item) => !item.defaultHidden,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ interface Options {
|
|||||||
function getKey(
|
function getKey(
|
||||||
record: Recordable,
|
record: Recordable,
|
||||||
rowKey: string | ((record: Record<string, any>) => string) | undefined,
|
rowKey: string | ((record: Record<string, any>) => string) | undefined,
|
||||||
autoCreateKey?: boolean
|
autoCreateKey?: boolean,
|
||||||
) {
|
) {
|
||||||
if (!rowKey || autoCreateKey) {
|
if (!rowKey || autoCreateKey) {
|
||||||
return record[ROW_KEY];
|
return record[ROW_KEY];
|
||||||
@ -31,7 +31,7 @@ function getKey(
|
|||||||
|
|
||||||
export function useCustomRow(
|
export function useCustomRow(
|
||||||
propsRef: ComputedRef<BasicTableProps>,
|
propsRef: ComputedRef<BasicTableProps>,
|
||||||
{ setSelectedRowKeys, getSelectRowKeys, getAutoCreateKey, clearSelectedRowKeys, emit }: Options
|
{ setSelectedRowKeys, getSelectRowKeys, getAutoCreateKey, clearSelectedRowKeys, emit }: Options,
|
||||||
) {
|
) {
|
||||||
const customRow = (record: Recordable, index: number) => {
|
const customRow = (record: Recordable, index: number) => {
|
||||||
return {
|
return {
|
||||||
|
@ -40,13 +40,14 @@ export function useDataSource(
|
|||||||
clearSelectedRowKeys,
|
clearSelectedRowKeys,
|
||||||
tableData,
|
tableData,
|
||||||
}: ActionType,
|
}: ActionType,
|
||||||
emit: EmitType
|
emit: EmitType,
|
||||||
) {
|
) {
|
||||||
const searchState = reactive<SearchState>({
|
const searchState = reactive<SearchState>({
|
||||||
sortInfo: {},
|
sortInfo: {},
|
||||||
filterInfo: {},
|
filterInfo: {},
|
||||||
});
|
});
|
||||||
const dataSourceRef = ref<Recordable[]>([]);
|
const dataSourceRef = ref<Recordable[]>([]);
|
||||||
|
const rawDataSourceRef = ref<Recordable>({});
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
tableData.value = unref(dataSourceRef);
|
tableData.value = unref(dataSourceRef);
|
||||||
@ -60,13 +61,13 @@ export function useDataSource(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleTableChange(
|
function handleTableChange(
|
||||||
pagination: PaginationProps,
|
pagination: PaginationProps,
|
||||||
filters: Partial<Recordable<string[]>>,
|
filters: Partial<Recordable<string[]>>,
|
||||||
sorter: SorterResult
|
sorter: SorterResult,
|
||||||
) {
|
) {
|
||||||
const { clearSelectOnPageChange, sortFn, filterFn } = unref(propsRef);
|
const { clearSelectOnPageChange, sortFn, filterFn } = unref(propsRef);
|
||||||
if (clearSelectOnPageChange) {
|
if (clearSelectOnPageChange) {
|
||||||
@ -147,7 +148,7 @@ export function useDataSource(
|
|||||||
|
|
||||||
function updateTableDataRecord(
|
function updateTableDataRecord(
|
||||||
rowKey: string | number,
|
rowKey: string | number,
|
||||||
record: Recordable
|
record: Recordable,
|
||||||
): Recordable | undefined {
|
): Recordable | undefined {
|
||||||
const row = findTableDataRecord(rowKey);
|
const row = findTableDataRecord(rowKey);
|
||||||
|
|
||||||
@ -205,7 +206,7 @@ export function useDataSource(
|
|||||||
const { pageField, sizeField, listField, totalField } = Object.assign(
|
const { pageField, sizeField, listField, totalField } = Object.assign(
|
||||||
{},
|
{},
|
||||||
FETCH_SETTING,
|
FETCH_SETTING,
|
||||||
fetchSetting
|
fetchSetting,
|
||||||
);
|
);
|
||||||
let pageParams: Recordable = {};
|
let pageParams: Recordable = {};
|
||||||
|
|
||||||
@ -235,6 +236,7 @@ export function useDataSource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const res = await api(params);
|
const res = await api(params);
|
||||||
|
rawDataSourceRef.value = res;
|
||||||
|
|
||||||
const isArrayResult = Array.isArray(res);
|
const isArrayResult = Array.isArray(res);
|
||||||
|
|
||||||
@ -287,6 +289,10 @@ export function useDataSource(
|
|||||||
return getDataSourceRef.value as T[];
|
return getDataSourceRef.value as T[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRawDataSource<T = Recordable>() {
|
||||||
|
return rawDataSourceRef.value as T;
|
||||||
|
}
|
||||||
|
|
||||||
async function reload(opt?: FetchParams) {
|
async function reload(opt?: FetchParams) {
|
||||||
await fetch(opt);
|
await fetch(opt);
|
||||||
}
|
}
|
||||||
@ -300,6 +306,7 @@ export function useDataSource(
|
|||||||
return {
|
return {
|
||||||
getDataSourceRef,
|
getDataSourceRef,
|
||||||
getDataSource,
|
getDataSource,
|
||||||
|
getRawDataSource,
|
||||||
getRowKey,
|
getRowKey,
|
||||||
setTableData,
|
setTableData,
|
||||||
getAutoCreateKey,
|
getAutoCreateKey,
|
||||||
|
@ -8,7 +8,7 @@ export function useLoading(props: ComputedRef<BasicTableProps>) {
|
|||||||
() => unref(props).loading,
|
() => unref(props).loading,
|
||||||
(loading) => {
|
(loading) => {
|
||||||
loadingRef.value = loading;
|
loadingRef.value = loading;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const getLoading = computed(() => unref(loadingRef));
|
const getLoading = computed(() => unref(loadingRef));
|
||||||
|
@ -8,7 +8,7 @@ import { findNodeAll } from '/@/utils/helper/treeHelper';
|
|||||||
export function useRowSelection(
|
export function useRowSelection(
|
||||||
propsRef: ComputedRef<BasicTableProps>,
|
propsRef: ComputedRef<BasicTableProps>,
|
||||||
tableData: Ref<Recordable[]>,
|
tableData: Ref<Recordable[]>,
|
||||||
emit: EmitType
|
emit: EmitType,
|
||||||
) {
|
) {
|
||||||
const selectedRowKeysRef = ref<string[]>([]);
|
const selectedRowKeysRef = ref<string[]>([]);
|
||||||
const selectedRowRef = ref<Recordable[]>([]);
|
const selectedRowRef = ref<Recordable[]>([]);
|
||||||
@ -35,7 +35,7 @@ export function useRowSelection(
|
|||||||
() => unref(propsRef).rowSelection?.selectedRowKeys,
|
() => unref(propsRef).rowSelection?.selectedRowKeys,
|
||||||
(v: string[]) => {
|
(v: string[]) => {
|
||||||
setSelectedRowKeys(v);
|
setSelectedRowKeys(v);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -52,7 +52,8 @@ export function useRowSelection(
|
|||||||
rows: getSelectRows(),
|
rows: getSelectRows(),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
{ deep: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
const getAutoCreateKey = computed(() => {
|
const getAutoCreateKey = computed(() => {
|
||||||
@ -66,13 +67,19 @@ export function useRowSelection(
|
|||||||
|
|
||||||
function setSelectedRowKeys(rowKeys: string[]) {
|
function setSelectedRowKeys(rowKeys: string[]) {
|
||||||
selectedRowKeysRef.value = rowKeys;
|
selectedRowKeysRef.value = rowKeys;
|
||||||
selectedRowRef.value = findNodeAll(
|
const allSelectedRows = findNodeAll(
|
||||||
toRaw(unref(tableData)),
|
toRaw(unref(tableData)).concat(toRaw(unref(selectedRowRef))),
|
||||||
(item) => rowKeys.includes(item[unref(getRowKey) as string]),
|
(item) => rowKeys.includes(item[unref(getRowKey) as string]),
|
||||||
{
|
{
|
||||||
children: propsRef.value.childrenColumnName ?? 'children',
|
children: propsRef.value.childrenColumnName ?? 'children',
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
const trueSelectedRows: any[] = [];
|
||||||
|
rowKeys.forEach((key: string) => {
|
||||||
|
const found = allSelectedRows.find((item) => item[unref(getRowKey) as string] === key);
|
||||||
|
found && trueSelectedRows.push(found);
|
||||||
|
});
|
||||||
|
selectedRowRef.value = trueSelectedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSelectedRows(rows: Recordable[]) {
|
function setSelectedRows(rows: Recordable[]) {
|
||||||
|
@ -18,7 +18,7 @@ export function useTable(tableProps?: Props): [
|
|||||||
(instance: TableActionType, formInstance: UseTableMethod) => void,
|
(instance: TableActionType, formInstance: UseTableMethod) => void,
|
||||||
TableActionType & {
|
TableActionType & {
|
||||||
getForm: () => FormActionType;
|
getForm: () => FormActionType;
|
||||||
}
|
},
|
||||||
] {
|
] {
|
||||||
const tableRef = ref<Nullable<TableActionType>>(null);
|
const tableRef = ref<Nullable<TableActionType>>(null);
|
||||||
const loadedRef = ref<Nullable<boolean>>(false);
|
const loadedRef = ref<Nullable<boolean>>(false);
|
||||||
@ -50,7 +50,7 @@ export function useTable(tableProps?: Props): [
|
|||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true,
|
deep: true,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ export function useTable(tableProps?: Props): [
|
|||||||
const table = unref(tableRef);
|
const table = unref(tableRef);
|
||||||
if (!table) {
|
if (!table) {
|
||||||
error(
|
error(
|
||||||
'The table instance has not been obtained yet, please make sure the table is presented when performing the table operation!'
|
'The table instance has not been obtained yet, please make sure the table is presented when performing the table operation!',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return table as TableActionType;
|
return table as TableActionType;
|
||||||
@ -82,6 +82,9 @@ export function useTable(tableProps?: Props): [
|
|||||||
getDataSource: () => {
|
getDataSource: () => {
|
||||||
return getTableInstance().getDataSource();
|
return getTableInstance().getDataSource();
|
||||||
},
|
},
|
||||||
|
getRawDataSource: () => {
|
||||||
|
return getTableInstance().getRawDataSource();
|
||||||
|
},
|
||||||
getColumns: ({ ignoreIndex = false }: { ignoreIndex?: boolean } = {}) => {
|
getColumns: ({ ignoreIndex = false }: { ignoreIndex?: boolean } = {}) => {
|
||||||
const columns = getTableInstance().getColumns({ ignoreIndex }) || [];
|
const columns = getTableInstance().getColumns({ ignoreIndex }) || [];
|
||||||
return toRaw(columns);
|
return toRaw(columns);
|
||||||
|
@ -6,7 +6,7 @@ import { ROW_KEY } from '../const';
|
|||||||
export function useTableExpand(
|
export function useTableExpand(
|
||||||
propsRef: ComputedRef<BasicTableProps>,
|
propsRef: ComputedRef<BasicTableProps>,
|
||||||
tableData: Ref<Recordable[]>,
|
tableData: Ref<Recordable[]>,
|
||||||
emit: EmitType
|
emit: EmitType,
|
||||||
) {
|
) {
|
||||||
const expandedRowKeys = ref<string[]>([]);
|
const expandedRowKeys = ref<string[]>([]);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ export function useTableFooter(
|
|||||||
scrollToFirstRowOnChange: boolean;
|
scrollToFirstRowOnChange: boolean;
|
||||||
}>,
|
}>,
|
||||||
tableElRef: Ref<ComponentRef>,
|
tableElRef: Ref<ComponentRef>,
|
||||||
getDataSourceRef: ComputedRef<Recordable>
|
getDataSourceRef: ComputedRef<Recordable>,
|
||||||
) {
|
) {
|
||||||
const getIsEmptyData = computed(() => {
|
const getIsEmptyData = computed(() => {
|
||||||
return (unref(getDataSourceRef) || []).length === 0;
|
return (unref(getDataSourceRef) || []).length === 0;
|
||||||
@ -43,7 +43,7 @@ export function useTableFooter(
|
|||||||
name: 'scroll',
|
name: 'scroll',
|
||||||
listener: () => {
|
listener: () => {
|
||||||
const footerBodyDom = tableEl.$el.querySelector(
|
const footerBodyDom = tableEl.$el.querySelector(
|
||||||
'.ant-table-footer .ant-table-body'
|
'.ant-table-footer .ant-table-body',
|
||||||
) as HTMLDivElement;
|
) as HTMLDivElement;
|
||||||
if (!footerBodyDom || !bodyDom) return;
|
if (!footerBodyDom || !bodyDom) return;
|
||||||
footerBodyDom.scrollLeft = bodyDom.scrollLeft;
|
footerBodyDom.scrollLeft = bodyDom.scrollLeft;
|
||||||
|
@ -8,7 +8,7 @@ export function useTableForm(
|
|||||||
propsRef: ComputedRef<BasicTableProps>,
|
propsRef: ComputedRef<BasicTableProps>,
|
||||||
slots: Slots,
|
slots: Slots,
|
||||||
fetch: (opt?: FetchParams | undefined) => Promise<void>,
|
fetch: (opt?: FetchParams | undefined) => Promise<void>,
|
||||||
getLoading: ComputedRef<boolean | undefined>
|
getLoading: ComputedRef<boolean | undefined>,
|
||||||
) {
|
) {
|
||||||
const getFormProps = computed((): Partial<FormProps> => {
|
const getFormProps = computed((): Partial<FormProps> => {
|
||||||
const { formConfig } = unref(propsRef);
|
const { formConfig } = unref(propsRef);
|
||||||
@ -21,9 +21,11 @@ export function useTableForm(
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const getFormSlotKeys = computed(() => {
|
const getFormSlotKeys: ComputedRef<string[]> = computed(() => {
|
||||||
const keys = Object.keys(slots);
|
const keys = Object.keys(slots);
|
||||||
return keys.map((item) => (item.startsWith('form-') ? item : null)).filter(Boolean);
|
return keys
|
||||||
|
.map((item) => (item.startsWith('form-') ? item : null))
|
||||||
|
.filter((item) => !!item) as string[];
|
||||||
});
|
});
|
||||||
|
|
||||||
function replaceFormSlotKey(key: string) {
|
function replaceFormSlotKey(key: string) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user