diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5b1a804 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +# 告诉EditorConfig插件,这是根文件,不用继续往上查找 +root = true + +# 匹配全部文件 +[*] +# 缩进风格,可选space、tab +indent_style = space +# 缩进的空格数 +indent_size = 2 +# 设置字符集 +charset = utf-8 +# 结尾换行符,可选lf、cr、crlf +end_of_line = lf +# 在文件结尾插入新行 +trim_trailing_whitespace = true +# 删除一行中的前后空格 +insert_final_newline = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..4a3b88c --- /dev/null +++ b/.env.development @@ -0,0 +1,35 @@ +# 页面标题 +VITE_APP_TITLE = 鱼测云后台管理系统 + +# 开发环境配置 +VITE_APP_ENV = 'development' + +# 开发环境 +VITE_APP_BASE_API = '/dev-api' + +# 应用访问路径 例如使用前缀 /admin/ +VITE_APP_CONTEXT_PATH = '/' + +# 监控地址 +VITE_APP_MONITOR_ADMIN = 'http://localhost:9090/admin/applications' + +# SnailJob 控制台地址 +VITE_APP_SNAILJOB_ADMIN = 'http://localhost:8800/snail-job' + +VITE_APP_PORT = 80 + +# 接口加密功能开关(如需关闭 后端也必须对应关闭) +VITE_APP_ENCRYPT = true +# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换 +VITE_APP_RSA_PUBLIC_KEY = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==' +# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换 +VITE_APP_RSA_PRIVATE_KEY = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE=' + +# 客户端id +VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e' + +# websocket 开关 默认使用sse推送 +VITE_APP_WEBSOCKET = false + +# sse 开关 +VITE_APP_SSE = true diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..1109bc6 --- /dev/null +++ b/.env.production @@ -0,0 +1,38 @@ +# 页面标题 +VITE_APP_TITLE = RuoYi-Vue-Plus多租户管理系统 + +# 生产环境配置 +VITE_APP_ENV = 'production' + +# 应用访问路径 例如使用前缀 /admin/ +VITE_APP_CONTEXT_PATH = '/' + +# 监控地址 +VITE_APP_MONITOR_ADMIN = '/admin/applications' + +# SnailJob 控制台地址 +VITE_APP_SNAILJOB_ADMIN = '/snail-job' + +# 生产环境 +VITE_APP_BASE_API = '/prod-api' + +# 是否在打包时开启压缩,支持 gzip 和 brotli +VITE_BUILD_COMPRESS = gzip + +VITE_APP_PORT = 80 + +# 接口加密功能开关(如需关闭 后端也必须对应关闭) +VITE_APP_ENCRYPT = true +# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换 +VITE_APP_RSA_PUBLIC_KEY = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==' +# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换 +VITE_APP_RSA_PRIVATE_KEY = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE=' + +# 客户端id +VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e' + +# websocket 开关 默认使用sse推送 +VITE_APP_WEBSOCKET = false + +# sse 开关 +VITE_APP_SSE = true diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json new file mode 100644 index 0000000..cb7058a --- /dev/null +++ b/.eslintrc-auto-import.json @@ -0,0 +1,323 @@ +{ + "globals": { + "Component": true, + "ComponentPublicInstance": true, + "ComputedRef": true, + "DirectiveBinding": true, + "EffectScope": true, + "ElLoading": true, + "ElMessage": true, + "ElMessageBox": true, + "ElNotification": true, + "ExtractDefaultPropTypes": true, + "ExtractPropTypes": true, + "ExtractPublicPropTypes": true, + "InjectionKey": true, + "MaybeRef": true, + "MaybeRefOrGetter": true, + "PropType": true, + "Ref": true, + "VNode": true, + "WritableComputedRef": true, + "acceptHMRUpdate": true, + "asyncComputed": true, + "autoResetRef": true, + "computed": true, + "computedAsync": true, + "computedEager": true, + "computedInject": true, + "computedWithControl": true, + "controlledComputed": true, + "controlledRef": true, + "createApp": true, + "createEventHook": true, + "createGlobalState": true, + "createInjectionState": true, + "createPinia": true, + "createReactiveFn": true, + "createReusableTemplate": true, + "createSharedComposable": true, + "createTemplatePromise": true, + "createUnrefFn": true, + "customRef": true, + "debouncedRef": true, + "debouncedWatch": true, + "defineAsyncComponent": true, + "defineComponent": true, + "defineStore": true, + "eagerComputed": true, + "effectScope": true, + "extendRef": true, + "getActivePinia": true, + "getCurrentInstance": true, + "getCurrentScope": true, + "h": true, + "ignorableWatch": true, + "inject": true, + "injectLocal": true, + "isDefined": true, + "isProxy": true, + "isReactive": true, + "isReadonly": true, + "isRef": true, + "makeDestructurable": true, + "mapActions": true, + "mapGetters": true, + "mapState": true, + "mapStores": true, + "mapWritableState": true, + "markRaw": true, + "nextTick": true, + "onActivated": true, + "onBeforeMount": true, + "onBeforeRouteLeave": true, + "onBeforeRouteUpdate": true, + "onBeforeUnmount": true, + "onBeforeUpdate": true, + "onClickOutside": true, + "onDeactivated": true, + "onElementRemoval": true, + "onErrorCaptured": true, + "onKeyStroke": true, + "onLongPress": true, + "onMounted": true, + "onRenderTracked": true, + "onRenderTriggered": true, + "onScopeDispose": true, + "onServerPrefetch": true, + "onStartTyping": true, + "onUnmounted": true, + "onUpdated": true, + "onWatcherCleanup": true, + "pausableWatch": true, + "provide": true, + "provideLocal": true, + "reactify": true, + "reactifyObject": true, + "reactive": true, + "reactiveComputed": true, + "reactiveOmit": true, + "reactivePick": true, + "readonly": true, + "ref": true, + "refAutoReset": true, + "refDebounced": true, + "refDefault": true, + "refThrottled": true, + "refWithControl": true, + "resolveComponent": true, + "resolveRef": true, + "resolveUnref": true, + "setActivePinia": true, + "setMapStoreSuffix": true, + "shallowReactive": true, + "shallowReadonly": true, + "shallowRef": true, + "storeToRefs": true, + "syncRef": true, + "syncRefs": true, + "templateRef": true, + "throttledRef": true, + "throttledWatch": true, + "toRaw": true, + "toReactive": true, + "toRef": true, + "toRefs": true, + "toValue": true, + "triggerRef": true, + "tryOnBeforeMount": true, + "tryOnBeforeUnmount": true, + "tryOnMounted": true, + "tryOnScopeDispose": true, + "tryOnUnmounted": true, + "unref": true, + "unrefElement": true, + "until": true, + "useActiveElement": true, + "useAnimate": true, + "useArrayDifference": true, + "useArrayEvery": true, + "useArrayFilter": true, + "useArrayFind": true, + "useArrayFindIndex": true, + "useArrayFindLast": true, + "useArrayIncludes": true, + "useArrayJoin": true, + "useArrayMap": true, + "useArrayReduce": true, + "useArraySome": true, + "useArrayUnique": true, + "useAsyncQueue": true, + "useAsyncState": true, + "useAttrs": true, + "useBase64": true, + "useBattery": true, + "useBluetooth": true, + "useBreakpoints": true, + "useBroadcastChannel": true, + "useBrowserLocation": true, + "useCached": true, + "useClipboard": true, + "useClipboardItems": true, + "useCloned": true, + "useColorMode": true, + "useConfirmDialog": true, + "useCountdown": true, + "useCounter": true, + "useCssModule": true, + "useCssVar": true, + "useCssVars": true, + "useCurrentElement": true, + "useCycleList": true, + "useDark": true, + "useDateFormat": true, + "useDebounce": true, + "useDebounceFn": true, + "useDebouncedRefHistory": true, + "useDeviceMotion": true, + "useDeviceOrientation": true, + "useDevicePixelRatio": true, + "useDevicesList": true, + "useDisplayMedia": true, + "useDocumentVisibility": true, + "useDraggable": true, + "useDropZone": true, + "useElementBounding": true, + "useElementByPoint": true, + "useElementHover": true, + "useElementSize": true, + "useElementVisibility": true, + "useEventBus": true, + "useEventListener": true, + "useEventSource": true, + "useEyeDropper": true, + "useFavicon": true, + "useFetch": true, + "useFileDialog": true, + "useFileSystemAccess": true, + "useFocus": true, + "useFocusWithin": true, + "useFps": true, + "useFullscreen": true, + "useGamepad": true, + "useGeolocation": true, + "useId": true, + "useIdle": true, + "useImage": true, + "useInfiniteScroll": true, + "useIntersectionObserver": true, + "useInterval": true, + "useIntervalFn": true, + "useKeyModifier": true, + "useLastChanged": true, + "useLink": true, + "useLocalStorage": true, + "useMagicKeys": true, + "useManualRefHistory": true, + "useMediaControls": true, + "useMediaQuery": true, + "useMemoize": true, + "useMemory": true, + "useModel": true, + "useMounted": true, + "useMouse": true, + "useMouseInElement": true, + "useMousePressed": true, + "useMutationObserver": true, + "useNavigatorLanguage": true, + "useNetwork": true, + "useNow": true, + "useObjectUrl": true, + "useOffsetPagination": true, + "useOnline": true, + "usePageLeave": true, + "useParallax": true, + "useParentElement": true, + "usePerformanceObserver": true, + "usePermission": true, + "usePointer": true, + "usePointerLock": true, + "usePointerSwipe": true, + "usePreferredColorScheme": true, + "usePreferredContrast": true, + "usePreferredDark": true, + "usePreferredLanguages": true, + "usePreferredReducedMotion": true, + "usePreferredReducedTransparency": true, + "usePrevious": true, + "useRafFn": true, + "useRefHistory": true, + "useResizeObserver": true, + "useRoute": true, + "useRouter": true, + "useSSRWidth": true, + "useScreenOrientation": true, + "useScreenSafeArea": true, + "useScriptTag": true, + "useScroll": true, + "useScrollLock": true, + "useSessionStorage": true, + "useShare": true, + "useSlots": true, + "useSorted": true, + "useSpeechRecognition": true, + "useSpeechSynthesis": true, + "useStepper": true, + "useStorage": true, + "useStorageAsync": true, + "useStyleTag": true, + "useSupported": true, + "useSwipe": true, + "useTemplateRef": true, + "useTemplateRefsList": true, + "useTextDirection": true, + "useTextSelection": true, + "useTextareaAutosize": true, + "useThrottle": true, + "useThrottleFn": true, + "useThrottledRefHistory": true, + "useTimeAgo": true, + "useTimeout": true, + "useTimeoutFn": true, + "useTimeoutPoll": true, + "useTimestamp": true, + "useTitle": true, + "useToNumber": true, + "useToString": true, + "useToggle": true, + "useTransition": true, + "useUrlSearchParams": true, + "useUserMedia": true, + "useVModel": true, + "useVModels": true, + "useVibrate": true, + "useVirtualList": true, + "useWakeLock": true, + "useWebNotification": true, + "useWebSocket": true, + "useWebWorker": true, + "useWebWorkerFn": true, + "useWindowFocus": true, + "useWindowScroll": true, + "useWindowSize": true, + "watch": true, + "watchArray": true, + "watchAtMost": true, + "watchDebounced": true, + "watchDeep": true, + "watchEffect": true, + "watchIgnorable": true, + "watchImmediate": true, + "watchOnce": true, + "watchPausable": true, + "watchPostEffect": true, + "watchSyncEffect": true, + "watchThrottled": true, + "watchTriggerable": true, + "watchWithFilter": true, + "whenever": true, + "Slot": true, + "Slots": true, + "createRef": true + } +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d251d2e --- /dev/null +++ b/.prettierignore @@ -0,0 +1,9 @@ +/dist/* +.local +.output.js +/node_modules/** + +**/*.svg +**/*.sh + +/public/* \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6ca3ce5 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,20 @@ +{ + "printWidth": 150, + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": true, + "quoteProps": "preserve", + "jsxSingleQuote": false, + "bracketSameLine": false, + "trailingComma": "none", + "bracketSpacing": true, + "embeddedLanguageFormatting": "auto", + "arrowParens": "always", + "requirePragma": false, + "insertPragma": false, + "proseWrap": "preserve", + "htmlWhitespaceSensitivity": "css", + "vueIndentScriptAndStyle": false, + "endOfLine": "auto" +} diff --git a/LICENSE b/LICENSE index 261eeb9..32b3071 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,20 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +The MIT License (MIT) - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +Copyright (c) 2019 RuoYi-Vue-Plus - 1. Definitions. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 7af4c84..1c89bf9 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,83 @@ -# fishery-ui +## 平台简介 -#### 介绍 -鱼测云PC前端 +- 本仓库为前端技术栈 [Vue3](https://v3.cn.vuejs.org) + [TS](https://www.typescriptlang.org/) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 版本。 +- 成员项目: 基于 vben5(ant-design-vue) 的前端项目 [ruoyi-plus-vben5](https://gitee.com/dapppp/ruoyi-plus-vben5) +- 成员项目: 基于soybean 的前端项目 [ruoyi-plus-soybean](https://gitee.com/xlsea/ruoyi-plus-soybean) -#### 软件架构 -软件架构说明 +## 配套后端代码仓库地址 +| 介绍 | 项目名 | 项目地址 | +|------------|:-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 🔥 分布式集群框架 | RuoYi-Vue-Plus | - [Gitee](https://gitee.com/dromara/RuoYi-Vue-Plus)
- [GitHub](https://github.com/dromara/RuoYi-Vue-Plus)
- [GitCode](https://gitcode.com/dromara/RuoYi-Vue-Plus) | +| 🔥 微服务框架 | RuoYi-Cloud-Plus | - [Gitee](https://gitee.com/dromara/RuoYi-Cloud-Plus)
- [GitHub](https://github.com/dromara/RuoYi-Cloud-Plus)
- [GitCode](https://gitcode.com/dromara/RuoYi-Cloud-Plus) | -#### 安装教程 +## 分支说明 -1. xxxx -2. xxxx -3. xxxx +- ts分支(稳定发布主分支 生产可用) +- dev分支(开发分支 开发过程中使用) -#### 使用说明 +## 前端运行 -1. xxxx -2. xxxx -3. xxxx +```bash +# 安装依赖 +npm install --registry=https://registry.npmmirror.com -#### 参与贡献 +# 启动服务 +npm run dev -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +# 构建生产环境 +npm run build:prod +# 前端访问地址 http://localhost:80 +``` -#### 特技 +## 本框架与RuoYi的业务差异 -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +| 业务 | 功能说明 | 本框架 | RuoYi | +| ------------ | ------------------------------------------------------------- | ------ | ----------------------------- | +| 租户管理 | 系统内租户的管理 如:租户套餐、过期时间、用户数量、企业信息等 | 支持 | 无 | +| 租户套餐管理 | 系统内租户所能使用的套餐管理 如:套餐内所包含的菜单等 | 支持 | 无 | +| 用户管理 | 用户的管理配置 如:新增用户、分配用户所属部门、角色、岗位等 | 支持 | 支持 | +| 部门管理 | 配置系统组织机构(公司、部门、小组) 树结构展现支持数据权限 | 支持 | 支持 | +| 岗位管理 | 配置系统用户所属担任职务 | 支持 | 支持 | +| 菜单管理 | 配置系统菜单、操作权限、按钮权限标识等 | 支持 | 支持 | +| 角色管理 | 角色菜单权限分配、设置角色按机构进行数据范围权限划分 | 支持 | 支持 | +| 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 | 支持 | 支持 | +| 参数管理 | 对系统动态配置常用参数 | 支持 | 支持 | +| 通知公告 | 系统通知公告信息发布维护 | 支持 | 支持 | +| 操作日志 | 系统正常操作日志记录和查询 系统异常信息日志记录和查询 | 支持 | 支持 | +| 登录日志 | 系统登录日志记录查询包含登录异常 | 支持 | 支持 | +| 文件管理 | 系统文件展示、上传、下载、删除等管理 | 支持 | 无 | +| 文件配置管理 | 系统文件上传、下载所需要的配置信息动态添加、修改、删除等管理 | 支持 | 无 | +| 在线用户管理 | 已登录系统的在线用户信息监控与强制踢出操作 | 支持 | 支持 | +| 定时任务 | 运行报表、任务管理(添加、修改、删除)、日志管理、执行器管理等 | 支持 | 仅支持任务与日志管理 | +| 代码生成 | 多数据源前后端代码的生成(java、html、xml、sql)支持CRUD下载 | 支持 | 仅支持单数据源 | +| 系统接口 | 根据业务代码自动生成相关的api接口文档 | 支持 | 支持 | +| 服务监控 | 监视集群系统CPU、内存、磁盘、堆栈、在线日志、Spring相关配置等 | 支持 | 仅支持单机CPU、内存、磁盘监控 | +| 缓存监控 | 对系统的缓存信息查询,命令统计等。 | 支持 | 支持 | +| 在线构建器 | 拖动表单元素生成相应的HTML代码。 | 支持 | 支持 | +| 使用案例 | 系统的一些功能案例 | 支持 | 不支持 | + +## 演示图例 + +| | | +| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| ![输入图片说明](https://foruda.gitee.com/images/1680077524361362822/270bb429_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680077619939771291/989bf9b6_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680077681751513929/1c27c5bd_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680077721559267315/74d63e23_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680077765638904515/1b75d4a6_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078026375951297/eded7a4b_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078237104531207/0eb1b6a7_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078254306078709/5931e22f_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078287971528493/0b9af60a_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078308138770249/8d3b6696_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078352553634393/db5ef880_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078378238393374/601e4357_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078414983206024/2aae27c1_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078446738419874/ecce7d59_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078475971341775/149e8634_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078491666717143/3fadece7_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078558863188826/fb8ced2a_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078574561685461/ae68a0b2_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078594932772013/9d8bfec6_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078626493093532/fcfe4ff6_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078643608812515/0295bd4f_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078685196286463/d7612c81_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078703877318597/56fce0bc_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078716586545643/b6dbd68f_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078734103217688/eb1e6aa6_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078759131415480/73c525d8_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078779416197879/75e3ed02_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078802329118061/77e10915_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078893627848351/34a1c342_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078928175016986/f126ec4a_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078941718318363/b68a0f72_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078963175518631/3bb769a1_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680078982294090567/b31c343d_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680079000642440444/77ca82a9_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680079020995074177/03b7d52e_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680079039367822173/76811806_1766278.png '屏幕截图') | +| ![输入图片说明](https://foruda.gitee.com/images/1680079274333484664/4dfdc7c0_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680079290467458224/d6715fcf_1766278.png '屏幕截图') | diff --git a/eslint.config.ts b/eslint.config.ts new file mode 100644 index 0000000..50458d1 --- /dev/null +++ b/eslint.config.ts @@ -0,0 +1,44 @@ +import pluginVue from 'eslint-plugin-vue'; +import globals from 'globals'; +import prettier from 'eslint-plugin-prettier'; +import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'; +import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'; + +export default defineConfigWithVueTs( + { + name: 'app/files-to-lint', + files: ['**/*.{js,cjs,ts,mts,tsx,vue}'] + }, + + { + name: 'app/files-to-ignore', + ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'] + }, + { + languageOptions: { + globals: globals.browser + } + }, + pluginVue.configs['flat/essential'], + vueTsConfigs.recommended, + skipFormatting, + { + plugins: { prettier }, + rules: { + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/no-this-alias': 'off', + // vue + 'vue/multi-word-component-names': 'off', + 'vue/valid-define-props': 'off', + 'vue/no-v-model-argument': 'off', + 'prefer-rest-params': 'off', + // prettier + 'prettier/prettier': 'error', + // 允许使用空Object类型 {} + '@typescript-eslint/no-empty-object-type': 'off', + '@typescript-eslint/no-unused-expressions': 'off' + } + } +); diff --git a/html/ie.html b/html/ie.html new file mode 100644 index 0000000..4d2773d --- /dev/null +++ b/html/ie.html @@ -0,0 +1,242 @@ + + + + + 请升级您的浏览器 + + + + + + +

请升级您的浏览器,以便我们更好的为您提供服务!

+

您正在使用 Internet Explorer 的早期版本(IE11以下版本或使用该内核的浏览器)。这意味着在升级浏览器前,您将无法访问此网站。

+
+

请注意:微软公司对Windows XP 及 Internet Explorer 早期版本的支持已经结束

+

+ 自 2016 年 1 月 12 日起,Microsoft 不再为 IE 11 + 以下版本提供相应支持和更新。没有关键的浏览器安全更新,您的电脑可能易受有害病毒、间谍软件和其他恶意软件的攻击,它们可以窃取或损害您的业务数据和信息。请参阅 + 微软对 Internet Explorer 早期版本的支持将于 2016 年 1 月 12 日结束的说明 + 。 +

+
+

您可以选择更先进的浏览器

+

推荐使用以下浏览器的最新版本。如果您的电脑已有以下浏览器的最新版本则直接使用该浏览器访问即可。

+ +
+ + diff --git a/index.html b/index.html new file mode 100644 index 0000000..15003f6 --- /dev/null +++ b/index.html @@ -0,0 +1,214 @@ + + + + + + + + + 鱼测云后台管理系统 + + + + + +
+
+
+
+
+
正在加载系统资源,请耐心等待
+
+
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2a2231c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7457 @@ +{ + "name": "ruoyi-vue-plus", + "version": "5.5.0-2.5.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ruoyi-vue-plus", + "version": "5.5.0-2.5.0", + "license": "MIT", + "dependencies": { + "@element-plus/icons-vue": "2.3.1", + "@highlightjs/vue-plugin": "2.1.0", + "@vueup/vue-quill": "1.2.0", + "@vueuse/core": "13.1.0", + "animate.css": "4.1.1", + "await-to-js": "3.0.0", + "axios": "1.8.4", + "crypto-js": "4.2.0", + "echarts": "5.6.0", + "element-plus": "2.9.8", + "file-saver": "2.0.5", + "highlight.js": "11.9.0", + "image-conversion": "2.1.1", + "js-cookie": "3.0.5", + "jsencrypt": "3.3.2", + "nprogress": "0.2.0", + "pinia": "3.0.2", + "screenfull": "6.0.2", + "vue": "3.5.13", + "vue-cropper": "1.1.1", + "vue-i18n": "11.1.3", + "vue-json-pretty": "2.4.0", + "vue-router": "4.5.0", + "vue-types": "6.0.0", + "vxe-table": "4.13.7" + }, + "devDependencies": { + "@iconify/json": "^2.2.276", + "@types/crypto-js": "4.2.2", + "@types/file-saver": "2.0.7", + "@types/js-cookie": "3.0.6", + "@types/node": "^22.13.4", + "@types/nprogress": "0.2.3", + "@unocss/preset-attributify": "66.0.0", + "@unocss/preset-icons": "66.0.0", + "@unocss/preset-uno": "66.0.0", + "@vitejs/plugin-vue": "5.2.3", + "@vue/compiler-sfc": "3.5.13", + "@vue/eslint-config-prettier": "10.2.0", + "@vue/eslint-config-typescript": "14.4.0", + "autoprefixer": "10.4.20", + "eslint": "9.21.0", + "eslint-plugin-prettier": "5.2.3", + "eslint-plugin-vue": "9.32.0", + "globals": "16.0.0", + "prettier": "3.5.2", + "sass": "1.87.0", + "typescript": "~5.8.3", + "unocss": "66.0.0", + "unplugin-auto-import": "19.1.2", + "unplugin-icons": "22.1.0", + "unplugin-vue-components": "28.5.0", + "unplugin-vue-setup-extend-plus": "1.0.1", + "vite": "6.3.2", + "vite-plugin-compression": "0.5.1", + "vite-plugin-svg-icons-ng": "^1.4.0", + "vite-plugin-vue-devtools": "7.7.5", + "vitest": "3.1.2", + "vue-tsc": "^2.2.8" + }, + "engines": { + "node": ">=18.18.0", + "npm": ">=8.9.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/utils": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/compat-data": { + "version": "7.28.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.4", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-decorators": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.4", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@element-plus/icons-vue": { + "version": "2.3.1", + "license": "MIT", + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.10", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/core": { + "version": "0.12.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.21.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.8", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.13.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.13.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "license": "MIT" + }, + "node_modules/@highlightjs/vue-plugin": { + "version": "2.1.0", + "license": "BSD-3-Clause", + "peerDependencies": { + "highlight.js": "^11.0.1", + "vue": "^3" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@iconify/json": { + "version": "2.2.393", + "dev": true, + "license": "MIT", + "dependencies": { + "@iconify/types": "*", + "pathe": "^2.0.0" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.0.0", + "@antfu/utils": "^8.1.0", + "@iconify/types": "^2.0.0", + "debug": "^4.4.0", + "globals": "^15.14.0", + "kolorist": "^1.8.0", + "local-pkg": "^1.0.0", + "mlly": "^1.7.4" + } + }, + "node_modules/@iconify/utils/node_modules/globals": { + "version": "15.15.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@intlify/core-base": { + "version": "11.1.3", + "license": "MIT", + "dependencies": { + "@intlify/message-compiler": "11.1.3", + "@intlify/shared": "11.1.3" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/message-compiler": { + "version": "11.1.3", + "license": "MIT", + "dependencies": { + "@intlify/shared": "11.1.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/shared": { + "version": "11.1.3", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "dev": true, + "license": "MIT" + }, + "node_modules/@popperjs/core": { + "name": "@sxzz/popperjs-es", + "version": "2.11.7", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.4", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.4", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/crypto-js": { + "version": "4.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/js-cookie": { + "version": "3.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.20", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/node": { + "version": "22.18.8", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/nprogress": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.21", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.0", + "@typescript-eslint/type-utils": "8.46.0", + "@typescript-eslint/utils": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.0", + "@typescript-eslint/types": "^8.46.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0", + "@typescript-eslint/utils": "8.46.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.0", + "@typescript-eslint/tsconfig-utils": "8.46.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@unocss/astro": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "@unocss/reset": "66.0.0", + "@unocss/vite": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/@unocss/cli": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@unocss/config": "66.0.0", + "@unocss/core": "66.0.0", + "@unocss/preset-uno": "66.0.0", + "cac": "^6.7.14", + "chokidar": "^3.6.0", + "colorette": "^2.0.20", + "consola": "^3.4.0", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "tinyglobby": "^0.2.10", + "unplugin-utils": "^0.2.4" + }, + "bin": { + "unocss": "bin/unocss.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/cli/node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@unocss/cli/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/@unocss/cli/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@unocss/cli/node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/@unocss/config": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "unconfig": "~7.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/core": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/extractor-arbitrary-variants": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/inspector": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "@unocss/rule-utils": "66.0.0", + "colorette": "^2.0.20", + "gzip-size": "^6.0.0", + "sirv": "^3.0.0", + "vue-flow-layout": "^0.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/postcss": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/config": "66.0.0", + "@unocss/core": "66.0.0", + "@unocss/rule-utils": "66.0.0", + "css-tree": "^3.1.0", + "postcss": "^8.5.2", + "tinyglobby": "^0.2.10" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/@unocss/preset-attributify": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-icons": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@iconify/utils": "^2.3.0", + "@unocss/core": "66.0.0", + "ofetch": "^1.4.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-mini": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "@unocss/extractor-arbitrary-variants": "66.0.0", + "@unocss/rule-utils": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-tagify": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-typography": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "@unocss/preset-mini": "66.0.0", + "@unocss/rule-utils": "66.0.0" + } + }, + "node_modules/@unocss/preset-uno": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "@unocss/preset-wind3": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-web-fonts": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "ofetch": "^1.4.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-wind": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "@unocss/preset-wind3": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/preset-wind3": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "@unocss/preset-mini": "66.0.0", + "@unocss/rule-utils": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/reset": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/rule-utils": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "^66.0.0", + "magic-string": "^0.30.17" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/transformer-attributify-jsx": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/transformer-compile-class": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/transformer-directives": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0", + "@unocss/rule-utils": "66.0.0", + "css-tree": "^3.1.0" + } + }, + "node_modules/@unocss/transformer-variant-group": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/core": "66.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@unocss/vite": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@unocss/config": "66.0.0", + "@unocss/core": "66.0.0", + "@unocss/inspector": "66.0.0", + "chokidar": "^3.6.0", + "magic-string": "^0.30.17", + "tinyglobby": "^0.2.10", + "unplugin-utils": "^0.2.4" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0" + } + }, + "node_modules/@unocss/vite/node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@unocss/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/@unocss/vite/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@unocss/vite/node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vitest/expect": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.1.2", + "@vitest/utils": "3.1.2", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.1.2", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.1.2", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.1.2", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.1.2", + "loupe": "^3.1.3", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/@vitest/pretty-format": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@volar/language-core": { + "version": "2.4.15", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.15" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@volar/typescript": { + "version": "2.4.15", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.15", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.2", + "@vue/babel-helper-vue-transform-on": "1.5.0", + "@vue/babel-plugin-resolve-type": "1.5.0", + "@vue/shared": "^3.5.18" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + } + } + }, + "node_modules/@vue/babel-plugin-jsx/node_modules/@vue/shared": { + "version": "3.5.22", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/babel-plugin-resolve-type": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/parser": "^7.28.0", + "@vue/compiler-sfc": "^3.5.18" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/compiler-core": { + "version": "3.5.22", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.4", + "@vue/shared": "3.5.22", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/compiler-dom": { + "version": "3.5.22", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/compiler-sfc": { + "version": "3.5.22", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.4", + "@vue/compiler-core": "3.5.22", + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.19", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/compiler-ssr": { + "version": "3.5.22", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/babel-plugin-resolve-type/node_modules/@vue/shared": { + "version": "3.5.22", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.13", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.13", + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.11", + "postcss": "^8.4.48", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/compiler-vue2": { + "version": "2.7.16", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.7.7", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.7" + } + }, + "node_modules/@vue/devtools-core": { + "version": "7.7.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.7", + "@vue/devtools-shared": "^7.7.7", + "mitt": "^3.0.1", + "nanoid": "^5.1.0", + "pathe": "^2.0.3", + "vite-hot-client": "^2.0.4" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@vue/devtools-core/node_modules/nanoid": { + "version": "5.1.6", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.7", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.7", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.7", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/eslint-config-prettier": { + "version": "10.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.2.2" + }, + "peerDependencies": { + "eslint": ">= 8.21.0", + "prettier": ">= 3.0.0" + } + }, + "node_modules/@vue/eslint-config-typescript": { + "version": "14.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.23.0", + "fast-glob": "^3.3.3", + "typescript-eslint": "^8.23.0", + "vue-eslint-parser": "^9.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.10.0", + "eslint-plugin-vue": "^9.28.0", + "typescript": ">=4.8.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/language-core": { + "version": "2.2.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.15", + "@vue/compiler-dom": "^3.5.0", + "@vue/compiler-vue2": "^2.7.16", + "@vue/shared": "^3.5.0", + "alien-signals": "^1.0.3", + "minimatch": "^9.0.3", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/runtime-core": "3.5.13", + "@vue/shared": "3.5.13", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "vue": "3.5.13" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.13", + "license": "MIT" + }, + "node_modules/@vueup/vue-quill": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "quill": "^1.3.7", + "quill-delta": "^4.2.2" + }, + "peerDependencies": { + "vue": "^3.2.41" + } + }, + "node_modules/@vueuse/core": { + "version": "13.1.0", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.21", + "@vueuse/metadata": "13.1.0", + "@vueuse/shared": "13.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/@vueuse/metadata": { + "version": "13.1.0", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "13.1.0", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/@vxe-ui/core": { + "version": "4.2.12", + "license": "MIT", + "dependencies": { + "dom-zindex": "^1.0.6", + "xe-utils": "^3.7.9" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/alien-signals": { + "version": "1.0.13", + "dev": true, + "license": "MIT" + }, + "node_modules/animate.css": { + "version": "4.1.1", + "license": "MIT" + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/async-validator": { + "version": "4.2.5", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/await-to-js": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/axios": { + "version": "1.8.4", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.13", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/birpc": { + "version": "2.6.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.26.3", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.9", + "caniuse-lite": "^1.0.30001746", + "electron-to-chromium": "^1.5.227", + "node-releases": "^2.0.21", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001749", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "5.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-js": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/css-select": { + "version": "5.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/dayjs": { + "version": "1.11.18", + "license": "MIT" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/default-browser": { + "version": "5.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-zindex": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/echarts": { + "version": "5.6.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.6.1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.233", + "dev": true, + "license": "ISC" + }, + "node_modules/element-plus": { + "version": "2.9.8", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^3.4.1", + "@element-plus/icons-vue": "^2.3.1", + "@floating-ui/dom": "^1.0.1", + "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", + "@types/lodash": "^4.14.182", + "@types/lodash-es": "^4.17.6", + "@vueuse/core": "^9.1.0", + "async-validator": "^4.2.5", + "dayjs": "^1.11.13", + "escape-html": "^1.0.3", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.2", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.2.0" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/element-plus/node_modules/@types/web-bluetooth": { + "version": "0.0.16", + "license": "MIT" + }, + "node_modules/element-plus/node_modules/@vueuse/core": { + "version": "9.13.0", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "9.13.0", + "@vueuse/shared": "9.13.0", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/element-plus/node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/element-plus/node_modules/@vueuse/metadata": { + "version": "9.13.0", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/element-plus/node_modules/@vueuse/shared": { + "version": "9.13.0", + "license": "MIT", + "dependencies": { + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/element-plus/node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.10", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-stack-parser-es": { + "version": "0.1.5", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.10", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" + } + }, + "node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.21.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-vue": { + "version": "9.32.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.3", + "vue-eslint-parser": "^9.4.3", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-vue/node_modules/globals": { + "version": "13.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "license": "MIT" + }, + "node_modules/execa": { + "version": "9.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/exsolve": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-saver": { + "version": "2.0.5", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "9.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/highlight.js": { + "version": "11.9.0", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "8.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-conversion": { + "version": "2.1.1", + "license": "MIT" + }, + "node_modules/immutable": { + "version": "5.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "4.1.16", + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.6.1", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsencrypt": { + "version": "3.3.2", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kolorist": { + "version": "1.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/local-pkg": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.3.0", + "quansync": "^0.2.11" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "license": "MIT" + }, + "node_modules/lodash-unified": { + "version": "1.0.3", + "license": "MIT", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.19", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/mlly": { + "version": "1.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "dev": true, + "license": "MIT" + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "dev": true, + "license": "MIT" + }, + "node_modules/node-html-parser": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "css-select": "^5.1.0", + "he": "1.2.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.23", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-wheel-es": { + "version": "1.2.0", + "license": "BSD-3-Clause" + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/ofetch": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "destr": "^2.0.3", + "node-fetch-native": "^1.6.4", + "ufo": "^1.5.4" + } + }, + "node_modules/open": { + "version": "10.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/parchment": { + "version": "3.0.0", + "license": "BSD-3-Clause" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pinia": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^7.7.2" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/pkg-types": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/quansync": { + "version": "0.2.11", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quill": { + "version": "2.0.2", + "license": "BSD-3-Clause", + "dependencies": { + "eventemitter3": "^5.0.1", + "lodash-es": "^4.17.21", + "parchment": "^3.0.0", + "quill-delta": "^5.1.0" + }, + "engines": { + "npm": ">=8.2.3" + } + }, + "node_modules/quill-delta": { + "version": "4.2.2", + "license": "MIT", + "dependencies": { + "fast-diff": "1.2.0", + "lodash.clonedeep": "^4.5.0", + "lodash.isequal": "^4.5.0" + } + }, + "node_modules/quill-delta/node_modules/fast-diff": { + "version": "1.2.0", + "license": "Apache-2.0" + }, + "node_modules/quill/node_modules/quill-delta": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "fast-diff": "^1.3.0", + "lodash.clonedeep": "^4.5.0", + "lodash.isequal": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.52.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.4", + "@rollup/rollup-android-arm64": "4.52.4", + "@rollup/rollup-darwin-arm64": "4.52.4", + "@rollup/rollup-darwin-x64": "4.52.4", + "@rollup/rollup-freebsd-arm64": "4.52.4", + "@rollup/rollup-freebsd-x64": "4.52.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", + "@rollup/rollup-linux-arm-musleabihf": "4.52.4", + "@rollup/rollup-linux-arm64-gnu": "4.52.4", + "@rollup/rollup-linux-arm64-musl": "4.52.4", + "@rollup/rollup-linux-loong64-gnu": "4.52.4", + "@rollup/rollup-linux-ppc64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-musl": "4.52.4", + "@rollup/rollup-linux-s390x-gnu": "4.52.4", + "@rollup/rollup-linux-x64-gnu": "4.52.4", + "@rollup/rollup-linux-x64-musl": "4.52.4", + "@rollup/rollup-openharmony-arm64": "4.52.4", + "@rollup/rollup-win32-arm64-msvc": "4.52.4", + "@rollup/rollup-win32-ia32-msvc": "4.52.4", + "@rollup/rollup-win32-x64-gnu": "4.52.4", + "@rollup/rollup-win32-x64-msvc": "4.52.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", + "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", + "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", + "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", + "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", + "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", + "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", + "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", + "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", + "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", + "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", + "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", + "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", + "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", + "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", + "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", + "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz", + "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", + "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", + "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", + "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sass": { + "version": "1.87.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/screenfull": { + "version": "6.0.2", + "license": "MIT", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/scule": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sirv": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "dev": true, + "license": "MIT" + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/superjson": { + "version": "2.2.2", + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svgo": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/css-tree": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/svgo/node_modules/mdn-data": { + "version": "2.0.30", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/synckit": { + "version": "0.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/synckit/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.3.0", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.46.0", + "@typescript-eslint/parser": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0", + "@typescript-eslint/utils": "8.46.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/unconfig": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^8.1.0", + "defu": "^6.1.4", + "jiti": "^2.4.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "dev": true, + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unimport": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.1", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "pkg-types": "^2.1.0", + "scule": "^1.3.0", + "strip-literal": "^3.0.0", + "tinyglobby": "^0.2.12", + "unplugin": "^2.2.2", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unimport/node_modules/escape-string-regexp": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unimport/node_modules/estree-walker": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/unimport/node_modules/picomatch": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unocss": { + "version": "66.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@unocss/astro": "66.0.0", + "@unocss/cli": "66.0.0", + "@unocss/core": "66.0.0", + "@unocss/postcss": "66.0.0", + "@unocss/preset-attributify": "66.0.0", + "@unocss/preset-icons": "66.0.0", + "@unocss/preset-mini": "66.0.0", + "@unocss/preset-tagify": "66.0.0", + "@unocss/preset-typography": "66.0.0", + "@unocss/preset-uno": "66.0.0", + "@unocss/preset-web-fonts": "66.0.0", + "@unocss/preset-wind": "66.0.0", + "@unocss/preset-wind3": "66.0.0", + "@unocss/transformer-attributify-jsx": "66.0.0", + "@unocss/transformer-compile-class": "66.0.0", + "@unocss/transformer-directives": "66.0.0", + "@unocss/transformer-variant-group": "66.0.0", + "@unocss/vite": "66.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@unocss/webpack": "66.0.0", + "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0" + }, + "peerDependenciesMeta": { + "@unocss/webpack": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/unplugin": { + "version": "2.3.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin-auto-import": { + "version": "19.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "picomatch": "^4.0.2", + "unimport": "^4.1.2", + "unplugin": "^2.2.2", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@nuxt/kit": "^3.2.2", + "@vueuse/core": "*" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + }, + "@vueuse/core": { + "optional": true + } + } + }, + "node_modules/unplugin-auto-import/node_modules/picomatch": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/unplugin-icons": { + "version": "22.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.0.0", + "@iconify/utils": "^2.3.0", + "debug": "^4.4.0", + "local-pkg": "^1.0.0", + "unplugin": "^2.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@svgr/core": ">=7.0.0", + "@svgx/core": "^1.0.1", + "@vue/compiler-sfc": "^3.0.2 || ^2.7.0", + "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0", + "vue-template-compiler": "^2.6.12", + "vue-template-es2015-compiler": "^1.9.0" + }, + "peerDependenciesMeta": { + "@svgr/core": { + "optional": true + }, + "@svgx/core": { + "optional": true + }, + "@vue/compiler-sfc": { + "optional": true + }, + "svelte": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + }, + "vue-template-es2015-compiler": { + "optional": true + } + } + }, + "node_modules/unplugin-utils": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/unplugin-utils/node_modules/picomatch": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/unplugin-vue-components": { + "version": "28.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.6.0", + "debug": "^4.4.0", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "tinyglobby": "^0.2.12", + "unplugin": "^2.3.2", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@babel/parser": "^7.15.8", + "@nuxt/kit": "^3.2.2", + "vue": "2 || 3" + }, + "peerDependenciesMeta": { + "@babel/parser": { + "optional": true + }, + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/unplugin-vue-components/node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/unplugin-vue-components/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/unplugin-vue-components/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/unplugin-vue-components/node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/unplugin-vue-setup-extend-plus": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-sfc": "^3.2.37", + "magic-string": "^0.26.2", + "unplugin": "^1.3.1" + } + }, + "node_modules/unplugin-vue-setup-extend-plus/node_modules/magic-string": { + "version": "0.26.7", + "dev": true, + "license": "MIT", + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/unplugin-vue-setup-extend-plus/node_modules/unplugin": { + "version": "1.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/unplugin/node_modules/picomatch": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "6.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.3", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.12" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-hot-client": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" + } + }, + "node_modules/vite-node": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.0", + "es-module-lexer": "^1.6.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-plugin-compression": { + "version": "0.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "debug": "^4.3.3", + "fs-extra": "^10.0.0" + }, + "peerDependencies": { + "vite": ">=2.0.0" + } + }, + "node_modules/vite-plugin-inspect": { + "version": "0.8.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.10", + "@rollup/pluginutils": "^5.1.3", + "debug": "^4.3.7", + "error-stack-parser-es": "^0.1.5", + "fs-extra": "^11.2.0", + "open": "^10.1.0", + "perfect-debounce": "^1.0.0", + "picocolors": "^1.1.1", + "sirv": "^3.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.1" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/vite-plugin-inspect/node_modules/@antfu/utils": { + "version": "0.7.10", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/vite-plugin-inspect/node_modules/fs-extra": { + "version": "11.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/vite-plugin-svg-icons-ng": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.3", + "fs-extra": "^11.3.0", + "node-html-parser": "^7.0.1", + "pathe": "^2.0.3", + "svgo": "^3.3.2" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": ">=5.0.0" + } + }, + "node_modules/vite-plugin-svg-icons-ng/node_modules/fs-extra": { + "version": "11.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/vite-plugin-vue-devtools": { + "version": "7.7.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-core": "^7.7.5", + "@vue/devtools-kit": "^7.7.5", + "@vue/devtools-shared": "^7.7.5", + "execa": "^9.5.2", + "sirv": "^3.0.1", + "vite-plugin-inspect": "0.8.9", + "vite-plugin-vue-inspector": "^5.3.1" + }, + "engines": { + "node": ">=v14.21.3" + }, + "peerDependencies": { + "vite": "^3.1.0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0" + } + }, + "node_modules/vite-plugin-vue-inspector": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.0", + "@babel/plugin-proposal-decorators": "^7.23.0", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.22.15", + "@vue/babel-plugin-jsx": "^1.1.5", + "@vue/compiler-dom": "^3.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.4" + }, + "peerDependencies": { + "vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "3.1.2", + "@vitest/mocker": "3.1.2", + "@vitest/pretty-format": "^3.1.2", + "@vitest/runner": "3.1.2", + "@vitest/snapshot": "3.1.2", + "@vitest/spy": "3.1.2", + "@vitest/utils": "3.1.2", + "chai": "^5.2.0", + "debug": "^4.4.0", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.13", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.1.2", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.1.2", + "@vitest/ui": "3.1.2", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/tinyexec": { + "version": "0.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.13", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-sfc": "3.5.13", + "@vue/runtime-dom": "3.5.13", + "@vue/server-renderer": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-cropper": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/vue-eslint-parser": { + "version": "9.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-scope": { + "version": "7.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/vue-eslint-parser/node_modules/espree": { + "version": "9.6.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/vue-flow-layout": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "peerDependencies": { + "vue": "^3.4.37" + } + }, + "node_modules/vue-i18n": { + "version": "11.1.3", + "license": "MIT", + "dependencies": { + "@intlify/core-base": "11.1.3", + "@intlify/shared": "11.1.3", + "@vue/devtools-api": "^6.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue-i18n/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "license": "MIT" + }, + "node_modules/vue-json-pretty": { + "version": "2.4.0", + "license": "MIT", + "engines": { + "node": ">= 10.0.0", + "npm": ">= 5.0.0" + }, + "peerDependencies": { + "vue": ">=3.0.0" + } + }, + "node_modules/vue-router": { + "version": "4.5.0", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "license": "MIT" + }, + "node_modules/vue-tsc": { + "version": "2.2.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "2.4.15", + "@vue/language-core": "2.2.12" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, + "node_modules/vue-types": { + "version": "6.0.0", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "vue": "^3.0.0" + }, + "peerDependenciesMeta": { + "vue": { + "optional": true + } + } + }, + "node_modules/vxe-pc-ui": { + "version": "4.9.41", + "license": "MIT", + "dependencies": { + "@vxe-ui/core": "^4.2.12" + } + }, + "node_modules/vxe-table": { + "version": "4.13.7", + "license": "MIT", + "dependencies": { + "vxe-pc-ui": "^4.5.27" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xe-utils": { + "version": "3.7.9", + "license": "MIT" + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zrender": { + "version": "5.6.1", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..084c104 --- /dev/null +++ b/package.json @@ -0,0 +1,96 @@ +{ + "$schema": "https://json.schemastore.org/package", + "name": "ruoyi-vue-plus", + "version": "5.5.0-2.5.0", + "description": "鱼测云后台管理系统", + "author": "LionLi", + "license": "MIT", + "type": "module", + "scripts": { + "dev": "vite serve --mode development", + "build:prod": "vite build --mode production", + "build:dev": "vite build --mode development", + "preview": "vite preview", + "lint:eslint": "eslint", + "lint:eslint:fix": "eslint --fix", + "prettier": "prettier --write ." + }, + "repository": { + "type": "git", + "url": "https://gitee.com/JavaLionLi/plus-ui.git" + }, + "dependencies": { + "@element-plus/icons-vue": "2.3.1", + "@highlightjs/vue-plugin": "2.1.0", + "@vueup/vue-quill": "1.2.0", + "@vueuse/core": "13.1.0", + "animate.css": "4.1.1", + "await-to-js": "3.0.0", + "axios": "1.8.4", + "crypto-js": "4.2.0", + "echarts": "5.6.0", + "element-plus": "2.9.8", + "file-saver": "2.0.5", + "highlight.js": "11.9.0", + "image-conversion": "2.1.1", + "js-cookie": "3.0.5", + "jsencrypt": "3.3.2", + "nprogress": "0.2.0", + "pinia": "3.0.2", + "screenfull": "6.0.2", + "vue": "3.5.13", + "vue-cropper": "1.1.1", + "vue-i18n": "11.1.3", + "vue-json-pretty": "2.4.0", + "vue-router": "4.5.0", + "vue-types": "6.0.0", + "vxe-table": "4.13.7" + }, + "devDependencies": { + "@iconify/json": "^2.2.276", + "@types/crypto-js": "4.2.2", + "@types/file-saver": "2.0.7", + "@types/js-cookie": "3.0.6", + "@types/node": "^22.13.4", + "@types/nprogress": "0.2.3", + "@unocss/preset-attributify": "66.0.0", + "@unocss/preset-icons": "66.0.0", + "@unocss/preset-uno": "66.0.0", + "@vitejs/plugin-vue": "5.2.3", + "@vue/compiler-sfc": "3.5.13", + "@vue/eslint-config-prettier": "10.2.0", + "@vue/eslint-config-typescript": "14.4.0", + "autoprefixer": "10.4.20", + "eslint": "9.21.0", + "eslint-plugin-prettier": "5.2.3", + "eslint-plugin-vue": "9.32.0", + "globals": "16.0.0", + "prettier": "3.5.2", + "sass": "1.87.0", + "typescript": "~5.8.3", + "unocss": "66.0.0", + "unplugin-auto-import": "19.1.2", + "unplugin-icons": "22.1.0", + "unplugin-vue-components": "28.5.0", + "unplugin-vue-setup-extend-plus": "1.0.1", + "vite": "6.3.2", + "vite-plugin-compression": "0.5.1", + "vite-plugin-svg-icons-ng": "^1.4.0", + "vite-plugin-vue-devtools": "7.7.5", + "vitest": "3.1.2", + "vue-tsc": "^2.2.8" + }, + "overrides": { + "quill": "2.0.2" + }, + "engines": { + "node": ">=18.18.0", + "npm": ">=8.9.0" + }, + "browserslist": [ + "Chrome >= 87", + "Edge >= 88", + "Safari >= 14", + "Firefox >= 78" + ] +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..d6191cc Binary files /dev/null and b/public/favicon.ico differ diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..617a10e --- /dev/null +++ b/src/App.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/animate.ts b/src/animate.ts new file mode 100644 index 0000000..7a23df8 --- /dev/null +++ b/src/animate.ts @@ -0,0 +1,48 @@ +// 前缀 +const animatePrefix = 'animate__animated '; +// 开启随机动画 随机动画值 +const animateList: string[] = [ + animatePrefix + 'animate__pulse', + animatePrefix + 'animate__rubberBand', + animatePrefix + 'animate__bounceIn', + animatePrefix + 'animate__bounceInLeft', + animatePrefix + 'animate__fadeIn', + animatePrefix + 'animate__fadeInLeft', + animatePrefix + 'animate__fadeInDown', + animatePrefix + 'animate__fadeInUp', + animatePrefix + 'animate__flipInX', + animatePrefix + 'animate__lightSpeedInLeft', + animatePrefix + 'animate__rotateInDownLeft', + animatePrefix + 'animate__rollIn', + animatePrefix + 'animate__rotateInDownLeft', + animatePrefix + 'animate__zoomIn', + animatePrefix + 'animate__zoomInDown', + animatePrefix + 'animate__slideInLeft', + animatePrefix + 'animate__lightSpeedIn' +]; +// 关闭随机动画后的默认效果 +const defaultAnimate = animatePrefix + 'animate__fadeIn'; +// 搜索隐藏显示动画 +const searchAnimate = { + enter: '', + leave: '' +}; + +// 菜单搜索动画 +const menuSearchAnimate = { + enter: animatePrefix + 'animate__fadeIn', + leave: animatePrefix + 'animate__fadeOut' +}; +// logo动画 +const logoAnimate = { + enter: animatePrefix + 'animate__fadeIn', + leave: animatePrefix + 'animate__fadeOut' +}; + +export default { + animateList, + defaultAnimate, + searchAnimate, + menuSearchAnimate, + logoAnimate +}; diff --git a/src/api/demo/demo/index.ts b/src/api/demo/demo/index.ts new file mode 100644 index 0000000..7441720 --- /dev/null +++ b/src/api/demo/demo/index.ts @@ -0,0 +1,62 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { DemoVO, DemoForm, DemoQuery } from '@/api/demo/demo/types'; + +/** + * 查询测试单列表 + * @param query + * @returns {*} + */ +export const listDemo = (query?: DemoQuery): AxiosPromise => { + return request({ + url: '/demo/demo/list', + method: 'get', + params: query + }); +}; + +/** + * 查询测试单详细 + * @param id + */ +export const getDemo = (id: string | number): AxiosPromise => { + return request({ + url: '/demo/demo/' + id, + method: 'get' + }); +}; + +/** + * 新增测试单 + * @param data + */ +export const addDemo = (data: DemoForm) => { + return request({ + url: '/demo/demo', + method: 'post', + data: data + }); +}; + +/** + * 修改测试单 + * @param data + */ +export const updateDemo = (data: DemoForm) => { + return request({ + url: '/demo/demo', + method: 'put', + data: data + }); +}; + +/** + * 删除测试单 + * @param id + */ +export const delDemo = (id: string | number | Array) => { + return request({ + url: '/demo/demo/' + id, + method: 'delete' + }); +}; diff --git a/src/api/demo/demo/types.ts b/src/api/demo/demo/types.ts new file mode 100644 index 0000000..ea51d32 --- /dev/null +++ b/src/api/demo/demo/types.ts @@ -0,0 +1,90 @@ +export interface DemoVO { + /** + * 主键 + */ + id: string | number; + + /** + * 部门id + */ + deptId: string | number; + + /** + * 用户id + */ + userId: string | number; + + /** + * 排序号 + */ + orderNum: number; + + /** + * key键 + */ + testKey: string; + + /** + * 值 + */ + value: string; +} + +export interface DemoForm extends BaseEntity { + /** + * 主键 + */ + id?: string | number; + + /** + * 部门id + */ + deptId?: string | number; + + /** + * 用户id + */ + userId?: string | number; + + /** + * 排序号 + */ + orderNum?: number; + + /** + * key键 + */ + testKey?: string; + + /** + * 值 + */ + value?: string; +} + +export interface DemoQuery extends PageQuery { + /** + * 部门id + */ + deptId?: string | number; + + /** + * 用户id + */ + userId?: string | number; + + /** + * 排序号 + */ + orderNum?: number; + + /** + * key键 + */ + testKey?: string; + + /** + * 值 + */ + value?: string; +} diff --git a/src/api/demo/tree/index.ts b/src/api/demo/tree/index.ts new file mode 100644 index 0000000..562deb6 --- /dev/null +++ b/src/api/demo/tree/index.ts @@ -0,0 +1,62 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { TreeVO, TreeForm, TreeQuery } from '@/api/demo/tree/types'; + +/** + * 查询测试树列表 + * @param query + * @returns {*} + */ +export const listTree = (query?: TreeQuery): AxiosPromise => { + return request({ + url: '/demo/tree/list', + method: 'get', + params: query + }); +}; + +/** + * 查询测试树详细 + * @param id + */ +export const getTree = (id: string | number): AxiosPromise => { + return request({ + url: '/demo/tree/' + id, + method: 'get' + }); +}; + +/** + * 新增测试树 + * @param data + */ +export const addTree = (data: TreeForm) => { + return request({ + url: '/demo/tree', + method: 'post', + data: data + }); +}; + +/** + * 修改测试树 + * @param data + */ +export const updateTree = (data: TreeForm) => { + return request({ + url: '/demo/tree', + method: 'put', + data: data + }); +}; + +/** + * 删除测试树 + * @param id + */ +export const delTree = (id: string | number | Array) => { + return request({ + url: '/demo/tree/' + id, + method: 'delete' + }); +}; diff --git a/src/api/demo/tree/types.ts b/src/api/demo/tree/types.ts new file mode 100644 index 0000000..e164d8b --- /dev/null +++ b/src/api/demo/tree/types.ts @@ -0,0 +1,80 @@ +export interface TreeVO { + /** + * 主键 + */ + id: string | number; + + /** + * 父id + */ + parentId: string | number; + + /** + * 部门id + */ + deptId: string | number; + + /** + * 用户id + */ + userId: string | number; + + /** + * 值 + */ + treeName: string; + + /** + * 子对象 + */ + children: TreeVO[]; +} + +export interface TreeForm extends BaseEntity { + /** + * 主键 + */ + id?: string | number; + + /** + * 父id + */ + parentId?: string | number; + + /** + * 部门id + */ + deptId?: string | number; + + /** + * 用户id + */ + userId?: string | number; + + /** + * 值 + */ + treeName?: string; +} + +export interface TreeQuery { + /** + * 父id + */ + parentId?: string | number; + + /** + * 部门id + */ + deptId?: string | number; + + /** + * 用户id + */ + userId?: string | number; + + /** + * 值 + */ + treeName?: string; +} diff --git a/src/api/fishery/aquUser/index.ts b/src/api/fishery/aquUser/index.ts new file mode 100644 index 0000000..ddd8dce --- /dev/null +++ b/src/api/fishery/aquUser/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { AquUserVO, AquUserForm, AquUserQuery } from '@/api/fishery/aquUser/types'; + +/** + * 查询养殖用户管理列表 + * @param query + * @returns {*} + */ + +export const listAquUser = (query?: AquUserQuery): AxiosPromise => { + return request({ + url: '/fishery/aquUser/list', + method: 'get', + params: query + }); +}; + +/** + * 查询养殖用户管理详细 + * @param id + */ +export const getAquUser = (id: string | number): AxiosPromise => { + return request({ + url: '/fishery/aquUser/' + id, + method: 'get' + }); +}; + +/** + * 新增养殖用户管理 + * @param data + */ +export const addAquUser = (data: AquUserForm) => { + return request({ + url: '/fishery/aquUser', + method: 'post', + data: data + }); +}; + +/** + * 修改养殖用户管理 + * @param data + */ +export const updateAquUser = (data: AquUserForm) => { + return request({ + url: '/fishery/aquUser', + method: 'put', + data: data + }); +}; + +/** + * 删除养殖用户管理 + * @param id + */ +export const delAquUser = (id: string | number | Array) => { + return request({ + url: '/fishery/aquUser/' + id, + method: 'delete' + }); +}; diff --git a/src/api/fishery/aquUser/types.ts b/src/api/fishery/aquUser/types.ts new file mode 100644 index 0000000..01443bc --- /dev/null +++ b/src/api/fishery/aquUser/types.ts @@ -0,0 +1,258 @@ +export interface AquUserVO { + /** + * 主键id + */ + id: string | number; + + /** + * 用户名 + */ + userName: string; + + /** + * 手机号 + */ + mobilePhone: string; + + /** + * 省份 + */ + province: string; + + /** + * 城市 + */ + city: string; + + /** + * 区县 + */ + district: string; + + /** + * 报警电话列表json + */ + warnPhoneJson: string; + + /** + * 访问Token + */ + accessToken: string; + + /** + * 刷新Token + */ + refreshToken: string; + + /** + * 小程序的openId + */ + wxOpenId: string | number; + + /** + * 微信SessionKey + */ + wxSessionKey: string; + + /** + * 是否管理员 + */ + isManager: number; + + /** + * 微信unionId + */ + wxUnionId: string | number; + + /** + * 公众号的openId + */ + tecentOpenId: string | number; + + /** + * 展示标题 + */ + title: string; + + /** + * 是否拥有大屏 + */ + hasScreen: number; + + /** + * 备注 + */ + remark: string; + +} + +export interface AquUserForm extends BaseEntity { + /** + * 主键id + */ + id?: string | number; + + /** + * 用户名 + */ + userName?: string; + + /** + * 手机号 + */ + mobilePhone?: string; + + /** + * 省份 + */ + province?: string; + + /** + * 城市 + */ + city?: string; + + /** + * 区县 + */ + district?: string; + + /** + * 报警电话列表json + */ + warnPhoneJson?: string; + + /** + * 访问Token + */ + accessToken?: string; + + /** + * 刷新Token + */ + refreshToken?: string; + + /** + * 小程序的openId + */ + wxOpenId?: string | number; + + /** + * 微信SessionKey + */ + wxSessionKey?: string; + + /** + * 是否管理员 + */ + isManager?: number; + + /** + * 微信unionId + */ + wxUnionId?: string | number; + + /** + * 公众号的openId + */ + tecentOpenId?: string | number; + + /** + * 展示标题 + */ + title?: string; + + /** + * 是否拥有大屏 + */ + hasScreen?: number; + + /** + * 备注 + */ + remark?: string; + +} + +export interface AquUserQuery extends PageQuery { + + /** + * 用户名 + */ + userName?: string; + + /** + * 手机号 + */ + mobilePhone?: string; + + /** + * 省份 + */ + province?: string; + + /** + * 城市 + */ + city?: string; + + /** + * 区县 + */ + district?: string; + + /** + * 报警电话列表json + */ + warnPhoneJson?: string; + + /** + * 访问Token + */ + accessToken?: string; + + /** + * 刷新Token + */ + refreshToken?: string; + + /** + * 小程序的openId + */ + wxOpenId?: string | number; + + /** + * 微信SessionKey + */ + wxSessionKey?: string; + + /** + * 是否管理员 + */ + isManager?: number; + + /** + * 微信unionId + */ + wxUnionId?: string | number; + + /** + * 公众号的openId + */ + tecentOpenId?: string | number; + + /** + * 展示标题 + */ + title?: string; + + /** + * 是否拥有大屏 + */ + hasScreen?: number; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/fishery/deviceThreshold/index.ts b/src/api/fishery/deviceThreshold/index.ts new file mode 100644 index 0000000..d458fc0 --- /dev/null +++ b/src/api/fishery/deviceThreshold/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { DeviceThresholdVO, DeviceThresholdForm, DeviceThresholdQuery } from '@/api/fishery/deviceThreshold/types'; + +/** + * 查询设备阈值管理列表 + * @param query + * @returns {*} + */ + +export const listDeviceThreshold = (query?: DeviceThresholdQuery): AxiosPromise => { + return request({ + url: '/fishery/deviceThreshold/list', + method: 'get', + params: query + }); +}; + +/** + * 查询设备阈值管理详细 + * @param id + */ +export const getDeviceThreshold = (id: string | number): AxiosPromise => { + return request({ + url: '/fishery/deviceThreshold/' + id, + method: 'get' + }); +}; + +/** + * 新增设备阈值管理 + * @param data + */ +export const addDeviceThreshold = (data: DeviceThresholdForm) => { + return request({ + url: '/fishery/deviceThreshold', + method: 'post', + data: data + }); +}; + +/** + * 修改设备阈值管理 + * @param data + */ +export const updateDeviceThreshold = (data: DeviceThresholdForm) => { + return request({ + url: '/fishery/deviceThreshold', + method: 'put', + data: data + }); +}; + +/** + * 删除设备阈值管理 + * @param id + */ +export const delDeviceThreshold = (id: string | number | Array) => { + return request({ + url: '/fishery/deviceThreshold/' + id, + method: 'delete' + }); +}; diff --git a/src/api/fishery/deviceThreshold/types.ts b/src/api/fishery/deviceThreshold/types.ts new file mode 100644 index 0000000..920926c --- /dev/null +++ b/src/api/fishery/deviceThreshold/types.ts @@ -0,0 +1,93 @@ +export interface DeviceThresholdVO { + /** + * 主键id + */ + id: string | number; + + /** + * 参数类型 + */ + thresholdType: number; + + /** + * 阈值名称 + */ + thresholdName: string; + + /** + * 最大值 + */ + limitUpper: number; + + /** + * 最小值 + */ + limitLower: number; + + /** + * 备注 + */ + remark: string; + +} + +export interface DeviceThresholdForm extends BaseEntity { + /** + * 主键id + */ + id?: string | number; + + /** + * 参数类型 + */ + thresholdType?: number; + + /** + * 阈值名称 + */ + thresholdName?: string; + + /** + * 最大值 + */ + limitUpper?: number; + + /** + * 最小值 + */ + limitLower?: number; + + /** + * 备注 + */ + remark?: string; + +} + +export interface DeviceThresholdQuery extends PageQuery { + + /** + * 参数类型 + */ + thresholdType?: number; + + /** + * 阈值名称 + */ + thresholdName?: string; + + /** + * 最大值 + */ + limitUpper?: number; + + /** + * 最小值 + */ + limitLower?: number; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/fishery/fish/index.ts b/src/api/fishery/fish/index.ts new file mode 100644 index 0000000..bcc8dfe --- /dev/null +++ b/src/api/fishery/fish/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { FishVO, FishForm, FishQuery } from '@/api/fishery/fish/types'; + +/** + * 查询鱼类管理列表 + * @param query + * @returns {*} + */ + +export const listFish = (query?: FishQuery): AxiosPromise => { + return request({ + url: '/fishery/fish/list', + method: 'get', + params: query + }); +}; + +/** + * 查询鱼类管理详细 + * @param id + */ +export const getFish = (id: string | number): AxiosPromise => { + return request({ + url: '/fishery/fish/' + id, + method: 'get' + }); +}; + +/** + * 新增鱼类管理 + * @param data + */ +export const addFish = (data: FishForm) => { + return request({ + url: '/fishery/fish', + method: 'post', + data: data + }); +}; + +/** + * 修改鱼类管理 + * @param data + */ +export const updateFish = (data: FishForm) => { + return request({ + url: '/fishery/fish', + method: 'put', + data: data + }); +}; + +/** + * 删除鱼类管理 + * @param id + */ +export const delFish = (id: string | number | Array) => { + return request({ + url: '/fishery/fish/' + id, + method: 'delete' + }); +}; diff --git a/src/api/fishery/fish/types.ts b/src/api/fishery/fish/types.ts new file mode 100644 index 0000000..2d0da55 --- /dev/null +++ b/src/api/fishery/fish/types.ts @@ -0,0 +1,63 @@ +export interface FishVO { + /** + * 主键id + */ + id: string | number; + + /** + * 鱼类类型 + */ + fishType: number; + + /** + * 鱼类名称 + */ + fishName: string; + + /** + * 备注 + */ + remark: string; + +} + +export interface FishForm extends BaseEntity { + /** + * 主键id + */ + id?: string | number; + + /** + * 鱼类类型 + */ + fishType?: number; + + /** + * 鱼类名称 + */ + fishName?: string; + + /** + * 备注 + */ + remark?: string; + +} + +export interface FishQuery extends PageQuery { + + /** + * 鱼类类型 + */ + fishType?: number; + + /** + * 鱼类名称 + */ + fishName?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/api/fishery/pond/index.ts b/src/api/fishery/pond/index.ts new file mode 100644 index 0000000..06118b2 --- /dev/null +++ b/src/api/fishery/pond/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { PondVO, PondForm, PondQuery } from '@/api/fishery/pond/types'; + +/** + * 查询塘口管理列表 + * @param query + * @returns {*} + */ + +export const listPond = (query?: PondQuery): AxiosPromise => { + return request({ + url: '/fishery/pond/list', + method: 'get', + params: query + }); +}; + +/** + * 查询塘口管理详细 + * @param id + */ +export const getPond = (id: string | number): AxiosPromise => { + return request({ + url: '/fishery/pond/' + id, + method: 'get' + }); +}; + +/** + * 新增塘口管理 + * @param data + */ +export const addPond = (data: PondForm) => { + return request({ + url: '/fishery/pond', + method: 'post', + data: data + }); +}; + +/** + * 修改塘口管理 + * @param data + */ +export const updatePond = (data: PondForm) => { + return request({ + url: '/fishery/pond', + method: 'put', + data: data + }); +}; + +/** + * 删除塘口管理 + * @param id + */ +export const delPond = (id: string | number | Array) => { + return request({ + url: '/fishery/pond/' + id, + method: 'delete' + }); +}; diff --git a/src/api/fishery/pond/types.ts b/src/api/fishery/pond/types.ts new file mode 100644 index 0000000..b734ec1 --- /dev/null +++ b/src/api/fishery/pond/types.ts @@ -0,0 +1,135 @@ +export interface PondVO { + /** + * 主键id + */ + id: string | number; + + /** + * 用户id + */ + userId: string | number; + + /** + * 塘口名称 + */ + pondName: string; + + /** + * 鱼品种列表 + */ + fishKindIds: string | number; + + /** + * 面积 + */ + area: number; + + /** + * 密度 + */ + density: number; + + /** + * 投苗日期 + */ + placeTime: string; + + /** + * 夜间防止误关 + */ + keepNightOpen: number; +} + +export interface PondForm extends BaseEntity { + /** + * 主键id + */ + id?: string | number; + + /** + * 用户id + */ + userId?: string | number; + + /** + * 塘口名称 + */ + pondName?: string; + + /** + * 鱼品种列表 + */ + fishKindIds?: string | number; + + /** + * 面积 + */ + area?: number; + + /** + * 密度 + */ + density?: number; + + /** + * 投苗日期 + */ + placeTime?: string; + + /** + * 夜间防止误关 + */ + keepNightOpen?: number; + + /** + * 备注 + */ + remark?: string; +} + +export interface PondQuery extends PageQuery { + /** + * 用户id + */ + userId?: string | number; + + /** + * 塘口名称 + */ + pondName?: string; + + /** + * 鱼品种列表 + */ + fishKindIds?: string | number; + + /** + * 投苗日期 + */ + placeTime?: string; + + /** + * 夜间防止误关 + */ + keepNightOpen?: number; + + /** + * 日期范围参数 + */ + params?: any; + + /** + * 投苗日期 + */ + time?: string; + + /** + * 投苗日期 + */ + startTime?: string; + + /** + * 投苗日期 + */ + endTime?: string; +} diff --git a/src/api/login.ts b/src/api/login.ts new file mode 100644 index 0000000..35e6a4e --- /dev/null +++ b/src/api/login.ts @@ -0,0 +1,113 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { LoginData, LoginResult, VerifyCodeResult, TenantInfo } from './types'; +import { UserInfo } from '@/api/system/user/types'; + +// pc端固定客户端授权id +const clientId = import.meta.env.VITE_APP_CLIENT_ID; + +/** + * @param data {LoginData} + * @returns + */ +export function login(data: LoginData): AxiosPromise { + const params = { + ...data, + clientId: data.clientId || clientId, + grantType: data.grantType || 'password' + }; + return request({ + url: '/auth/login', + headers: { + isToken: false, + isEncrypt: true, + repeatSubmit: false + }, + method: 'post', + data: params + }); +} + +// 注册方法 +export function register(data: any) { + const params = { + ...data, + clientId: clientId, + grantType: 'password' + }; + return request({ + url: '/auth/register', + headers: { + isToken: false, + isEncrypt: true, + repeatSubmit: false + }, + method: 'post', + data: params + }); +} + +/** + * 注销 + */ +export function logout() { + if (import.meta.env.VITE_APP_SSE === 'true') { + request({ + url: '/resource/sse/close', + method: 'get' + }); + } + return request({ + url: '/auth/logout', + method: 'post' + }); +} + +/** + * 获取验证码 + */ +export function getCodeImg(): AxiosPromise { + return request({ + url: '/auth/code', + headers: { + isToken: false + }, + method: 'get', + timeout: 20000 + }); +} + +/** + * 第三方登录 + */ +export function callback(data: LoginData): AxiosPromise { + const LoginData = { + ...data, + clientId: clientId, + grantType: 'social' + }; + return request({ + url: '/auth/social/callback', + method: 'post', + data: LoginData + }); +} + +// 获取用户详细信息 +export function getInfo(): AxiosPromise { + return request({ + url: '/system/user/getInfo', + method: 'get' + }); +} + +// 获取租户列表 +export function getTenantList(isToken: boolean): AxiosPromise { + return request({ + url: '/auth/tenant/list', + headers: { + isToken: isToken + }, + method: 'get' + }); +} diff --git a/src/api/menu.ts b/src/api/menu.ts new file mode 100644 index 0000000..a3ae80e --- /dev/null +++ b/src/api/menu.ts @@ -0,0 +1,11 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { RouteRecordRaw } from 'vue-router'; + +// 获取路由 +export function getRouters(): AxiosPromise { + return request({ + url: '/system/menu/getRouters', + method: 'get' + }); +} diff --git a/src/api/monitor/cache/index.ts b/src/api/monitor/cache/index.ts new file mode 100644 index 0000000..e45d6fb --- /dev/null +++ b/src/api/monitor/cache/index.ts @@ -0,0 +1,59 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { CacheVO } from './types'; + +// 查询缓存详细 +export function getCache(): AxiosPromise { + return request({ + url: '/monitor/cache', + method: 'get' + }); +} + +// 查询缓存名称列表 +export function listCacheName() { + return request({ + url: '/monitor/cache/getNames', + method: 'get' + }); +} + +// 查询缓存键名列表 +export function listCacheKey(cacheName: string) { + return request({ + url: '/monitor/cache/getKeys/' + cacheName, + method: 'get' + }); +} + +// 查询缓存内容 +export function getCacheValue(cacheName: string, cacheKey: string) { + return request({ + url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey, + method: 'get' + }); +} + +// 清理指定名称缓存 +export function clearCacheName(cacheName: string) { + return request({ + url: '/monitor/cache/clearCacheName/' + cacheName, + method: 'delete' + }); +} + +// 清理指定键名缓存 +export function clearCacheKey(cacheName: string, cacheKey: string) { + return request({ + url: '/monitor/cache/clearCacheKey/' + cacheName + '/' + cacheKey, + method: 'delete' + }); +} + +// 清理全部缓存 +export function clearCacheAll() { + return request({ + url: '/monitor/cache/clearCacheAll', + method: 'delete' + }); +} diff --git a/src/api/monitor/cache/types.ts b/src/api/monitor/cache/types.ts new file mode 100644 index 0000000..4017b65 --- /dev/null +++ b/src/api/monitor/cache/types.ts @@ -0,0 +1,7 @@ +export interface CacheVO { + commandStats: Array<{ name: string; value: string }>; + + dbSize: number; + + info: { [key: string]: string }; +} diff --git a/src/api/monitor/loginInfo/index.ts b/src/api/monitor/loginInfo/index.ts new file mode 100644 index 0000000..f8877c9 --- /dev/null +++ b/src/api/monitor/loginInfo/index.ts @@ -0,0 +1,36 @@ +import request from '@/utils/request'; +import { LoginInfoQuery, LoginInfoVO } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询登录日志列表 +export function list(query: LoginInfoQuery): AxiosPromise { + return request({ + url: '/monitor/logininfor/list', + method: 'get', + params: query + }); +} + +// 删除登录日志 +export function delLoginInfo(infoId: string | number | Array) { + return request({ + url: '/monitor/logininfor/' + infoId, + method: 'delete' + }); +} + +// 解锁用户登录状态 +export function unlockLoginInfo(userName: string | Array) { + return request({ + url: '/monitor/logininfor/unlock/' + userName, + method: 'get' + }); +} + +// 清空登录日志 +export function cleanLoginInfo() { + return request({ + url: '/monitor/logininfor/clean', + method: 'delete' + }); +} diff --git a/src/api/monitor/loginInfo/types.ts b/src/api/monitor/loginInfo/types.ts new file mode 100644 index 0000000..202c779 --- /dev/null +++ b/src/api/monitor/loginInfo/types.ts @@ -0,0 +1,20 @@ +export interface LoginInfoVO { + infoId: string | number; + tenantId: string | number; + userName: string; + status: string; + ipaddr: string; + loginLocation: string; + browser: string; + os: string; + msg: string; + loginTime: string; +} + +export interface LoginInfoQuery extends PageQuery { + ipaddr: string; + userName: string; + status: string; + orderByColumn: string; + isAsc: string; +} diff --git a/src/api/monitor/online/index.ts b/src/api/monitor/online/index.ts new file mode 100644 index 0000000..5b3221c --- /dev/null +++ b/src/api/monitor/online/index.ts @@ -0,0 +1,36 @@ +import request from '@/utils/request'; +import { OnlineQuery, OnlineVO } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询在线用户列表 +export function list(query: OnlineQuery): AxiosPromise { + return request({ + url: '/monitor/online/list', + method: 'get', + params: query + }); +} + +// 强退用户 +export function forceLogout(tokenId: string) { + return request({ + url: '/monitor/online/' + tokenId, + method: 'delete' + }); +} + +// 获取当前用户登录在线设备 +export function getOnline() { + return request({ + url: '/monitor/online', + method: 'get' + }); +} + +// 删除当前在线设备 +export function delOnline(tokenId: string) { + return request({ + url: '/monitor/online/myself/' + tokenId, + method: 'delete' + }); +} diff --git a/src/api/monitor/online/types.ts b/src/api/monitor/online/types.ts new file mode 100644 index 0000000..8c0ec27 --- /dev/null +++ b/src/api/monitor/online/types.ts @@ -0,0 +1,15 @@ +export interface OnlineQuery extends PageQuery { + ipaddr: string; + userName: string; +} + +export interface OnlineVO extends BaseEntity { + tokenId: string; + deptName: string; + userName: string; + ipaddr: string; + loginLocation: string; + browser: string; + os: string; + loginTime: number; +} diff --git a/src/api/monitor/operlog/index.ts b/src/api/monitor/operlog/index.ts new file mode 100644 index 0000000..7ac3453 --- /dev/null +++ b/src/api/monitor/operlog/index.ts @@ -0,0 +1,28 @@ +import request from '@/utils/request'; +import { OperLogQuery, OperLogVO } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询操作日志列表 +export function list(query: OperLogQuery): AxiosPromise { + return request({ + url: '/monitor/operlog/list', + method: 'get', + params: query + }); +} + +// 删除操作日志 +export function delOperlog(operId: string | number | Array) { + return request({ + url: '/monitor/operlog/' + operId, + method: 'delete' + }); +} + +// 清空操作日志 +export function cleanOperlog() { + return request({ + url: '/monitor/operlog/clean', + method: 'delete' + }); +} diff --git a/src/api/monitor/operlog/types.ts b/src/api/monitor/operlog/types.ts new file mode 100644 index 0000000..10f65c7 --- /dev/null +++ b/src/api/monitor/operlog/types.ts @@ -0,0 +1,53 @@ +export interface OperLogQuery extends PageQuery { + operIp: string; + title: string; + operName: string; + businessType: string; + status: string; + orderByColumn: string; + isAsc: string; +} + +export interface OperLogVO extends BaseEntity { + operId: string | number; + tenantId: string; + title: string; + businessType: number; + businessTypes: number[] | undefined; + method: string; + requestMethod: string; + operatorType: number; + operName: string; + deptName: string; + operUrl: string; + operIp: string; + operLocation: string; + operParam: string; + jsonResult: string; + status: number; + errorMsg: string; + operTime: string; + costTime: number; +} + +export interface OperLogForm { + operId: number | string | undefined; + tenantId: string | number | undefined; + title: string; + businessType: number; + businessTypes: number[] | undefined; + method: string; + requestMethod: string; + operatorType: number; + operName: string; + deptName: string; + operUrl: string; + operIp: string; + operLocation: string; + operParam: string; + jsonResult: string; + status: number; + errorMsg: string; + operTime: string; + costTime: number; +} diff --git a/src/api/system/client/index.ts b/src/api/system/client/index.ts new file mode 100644 index 0000000..6b302b0 --- /dev/null +++ b/src/api/system/client/index.ts @@ -0,0 +1,80 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { ClientVO, ClientForm, ClientQuery } from '@/api/system/client/types'; + +/** + * 查询客户端管理列表 + * @param query + * @returns {*} + */ + +export const listClient = (query?: ClientQuery): AxiosPromise => { + return request({ + url: '/system/client/list', + method: 'get', + params: query + }); +}; + +/** + * 查询客户端管理详细 + * @param id + */ +export const getClient = (id: string | number): AxiosPromise => { + return request({ + url: '/system/client/' + id, + method: 'get' + }); +}; + +/** + * 新增客户端管理 + * @param data + */ +export const addClient = (data: ClientForm) => { + return request({ + url: '/system/client', + method: 'post', + data: data + }); +}; + +/** + * 修改客户端管理 + * @param data + */ +export const updateClient = (data: ClientForm) => { + return request({ + url: '/system/client', + method: 'put', + data: data + }); +}; + +/** + * 删除客户端管理 + * @param id + */ +export const delClient = (id: string | number | Array) => { + return request({ + url: '/system/client/' + id, + method: 'delete' + }); +}; + +/** + * 状态修改 + * @param clientId 客户端id + * @param status 状态 + */ +export function changeStatus(clientId: string, status: string) { + const data = { + clientId, + status + }; + return request({ + url: '/system/client/changeStatus', + method: 'put', + data: data + }); +} diff --git a/src/api/system/client/types.ts b/src/api/system/client/types.ts new file mode 100644 index 0000000..142118d --- /dev/null +++ b/src/api/system/client/types.ts @@ -0,0 +1,135 @@ +export interface ClientVO { + /** + * id + */ + id: string | number; + + /** + * 客户端id + */ + clientId: string; + + /** + * 客户端key + */ + clientKey: string; + + /** + * 客户端秘钥 + */ + clientSecret: string; + + /** + * 授权类型 + */ + grantTypeList: string[]; + + /** + * 设备类型 + */ + deviceType: string; + + /** + * token活跃超时时间 + */ + activeTimeout: number; + + /** + * token固定超时 + */ + timeout: number; + + /** + * 状态(0正常 1停用) + */ + status: string; +} + +export interface ClientForm extends BaseEntity { + /** + * id + */ + id?: string | number; + + /** + * 客户端id + */ + clientId?: string | number; + + /** + * 客户端key + */ + clientKey?: string; + + /** + * 客户端秘钥 + */ + clientSecret?: string; + + /** + * 授权类型 + */ + grantTypeList?: string[]; + + /** + * 设备类型 + */ + deviceType?: string; + + /** + * token活跃超时时间 + */ + activeTimeout?: number; + + /** + * token固定超时 + */ + timeout?: number; + + /** + * 状态(0正常 1停用) + */ + status?: string; +} + +export interface ClientQuery extends PageQuery { + /** + * 客户端id + */ + clientId?: string | number; + + /** + * 客户端key + */ + clientKey?: string; + + /** + * 客户端秘钥 + */ + clientSecret?: string; + + /** + * 授权类型 + */ + grantType?: string; + + /** + * 设备类型 + */ + deviceType?: string; + + /** + * token活跃超时时间 + */ + activeTimeout?: number; + + /** + * token固定超时 + */ + timeout?: number; + + /** + * 状态(0正常 1停用) + */ + status?: string; +} diff --git a/src/api/system/config/index.ts b/src/api/system/config/index.ts new file mode 100644 index 0000000..1e4842d --- /dev/null +++ b/src/api/system/config/index.ts @@ -0,0 +1,74 @@ +import request from '@/utils/request'; +import { ConfigForm, ConfigQuery, ConfigVO } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询参数列表 +export function listConfig(query: ConfigQuery): AxiosPromise { + return request({ + url: '/system/config/list', + method: 'get', + params: query + }); +} + +// 查询参数详细 +export function getConfig(configId: string | number): AxiosPromise { + return request({ + url: '/system/config/' + configId, + method: 'get' + }); +} + +// 根据参数键名查询参数值 +export function getConfigKey(configKey: string): AxiosPromise { + return request({ + url: '/system/config/configKey/' + configKey, + method: 'get' + }); +} + +// 新增参数配置 +export function addConfig(data: ConfigForm) { + return request({ + url: '/system/config', + method: 'post', + data: data + }); +} + +// 修改参数配置 +export function updateConfig(data: ConfigForm) { + return request({ + url: '/system/config', + method: 'put', + data: data + }); +} + +// 修改参数配置 +export function updateConfigByKey(key: string, value: any) { + return request({ + url: '/system/config/updateByKey', + method: 'put', + data: { + configKey: key, + configValue: value + } + }); +} + +// 删除参数配置 +export function delConfig(configId: string | number | Array) { + return request({ + url: '/system/config/' + configId, + method: 'delete' + }); +} + +// 刷新参数缓存 +export function refreshCache() { + return request({ + url: '/system/config/refreshCache', + method: 'delete' + }); +} diff --git a/src/api/system/config/types.ts b/src/api/system/config/types.ts new file mode 100644 index 0000000..b68f073 --- /dev/null +++ b/src/api/system/config/types.ts @@ -0,0 +1,23 @@ +export interface ConfigVO extends BaseEntity { + configId: number | string; + configName: string; + configKey: string; + configValue: string; + configType: string; + remark: string; +} + +export interface ConfigForm { + configId: number | string | undefined; + configName: string; + configKey: string; + configValue: string; + configType: string; + remark: string; +} + +export interface ConfigQuery extends PageQuery { + configName: string; + configKey: string; + configType: string; +} diff --git a/src/api/system/dept/index.ts b/src/api/system/dept/index.ts new file mode 100644 index 0000000..03c54d5 --- /dev/null +++ b/src/api/system/dept/index.ts @@ -0,0 +1,65 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { DeptForm, DeptQuery, DeptTreeVO, DeptVO } from './types'; + +// 查询部门列表 +export const listDept = (query?: DeptQuery) => { + return request({ + url: '/system/dept/list', + method: 'get', + params: query + }); +}; + +/** + * 通过deptIds查询部门 + * @param deptIds + */ +export const optionSelect = (deptIds: (number | string)[]): AxiosPromise => { + return request({ + url: '/system/dept/optionselect?deptIds=' + deptIds, + method: 'get' + }); +}; + +// 查询部门列表(排除节点) +export const listDeptExcludeChild = (deptId: string | number): AxiosPromise => { + return request({ + url: '/system/dept/list/exclude/' + deptId, + method: 'get' + }); +}; + +// 查询部门详细 +export const getDept = (deptId: string | number): AxiosPromise => { + return request({ + url: '/system/dept/' + deptId, + method: 'get' + }); +}; + +// 新增部门 +export const addDept = (data: DeptForm) => { + return request({ + url: '/system/dept', + method: 'post', + data: data + }); +}; + +// 修改部门 +export const updateDept = (data: DeptForm) => { + return request({ + url: '/system/dept', + method: 'put', + data: data + }); +}; + +// 删除部门 +export const delDept = (deptId: number | string) => { + return request({ + url: '/system/dept/' + deptId, + method: 'delete' + }); +}; diff --git a/src/api/system/dept/types.ts b/src/api/system/dept/types.ts new file mode 100644 index 0000000..adaefd2 --- /dev/null +++ b/src/api/system/dept/types.ts @@ -0,0 +1,60 @@ +/** + * 部门查询参数 + */ +export interface DeptQuery extends PageQuery { + deptName?: string; + deptCategory?: string; + status?: number; +} + +/** + * 部门类型 + */ +export interface DeptVO extends BaseEntity { + id: number | string; + parentName: string; + parentId: number | string; + children: DeptVO[]; + deptId: number | string; + deptName: string; + deptCategory: string; + orderNum: number; + leader: string; + phone: string; + email: string; + status: string; + delFlag: string; + ancestors: string; + menuId: string | number; +} + +/** + * 部门类型 + */ +export interface DeptTreeVO extends BaseEntity { + id: number | string; + label: string; + parentId: number | string; + weight: number; + children: DeptTreeVO[]; + disabled: boolean; +} + +/** + * 部门表单类型 + */ +export interface DeptForm { + parentName?: string; + parentId?: number | string; + children?: DeptForm[]; + deptId?: number | string; + deptName?: string; + deptCategory?: string; + orderNum?: number; + leader?: string; + phone?: string; + email?: string; + status?: string; + delFlag?: string; + ancestors?: string; +} diff --git a/src/api/system/dict/data/index.ts b/src/api/system/dict/data/index.ts new file mode 100644 index 0000000..7692abc --- /dev/null +++ b/src/api/system/dict/data/index.ts @@ -0,0 +1,53 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { DictDataForm, DictDataQuery, DictDataVO } from './types'; +// 根据字典类型查询字典数据信息 +export function getDicts(dictType: string): AxiosPromise { + return request({ + url: '/system/dict/data/type/' + dictType, + method: 'get' + }); +} + +// 查询字典数据列表 +export function listData(query: DictDataQuery): AxiosPromise { + return request({ + url: '/system/dict/data/list', + method: 'get', + params: query + }); +} + +// 查询字典数据详细 +export function getData(dictCode: string | number): AxiosPromise { + return request({ + url: '/system/dict/data/' + dictCode, + method: 'get' + }); +} + +// 新增字典数据 +export function addData(data: DictDataForm) { + return request({ + url: '/system/dict/data', + method: 'post', + data: data + }); +} + +// 修改字典数据 +export function updateData(data: DictDataForm) { + return request({ + url: '/system/dict/data', + method: 'put', + data: data + }); +} + +// 删除字典数据 +export function delData(dictCode: string | number | Array) { + return request({ + url: '/system/dict/data/' + dictCode, + method: 'delete' + }); +} diff --git a/src/api/system/dict/data/types.ts b/src/api/system/dict/data/types.ts new file mode 100644 index 0000000..e4abb9b --- /dev/null +++ b/src/api/system/dict/data/types.ts @@ -0,0 +1,26 @@ +export interface DictDataQuery extends PageQuery { + dictName: string; + dictType: string; + dictLabel: string; +} + +export interface DictDataVO extends BaseEntity { + dictCode: string; + dictLabel: string; + dictValue: string; + cssClass: string; + listClass: ElTagType; + dictSort: number; + remark: string; +} + +export interface DictDataForm { + dictType?: string; + dictCode: string | undefined; + dictLabel: string; + dictValue: string; + cssClass: string; + listClass: ElTagType; + dictSort: number; + remark: string; +} diff --git a/src/api/system/dict/type/index.ts b/src/api/system/dict/type/index.ts new file mode 100644 index 0000000..7dc3d66 --- /dev/null +++ b/src/api/system/dict/type/index.ts @@ -0,0 +1,62 @@ +import request from '@/utils/request'; +import { DictTypeForm, DictTypeVO, DictTypeQuery } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询字典类型列表 +export function listType(query: DictTypeQuery): AxiosPromise { + return request({ + url: '/system/dict/type/list', + method: 'get', + params: query + }); +} + +// 查询字典类型详细 +export function getType(dictId: number | string): AxiosPromise { + return request({ + url: '/system/dict/type/' + dictId, + method: 'get' + }); +} + +// 新增字典类型 +export function addType(data: DictTypeForm) { + return request({ + url: '/system/dict/type', + method: 'post', + data: data + }); +} + +// 修改字典类型 +export function updateType(data: DictTypeForm) { + return request({ + url: '/system/dict/type', + method: 'put', + data: data + }); +} + +// 删除字典类型 +export function delType(dictId: string | number | Array) { + return request({ + url: '/system/dict/type/' + dictId, + method: 'delete' + }); +} + +// 刷新字典缓存 +export function refreshCache() { + return request({ + url: '/system/dict/type/refreshCache', + method: 'delete' + }); +} + +// 获取字典选择框列表 +export function optionselect(): AxiosPromise { + return request({ + url: '/system/dict/type/optionselect', + method: 'get' + }); +} diff --git a/src/api/system/dict/type/types.ts b/src/api/system/dict/type/types.ts new file mode 100644 index 0000000..4987dbf --- /dev/null +++ b/src/api/system/dict/type/types.ts @@ -0,0 +1,18 @@ +export interface DictTypeVO extends BaseEntity { + dictId: number | string; + dictName: string; + dictType: string; + remark: string; +} + +export interface DictTypeForm { + dictId: number | string | undefined; + dictName: string; + dictType: string; + remark: string; +} + +export interface DictTypeQuery extends PageQuery { + dictName: string; + dictType: string; +} diff --git a/src/api/system/menu/index.ts b/src/api/system/menu/index.ts new file mode 100644 index 0000000..81461fd --- /dev/null +++ b/src/api/system/menu/index.ts @@ -0,0 +1,78 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { MenuQuery, MenuVO, MenuForm, MenuTreeOption, RoleMenuTree } from './types'; + +// 查询菜单列表 +export const listMenu = (query?: MenuQuery): AxiosPromise => { + return request({ + url: '/system/menu/list', + method: 'get', + params: query + }); +}; + +// 查询菜单详细 +export const getMenu = (menuId: string | number): AxiosPromise => { + return request({ + url: '/system/menu/' + menuId, + method: 'get' + }); +}; + +// 查询菜单下拉树结构 +export const treeselect = (): AxiosPromise => { + return request({ + url: '/system/menu/treeselect', + method: 'get' + }); +}; + +// 根据角色ID查询菜单下拉树结构 +export const roleMenuTreeselect = (roleId: string | number): AxiosPromise => { + return request({ + url: '/system/menu/roleMenuTreeselect/' + roleId, + method: 'get' + }); +}; + +// 根据角色ID查询菜单下拉树结构 +export const tenantPackageMenuTreeselect = (packageId: string | number): AxiosPromise => { + return request({ + url: '/system/menu/tenantPackageMenuTreeselect/' + packageId, + method: 'get' + }); +}; + +// 新增菜单 +export const addMenu = (data: MenuForm) => { + return request({ + url: '/system/menu', + method: 'post', + data: data + }); +}; + +// 修改菜单 +export const updateMenu = (data: MenuForm) => { + return request({ + url: '/system/menu', + method: 'put', + data: data + }); +}; + +// 删除菜单 +export const delMenu = (menuId: string | number) => { + return request({ + url: '/system/menu/' + menuId, + method: 'delete' + }); +}; + +// 级联删除菜单 +export const cascadeDelMenu = (menuIds: Array) => { + return request({ + url: '/system/menu/cascade/' + menuIds, + method: 'delete' + }); +}; diff --git a/src/api/system/menu/types.ts b/src/api/system/menu/types.ts new file mode 100644 index 0000000..ca19840 --- /dev/null +++ b/src/api/system/menu/types.ts @@ -0,0 +1,69 @@ +import { MenuTypeEnum } from '@/enums/MenuTypeEnum'; + +/** + * 菜单树形结构类型 + */ +export interface MenuTreeOption { + id: string | number; + label: string; + parentId: string | number; + weight: number; + children?: MenuTreeOption[]; +} + +export interface RoleMenuTree { + menus: MenuTreeOption[]; + checkedKeys: string[]; +} + +/** + * 菜单查询参数类型 + */ +export interface MenuQuery { + keywords?: string; + menuName?: string; + status?: string; +} + +/** + * 菜单视图对象类型 + */ +export interface MenuVO extends BaseEntity { + parentName: string; + parentId: string | number; + children: MenuVO[]; + menuId: string | number; + menuName: string; + orderNum: number; + path: string; + component: string; + queryParam: string; + isFrame: string; + isCache: string; + menuType: MenuTypeEnum; + visible: string; + status: string; + icon: string; + remark: string; +} + +export interface MenuForm { + parentName?: string; + parentId?: string | number; + children?: MenuForm[]; + menuId?: string | number; + menuName: string; + orderNum: number; + path: string; + component?: string; + queryParam?: string; + isFrame?: string; + isCache?: string; + menuType?: MenuTypeEnum; + visible?: string; + status?: string; + icon?: string; + remark?: string; + query?: string; + perms?: string; +} diff --git a/src/api/system/notice/index.ts b/src/api/system/notice/index.ts new file mode 100644 index 0000000..285d1f4 --- /dev/null +++ b/src/api/system/notice/index.ts @@ -0,0 +1,45 @@ +import request from '@/utils/request'; +import { NoticeForm, NoticeQuery, NoticeVO } from './types'; +import { AxiosPromise } from 'axios'; +// 查询公告列表 +export function listNotice(query: NoticeQuery): AxiosPromise { + return request({ + url: '/system/notice/list', + method: 'get', + params: query + }); +} + +// 查询公告详细 +export function getNotice(noticeId: string | number): AxiosPromise { + return request({ + url: '/system/notice/' + noticeId, + method: 'get' + }); +} + +// 新增公告 +export function addNotice(data: NoticeForm) { + return request({ + url: '/system/notice', + method: 'post', + data: data + }); +} + +// 修改公告 +export function updateNotice(data: NoticeForm) { + return request({ + url: '/system/notice', + method: 'put', + data: data + }); +} + +// 删除公告 +export function delNotice(noticeId: string | number | Array) { + return request({ + url: '/system/notice/' + noticeId, + method: 'delete' + }); +} diff --git a/src/api/system/notice/types.ts b/src/api/system/notice/types.ts new file mode 100644 index 0000000..abfd5b2 --- /dev/null +++ b/src/api/system/notice/types.ts @@ -0,0 +1,26 @@ +export interface NoticeVO extends BaseEntity { + noticeId: number; + noticeTitle: string; + noticeType: string; + noticeContent: string; + status: string; + remark: string; + createByName: string; +} + +export interface NoticeQuery extends PageQuery { + noticeTitle: string; + createByName: string; + status: string; + noticeType: string; +} + +export interface NoticeForm { + noticeId: number | string | undefined; + noticeTitle: string; + noticeType: string; + noticeContent: string; + status: string; + remark: string; + createByName: string; +} diff --git a/src/api/system/oss/index.ts b/src/api/system/oss/index.ts new file mode 100644 index 0000000..4472112 --- /dev/null +++ b/src/api/system/oss/index.ts @@ -0,0 +1,28 @@ +import request from '@/utils/request'; +import { OssQuery, OssVO } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询OSS对象存储列表 +export function listOss(query: OssQuery): AxiosPromise { + return request({ + url: '/resource/oss/list', + method: 'get', + params: query + }); +} + +// 查询OSS对象基于id串 +export function listByIds(ossId: string | number): AxiosPromise { + return request({ + url: '/resource/oss/listByIds/' + ossId, + method: 'get' + }); +} + +// 删除OSS对象存储 +export function delOss(ossId: string | number | Array) { + return request({ + url: '/resource/oss/' + ossId, + method: 'delete' + }); +} diff --git a/src/api/system/oss/types.ts b/src/api/system/oss/types.ts new file mode 100644 index 0000000..bc0bc1f --- /dev/null +++ b/src/api/system/oss/types.ts @@ -0,0 +1,22 @@ +export interface OssVO extends BaseEntity { + ossId: string | number; + fileName: string; + originalName: string; + fileSuffix: string; + url: string; + createByName: string; + service: string; +} + +export interface OssQuery extends PageQuery { + fileName: string; + originalName: string; + fileSuffix: string; + createTime: string; + service: string; + orderByColumn: string; + isAsc: string; +} +export interface OssForm { + file: undefined | string; +} diff --git a/src/api/system/ossConfig/index.ts b/src/api/system/ossConfig/index.ts new file mode 100644 index 0000000..d0faefe --- /dev/null +++ b/src/api/system/ossConfig/index.ts @@ -0,0 +1,60 @@ +import request from '@/utils/request'; +import { OssConfigForm, OssConfigQuery, OssConfigVO } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询对象存储配置列表 +export function listOssConfig(query: OssConfigQuery): AxiosPromise { + return request({ + url: '/resource/oss/config/list', + method: 'get', + params: query + }); +} + +// 查询对象存储配置详细 +export function getOssConfig(ossConfigId: string | number): AxiosPromise { + return request({ + url: '/resource/oss/config/' + ossConfigId, + method: 'get' + }); +} + +// 新增对象存储配置 +export function addOssConfig(data: OssConfigForm) { + return request({ + url: '/resource/oss/config', + method: 'post', + data: data + }); +} + +// 修改对象存储配置 +export function updateOssConfig(data: OssConfigForm) { + return request({ + url: '/resource/oss/config', + method: 'put', + data: data + }); +} + +// 删除对象存储配置 +export function delOssConfig(ossConfigId: string | number | Array) { + return request({ + url: '/resource/oss/config/' + ossConfigId, + method: 'delete' + }); +} + +// 对象存储状态修改 +export function changeOssConfigStatus(ossConfigId: string | number, status: string, configKey: string) { + const data = { + ossConfigId, + status, + configKey + }; + return request({ + url: '/resource/oss/config/changeStatus', + method: 'put', + data: data + }); +} diff --git a/src/api/system/ossConfig/types.ts b/src/api/system/ossConfig/types.ts new file mode 100644 index 0000000..d227bd0 --- /dev/null +++ b/src/api/system/ossConfig/types.ts @@ -0,0 +1,38 @@ +export interface OssConfigVO extends BaseEntity { + ossConfigId: number | string; + configKey: string; + accessKey: string; + secretKey: string; + bucketName: string; + prefix: string; + endpoint: string; + domain: string; + isHttps: string; + region: string; + status: string; + ext1: string; + remark: string; + accessPolicy: string; +} + +export interface OssConfigQuery extends PageQuery { + configKey: string; + bucketName: string; + status: string; +} + +export interface OssConfigForm { + ossConfigId: string | number | undefined; + configKey: string; + accessKey: string; + secretKey: string; + bucketName: string; + prefix: string; + endpoint: string; + domain: string; + isHttps: string; + accessPolicy: string; + region: string; + status: string; + remark: string; +} diff --git a/src/api/system/post/index.ts b/src/api/system/post/index.ts new file mode 100644 index 0000000..aba1ec1 --- /dev/null +++ b/src/api/system/post/index.ts @@ -0,0 +1,69 @@ +import request from '@/utils/request'; +import { PostForm, PostQuery, PostVO } from './types'; +import { AxiosPromise } from 'axios'; +import { DeptTreeVO } from '../dept/types'; + +// 查询岗位列表 +export function listPost(query: PostQuery): AxiosPromise { + return request({ + url: '/system/post/list', + method: 'get', + params: query + }); +} + +// 查询岗位详细 +export function getPost(postId: string | number): AxiosPromise { + return request({ + url: '/system/post/' + postId, + method: 'get' + }); +} + +// 获取岗位选择框列表 +export function optionselect(deptId?: number | string, postIds?: (number | string)[]): AxiosPromise { + return request({ + url: '/system/post/optionselect', + method: 'get', + params: { + postIds: postIds, + deptId: deptId + } + }); +} + +// 新增岗位 +export function addPost(data: PostForm) { + return request({ + url: '/system/post', + method: 'post', + data: data + }); +} + +// 修改岗位 +export function updatePost(data: PostForm) { + return request({ + url: '/system/post', + method: 'put', + data: data + }); +} + +// 删除岗位 +export function delPost(postId: string | number | (string | number)[]) { + return request({ + url: '/system/post/' + postId, + method: 'delete' + }); +} + +/** + * 查询部门下拉树结构 + */ +export const deptTreeSelect = (): AxiosPromise => { + return request({ + url: '/system/post/deptTree', + method: 'get' + }); +}; diff --git a/src/api/system/post/types.ts b/src/api/system/post/types.ts new file mode 100644 index 0000000..45a0540 --- /dev/null +++ b/src/api/system/post/types.ts @@ -0,0 +1,31 @@ +export interface PostVO extends BaseEntity { + postId: number | string; + deptId: number | string; + postCode: string; + postName: string; + postCategory: string; + deptName: string; + postSort: number; + status: string; + remark: string; +} + +export interface PostForm { + postId: number | string | undefined; + deptId: number | string | undefined; + postCode: string; + postName: string; + postCategory: string; + postSort: number; + status: string; + remark: string; +} + +export interface PostQuery extends PageQuery { + deptId: number | string; + belongDeptId: number | string; + postCode: string; + postName: string; + postCategory: string; + status: string; +} diff --git a/src/api/system/role/index.ts b/src/api/system/role/index.ts new file mode 100644 index 0000000..fb0fcab --- /dev/null +++ b/src/api/system/role/index.ts @@ -0,0 +1,160 @@ +import { UserVO } from '@/api/system/user/types'; +import { UserQuery } from '@/api/system/user/types'; +import { AxiosPromise } from 'axios'; +import { RoleQuery, RoleVO, RoleDeptTree } from './types'; +import request from '@/utils/request'; + +export const listRole = (query: RoleQuery): AxiosPromise => { + return request({ + url: '/system/role/list', + method: 'get', + params: query + }); +}; + +/** + * 通过roleIds查询角色 + * @param roleIds + */ +export const optionSelect = (roleIds: (number | string)[]): AxiosPromise => { + return request({ + url: '/system/role/optionselect?roleIds=' + roleIds, + method: 'get' + }); +}; + +/** + * 查询角色详细 + */ +export const getRole = (roleId: string | number): AxiosPromise => { + return request({ + url: '/system/role/' + roleId, + method: 'get' + }); +}; + +/** + * 新增角色 + */ +export const addRole = (data: any) => { + return request({ + url: '/system/role', + method: 'post', + data: data + }); +}; + +/** + * 修改角色 + * @param data + */ +export const updateRole = (data: any) => { + return request({ + url: '/system/role', + method: 'put', + data: data + }); +}; + +/** + * 角色数据权限 + */ +export const dataScope = (data: any) => { + return request({ + url: '/system/role/dataScope', + method: 'put', + data: data + }); +}; + +/** + * 角色状态修改 + */ +export const changeRoleStatus = (roleId: string | number, status: string) => { + const data = { + roleId, + status + }; + return request({ + url: '/system/role/changeStatus', + method: 'put', + data: data + }); +}; + +/** + * 删除角色 + */ +export const delRole = (roleId: Array | string | number) => { + return request({ + url: '/system/role/' + roleId, + method: 'delete' + }); +}; + +/** + * 查询角色已授权用户列表 + */ +export const allocatedUserList = (query: UserQuery): AxiosPromise => { + return request({ + url: '/system/role/authUser/allocatedList', + method: 'get', + params: query + }); +}; + +/** + * 查询角色未授权用户列表 + */ +export const unallocatedUserList = (query: UserQuery): AxiosPromise => { + return request({ + url: '/system/role/authUser/unallocatedList', + method: 'get', + params: query + }); +}; + +/** + * 取消用户授权角色 + */ +export const authUserCancel = (data: any) => { + return request({ + url: '/system/role/authUser/cancel', + method: 'put', + data: data + }); +}; + +/** + * 批量取消用户授权角色 + */ +export const authUserCancelAll = (data: any) => { + return request({ + url: '/system/role/authUser/cancelAll', + method: 'put', + params: data + }); +}; + +/** + * 授权用户选择 + */ +export const authUserSelectAll = (data: any) => { + return request({ + url: '/system/role/authUser/selectAll', + method: 'put', + params: data + }); +}; +// 根据角色ID查询部门树结构 +export const deptTreeSelect = (roleId: string | number): AxiosPromise => { + return request({ + url: '/system/role/deptTree/' + roleId, + method: 'get' + }); +}; + +export default { + optionSelect, + listRole +}; diff --git a/src/api/system/role/types.ts b/src/api/system/role/types.ts new file mode 100644 index 0000000..7dbb6ff --- /dev/null +++ b/src/api/system/role/types.ts @@ -0,0 +1,52 @@ +/** + * 菜单树形结构类型 + */ +export interface DeptTreeOption { + id: string; + label: string; + parentId: string; + weight: number; + children?: DeptTreeOption[]; +} + +export interface RoleDeptTree { + checkedKeys: string[]; + depts: DeptTreeOption[]; +} + +export interface RoleVO extends BaseEntity { + roleId: string | number; + roleName: string; + roleKey: string; + roleSort: number; + dataScope: string; + menuCheckStrictly: boolean; + deptCheckStrictly: boolean; + status: string; + delFlag: string; + remark?: any; + flag: boolean; + menuIds?: Array; + deptIds?: Array; + admin: boolean; +} + +export interface RoleQuery extends PageQuery { + roleName: string; + roleKey: string; + status: string; +} + +export interface RoleForm { + roleName: string; + roleKey: string; + roleSort: number; + status: string; + menuCheckStrictly: boolean; + deptCheckStrictly: boolean; + remark: string; + dataScope?: string; + roleId: string | undefined; + menuIds: Array; + deptIds: Array; +} diff --git a/src/api/system/social/auth.ts b/src/api/system/social/auth.ts new file mode 100644 index 0000000..69f0d7e --- /dev/null +++ b/src/api/system/social/auth.ts @@ -0,0 +1,28 @@ +import request from '@/utils/request'; + +// 绑定账号 +export function authBinding(source: string, tenantId: string) { + return request({ + url: '/auth/binding/' + source, + method: 'get', + params: { + tenantId: tenantId, + domain: window.location.host + } + }); +} + +// 解绑账号 +export function authUnlock(authId: string) { + return request({ + url: '/auth/unlock/' + authId, + method: 'delete' + }); +} +//获取授权列表 +export function getAuthList() { + return request({ + url: '/system/social/list', + method: 'get' + }); +} diff --git a/src/api/system/tenant/index.ts b/src/api/system/tenant/index.ts new file mode 100644 index 0000000..d1d8ff8 --- /dev/null +++ b/src/api/system/tenant/index.ts @@ -0,0 +1,101 @@ +import request from '@/utils/request'; +import { TenantForm, TenantQuery, TenantVO } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询租户列表 +export function listTenant(query: TenantQuery): AxiosPromise { + return request({ + url: '/system/tenant/list', + method: 'get', + params: query + }); +} + +// 查询租户详细 +export function getTenant(id: string | number): AxiosPromise { + return request({ + url: '/system/tenant/' + id, + method: 'get' + }); +} + +// 新增租户 +export function addTenant(data: TenantForm) { + return request({ + url: '/system/tenant', + method: 'post', + headers: { + isEncrypt: true, + repeatSubmit: false + }, + data: data + }); +} + +// 修改租户 +export function updateTenant(data: TenantForm) { + return request({ + url: '/system/tenant', + method: 'put', + data: data + }); +} + +// 租户状态修改 +export function changeTenantStatus(id: string | number, tenantId: string | number, status: string) { + const data = { + id, + tenantId, + status + }; + return request({ + url: '/system/tenant/changeStatus', + method: 'put', + data: data + }); +} + +// 删除租户 +export function delTenant(id: string | number | Array) { + return request({ + url: '/system/tenant/' + id, + method: 'delete' + }); +} + +// 动态切换租户 +export function dynamicTenant(tenantId: string | number) { + return request({ + url: '/system/tenant/dynamic/' + tenantId, + method: 'get' + }); +} + +// 清除动态租户 +export function dynamicClear() { + return request({ + url: '/system/tenant/dynamic/clear', + method: 'get' + }); +} + +// 同步租户套餐 +export function syncTenantPackage(tenantId: string | number, packageId: string | number) { + const data = { + tenantId, + packageId + }; + return request({ + url: '/system/tenant/syncTenantPackage', + method: 'get', + params: data + }); +} + +// 同步租户字典 +export function syncTenantDict() { + return request({ + url: '/system/tenant/syncTenantDict', + method: 'get' + }); +} diff --git a/src/api/system/tenant/types.ts b/src/api/system/tenant/types.ts new file mode 100644 index 0000000..25395fa --- /dev/null +++ b/src/api/system/tenant/types.ts @@ -0,0 +1,46 @@ +export interface TenantVO extends BaseEntity { + id: number | string; + tenantId: number | string; + username: string; + contactUserName: string; + contactPhone: string; + companyName: string; + licenseNumber: string; + address: string; + domain: string; + intro: string; + remark: string; + packageId: string | number; + expireTime: string; + accountCount: number; + status: string; +} + +export interface TenantQuery extends PageQuery { + tenantId: string | number; + + contactUserName: string; + + contactPhone: string; + + companyName: string; +} + +export interface TenantForm { + id: number | string | undefined; + tenantId: number | string | undefined; + username: string; + password: string; + contactUserName: string; + contactPhone: string; + companyName: string; + licenseNumber: string; + domain: string; + address: string; + intro: string; + remark: string; + packageId: string | number; + expireTime: string; + accountCount: number; + status: string; +} diff --git a/src/api/system/tenantPackage/index.ts b/src/api/system/tenantPackage/index.ts new file mode 100644 index 0000000..70d0dab --- /dev/null +++ b/src/api/system/tenantPackage/index.ts @@ -0,0 +1,67 @@ +import request from '@/utils/request'; +import { TenantPkgForm, TenantPkgQuery, TenantPkgVO } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询租户套餐列表 +export function listTenantPackage(query?: TenantPkgQuery): AxiosPromise { + return request({ + url: '/system/tenant/package/list', + method: 'get', + params: query + }); +} + +// 查询租户套餐下拉选列表 +export function selectTenantPackage(): AxiosPromise { + return request({ + url: '/system/tenant/package/selectList', + method: 'get' + }); +} + +// 查询租户套餐详细 +export function getTenantPackage(packageId: string | number): AxiosPromise { + return request({ + url: '/system/tenant/package/' + packageId, + method: 'get' + }); +} + +// 新增租户套餐 +export function addTenantPackage(data: TenantPkgForm) { + return request({ + url: '/system/tenant/package', + method: 'post', + data: data + }); +} + +// 修改租户套餐 +export function updateTenantPackage(data: TenantPkgForm) { + return request({ + url: '/system/tenant/package', + method: 'put', + data: data + }); +} + +// 租户套餐状态修改 +export function changePackageStatus(packageId: number | string, status: string) { + const data = { + packageId, + status + }; + return request({ + url: '/system/tenant/package/changeStatus', + method: 'put', + data: data + }); +} + +// 删除租户套餐 +export function delTenantPackage(packageId: string | number | Array) { + return request({ + url: '/system/tenant/package/' + packageId, + method: 'delete' + }); +} diff --git a/src/api/system/tenantPackage/types.ts b/src/api/system/tenantPackage/types.ts new file mode 100644 index 0000000..c24b8fc --- /dev/null +++ b/src/api/system/tenantPackage/types.ts @@ -0,0 +1,20 @@ +export interface TenantPkgVO extends BaseEntity { + packageId: string | number; + packageName: string; + menuIds: string; + remark: string; + menuCheckStrictly: boolean; + status: string; +} + +export interface TenantPkgQuery extends PageQuery { + packageName: string; +} + +export interface TenantPkgForm { + packageId: string | number | undefined; + packageName: string; + menuIds: string; + remark: string; + menuCheckStrictly: boolean; +} diff --git a/src/api/system/user/index.ts b/src/api/system/user/index.ts new file mode 100644 index 0000000..caffecc --- /dev/null +++ b/src/api/system/user/index.ts @@ -0,0 +1,229 @@ +import { DeptTreeVO } from './../dept/types'; +import { RoleVO } from '@/api/system/role/types'; +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { UserForm, UserQuery, UserVO, UserInfoVO } from './types'; +import { parseStrEmpty } from '@/utils/ruoyi'; + +/** + * 查询用户列表 + * @param query + */ +export const listUser = (query: UserQuery): AxiosPromise => { + return request({ + url: '/system/user/list', + method: 'get', + params: query + }); +}; + +/** + * 通过用户ids查询用户 + * @param userIds + */ +export const optionSelect = (userIds: (number | string)[]): AxiosPromise => { + return request({ + url: '/system/user/optionselect?userIds=' + userIds, + method: 'get' + }); +}; + +/** + * 获取用户详情 + * @param userId + */ +export const getUser = (userId?: string | number): AxiosPromise => { + return request({ + url: '/system/user/' + parseStrEmpty(userId), + method: 'get' + }); +}; + +/** + * 新增用户 + */ +export const addUser = (data: UserForm) => { + return request({ + url: '/system/user', + method: 'post', + data: data + }); +}; + +/** + * 修改用户 + */ +export const updateUser = (data: UserForm) => { + return request({ + url: '/system/user', + method: 'put', + data: data + }); +}; + +/** + * 删除用户 + * @param userId 用户ID + */ +export const delUser = (userId: Array | string | number) => { + return request({ + url: '/system/user/' + userId, + method: 'delete' + }); +}; + +/** + * 用户密码重置 + * @param userId 用户ID + * @param password 密码 + */ +export const resetUserPwd = (userId: string | number, password: string) => { + const data = { + userId, + password + }; + return request({ + url: '/system/user/resetPwd', + method: 'put', + headers: { + isEncrypt: true, + repeatSubmit: false + }, + data: data + }); +}; + +/** + * 用户状态修改 + * @param userId 用户ID + * @param status 用户状态 + */ +export const changeUserStatus = (userId: number | string, status: string) => { + const data = { + userId, + status + }; + return request({ + url: '/system/user/changeStatus', + method: 'put', + data: data + }); +}; + +/** + * 查询用户个人信息 + */ +export const getUserProfile = (): AxiosPromise => { + return request({ + url: '/system/user/profile', + method: 'get' + }); +}; + +/** + * 修改用户个人信息 + * @param data 用户信息 + */ +export const updateUserProfile = (data: UserForm) => { + return request({ + url: '/system/user/profile', + method: 'put', + data: data + }); +}; + +/** + * 用户密码重置 + * @param oldPassword 旧密码 + * @param newPassword 新密码 + */ +export const updateUserPwd = (oldPassword: string, newPassword: string) => { + const data = { + oldPassword, + newPassword + }; + return request({ + url: '/system/user/profile/updatePwd', + method: 'put', + headers: { + isEncrypt: true, + repeatSubmit: false + }, + data: data + }); +}; + +/** + * 用户头像上传 + * @param data 头像文件 + */ +export const uploadAvatar = (data: FormData) => { + return request({ + url: '/system/user/profile/avatar', + method: 'post', + data: data + }); +}; + +/** + * 查询授权角色 + * @param userId 用户ID + */ +export const getAuthRole = (userId: string | number): AxiosPromise<{ user: UserVO; roles: RoleVO[] }> => { + return request({ + url: '/system/user/authRole/' + userId, + method: 'get' + }); +}; + +/** + * 保存授权角色 + * @param data 用户ID + */ +export const updateAuthRole = (data: { userId: string; roleIds: string }) => { + return request({ + url: '/system/user/authRole', + method: 'put', + params: data + }); +}; + +/** + * 查询当前部门的所有用户信息 + * @param deptId + */ +export const listUserByDeptId = (deptId: string | number): AxiosPromise => { + return request({ + url: '/system/user/list/dept/' + deptId, + method: 'get' + }); +}; + +/** + * 查询部门下拉树结构 + */ +export const deptTreeSelect = (): AxiosPromise => { + return request({ + url: '/system/user/deptTree', + method: 'get' + }); +}; + +export default { + listUser, + getUser, + optionSelect, + addUser, + updateUser, + delUser, + resetUserPwd, + changeUserStatus, + getUserProfile, + updateUserProfile, + updateUserPwd, + uploadAvatar, + getAuthRole, + updateAuthRole, + deptTreeSelect, + listUserByDeptId +}; diff --git a/src/api/system/user/types.ts b/src/api/system/user/types.ts new file mode 100644 index 0000000..8b6924e --- /dev/null +++ b/src/api/system/user/types.ts @@ -0,0 +1,86 @@ +import { RoleVO } from '@/api/system/role/types'; +import { PostVO } from '@/api/system/post/types'; + +/** + * 用户信息 + */ +export interface UserInfo { + user: UserVO; + roles: string[]; + permissions: string[]; +} + +/** + * 用户查询对象类型 + */ +export interface UserQuery extends PageQuery { + userName?: string; + nickName?: string; + phonenumber?: string; + status?: string; + deptId?: string | number; + roleId?: string | number; + userIds?: string | number | (string | number)[] | undefined; +} + +/** + * 用户返回对象 + */ +export interface UserVO extends BaseEntity { + userId: string | number; + tenantId: string; + deptId: number; + userName: string; + nickName: string; + userType: string; + email: string; + phonenumber: string; + sex: string; + avatar: string; + status: string; + delFlag: string; + loginIp: string; + loginDate: string; + remark: string; + deptName: string; + roles: RoleVO[]; + roleIds: any; + postIds: any; + roleId: any; + admin: boolean; +} + +/** + * 用户表单类型 + */ +export interface UserForm { + id?: string; + userId?: string; + deptId?: number; + userName: string; + nickName?: string; + password: string; + phonenumber?: string; + email?: string; + sex?: string; + status: string; + remark?: string; + postIds: string[]; + roleIds: string[]; +} + +export interface UserInfoVO { + user: UserVO; + roles: RoleVO[]; + roleIds: string[]; + posts: PostVO[]; + postIds: string[]; + roleGroup: string; + postGroup: string; +} + +export interface ResetPwdForm { + oldPassword: string; + newPassword: string; + confirmPassword: string; +} diff --git a/src/api/tool/gen/index.ts b/src/api/tool/gen/index.ts new file mode 100644 index 0000000..efe079c --- /dev/null +++ b/src/api/tool/gen/index.ts @@ -0,0 +1,86 @@ +import request from '@/utils/request'; +import { DbTableQuery, DbTableVO, TableQuery, TableVO, GenTableVO, DbTableForm } from './types'; +import { AxiosPromise } from 'axios'; + +// 查询生成表数据 +export const listTable = (query: TableQuery): AxiosPromise => { + return request({ + url: '/tool/gen/list', + method: 'get', + params: query + }); +}; +// 查询db数据库列表 +export const listDbTable = (query: DbTableQuery): AxiosPromise => { + return request({ + url: '/tool/gen/db/list', + method: 'get', + params: query + }); +}; + +// 查询表详细信息 +export const getGenTable = (tableId: string | number): AxiosPromise => { + return request({ + url: '/tool/gen/' + tableId, + method: 'get' + }); +}; + +// 修改代码生成信息 +export const updateGenTable = (data: DbTableForm): AxiosPromise => { + return request({ + url: '/tool/gen', + method: 'put', + data: data + }); +}; + +// 导入表 +export const importTable = (data: { tables: string; dataName: string }): AxiosPromise => { + return request({ + url: '/tool/gen/importTable', + method: 'post', + params: data + }); +}; + +// 预览生成代码 +export const previewTable = (tableId: string | number) => { + return request({ + url: '/tool/gen/preview/' + tableId, + method: 'get' + }); +}; + +// 删除表数据 +export const delTable = (tableId: string | number | Array) => { + return request({ + url: '/tool/gen/' + tableId, + method: 'delete' + }); +}; + +// 生成代码(自定义路径) +export const genCode = (tableId: string | number) => { + return request({ + url: '/tool/gen/genCode/' + tableId, + method: 'get' + }); +}; + +// 同步数据库 +export const synchDb = (tableId: string | number) => { + return request({ + url: '/tool/gen/synchDb/' + tableId, + method: 'get' + }); +}; + +// 获取数据源名称 +export const getDataNames = () => { + return request({ + url: '/tool/gen/getDataNames', + method: 'get' + }); +}; diff --git a/src/api/tool/gen/types.ts b/src/api/tool/gen/types.ts new file mode 100644 index 0000000..7f7b62f --- /dev/null +++ b/src/api/tool/gen/types.ts @@ -0,0 +1,180 @@ +export interface TableVO extends BaseEntity { + createDept: number | string; + tableId: string | number; + dataName: string; + tableName: string; + tableComment: string; + subTableName?: any; + subTableFkName?: any; + className: string; + tplCategory: string; + packageName: string; + moduleName: string; + businessName: string; + functionName: string; + functionAuthor: string; + genType: string; + genPath: string; + pkColumn?: any; + columns?: any; + options?: any; + remark?: any; + treeCode?: any; + treeParentCode?: any; + treeName?: any; + menuIds?: any; + parentMenuId?: any; + parentMenuName?: any; + tree: boolean; + crud: boolean; +} + +export interface TableQuery extends PageQuery { + tableName: string; + tableComment: string; + dataName: string; +} + +export interface DbColumnVO extends BaseEntity { + createDept?: any; + columnId?: any; + tableId?: any; + columnName?: any; + columnComment?: any; + columnType?: any; + javaType?: any; + javaField?: any; + isPk?: any; + isIncrement?: any; + isRequired?: any; + isInsert?: any; + isEdit?: any; + isList?: any; + isQuery?: any; + queryType?: any; + htmlType?: any; + dictType?: any; + sort?: any; + increment: boolean; + capJavaField?: any; + usableColumn: boolean; + superColumn: boolean; + list: boolean; + pk: boolean; + insert: boolean; + edit: boolean; + query: boolean; + required: boolean; +} + +export interface DbTableVO { + createDept?: any; + tableId?: any; + tableName: string; + tableComment: string; + subTableName?: any; + subTableFkName?: any; + className?: any; + tplCategory?: any; + packageName?: any; + moduleName?: any; + businessName?: any; + functionName?: any; + functionAuthor?: any; + genType?: any; + genPath?: any; + pkColumn?: any; + columns: DbColumnVO[]; + options?: any; + remark?: any; + treeCode?: any; + treeParentCode?: any; + treeName?: any; + menuIds?: any; + parentMenuId?: any; + parentMenuName?: any; + tree: boolean; + crud: boolean; +} + +export interface DbTableQuery extends PageQuery { + dataName: string; + tableName: string; + tableComment: string; +} + +export interface GenTableVO { + info: DbTableVO; + rows: DbColumnVO[]; + tables: DbTableVO[]; +} + +export interface DbColumnForm extends BaseEntity { + createDept: number; + columnId: string; + tableId: string; + columnName: string; + columnComment: string; + columnType: string; + javaType: string; + javaField: string; + isPk: string; + isIncrement: string; + isRequired: string; + isInsert?: any; + isEdit: string; + isList: string; + isQuery?: any; + queryType: string; + htmlType: string; + dictType: string; + sort: number; + increment: boolean; + capJavaField: string; + usableColumn: boolean; + superColumn: boolean; + list: boolean; + pk: boolean; + insert: boolean; + edit: boolean; + query: boolean; + required: boolean; +} + +export interface DbParamForm { + treeCode?: any; + treeName?: any; + treeParentCode?: any; + parentMenuId: string; +} + +export interface DbTableForm extends BaseEntity { + createDept?: any; + tableId: string | string; + tableName: string; + tableComment: string; + subTableName?: any; + subTableFkName?: any; + className: string; + tplCategory: string; + packageName: string; + moduleName: string; + businessName: string; + functionName: string; + functionAuthor: string; + genType: string; + genPath: string; + pkColumn?: any; + columns: DbColumnForm[]; + options: string; + remark?: any; + treeCode?: any; + treeParentCode?: any; + treeName?: any; + menuIds?: any; + parentMenuId: string; + parentMenuName?: any; + tree: boolean; + crud: boolean; + params: DbParamForm; +} diff --git a/src/api/types.ts b/src/api/types.ts new file mode 100644 index 0000000..617286c --- /dev/null +++ b/src/api/types.ts @@ -0,0 +1,59 @@ +/** + * 注册 + */ +export type RegisterForm = { + tenantId: string; + username: string; + password: string; + confirmPassword?: string; + code?: string; + uuid?: string; + userType?: string; +}; + +/** + * 登录请求 + */ +export interface LoginData { + tenantId?: string; + username?: string; + password?: string; + rememberMe?: boolean; + socialCode?: string; + socialState?: string; + source?: string; + code?: string; + uuid?: string; + clientId: string; + grantType: string; +} + +/** + * 登录响应 + */ +export interface LoginResult { + access_token: string; +} + +/** + * 验证码返回 + */ +export interface VerifyCodeResult { + captchaEnabled: boolean; + uuid?: string; + img?: string; +} + +/** + * 租户 + */ +export interface TenantVO { + companyName: string; + domain: any; + tenantId: string; +} + +export interface TenantInfo { + tenantEnabled: boolean; + voList: TenantVO[]; +} diff --git a/src/api/workflow/category/index.ts b/src/api/workflow/category/index.ts new file mode 100644 index 0000000..b6a83ea --- /dev/null +++ b/src/api/workflow/category/index.ts @@ -0,0 +1,76 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { CategoryVO, CategoryForm, CategoryQuery, CategoryTreeVO } from '@/api/workflow/category/types'; + +/** + * 查询流程分类列表 + * @param query + * @returns {*} + */ + +export const listCategory = (query?: CategoryQuery): AxiosPromise => { + return request({ + url: '/workflow/category/list', + method: 'get', + params: query + }); +}; + +/** + * 查询流程分类详细 + * @param categoryId + */ +export const getCategory = (categoryId: string | number): AxiosPromise => { + return request({ + url: '/workflow/category/' + categoryId, + method: 'get' + }); +}; + +/** + * 新增流程分类 + * @param data + */ +export const addCategory = (data: CategoryForm) => { + return request({ + url: '/workflow/category', + method: 'post', + data: data + }); +}; + +/** + * 修改流程分类 + * @param data + */ +export const updateCategory = (data: CategoryForm) => { + return request({ + url: '/workflow/category', + method: 'put', + data: data + }); +}; + +/** + * 删除流程分类 + * @param categoryId + */ +export const delCategory = (categoryId: string | number | Array) => { + return request({ + url: '/workflow/category/' + categoryId, + method: 'delete' + }); +}; + +/** + * 获取流程分类树列表 + * @param query 流程实例id + * @returns + */ +export const categoryTree = (query?: CategoryForm): AxiosPromise => { + return request({ + url: `/workflow/category/categoryTree`, + method: 'get', + params: query + }); +}; diff --git a/src/api/workflow/category/types.ts b/src/api/workflow/category/types.ts new file mode 100644 index 0000000..99a53a6 --- /dev/null +++ b/src/api/workflow/category/types.ts @@ -0,0 +1,67 @@ +export interface CategoryTreeVO { + id: number | string; + label: string; + parentId: number | string; + weight: number; + children: CategoryTreeVO[]; +} +export interface CategoryVO { + /** + * 流程分类ID + */ + categoryId: string | number; + + /** + * 父级id + */ + parentId: string | number; + + /** + * 流程分类名称 + */ + categoryName: string; + + /** + * 显示顺序 + */ + orderNum: number; + + /** + * 创建时间 + */ + createTime: string; + + /** + * 子对象 + */ + children: CategoryVO[]; +} + +export interface CategoryForm extends BaseEntity { + /** + * 流程分类ID + */ + categoryId?: string | number; + + /** + * 流程分类名称 + */ + categoryName?: string; + + /** + * 父流程分类id + */ + parentId?: string | number; + + /** + * 显示顺序 + */ + orderNum?: number; +} + +export interface CategoryQuery { + /** + * 流程分类名称 + */ + categoryName?: string; +} diff --git a/src/api/workflow/definition/index.ts b/src/api/workflow/definition/index.ts new file mode 100644 index 0000000..49e6ee8 --- /dev/null +++ b/src/api/workflow/definition/index.ts @@ -0,0 +1,170 @@ +import request from '@/utils/request'; +import { FlowDefinitionQuery, definitionXmlVO, FlowDefinitionForm, FlowDefinitionVo } from '@/api/workflow/definition/types'; +import { AxiosPromise } from 'axios'; + +/** + * 获取流程定义列表 + * @param query 流程实例id + * @returns + */ +export const listDefinition = (query: FlowDefinitionQuery): AxiosPromise => { + return request({ + url: `/workflow/definition/list`, + method: 'get', + params: query + }); +}; + +/** + * 查询未发布的流程定义列表 + * @param query 流程实例id + * @returns + */ +export const unPublishList = (query: FlowDefinitionQuery): AxiosPromise => { + return request({ + url: `/workflow/definition/unPublishList`, + method: 'get', + params: query + }); +}; + +/** + * 通过流程定义id获取xml + * @param definitionId 流程定义id + * @returns + */ +export const definitionXml = (definitionId: string): AxiosPromise => { + return request({ + url: `/workflow/definition/definitionXml/${definitionId}`, + method: 'get' + }); +}; + +/** + * 删除流程定义 + * @param id 流程定义id + * @returns + */ +export const deleteDefinition = (id: string | string[]) => { + return request({ + url: `/workflow/definition/${id}`, + method: 'delete' + }); +}; + +/** + * 挂起/激活 + * @param definitionId 流程定义id + * @param activityStatus 状态 + * @returns + */ +export const active = (definitionId: string, activityStatus: boolean) => { + return request({ + url: `/workflow/definition/active/${definitionId}`, + method: 'put', + params: { + active: activityStatus + } + }); +}; + +/** + * 通过zip或xml部署流程定义 + * @returns + */ +export function importDef(data: any) { + return request({ + url: '/workflow/definition/importDef', + method: 'post', + data: data, + headers: { + repeatSubmit: false + } + }); +} + +/** + * 发布流程定义 + * @param id 流程定义id + * @returns + */ +export const publish = (id: string) => { + return request({ + url: `/workflow/definition/publish/${id}`, + method: 'put' + }); +}; + +/** + * 取消发布流程定义 + * @param id 流程定义id + * @returns + */ +export const unPublish = (id: string) => { + return request({ + url: `/workflow/definition/unPublish/${id}`, + method: 'put' + }); +}; + +/** + * 获取流程定义xml字符串 + * @param id 流程定义id + * @returns + */ +export const xmlString = (id: string) => { + return request({ + url: `/workflow/definition/xmlString/${id}`, + method: 'get' + }); +}; + +/** + * 新增 + * @param data 参数 + * @returns + */ +export const add = (data: FlowDefinitionForm) => { + return request({ + url: `/workflow/definition`, + method: 'post', + data: data + }); +}; + +/** + * 修改 + * @param data 参数 + * @returns + */ +export const edit = (data: FlowDefinitionForm) => { + return request({ + url: `/workflow/definition`, + method: 'put', + data: data + }); +}; + +/** + * 查询详情 + * @param id 参数 + * @returns + */ +export const getInfo = (id: number | string) => { + return request({ + url: `/workflow/definition/${id}`, + method: 'get' + }); +}; + +/** + * 复制流程定义 + * @param id 流程定义id + * @returns + */ +export const copy = (id: string) => { + return request({ + url: `/workflow/definition/copy/${id}`, + method: 'post' + }); +}; diff --git a/src/api/workflow/definition/types.ts b/src/api/workflow/definition/types.ts new file mode 100644 index 0000000..93d081e --- /dev/null +++ b/src/api/workflow/definition/types.ts @@ -0,0 +1,34 @@ +export interface FlowDefinitionQuery extends PageQuery { + flowCode?: string; + flowName?: string; + category: string | number; + isPublish?: number; +} + +export interface FlowDefinitionVo { + id: string; + flowName: string; + flowCode: string; + formPath: string; + version: string; + isPublish: number; + activityStatus: number; + createTime: Date; + updateTime: Date; +} + +export interface FlowDefinitionForm { + id: string; + flowName: string; + flowCode: string; + category: string; + ext: string; + formPath: string; + formCustom: string; + modelValue: string; +} + +export interface definitionXmlVO { + xml: string[]; + xmlStr: string; +} diff --git a/src/api/workflow/instance/index.ts b/src/api/workflow/instance/index.ts new file mode 100644 index 0000000..ad136f0 --- /dev/null +++ b/src/api/workflow/instance/index.ts @@ -0,0 +1,125 @@ +import request from '@/utils/request'; +import { FlowInstanceQuery, FlowInstanceVO } from '@/api/workflow/instance/types'; +import { AxiosPromise } from 'axios'; + +/** + * 查询运行中实例列表 + * @param query + * @returns {*} + */ +export const pageByRunning = (query: FlowInstanceQuery): AxiosPromise => { + return request({ + url: '/workflow/instance/pageByRunning', + method: 'get', + params: query + }); +}; + +/** + * 查询已完成实例列表 + * @param query + * @returns {*} + */ +export const pageByFinish = (query: FlowInstanceQuery): AxiosPromise => { + return request({ + url: '/workflow/instance/pageByFinish', + method: 'get', + params: query + }); +}; + +/** + * 通过业务id获取历史流程图 + */ +export const flowHisTaskList = (businessId: string | number) => { + return request({ + url: `/workflow/instance/flowHisTaskList/${businessId}` + '?t' + Math.random(), + method: 'get' + }); +}; + +/** + * 分页查询当前登录人单据 + * @param query + * @returns {*} + */ +export const pageByCurrent = (query: FlowInstanceQuery): AxiosPromise => { + return request({ + url: '/workflow/instance/pageByCurrent', + method: 'get', + params: query + }); +}; + +/** + * 撤销流程 + * @param data 参数 + * @returns + */ +export const cancelProcessApply = (data: any) => { + return request({ + url: `/workflow/instance/cancelProcessApply`, + method: 'put', + data: data + }); +}; + +/** + * 获取流程变量 + * @param instanceId 实例id + * @returns + */ +export const instanceVariable = (instanceId: string | number) => { + return request({ + url: `/workflow/instance/instanceVariable/${instanceId}`, + method: 'get' + }); +}; + +/** + * 删除 + * @param instanceIds 流程实例id + * @returns + */ +export const deleteByInstanceIds = (instanceIds: Array | string | number) => { + return request({ + url: `/workflow/instance/deleteByInstanceIds/${instanceIds}`, + method: 'delete' + }); +}; + +/** + * 删除历史流程实例 + * @param instanceIds + */ +export const deleteHisByInstanceIds = (instanceIds: Array | string | number) => { + return request({ + url: `/workflow/instance/deleteHisByInstanceIds/${instanceIds}`, + method: 'delete' + }); +}; + +/** + * 作废流程 + * @param data 参数 + * @returns + */ +export const invalid = (data: any) => { + return request({ + url: `/workflow/instance/invalid`, + method: 'post', + data: data + }); +}; +/** + * 修改流程变量 + * @param data 参数 + * @returns + */ +export const updateVariable = (data: any) => { + return request({ + url: `/workflow/instance/updateVariable`, + method: 'put', + data: data + }); +}; diff --git a/src/api/workflow/instance/types.ts b/src/api/workflow/instance/types.ts new file mode 100644 index 0000000..7cb7f97 --- /dev/null +++ b/src/api/workflow/instance/types.ts @@ -0,0 +1,28 @@ +import { FlowTaskVO } from '@/api/workflow/task/types'; + +export interface FlowInstanceQuery extends PageQuery { + category?: string | number; + nodeName?: string; + flowCode?: string; + flowName?: string; + createByIds?: string[] | number[]; + businessId?: string; +} + +export interface FlowInstanceVO extends BaseEntity { + id: string | number; + definitionId: string; + flowName: string; + flowCode: string; + version: string; + businessId: string; + activityStatus: number; + tenantId: string; + createTime: string; + createBy: string; + flowStatus: string; + flowStatusName: string; + flowTaskList: FlowTaskVO[]; + businessCode: string; + businessTitle: string; +} diff --git a/src/api/workflow/leave/index.ts b/src/api/workflow/leave/index.ts new file mode 100644 index 0000000..5a88edb --- /dev/null +++ b/src/api/workflow/leave/index.ts @@ -0,0 +1,75 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { LeaveVO, LeaveQuery, LeaveForm } from '@/api/workflow/leave/types'; + +/** + * 查询请假列表 + * @param query + * @returns {*} + */ + +export const listLeave = (query?: LeaveQuery): AxiosPromise => { + return request({ + url: '/workflow/leave/list', + method: 'get', + params: query + }); +}; + +/** + * 查询请假详细 + * @param id + */ +export const getLeave = (id: string | number): AxiosPromise => { + return request({ + url: '/workflow/leave/' + id, + method: 'get' + }); +}; + +/** + * 新增请假 + * @param data + */ +export const addLeave = (data: LeaveForm): AxiosPromise => { + return request({ + url: '/workflow/leave', + method: 'post', + data: data + }); +}; + +/** + * 提交请假并发起流程 + * @param data + */ +export const submitAndFlowStart = (data: LeaveForm): AxiosPromise => { + return request({ + url: '/workflow/leave/submitAndFlowStart', + method: 'post', + data: data + }); +}; + +/** + * 修改请假 + * @param data + */ +export const updateLeave = (data: LeaveForm): AxiosPromise => { + return request({ + url: '/workflow/leave', + method: 'put', + data: data + }); +}; + +/** + * 删除请假 + * @param id + */ +export const delLeave = (id: string | number | Array) => { + return request({ + url: '/workflow/leave/' + id, + method: 'delete' + }); +}; diff --git a/src/api/workflow/leave/types.ts b/src/api/workflow/leave/types.ts new file mode 100644 index 0000000..c8e58a7 --- /dev/null +++ b/src/api/workflow/leave/types.ts @@ -0,0 +1,26 @@ +export interface LeaveVO { + id: string | number; + applyCode?: string; + leaveType: string; + startDate: string; + endDate: string; + leaveDays: number; + remark: string; + status?: string; +} + +export interface LeaveForm extends BaseEntity { + id?: string | number; + applyCode?: string; + leaveType?: string; + startDate?: string; + endDate?: string; + leaveDays?: number; + remark?: string; + status?: string; +} + +export interface LeaveQuery extends PageQuery { + startLeaveDays?: number; + endLeaveDays?: number; +} diff --git a/src/api/workflow/spel/index.ts b/src/api/workflow/spel/index.ts new file mode 100644 index 0000000..0cc8746 --- /dev/null +++ b/src/api/workflow/spel/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { SpelVO, SpelForm, SpelQuery } from '@/api/workflow/spel/types'; + +/** + * 查询流程spel表达式定义列表 + * @param query + * @returns {*} + */ + +export const listSpel = (query?: SpelQuery): AxiosPromise => { + return request({ + url: '/workflow/spel/list', + method: 'get', + params: query + }); +}; + +/** + * 查询流程spel表达式定义详细 + * @param id + */ +export const getSpel = (id: string | number): AxiosPromise => { + return request({ + url: '/workflow/spel/' + id, + method: 'get' + }); +}; + +/** + * 新增流程spel表达式定义 + * @param data + */ +export const addSpel = (data: SpelForm) => { + return request({ + url: '/workflow/spel', + method: 'post', + data: data + }); +}; + +/** + * 修改流程spel表达式定义 + * @param data + */ +export const updateSpel = (data: SpelForm) => { + return request({ + url: '/workflow/spel', + method: 'put', + data: data + }); +}; + +/** + * 删除流程spel表达式定义 + * @param id + */ +export const delSpel = (id: string | number | Array) => { + return request({ + url: '/workflow/spel/' + id, + method: 'delete' + }); +}; diff --git a/src/api/workflow/spel/types.ts b/src/api/workflow/spel/types.ts new file mode 100644 index 0000000..e0a694c --- /dev/null +++ b/src/api/workflow/spel/types.ts @@ -0,0 +1,111 @@ +export interface SpelVO { + /** + * 主键id + */ + id: string | number; + + /** + * 组件名称 + */ + componentName: string; + + /** + * 方法名 + */ + methodName: string; + + /** + * 参数 + */ + methodParams: string; + + /** + * 预览spel值 + */ + viewSpel: string; + + /** + * 状态(0正常 1停用) + */ + status: string; + + /** + * 备注 + */ + remark?: string; + +} + +export interface SpelForm extends BaseEntity { + /** + * 主键id + */ + id?: string | number; + + /** + * 组件名称 + */ + componentName?: string; + + /** + * 方法名 + */ + methodName?: string; + + /** + * 参数 + */ + methodParams?: string; + + /** + * 预览spel值 + */ + viewSpel?: string; + + /** + * 状态(0正常 1停用) + */ + status?: string; + + /** + * 备注 + */ + remark?: string; + +} + +export interface SpelQuery extends PageQuery { + + /** + * 组件名称 + */ + componentName?: string; + + /** + * 方法名 + */ + methodName?: string; + + /** + * 参数 + */ + methodParams?: string; + + /** + * 预览spel值 + */ + viewSpel?: string; + + /** + * 状态(0正常 1停用) + */ + status?: string; + + /** + * 日期范围参数 + */ + params?: any; +} + + + diff --git a/src/api/workflow/task/index.ts b/src/api/workflow/task/index.ts new file mode 100644 index 0000000..dc52f62 --- /dev/null +++ b/src/api/workflow/task/index.ts @@ -0,0 +1,206 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { TaskQuery, FlowTaskVO, TaskOperationBo } from '@/api/workflow/task/types'; + +/** + * 查询待办列表 + * @param query + * @returns {*} + */ +export const pageByTaskWait = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/pageByTaskWait', + method: 'get', + params: query + }); +}; + +/** + * 查询已办列表 + * @param query + * @returns {*} + */ +export const pageByTaskFinish = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/pageByTaskFinish', + method: 'get', + params: query + }); +}; + +/** + * 查询当前用户的抄送列表 + * @param query + * @returns {*} + */ +export const pageByTaskCopy = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/pageByTaskCopy', + method: 'get', + params: query + }); +}; + +/** + * 当前租户所有待办任务 + * @param query + * @returns {*} + */ +export const pageByAllTaskWait = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/pageByAllTaskWait', + method: 'get', + params: query + }); +}; + +/** + * 当前租户所有已办任务 + * @param query + * @returns {*} + */ +export const pageByAllTaskFinish = (query: TaskQuery): AxiosPromise => { + return request({ + url: '/workflow/task/pageByAllTaskFinish', + method: 'get', + params: query + }); +}; + +/** + * 启动流程 + * @param data + * @returns {*} + */ +export const startWorkFlow = (data: object): any => { + return request({ + url: '/workflow/task/startWorkFlow', + method: 'post', + data: data + }); +}; + +/** + * 办理流程 + * @param data + * @returns {*} + */ +export const completeTask = (data: object) => { + return request({ + url: '/workflow/task/completeTask', + method: 'post', + data: data + }); +}; + +/** + * 任务驳回 + * @param data + * @returns {*} + */ +export const backProcess = (data: any): any => { + return request({ + url: '/workflow/task/backProcess', + method: 'post', + data: data + }); +}; + +/** + * 获取当前任务 + * @param taskId + * @returns + */ +export const getTask = (taskId: string) => { + return request({ + url: '/workflow/task/getTask/' + taskId, + method: 'get' + }); +}; + +/** + * 修改任务办理人 + * @param taskIdList + * @param userId + * @returns + */ +export const updateAssignee = (taskIdList: Array, userId: string) => { + return request({ + url: `/workflow/task/updateAssignee/${userId}`, + method: 'put', + data: taskIdList + }); +}; + +/** + * 终止任务 + * @returns + */ +export const terminationTask = (data: any) => { + return request({ + url: `/workflow/task/terminationTask`, + method: 'post', + data: data + }); +}; + +/** + * 获取可驳回得任务节点 + * @returns + */ +export const getBackTaskNode = (taskId: string | number, nodeCode: string) => { + return request({ + url: `/workflow/task/getBackTaskNode/${taskId}/${nodeCode}`, + method: 'get' + }); +}; + +/** + * 任务操作 操作类型,委派 delegateTask、转办 transferTask、加签 addSignature、减签 reductionSignature + * @returns + */ +export const taskOperation = (data: TaskOperationBo, operation: string) => { + return request({ + url: `/workflow/task/taskOperation/${operation}`, + method: 'post', + data: data + }); +}; + +/** + * 获取当前任务办理人 + * @param taskId 任务id + * @returns + */ +export const currentTaskAllUser = (taskId: string | number) => { + return request({ + url: `/workflow/task/currentTaskAllUser/${taskId}`, + method: 'get' + }); +}; + +/** + * 获取下一节点写 + * @param data参数 + * @returns + */ +export const getNextNodeList = (data: any): any => { + return request({ + url: '/workflow/task/getNextNodeList', + method: 'post', + data: data + }); +}; + +/** + * 催办任务 + * @param data参数 + * @returns + */ +export const urgeTask = (data: any): any => { + return request({ + url: '/workflow/task/urgeTask', + method: 'post', + data: data + }); +}; diff --git a/src/api/workflow/task/types.ts b/src/api/workflow/task/types.ts new file mode 100644 index 0000000..e3c9abf --- /dev/null +++ b/src/api/workflow/task/types.ts @@ -0,0 +1,58 @@ +export interface TaskQuery extends PageQuery { + nodeName?: string; + flowCode?: string; + flowName?: string; + createByIds?: string[] | number[]; +} + +export interface ParticipantVo { + groupIds?: string[] | number[]; + candidate: string[] | number[]; + candidateName: string[]; + claim: boolean; +} +export interface FlowTaskVO { + id: string | number; + createTime?: Date; + updateTime?: Date; + tenantId?: string; + definitionId?: string; + instanceId: string; + flowName: string; + businessId: string; + nodeCode: string; + nodeName: string; + flowCode: string; + flowStatus: string; + formCustom: string; + formPath: string; + nodeType: number; + nodeRatio: string | number; + version?: string; + applyNode?: boolean; + buttonList?: ButtonList[]; + copyList?: FlowCopyVo[]; + varList?: Map; + businessCode: string; + businessTitle: string; +} + +export interface ButtonList { + code: string; + show: boolean; +} +export interface FlowCopyVo { + userId: string | number; + userName: string; +} + +export interface TaskOperationBo { + //委派/转办人的用户ID(必填,准对委派/转办人操作) + userId?: string; + //加签/减签人的用户ID列表(必填,针对加签/减签操作) + userIds?: string[]; + //任务ID(必填) + taskId: string | number; + //意见或备注信息(可选) + message?: string; +} diff --git a/src/api/workflow/workflowCommon/index.ts b/src/api/workflow/workflowCommon/index.ts new file mode 100644 index 0000000..0f5ce1b --- /dev/null +++ b/src/api/workflow/workflowCommon/index.ts @@ -0,0 +1,15 @@ +import { RouterJumpVo } from '@/api/workflow/workflowCommon/types'; + +export default { + routerJump(routerJumpVo: RouterJumpVo, proxy) { + proxy.$tab.closePage(proxy.$route); + proxy.$router.push({ + path: routerJumpVo.formPath, + query: { + id: routerJumpVo.businessId, + type: routerJumpVo.type, + taskId: routerJumpVo.taskId + } + }); + } +}; diff --git a/src/api/workflow/workflowCommon/types.ts b/src/api/workflow/workflowCommon/types.ts new file mode 100644 index 0000000..8ab5a67 --- /dev/null +++ b/src/api/workflow/workflowCommon/types.ts @@ -0,0 +1,14 @@ +export interface RouterJumpVo { + businessId: string; + taskId: string | number; + type: string; + formCustom: string; + formPath: string; +} + +export interface StartProcessBo { + businessId: string | number; + flowCode: string; + variables: any; + flowInstanceBizExtBo: any; +} diff --git a/src/assets/401_images/401.gif b/src/assets/401_images/401.gif new file mode 100644 index 0000000..cd6e0d9 Binary files /dev/null and b/src/assets/401_images/401.gif differ diff --git a/src/assets/404_images/404.png b/src/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 Binary files /dev/null and b/src/assets/404_images/404.png differ diff --git a/src/assets/404_images/404_cloud.png b/src/assets/404_images/404_cloud.png new file mode 100644 index 0000000..c6281d0 Binary files /dev/null and b/src/assets/404_images/404_cloud.png differ diff --git a/src/assets/icons/svg/404.svg b/src/assets/icons/svg/404.svg new file mode 100644 index 0000000..6df5019 --- /dev/null +++ b/src/assets/icons/svg/404.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/bug.svg b/src/assets/icons/svg/bug.svg new file mode 100644 index 0000000..05a150d --- /dev/null +++ b/src/assets/icons/svg/bug.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/build.svg b/src/assets/icons/svg/build.svg new file mode 100644 index 0000000..97c4688 --- /dev/null +++ b/src/assets/icons/svg/build.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/button.svg b/src/assets/icons/svg/button.svg new file mode 100644 index 0000000..d14d580 --- /dev/null +++ b/src/assets/icons/svg/button.svg @@ -0,0 +1 @@ + diff --git a/src/assets/icons/svg/caret-back.svg b/src/assets/icons/svg/caret-back.svg new file mode 100644 index 0000000..9bae722 --- /dev/null +++ b/src/assets/icons/svg/caret-back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/caret-forward.svg b/src/assets/icons/svg/caret-forward.svg new file mode 100644 index 0000000..1ec3f7d --- /dev/null +++ b/src/assets/icons/svg/caret-forward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/cascader.svg b/src/assets/icons/svg/cascader.svg new file mode 100644 index 0000000..e256024 --- /dev/null +++ b/src/assets/icons/svg/cascader.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/category.svg b/src/assets/icons/svg/category.svg new file mode 100644 index 0000000..df92526 --- /dev/null +++ b/src/assets/icons/svg/category.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/chart.svg b/src/assets/icons/svg/chart.svg new file mode 100644 index 0000000..27728fb --- /dev/null +++ b/src/assets/icons/svg/chart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/checkbox.svg b/src/assets/icons/svg/checkbox.svg new file mode 100644 index 0000000..013fd3a --- /dev/null +++ b/src/assets/icons/svg/checkbox.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/clipboard.svg b/src/assets/icons/svg/clipboard.svg new file mode 100644 index 0000000..90923ff --- /dev/null +++ b/src/assets/icons/svg/clipboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/code.svg b/src/assets/icons/svg/code.svg new file mode 100644 index 0000000..5f9c5ab --- /dev/null +++ b/src/assets/icons/svg/code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/color.svg b/src/assets/icons/svg/color.svg new file mode 100644 index 0000000..44a81aa --- /dev/null +++ b/src/assets/icons/svg/color.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/company.svg b/src/assets/icons/svg/company.svg new file mode 100644 index 0000000..fcf1394 --- /dev/null +++ b/src/assets/icons/svg/company.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/component.svg b/src/assets/icons/svg/component.svg new file mode 100644 index 0000000..29c3458 --- /dev/null +++ b/src/assets/icons/svg/component.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/dashboard.svg b/src/assets/icons/svg/dashboard.svg new file mode 100644 index 0000000..5317d37 --- /dev/null +++ b/src/assets/icons/svg/dashboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/date-range.svg b/src/assets/icons/svg/date-range.svg new file mode 100644 index 0000000..fda571e --- /dev/null +++ b/src/assets/icons/svg/date-range.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/date.svg b/src/assets/icons/svg/date.svg new file mode 100644 index 0000000..52dc73e --- /dev/null +++ b/src/assets/icons/svg/date.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/dict.svg b/src/assets/icons/svg/dict.svg new file mode 100644 index 0000000..4849377 --- /dev/null +++ b/src/assets/icons/svg/dict.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/documentation.svg b/src/assets/icons/svg/documentation.svg new file mode 100644 index 0000000..7043122 --- /dev/null +++ b/src/assets/icons/svg/documentation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/download.svg b/src/assets/icons/svg/download.svg new file mode 100644 index 0000000..c896951 --- /dev/null +++ b/src/assets/icons/svg/download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/drag.svg b/src/assets/icons/svg/drag.svg new file mode 100644 index 0000000..4185d3c --- /dev/null +++ b/src/assets/icons/svg/drag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/druid.svg b/src/assets/icons/svg/druid.svg new file mode 100644 index 0000000..a2b4b4e --- /dev/null +++ b/src/assets/icons/svg/druid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/edit.svg b/src/assets/icons/svg/edit.svg new file mode 100644 index 0000000..d26101f --- /dev/null +++ b/src/assets/icons/svg/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/education.svg b/src/assets/icons/svg/education.svg new file mode 100644 index 0000000..7bfb01d --- /dev/null +++ b/src/assets/icons/svg/education.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/email.svg b/src/assets/icons/svg/email.svg new file mode 100644 index 0000000..74d25e2 --- /dev/null +++ b/src/assets/icons/svg/email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/example.svg b/src/assets/icons/svg/example.svg new file mode 100644 index 0000000..46f42b5 --- /dev/null +++ b/src/assets/icons/svg/example.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/excel.svg b/src/assets/icons/svg/excel.svg new file mode 100644 index 0000000..74d97b8 --- /dev/null +++ b/src/assets/icons/svg/excel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/exit-fullscreen.svg b/src/assets/icons/svg/exit-fullscreen.svg new file mode 100644 index 0000000..485c128 --- /dev/null +++ b/src/assets/icons/svg/exit-fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/eye-open.svg b/src/assets/icons/svg/eye-open.svg new file mode 100644 index 0000000..88dcc98 --- /dev/null +++ b/src/assets/icons/svg/eye-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/eye.svg b/src/assets/icons/svg/eye.svg new file mode 100644 index 0000000..16ed2d8 --- /dev/null +++ b/src/assets/icons/svg/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/finish.svg b/src/assets/icons/svg/finish.svg new file mode 100644 index 0000000..4685c23 --- /dev/null +++ b/src/assets/icons/svg/finish.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/form.svg b/src/assets/icons/svg/form.svg new file mode 100644 index 0000000..dcbaa18 --- /dev/null +++ b/src/assets/icons/svg/form.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/fullscreen.svg b/src/assets/icons/svg/fullscreen.svg new file mode 100644 index 0000000..0e86b6f --- /dev/null +++ b/src/assets/icons/svg/fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/gitee.svg b/src/assets/icons/svg/gitee.svg new file mode 100644 index 0000000..6324608 --- /dev/null +++ b/src/assets/icons/svg/gitee.svg @@ -0,0 +1 @@ + diff --git a/src/assets/icons/svg/github.svg b/src/assets/icons/svg/github.svg new file mode 100644 index 0000000..db0a0d4 --- /dev/null +++ b/src/assets/icons/svg/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/guide.svg b/src/assets/icons/svg/guide.svg new file mode 100644 index 0000000..b271001 --- /dev/null +++ b/src/assets/icons/svg/guide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/icon.svg b/src/assets/icons/svg/icon.svg new file mode 100644 index 0000000..82be8ee --- /dev/null +++ b/src/assets/icons/svg/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/input.svg b/src/assets/icons/svg/input.svg new file mode 100644 index 0000000..ab91381 --- /dev/null +++ b/src/assets/icons/svg/input.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/international.svg b/src/assets/icons/svg/international.svg new file mode 100644 index 0000000..e9b56ee --- /dev/null +++ b/src/assets/icons/svg/international.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/job.svg b/src/assets/icons/svg/job.svg new file mode 100644 index 0000000..2a93a25 --- /dev/null +++ b/src/assets/icons/svg/job.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/language.svg b/src/assets/icons/svg/language.svg new file mode 100644 index 0000000..0082b57 --- /dev/null +++ b/src/assets/icons/svg/language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/link.svg b/src/assets/icons/svg/link.svg new file mode 100644 index 0000000..48197ba --- /dev/null +++ b/src/assets/icons/svg/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/list.svg b/src/assets/icons/svg/list.svg new file mode 100644 index 0000000..20259ed --- /dev/null +++ b/src/assets/icons/svg/list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/lock.svg b/src/assets/icons/svg/lock.svg new file mode 100644 index 0000000..74fee54 --- /dev/null +++ b/src/assets/icons/svg/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/log.svg b/src/assets/icons/svg/log.svg new file mode 100644 index 0000000..d879d33 --- /dev/null +++ b/src/assets/icons/svg/log.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/logininfor.svg b/src/assets/icons/svg/logininfor.svg new file mode 100644 index 0000000..267f844 --- /dev/null +++ b/src/assets/icons/svg/logininfor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/maxkey.svg b/src/assets/icons/svg/maxkey.svg new file mode 100644 index 0000000..f8f8a7d --- /dev/null +++ b/src/assets/icons/svg/maxkey.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/svg/message.svg b/src/assets/icons/svg/message.svg new file mode 100644 index 0000000..14ca817 --- /dev/null +++ b/src/assets/icons/svg/message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/model.svg b/src/assets/icons/svg/model.svg new file mode 100644 index 0000000..0c57d70 --- /dev/null +++ b/src/assets/icons/svg/model.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/money.svg b/src/assets/icons/svg/money.svg new file mode 100644 index 0000000..c1580de --- /dev/null +++ b/src/assets/icons/svg/money.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/monitor.svg b/src/assets/icons/svg/monitor.svg new file mode 100644 index 0000000..bc308cb --- /dev/null +++ b/src/assets/icons/svg/monitor.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/my-copy.svg b/src/assets/icons/svg/my-copy.svg new file mode 100644 index 0000000..49f69fa --- /dev/null +++ b/src/assets/icons/svg/my-copy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/my-task.svg b/src/assets/icons/svg/my-task.svg new file mode 100644 index 0000000..1f1ea44 --- /dev/null +++ b/src/assets/icons/svg/my-task.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/nested.svg b/src/assets/icons/svg/nested.svg new file mode 100644 index 0000000..06713a8 --- /dev/null +++ b/src/assets/icons/svg/nested.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/number.svg b/src/assets/icons/svg/number.svg new file mode 100644 index 0000000..ad5ce9a --- /dev/null +++ b/src/assets/icons/svg/number.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/online.svg b/src/assets/icons/svg/online.svg new file mode 100644 index 0000000..330a202 --- /dev/null +++ b/src/assets/icons/svg/online.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/password.svg b/src/assets/icons/svg/password.svg new file mode 100644 index 0000000..6c64def --- /dev/null +++ b/src/assets/icons/svg/password.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/pdf.svg b/src/assets/icons/svg/pdf.svg new file mode 100644 index 0000000..957aa0c --- /dev/null +++ b/src/assets/icons/svg/pdf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/people.svg b/src/assets/icons/svg/people.svg new file mode 100644 index 0000000..2bd54ae --- /dev/null +++ b/src/assets/icons/svg/people.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/peoples.svg b/src/assets/icons/svg/peoples.svg new file mode 100644 index 0000000..aab852e --- /dev/null +++ b/src/assets/icons/svg/peoples.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/phone.svg b/src/assets/icons/svg/phone.svg new file mode 100644 index 0000000..ab8e8c4 --- /dev/null +++ b/src/assets/icons/svg/phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/post.svg b/src/assets/icons/svg/post.svg new file mode 100644 index 0000000..2922c61 --- /dev/null +++ b/src/assets/icons/svg/post.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/process-definition.svg b/src/assets/icons/svg/process-definition.svg new file mode 100644 index 0000000..202d200 --- /dev/null +++ b/src/assets/icons/svg/process-definition.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/qq.svg b/src/assets/icons/svg/qq.svg new file mode 100644 index 0000000..ee13d4e --- /dev/null +++ b/src/assets/icons/svg/qq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/question.svg b/src/assets/icons/svg/question.svg new file mode 100644 index 0000000..cf75bd4 --- /dev/null +++ b/src/assets/icons/svg/question.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/radio.svg b/src/assets/icons/svg/radio.svg new file mode 100644 index 0000000..0cde345 --- /dev/null +++ b/src/assets/icons/svg/radio.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/rate.svg b/src/assets/icons/svg/rate.svg new file mode 100644 index 0000000..aa3b14d --- /dev/null +++ b/src/assets/icons/svg/rate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/redis-list.svg b/src/assets/icons/svg/redis-list.svg new file mode 100644 index 0000000..98a15b2 --- /dev/null +++ b/src/assets/icons/svg/redis-list.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/redis.svg b/src/assets/icons/svg/redis.svg new file mode 100644 index 0000000..2f1d62d --- /dev/null +++ b/src/assets/icons/svg/redis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/row.svg b/src/assets/icons/svg/row.svg new file mode 100644 index 0000000..0780992 --- /dev/null +++ b/src/assets/icons/svg/row.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/search.svg b/src/assets/icons/svg/search.svg new file mode 100644 index 0000000..84233dd --- /dev/null +++ b/src/assets/icons/svg/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/select.svg b/src/assets/icons/svg/select.svg new file mode 100644 index 0000000..d628382 --- /dev/null +++ b/src/assets/icons/svg/select.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/server.svg b/src/assets/icons/svg/server.svg new file mode 100644 index 0000000..eb287e3 --- /dev/null +++ b/src/assets/icons/svg/server.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/shopping.svg b/src/assets/icons/svg/shopping.svg new file mode 100644 index 0000000..87513e7 --- /dev/null +++ b/src/assets/icons/svg/shopping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/size.svg b/src/assets/icons/svg/size.svg new file mode 100644 index 0000000..ddb25b8 --- /dev/null +++ b/src/assets/icons/svg/size.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/skill.svg b/src/assets/icons/svg/skill.svg new file mode 100644 index 0000000..a3b7312 --- /dev/null +++ b/src/assets/icons/svg/skill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/slider.svg b/src/assets/icons/svg/slider.svg new file mode 100644 index 0000000..fbe4f39 --- /dev/null +++ b/src/assets/icons/svg/slider.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/star.svg b/src/assets/icons/svg/star.svg new file mode 100644 index 0000000..6cf86e6 --- /dev/null +++ b/src/assets/icons/svg/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/swagger.svg b/src/assets/icons/svg/swagger.svg new file mode 100644 index 0000000..05d4e7b --- /dev/null +++ b/src/assets/icons/svg/swagger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/switch.svg b/src/assets/icons/svg/switch.svg new file mode 100644 index 0000000..0ba61e3 --- /dev/null +++ b/src/assets/icons/svg/switch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/system.svg b/src/assets/icons/svg/system.svg new file mode 100644 index 0000000..5992593 --- /dev/null +++ b/src/assets/icons/svg/system.svg @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/tab.svg b/src/assets/icons/svg/tab.svg new file mode 100644 index 0000000..b4b48e4 --- /dev/null +++ b/src/assets/icons/svg/tab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/table.svg b/src/assets/icons/svg/table.svg new file mode 100644 index 0000000..0e3dc9d --- /dev/null +++ b/src/assets/icons/svg/table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/textarea.svg b/src/assets/icons/svg/textarea.svg new file mode 100644 index 0000000..2709f29 --- /dev/null +++ b/src/assets/icons/svg/textarea.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/theme.svg b/src/assets/icons/svg/theme.svg new file mode 100644 index 0000000..5982a2f --- /dev/null +++ b/src/assets/icons/svg/theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/time-range.svg b/src/assets/icons/svg/time-range.svg new file mode 100644 index 0000000..13c1202 --- /dev/null +++ b/src/assets/icons/svg/time-range.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/time.svg b/src/assets/icons/svg/time.svg new file mode 100644 index 0000000..b376e32 --- /dev/null +++ b/src/assets/icons/svg/time.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/tool.svg b/src/assets/icons/svg/tool.svg new file mode 100644 index 0000000..48e0e35 --- /dev/null +++ b/src/assets/icons/svg/tool.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/topiam.svg b/src/assets/icons/svg/topiam.svg new file mode 100644 index 0000000..e7ea057 --- /dev/null +++ b/src/assets/icons/svg/topiam.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/icons/svg/tree-table.svg b/src/assets/icons/svg/tree-table.svg new file mode 100644 index 0000000..8aafdb8 --- /dev/null +++ b/src/assets/icons/svg/tree-table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/tree.svg b/src/assets/icons/svg/tree.svg new file mode 100644 index 0000000..dd4b7dd --- /dev/null +++ b/src/assets/icons/svg/tree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/upload.svg b/src/assets/icons/svg/upload.svg new file mode 100644 index 0000000..bae49c0 --- /dev/null +++ b/src/assets/icons/svg/upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/user.svg b/src/assets/icons/svg/user.svg new file mode 100644 index 0000000..0ba0716 --- /dev/null +++ b/src/assets/icons/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/validCode.svg b/src/assets/icons/svg/validCode.svg new file mode 100644 index 0000000..cfb1021 --- /dev/null +++ b/src/assets/icons/svg/validCode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/waiting.svg b/src/assets/icons/svg/waiting.svg new file mode 100644 index 0000000..2c2042d --- /dev/null +++ b/src/assets/icons/svg/waiting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/wechat.svg b/src/assets/icons/svg/wechat.svg new file mode 100644 index 0000000..c586e55 --- /dev/null +++ b/src/assets/icons/svg/wechat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/workflow.svg b/src/assets/icons/svg/workflow.svg new file mode 100644 index 0000000..2f7423a --- /dev/null +++ b/src/assets/icons/svg/workflow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/zip.svg b/src/assets/icons/svg/zip.svg new file mode 100644 index 0000000..f806fc4 --- /dev/null +++ b/src/assets/icons/svg/zip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/1.jpg b/src/assets/images/1.jpg new file mode 100644 index 0000000..fa6408b Binary files /dev/null and b/src/assets/images/1.jpg differ diff --git a/src/assets/images/2.jpg b/src/assets/images/2.jpg new file mode 100644 index 0000000..2580d86 Binary files /dev/null and b/src/assets/images/2.jpg differ diff --git a/src/assets/images/dark.svg b/src/assets/images/dark.svg new file mode 100644 index 0000000..f646bd7 --- /dev/null +++ b/src/assets/images/dark.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/light.svg b/src/assets/images/light.svg new file mode 100644 index 0000000..ab7cc08 --- /dev/null +++ b/src/assets/images/light.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/login-background.jpg b/src/assets/images/login-background.jpg new file mode 100644 index 0000000..8a713c3 Binary files /dev/null and b/src/assets/images/login-background.jpg differ diff --git a/src/assets/images/login-background.png b/src/assets/images/login-background.png new file mode 100644 index 0000000..6a86aa0 Binary files /dev/null and b/src/assets/images/login-background.png differ diff --git a/src/assets/images/profile.jpg b/src/assets/images/profile.jpg new file mode 100644 index 0000000..f4fde57 Binary files /dev/null and b/src/assets/images/profile.jpg differ diff --git a/src/assets/images/profile.png b/src/assets/images/profile.png new file mode 100644 index 0000000..af46228 Binary files /dev/null and b/src/assets/images/profile.png differ diff --git a/src/assets/logo/logo - 副本.png b/src/assets/logo/logo - 副本.png new file mode 100644 index 0000000..af46228 Binary files /dev/null and b/src/assets/logo/logo - 副本.png differ diff --git a/src/assets/logo/logo.png b/src/assets/logo/logo.png new file mode 100644 index 0000000..af46228 Binary files /dev/null and b/src/assets/logo/logo.png differ diff --git a/src/assets/styles/btn.scss b/src/assets/styles/btn.scss new file mode 100644 index 0000000..d614f2f --- /dev/null +++ b/src/assets/styles/btn.scss @@ -0,0 +1,99 @@ +@use './variables.module.scss' as *; + +@mixin colorBtn($color) { + background: $color; + + &:hover { + color: $color; + + &:before, + &:after { + background: $color; + } + } +} + +.blue-btn { + @include colorBtn($blue); +} + +.light-blue-btn { + @include colorBtn($light-blue); +} + +.red-btn { + @include colorBtn($red); +} + +.pink-btn { + @include colorBtn($pink); +} + +.green-btn { + @include colorBtn($green); +} + +.tiffany-btn { + @include colorBtn($tiffany); +} + +.yellow-btn { + @include colorBtn($yellow); +} + +.pan-btn { + font-size: 14px; + color: #fff; + padding: 14px 36px; + border-radius: 8px; + border: none; + outline: none; + transition: 600ms ease all; + position: relative; + display: inline-block; + + &:hover { + background: #fff; + + &:before, + &:after { + width: 100%; + transition: 600ms ease all; + } + } + + &:before, + &:after { + content: ''; + position: absolute; + top: 0; + right: 0; + height: 2px; + width: 0; + transition: 400ms ease all; + } + + &::after { + right: inherit; + top: inherit; + left: 0; + bottom: 0; + } +} + +.custom-button { + display: inline-block; + line-height: 1; + white-space: nowrap; + cursor: pointer; + background: #fff; + color: #fff; + -webkit-appearance: none; + text-align: center; + box-sizing: border-box; + outline: 0; + margin: 0; + padding: 10px 15px; + font-size: 14px; + border-radius: 4px; +} diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss new file mode 100644 index 0000000..e38c703 --- /dev/null +++ b/src/assets/styles/element-ui.scss @@ -0,0 +1,153 @@ +.el-collapse { + .collapse__title { + font-weight: 600; + padding: 0 8px; + font-size: 1.2em; + line-height: 1.1em; + } + .el-collapse-item__content { + padding: 0 8px; + } +} + +.el-divider--horizontal { + margin-bottom: 10px; + margin-top: 10px; +} + +.el-breadcrumb__inner, +.el-breadcrumb__inner a { + font-weight: 400 !important; +} + +.el-upload { + input[type='file'] { + display: none !important; + } +} + +.el-upload__input { + display: none; +} + +.cell { + .el-tag { + margin-right: 0px; + } +} + +.small-padding { + .cell { + padding-left: 5px; + padding-right: 5px; + } +} + +.fixed-width { + .el-button--mini { + padding: 7px 10px; + width: 60px; + } +} + +.status-col { + .cell { + padding: 0 10px; + text-align: center; + + .el-tag { + margin-right: 0px; + } + } +} + +/*-------------Dialog-------------**/ +.el-overlay { + overflow: hidden; + + .el-overlay-dialog { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + + .el-dialog { + margin: 0 auto !important; + + .el-dialog__body { + padding: 15px !important; + } + .el-dialog__header { + padding: 16px 16px 8px 16px; + box-sizing: border-box; + border-bottom: 1px solid var(--brder-color); + margin-right: 0; + } + } + } +} + +.el-dialog__body { + max-height: calc(90vh - 111px) !important; + overflow-y: auto; + overflow-x: hidden; +} + +// refine element ui upload +.upload-container { + .el-upload { + width: 100%; + + .el-upload-dragger { + width: 100%; + height: 200px; + } + } +} + +// dropdown +.el-dropdown-menu { + a { + display: block; + } +} + +// fix date-picker ui bug in filter-item +.el-range-editor.el-input__inner { + display: inline-flex !important; +} + +// to fix el-date-picker css style +.el-range-separator { + box-sizing: content-box; +} + +.el-menu--collapse > div > .el-submenu > .el-submenu__title .el-submenu__icon-arrow { + display: none; +} + +.el-dropdown .el-dropdown-link { + color: var(--el-color-primary) !important; +} + +/* 当 el-form 的 inline 属性为 true 时 */ +/* 设置 label 的宽度默认为 68px */ +.el-form--inline .el-form-item__label { + width: 68px; +} + +/* 设置 el-select 的宽度默认为 240px */ +.el-form--inline .el-select { + width: 240px; +} + +/* 设置 el-input 的宽度默认为 240px */ +.el-form--inline .el-input { + width: 240px; +} + +/* 设置 el-message-box 消息弹框内容强制换行 */ +.el-message-box .el-message-box__message { + word-break: break-word; +} diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss new file mode 100644 index 0000000..7228c52 --- /dev/null +++ b/src/assets/styles/index.scss @@ -0,0 +1,211 @@ +@use './variables.module.scss' as *; +@use './mixin.scss'; +@use './transition.scss'; +@use './element-ui.scss'; +@use './sidebar.scss'; +@use './btn.scss'; +@use './ruoyi.scss'; +@use 'animate.css'; +@use 'element-plus/dist/index.css'; + +body { + height: 100%; + margin: 0; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: + Helvetica Neue, + Helvetica, + PingFang SC, + Hiragino Sans GB, + Microsoft YaHei, + Arial, + sans-serif; +} + +label { + font-weight: 700; +} + +html { + height: 100%; + box-sizing: border-box; +} + +html.dark .svg-icon, +html.dark svg { + fill: var(--el-text-color-regular); +} + +#app { + height: 100%; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +.no-padding { + padding: 0px !important; +} + +.padding-content { + padding: 4px 0; +} + +a:focus, +a:active { + outline: none; +} + +a, +a:focus, +a:hover { + cursor: pointer; + color: inherit; + text-decoration: none; +} + +div:focus { + outline: none; +} + +.fr { + float: right; +} + +.fl { + float: left; +} + +.pr-5 { + padding-right: 5px; +} + +.pl-5 { + padding-left: 5px; +} + +.block { + display: block; +} + +.pointer { + cursor: pointer; +} + +.inlineBlock { + display: block; +} + +.clearfix { + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: ' '; + clear: both; + height: 0; + } +} + +aside { + background: #eef1f6; + padding: 8px 24px; + margin-bottom: 20px; + border-radius: 2px; + display: block; + line-height: 32px; + font-size: 16px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + color: #2c3e50; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + a { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } + } +} + +//main-container全局样式 +.app-container { + padding: 20px; +} + +// search面板样式 +.panel, +.search { + margin-bottom: 0.75rem; + border-radius: 0.25rem; + border: 1px solid var(--el-border-color-light); + background-color: var(--el-bg-color-overlay); + padding: 0.75rem; + transition: all ease 0.3s; + + &:hover { + box-shadow: 0 2px 12px #0000001a; + transition: all ease 0.3s; + } +} + +.components-container { + margin: 30px 50px; + position: relative; +} + +.text-center { + text-align: center; +} + +.sub-navbar { + height: 50px; + line-height: 50px; + position: relative; + width: 100%; + text-align: right; + padding-right: 20px; + transition: 600ms ease position; + background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); + + .subtitle { + font-size: 20px; + color: #fff; + } + + &.draft { + background: #d0d0d0; + } + + &.deleted { + background: #d0d0d0; + } +} + +.link-type, +.link-type:focus { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } +} + +.filter-container { + padding-bottom: 10px; + + .filter-item { + display: inline-block; + vertical-align: middle; + margin-bottom: 10px; + } +} diff --git a/src/assets/styles/mixin.scss b/src/assets/styles/mixin.scss new file mode 100644 index 0000000..5250e71 --- /dev/null +++ b/src/assets/styles/mixin.scss @@ -0,0 +1,60 @@ +@mixin clearfix { + &:after { + content: ''; + display: table; + clear: both; + } +} + +@mixin scrollBar { + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } +} + +@mixin relative { + position: relative; + width: 100%; + height: 100%; +} + +@mixin pct($pct) { + width: #{$pct}; + position: relative; + margin: 0 auto; +} + +@mixin triangle($width, $height, $color, $direction) { + $width: $width/2; + $color-border-style: $height solid $color; + $transparent-border-style: $width solid transparent; + height: 0; + width: 0; + + @if $direction==up { + border-bottom: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } @else if $direction==right { + border-left: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } @else if $direction==down { + border-top: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } @else if $direction==left { + border-right: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } +} diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss new file mode 100644 index 0000000..9526017 --- /dev/null +++ b/src/assets/styles/ruoyi.scss @@ -0,0 +1,284 @@ +@use './variables.module.scss' as *; + +/** + * 通用css样式布局处理 + * Copyright (c) 2019 ruoyi + */ + +/** 基础通用 **/ +.pt5 { + padding-top: 5px; +} +.pr5 { + padding-right: 5px; +} +.pb5 { + padding-bottom: 5px; +} +.mt5 { + margin-top: 5px; +} +.mr5 { + margin-right: 5px; +} +.mb5 { + margin-bottom: 5px; +} +.mb8 { + margin-bottom: 8px; +} +.ml5 { + margin-left: 5px; +} +.mt10 { + margin-top: 10px; +} +.mr10 { + margin-right: 10px; +} +.mb10 { + margin-bottom: 10px; +} +.ml10 { + margin-left: 10px; +} +.mt20 { + margin-top: 20px; +} +.mr20 { + margin-right: 20px; +} +.mb20 { + margin-bottom: 20px; +} +.ml20 { + margin-left: 20px; +} + +.h1, +.h2, +.h3, +.h4, +.h5, +.h6, +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} + +.el-form .el-form-item__label { + font-weight: 700; +} +.el-dialog:not(.is-fullscreen) { + margin-top: 6vh !important; +} + +.el-dialog.scrollbar .el-dialog__body { + overflow: auto; + overflow-x: hidden; + max-height: 70vh; + padding: 10px 20px 0; +} + +.el-table { + .el-table__header-wrapper, + .el-table__fixed-header-wrapper { + th { + word-break: break-word; + background-color: $table-header-bg !important; + color: $table-header-text-color; + height: 40px !important; + font-size: 13px; + } + } + .el-table__body-wrapper { + .el-button [class*='el-icon-'] + span { + margin-left: 1px; + } + } +} + +/** 表单布局 **/ +.form-header { + font-size: 15px; + color: #6379bb; + border-bottom: 1px solid #ddd; + margin: 8px 10px 25px 10px; + padding-bottom: 5px; +} + +/** 表格布局 **/ +.pagination-container { + display: flex; + justify-content: flex-end; + margin-top: 20px; + padding: 10px 20px !important; +} + +/* tree border */ +.tree-border { + margin-top: 5px; + border: 1px solid #e5e6e7; + background: #ffffff none; + border-radius: 4px; + width: 100%; +} + +@media (max-width: 768px) { + .pagination-container .el-pagination > .el-pagination__jump { + display: none !important; + } + .pagination-container .el-pagination > .el-pagination__sizes { + display: none !important; + } +} + +.el-table .fixed-width .el-button--small { + padding-left: 0; + padding-right: 0; + width: inherit; +} + +/** 表格更多操作下拉样式 */ +.el-table .el-dropdown-link { + cursor: pointer; + color: #409eff; + margin-left: 10px; +} + +.el-table .el-dropdown, +.el-icon-arrow-down { + font-size: 12px; +} + +.el-tree-node__content > .el-checkbox { + margin-right: 8px; +} + +.list-group-striped > .list-group-item { + border-left: 0; + border-right: 0; + border-radius: 0; + padding-left: 0; + padding-right: 0; +} + +.list-group { + padding-left: 0px; + list-style: none; +} + +.list-group-item { + border-bottom: 1px solid #e7eaec; + border-top: 1px solid #e7eaec; + margin-bottom: -1px; + padding: 11px 0px; + font-size: 13px; +} + +.pull-right { + float: right !important; +} + +.el-card__header { + padding: 14px 15px 7px !important; + min-height: 40px; +} + +.el-card__body { + padding: 15px 20px 20px 20px !important; +} + +.card-box { + margin-bottom: 10px; +} + +/* button color */ +.el-button--cyan.is-active, +.el-button--cyan:active { + background: #20b2aa; + border-color: #20b2aa; + color: #ffffff; +} + +.el-button--cyan:focus, +.el-button--cyan:hover { + background: #48d1cc; + border-color: #48d1cc; + color: #ffffff; +} + +.el-button--cyan { + background-color: #20b2aa; + border-color: #20b2aa; + color: #ffffff; +} + +/* text color */ +.text-navy { + color: #1ab394; +} + +.text-primary { + color: inherit; +} + +.text-success { + color: #1c84c6; +} + +.text-info { + color: #23c6c8; +} + +.text-warning { + color: #f8ac59; +} + +.text-danger { + color: #ed5565; +} + +.text-muted { + color: #888888; +} + +/* image */ +.img-circle { + border-radius: 50%; +} + +.img-lg { + width: 120px; + height: 120px; +} + +.avatar-upload-preview { + position: absolute; + top: 50%; + transform: translate(50%, -50%); + width: 200px; + height: 200px; + border-radius: 50%; + box-shadow: 0 0 4px #ccc; + overflow: hidden; +} + +/* 拖拽列样式 */ +.sortable-ghost { + opacity: 0.8; + color: #fff !important; + background: #42b983 !important; +} + +/* 表格右侧工具栏样式 */ +.top-right-btn { + margin-left: auto; +} diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss new file mode 100644 index 0000000..6ffcd33 --- /dev/null +++ b/src/assets/styles/sidebar.scss @@ -0,0 +1,296 @@ +@use './variables.module.scss' as *; + +#app { + .main-container { + height: 100%; + transition: margin-left 0.28s; + margin-left: $base-sidebar-width; + position: relative; + } + + .sidebarHide { + margin-left: 0 !important; + } + + .sidebar-container { + -webkit-transition: width 0.28s; + transition: width 0.28s; + width: $base-sidebar-width !important; + background-color: $base-menu-background; + height: 100%; + position: fixed; + font-size: 0; + top: 0; + bottom: 0; + left: 0; + z-index: 1001; + overflow: hidden; + -webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35); + box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.1); + + // reset element-ui css + .horizontal-collapse-transition { + transition: + 0s width ease-in-out, + 0s padding-left ease-in-out, + 0s padding-right ease-in-out; + } + + .scrollbar-wrapper { + overflow-x: hidden !important; + } + + .el-scrollbar__bar.is-vertical { + right: 0; + } + + .el-scrollbar { + height: 100%; + } + + &.has-logo { + .el-scrollbar { + height: calc(100% - 50px); + } + } + + .is-horizontal { + display: none; + } + + a { + display: inline-block; + width: 100%; + overflow: hidden; + } + + .svg-icon { + margin-right: 10px; + } + + .el-menu { + border: none; + height: 100%; + width: 100% !important; + } + + .el-menu-item, + .menu-title { + overflow: hidden !important; + text-overflow: ellipsis !important; + white-space: nowrap !important; + } + + .el-menu-item .el-menu-tooltip__trigger { + display: inline-block !important; + } + + // menu hover + .theme-dark .sub-menu-title-noDropdown, + .theme-dark .el-sub-menu__title { + border-radius: 8px; + margin: 1px 5px 1px 5px; + &:hover { + background-color: $base-sub-menu-title-hover !important; + } + } + .sub-menu-title-noDropdown, + .el-sub-menu__title { + border-radius: 8px; + margin: 1px 5px 1px 5px; + &:hover { + background-color: rgba(0, 0, 0, 0.05) !important; + } + } + + & .theme-dark .is-active > .el-sub-menu__title { + color: $base-menu-color-active !important; + } + + & .nest-menu .el-sub-menu > .el-sub-menu__title, + & .el-sub-menu .el-menu-item { + min-width: calc($base-sidebar-width - 20px) !important; + border-radius: 8px; + height: 45px; + margin: 1px 5px 1px 5px; + &:not(.is-active):hover { + background-color: rgba(0, 0, 0, 0.1) !important; + } + } + + & .theme-dark .nest-menu .el-sub-menu > .el-sub-menu__title, + & .theme-dark .el-sub-menu .el-menu-item { + background-color: $base-sub-menu-background !important; + border-radius: 8px; + height: 45px; + margin: 1px 5px 1px 5px; + + &.is-active { + background-color: var(--el-menu-active-color) !important; + color: #fff; + } + &:not(.is-active):hover { + // you can use $sub-menuHover + background-color: $base-sub-menu-hover !important; + } + } + + & .theme-dark .nest-menu .el-sub-menu > .el-sub-menu__title, + & .theme-dark .el-menu-item { + border-radius: 8px; + height: 45px; + margin: 1px 5px 1px 5px; + + &.is-active { + background-color: var(--el-menu-active-color) !important; + color: #fff; + } + &:not(.is-active):hover { + // you can use $sub-menuHover + background-color: $base-menu-hover !important; + } + } + + & .nest-menu .el-sub-menu > .el-sub-menu__title, + & .el-menu-item { + border-radius: 8px; + height: 45px; + margin: 1px 5px 1px 5px; + + &.is-active { + background-color: var(--el-menu-active-color) !important; + color: #fff; + } + &:not(.is-active):hover { + // you can use $sub-menuHover + background-color: rgba(0, 0, 0, 0.04) !important; + } + } + } + + // 收起菜单后的样式 + .hideSidebar { + .sidebar-container { + width: 54px !important; + } + + .main-container { + margin-left: 54px; + } + + .sub-menu-title-noDropdown { + padding: 0 !important; + position: relative; + height: 45px; + // 选中状态的菜单 + &.is-active { + background-color: var(--el-menu-active-color) !important; + color: #fff !important; + } + + .el-tooltip { + padding: 0 !important; + } + } + + + & .el-sub-menu { + overflow: hidden; + border-radius: 8px; + .el-sub-menu__title.el-tooltip__trigger { + border-radius: 8px; + height: 45px; + } + + // 选中状态的菜单 + &.is-active .el-sub-menu__title.el-tooltip__trigger { + background-color: var(--el-menu-active-color) !important; + } + + + & > .el-sub-menu__title { + padding: 0 !important; + } + } + + .el-menu--collapse { + .is-active .svg-icon { + fill: #fff; + } + .svg-icon { + display: flex; + margin: auto; + height: 100%; + // 这里设置width会跟随sidebar-container的transition 不符合预期 + } + .el-sub-menu { + & > .el-sub-menu__title { + & > span { + height: 0; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + & > i { + height: 0; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + } + } + } + } + + .el-menu--collapse .el-menu .el-sub-menu { + min-width: $base-sidebar-width !important; + } + + // mobile responsive + .mobile { + .main-container { + margin-left: 0px; + } + + .sidebar-container { + transition: transform 0.28s; + width: $base-sidebar-width !important; + } + + &.hideSidebar { + .sidebar-container { + pointer-events: none; + transition-duration: 0.3s; + transform: translate3d(-$base-sidebar-width, 0, 0); + } + } + } + + .withoutAnimation { + .main-container, + .sidebar-container { + transition: none; + } + } +} + +// when menu collapsed +.el-menu--vertical { + & > .el-menu { + .svg-icon { + margin-right: 16px; + } + } +} +// 收起菜单后悬浮的菜单样式 +.el-popper.is-pure{ + border-radius: 8px; + .el-menu--popup{ + border-radius: 8px; + } + .el-menu-item{ + border-radius: 4px; + } +} diff --git a/src/assets/styles/transition.scss b/src/assets/styles/transition.scss new file mode 100644 index 0000000..7a548ca --- /dev/null +++ b/src/assets/styles/transition.scss @@ -0,0 +1,49 @@ +// global transition css + +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter-from, +.fade-leave-active { + opacity: 0; +} + +/* fade-transform */ +.fade-transform--move, +.fade-transform-leave-active, +.fade-transform-enter-active { + transition: all 0.5s; +} + +.fade-transform-enter-from { + opacity: 0; + transform: translateX(-30px); +} + +.fade-transform-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* breadcrumb transition */ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all 0.5s; +} + +.breadcrumb-enter-from, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all 0.5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss new file mode 100644 index 0000000..8f9c4bd --- /dev/null +++ b/src/assets/styles/variables.module.scss @@ -0,0 +1,140 @@ +// 全局SCSS变量 +:root { + --menuBg: #1f2d3d; + --menuColor: #bfcbd9; + --menuActiveText: #f4f4f5; + --menuHover: #263445; + + --subMenuBg: #1f2d3d; + --subMenuActiveText: #f4f4f5; + --subMenuHover: #001528; + --subMenuTitleHover: #293444; + + // 菜单栏缩进 + --el-menu-base-level-padding: 12px; + --el-menu-level-padding: 8px; + --el-menu-item-height: 50px; + + --fixedHeaderBg: #ffffff; + --tableHeaderBg: #f8f8f9; + --tableHeaderTextColor: #515a6e; + + // ele + --brder-color: #e8e8e8; + + // 添加 tag 相关变量 + --tags-view-active-bg: var(--el-color-primary); + --tags-view-active-border-color: var(--el-color-primary); +} + +html.dark { + --menuBg: #1d1e1f; + --menuColor: #bfcbd9; + --menuActiveText: #f4f4f5; + --menuHover: #171819; + + --subMenuBg: #1d1e1f; + --subMenuActiveText: #1d1e1f; + --subMenuHover: #171819; + --subMenuTitleHover: #171819; + + --fixedHeaderBg: #171819; + --tableHeaderBg: var(--el-bg-color); + --tableHeaderTextColor: var(--el-text-color); + + // 覆盖ele 高亮当前行的标准暗色 + .el-tree-node__content { + --el-color-primary-light-9: #262727; + } + + .el-button--primary { + --el-button-bg-color: var(--el-color-primary-dark-6); + --el-button-border-color: var(--el-color-primary-light-2); + } + + .el-switch { + --el-switch-on-color: var(--el-color-primary-dark-6); + --el-switch-border-color: var(--el-color-primary-light-2); + } + + .el-tag--primary { + --el-tag-bg-color: var(--el-color-primary-dark-6); + --el-tag-border-color: var(--el-color-primary-light-2); + } + + // 在深色模式下使用更深的颜色 + --tags-view-active-bg: var(--el-color-primary-dark-6); + --tags-view-active-border-color: var(--el-color-primary-light-2); + // vxe-table 主题 + --vxe-font-color: #98989e; + --vxe-primary-color: #2c7ecf; + --vxe-icon-background-color: #98989e; + --vxe-table-font-color: #98989e; + --vxe-table-resizable-color: #95969a; + --vxe-table-header-background-color: #28282a; + --vxe-table-body-background-color: #151518; + --vxe-table-background-color: #4a5663; + --vxe-table-border-width: 1px; + --vxe-table-border-color: #37373a; + --vxe-toolbar-background-color: #37373a; + + // ele + --brder-color: #37373a; +} + +// base color +$blue: #324157; +$light-blue: #3a71a8; +$red: #c03639; +$pink: #e65d6e; +$green: #30b08f; +$tiffany: #4ab7bd; +$yellow: #fec171; +$panGreen: #30b08f; + +// 默认菜单主题风格 +$base-menu-color: var(--menuColor); +$base-menu-hover: var(--menuHover); +$base-menu-color-active: var(--menuActiveText); +$base-menu-background: var(--menuBg); +$base-logo-title-color: #ffffff; + +$base-menu-light-color: rgba(0, 0, 0, 0.7); +$base-menu-light-background: #ffffff; +$base-logo-light-title-color: #001529; + +$base-sub-menu-background: var(--subMenuBg); +$base-sub-menu-hover: var(--subMenuHover); +$base-sub-menu-title-hover: var(--subMenuTitleHover); +// 表单头背景色和标题颜色 +$fixed-header-bg: var(--fixedHeaderBg); +$table-header-bg: var(--tableHeaderBg); +$table-header-text-color: var(--tableHeaderTextColor); + +$--color-primary: #409eff; +$--color-success: #67c23a; +$--color-warning: #e6a23c; +$--color-danger: #f56c6c; +$--color-info: #909399; + +$base-sidebar-width: 200px; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + menuColor: $base-menu-color; + menuLightColor: $base-menu-light-color; + menuColorActive: $base-menu-color-active; + menuBackground: $base-menu-background; + menuLightBackground: $base-menu-light-background; + subMenuBackground: $base-sub-menu-background; + subMenuHover: $base-sub-menu-hover; + sideBarWidth: $base-sidebar-width; + logoTitleColor: $base-logo-title-color; + logoLightTitleColor: $base-logo-light-title-color; + primaryColor: $--color-primary; + successColor: $--color-success; + dangerColor: $--color-danger; + infoColor: $--color-info; + warningColor: $--color-warning; +} \ No newline at end of file diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..a9cdef4 --- /dev/null +++ b/src/components/Breadcrumb/index.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/src/components/DictTag/index.vue b/src/components/DictTag/index.vue new file mode 100644 index 0000000..dbf5d7f --- /dev/null +++ b/src/components/DictTag/index.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue new file mode 100644 index 0000000..67394aa --- /dev/null +++ b/src/components/Editor/index.vue @@ -0,0 +1,244 @@ + + + + + diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue new file mode 100644 index 0000000..1767b1b --- /dev/null +++ b/src/components/FileUpload/index.vue @@ -0,0 +1,241 @@ + + + + + diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue new file mode 100644 index 0000000..f9f5e62 --- /dev/null +++ b/src/components/Hamburger/index.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/IconSelect/index.vue b/src/components/IconSelect/index.vue new file mode 100644 index 0000000..4be0219 --- /dev/null +++ b/src/components/IconSelect/index.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/src/components/IconSelect/requireIcons.ts b/src/components/IconSelect/requireIcons.ts new file mode 100644 index 0000000..9f06d69 --- /dev/null +++ b/src/components/IconSelect/requireIcons.ts @@ -0,0 +1,7 @@ +const icons: string[] = []; +const modules = import.meta.glob('./../../assets/icons/svg/*.svg'); +for (const path in modules) { + const p = path.split('assets/icons/svg/')[1].split('.svg')[0]; + icons.push(p); +} +export default icons; diff --git a/src/components/ImagePreview/index.vue b/src/components/ImagePreview/index.vue new file mode 100644 index 0000000..afe02c7 --- /dev/null +++ b/src/components/ImagePreview/index.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/components/ImageUpload/index.vue b/src/components/ImageUpload/index.vue new file mode 100644 index 0000000..f81e4bc --- /dev/null +++ b/src/components/ImageUpload/index.vue @@ -0,0 +1,242 @@ + + + + + diff --git a/src/components/LangSelect/index.vue b/src/components/LangSelect/index.vue new file mode 100644 index 0000000..b5fafd3 --- /dev/null +++ b/src/components/LangSelect/index.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue new file mode 100644 index 0000000..f615f61 --- /dev/null +++ b/src/components/Pagination/index.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/src/components/ParentView/index.vue b/src/components/ParentView/index.vue new file mode 100644 index 0000000..98240ae --- /dev/null +++ b/src/components/ParentView/index.vue @@ -0,0 +1,3 @@ + diff --git a/src/components/Process/MessageType.vue b/src/components/Process/MessageType.vue new file mode 100644 index 0000000..4ef5fa9 --- /dev/null +++ b/src/components/Process/MessageType.vue @@ -0,0 +1,100 @@ + + diff --git a/src/components/Process/approvalButton.vue b/src/components/Process/approvalButton.vue new file mode 100644 index 0000000..e53ad3b --- /dev/null +++ b/src/components/Process/approvalButton.vue @@ -0,0 +1,57 @@ + + diff --git a/src/components/Process/approvalRecord.vue b/src/components/Process/approvalRecord.vue new file mode 100644 index 0000000..2413f08 --- /dev/null +++ b/src/components/Process/approvalRecord.vue @@ -0,0 +1,127 @@ + + + diff --git a/src/components/Process/flowChart.vue b/src/components/Process/flowChart.vue new file mode 100644 index 0000000..7603375 --- /dev/null +++ b/src/components/Process/flowChart.vue @@ -0,0 +1,40 @@ + + + diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue new file mode 100644 index 0000000..2aaa4d3 --- /dev/null +++ b/src/layout/components/Navbar.vue @@ -0,0 +1,308 @@ + + + + + diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue new file mode 100644 index 0000000..bbd53cb --- /dev/null +++ b/src/layout/components/Settings/index.vue @@ -0,0 +1,246 @@ + + + + + diff --git a/src/layout/components/Sidebar/Link.vue b/src/layout/components/Sidebar/Link.vue new file mode 100644 index 0000000..fd75f35 --- /dev/null +++ b/src/layout/components/Sidebar/Link.vue @@ -0,0 +1,40 @@ + + + diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue new file mode 100644 index 0000000..3aa121b --- /dev/null +++ b/src/layout/components/Sidebar/Logo.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue new file mode 100644 index 0000000..a11159b --- /dev/null +++ b/src/layout/components/Sidebar/SidebarItem.vue @@ -0,0 +1,101 @@ + + + diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue new file mode 100644 index 0000000..b6ecbfa --- /dev/null +++ b/src/layout/components/Sidebar/index.vue @@ -0,0 +1,56 @@ + + + diff --git a/src/layout/components/SocialCallback/index.vue b/src/layout/components/SocialCallback/index.vue new file mode 100644 index 0000000..a5cd768 --- /dev/null +++ b/src/layout/components/SocialCallback/index.vue @@ -0,0 +1,95 @@ + + + diff --git a/src/layout/components/TagsView/ScrollPane.vue b/src/layout/components/TagsView/ScrollPane.vue new file mode 100644 index 0000000..e24f5ec --- /dev/null +++ b/src/layout/components/TagsView/ScrollPane.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue new file mode 100644 index 0000000..e9ee675 --- /dev/null +++ b/src/layout/components/TagsView/index.vue @@ -0,0 +1,347 @@ + + + + + + + diff --git a/src/layout/components/TopBar/search.vue b/src/layout/components/TopBar/search.vue new file mode 100644 index 0000000..9cb36db --- /dev/null +++ b/src/layout/components/TopBar/search.vue @@ -0,0 +1,158 @@ + + + + + diff --git a/src/layout/components/index.ts b/src/layout/components/index.ts new file mode 100644 index 0000000..47c83e1 --- /dev/null +++ b/src/layout/components/index.ts @@ -0,0 +1,4 @@ +export { default as AppMain } from './AppMain.vue'; +export { default as Navbar } from './Navbar.vue'; +export { default as Settings } from './Settings/index.vue'; +export { default as TagsView } from './TagsView/index.vue'; diff --git a/src/layout/components/notice/index.vue b/src/layout/components/notice/index.vue new file mode 100644 index 0000000..684ae6a --- /dev/null +++ b/src/layout/components/notice/index.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/src/layout/index.vue b/src/layout/index.vue new file mode 100644 index 0000000..b2d06dc --- /dev/null +++ b/src/layout/index.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..16ac610 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,57 @@ +import { createApp } from 'vue'; +// global css +import 'virtual:uno.css'; +import 'element-plus/theme-chalk/dark/css-vars.css'; +import '@/assets/styles/index.scss'; + +// App、router、store +import App from './App.vue'; +import store from './store'; +import router from './router'; + +// 自定义指令 +import directive from './directive'; + +// 注册插件 +import plugins from './plugins/index'; // plugins + +// 高亮组件 +// import 'highlight.js/styles/a11y-light.css'; +import 'highlight.js/styles/atom-one-dark.css'; +import 'highlight.js/lib/common'; +import HighLight from '@highlightjs/vue-plugin'; + +// svg图标 +import 'virtual:svg-icons-register'; +import ElementIcons from '@/plugins/svgicon'; + +// permission control +import './permission'; + +// 国际化 +import i18n from '@/lang/index'; + +// vxeTable +import VXETable from 'vxe-table'; +import 'vxe-table/lib/style.css'; +VXETable.setConfig({ + zIndex: 999999 +}); + +// 修改 el-dialog 默认点击遮照为不关闭 +import { ElDialog } from 'element-plus'; +ElDialog.props.closeOnClickModal.default = false; + +const app = createApp(App); + +app.use(HighLight); +app.use(ElementIcons); +app.use(router); +app.use(store); +app.use(i18n); +app.use(VXETable); +app.use(plugins); +// 自定义指令 +directive(app); + +app.mount('#app'); diff --git a/src/permission.ts b/src/permission.ts new file mode 100644 index 0000000..fb60b07 --- /dev/null +++ b/src/permission.ts @@ -0,0 +1,70 @@ +import { to as tos } from 'await-to-js'; +import router from './router'; +import NProgress from 'nprogress'; +import 'nprogress/nprogress.css'; +import { getToken } from '@/utils/auth'; +import { isHttp, isPathMatch } from '@/utils/validate'; +import { isRelogin } from '@/utils/request'; +import { useUserStore } from '@/store/modules/user'; +import { useSettingsStore } from '@/store/modules/settings'; +import { usePermissionStore } from '@/store/modules/permission'; +import { ElMessage } from 'element-plus/es'; + +NProgress.configure({ showSpinner: false }); +const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*']; + +const isWhiteList = (path: string) => { + return whiteList.some((pattern) => isPathMatch(pattern, path)); +}; + +router.beforeEach(async (to, from, next) => { + NProgress.start(); + if (getToken()) { + to.meta.title && useSettingsStore().setTitle(to.meta.title as string); + /* has token*/ + if (to.path === '/login') { + next({ path: '/' }); + NProgress.done(); + } else if (isWhiteList(to.path)) { + next(); + } else { + if (useUserStore().roles.length === 0) { + isRelogin.show = true; + // 判断当前用户是否已拉取完user_info信息 + const [err] = await tos(useUserStore().getInfo()); + if (err) { + await useUserStore().logout(); + ElMessage.error(err); + next({ path: '/' }); + } else { + isRelogin.show = false; + const accessRoutes = await usePermissionStore().generateRoutes(); + // 根据roles权限生成可访问的路由表 + accessRoutes.forEach((route) => { + if (!isHttp(route.path)) { + router.addRoute(route); // 动态添加可访问路由表 + } + }); + // @ts-expect-error hack方法 确保addRoutes已完成 + next({ path: to.path, replace: true, params: to.params, query: to.query, hash: to.hash, name: to.name as string }); // hack方法 确保addRoutes已完成 + } + } else { + next(); + } + } + } else { + // 没有token + if (isWhiteList(to.path)) { + // 在免登录白名单,直接进入 + next(); + } else { + const redirect = encodeURIComponent(to.fullPath || '/'); + next(`/login?redirect=${redirect}`); // 否则全部重定向到登录页 + NProgress.done(); + } + } +}); + +router.afterEach(() => { + NProgress.done(); +}); diff --git a/src/plugins/auth.ts b/src/plugins/auth.ts new file mode 100644 index 0000000..a5aaef9 --- /dev/null +++ b/src/plugins/auth.ts @@ -0,0 +1,60 @@ +import { useUserStore } from '@/store/modules/user'; + +const authPermission = (permission: string): boolean => { + const all_permission = '*:*:*'; + const permissions: string[] = useUserStore().permissions; + if (permission && permission.length > 0) { + return permissions.some((v) => { + return all_permission === v || v === permission; + }); + } else { + return false; + } +}; + +const authRole = (role: string): boolean => { + const super_admin = 'admin'; + const roles = useUserStore().roles; + if (role && role.length > 0) { + return roles.some((v) => { + return super_admin === v || v === role; + }); + } else { + return false; + } +}; + +export default { + // 验证用户是否具备某权限 + hasPermi(permission: string): boolean { + return authPermission(permission); + }, + // 验证用户是否含有指定权限,只需包含其中一个 + hasPermiOr(permissions: string[]): boolean { + return permissions.some((item) => { + return authPermission(item); + }); + }, + // 验证用户是否含有指定权限,必须全部拥有 + hasPermiAnd(permissions: string[]): boolean { + return permissions.every((item) => { + return authPermission(item); + }); + }, + // 验证用户是否具备某角色 + hasRole(role: string): boolean { + return authRole(role); + }, + // 验证用户是否含有指定角色,只需包含其中一个 + hasRoleOr(roles: string[]): boolean { + return roles.some((item) => { + return authRole(item); + }); + }, + // 验证用户是否含有指定角色,必须全部拥有 + hasRoleAnd(roles: string[]): boolean { + return roles.every((item) => { + return authRole(item); + }); + } +}; diff --git a/src/plugins/cache.ts b/src/plugins/cache.ts new file mode 100644 index 0000000..e5ceead --- /dev/null +++ b/src/plugins/cache.ts @@ -0,0 +1,79 @@ +const sessionCache = { + set(key: string, value: any) { + if (!sessionStorage) { + return; + } + if (key != null && value != null) { + sessionStorage.setItem(key, value); + } + }, + get(key: string) { + if (!sessionStorage) { + return null; + } + if (key == null) { + return null; + } + return sessionStorage.getItem(key); + }, + setJSON(key: string, jsonValue: any) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)); + } + }, + getJSON(key: string) { + const value = this.get(key); + if (value != null) { + return JSON.parse(value); + } + return null; + }, + remove(key: string) { + sessionStorage.removeItem(key); + } +}; +const localCache = { + set(key: string, value: any) { + if (!localStorage) { + return; + } + if (key != null && value != null) { + localStorage.setItem(key, value); + } + }, + get(key: string) { + if (!localStorage) { + return null; + } + if (key == null) { + return null; + } + return localStorage.getItem(key); + }, + setJSON(key: string, jsonValue: any) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)); + } + }, + getJSON(key: string) { + const value = this.get(key); + if (value != null) { + return JSON.parse(value); + } + return null; + }, + remove(key: string) { + localStorage.removeItem(key); + } +}; + +export default { + /** + * 会话级缓存 + */ + session: sessionCache, + /** + * 本地缓存 + */ + local: localCache +}; diff --git a/src/plugins/download.ts b/src/plugins/download.ts new file mode 100644 index 0000000..ef66b3a --- /dev/null +++ b/src/plugins/download.ts @@ -0,0 +1,65 @@ +import axios from 'axios'; +import FileSaver from 'file-saver'; +import errorCode from '@/utils/errorCode'; +import { blobValidate } from '@/utils/ruoyi'; +import { LoadingInstance } from 'element-plus/es/components/loading/src/loading'; +import { globalHeaders } from '@/utils/request'; + +const baseURL = import.meta.env.VITE_APP_BASE_API; +let downloadLoadingInstance: LoadingInstance; +export default { + async oss(ossId: string | number) { + const url = baseURL + '/resource/oss/download/' + ossId; + downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' }); + try { + const res = await axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: globalHeaders() + }); + const isBlob = blobValidate(res.data); + if (isBlob) { + const blob = new Blob([res.data], { type: 'application/octet-stream' }); + FileSaver.saveAs(blob, decodeURIComponent(res.headers['download-filename'] as string)); + } else { + this.printErrMsg(res.data); + } + downloadLoadingInstance.close(); + } catch (r) { + console.error(r); + ElMessage.error('下载文件出现错误,请联系管理员!'); + downloadLoadingInstance.close(); + } + }, + async zip(url: string, name: string) { + url = baseURL + url; + downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' }); + try { + const res = await axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: globalHeaders() + }); + const isBlob = blobValidate(res.data); + if (isBlob) { + const blob = new Blob([res.data], { type: 'application/zip' }); + FileSaver.saveAs(blob, name); + } else { + this.printErrMsg(res.data); + } + downloadLoadingInstance.close(); + } catch (r) { + console.error(r); + ElMessage.error('下载文件出现错误,请联系管理员!'); + downloadLoadingInstance.close(); + } + }, + async printErrMsg(data: any) { + const resText = await data.text(); + const rspObj = JSON.parse(resText); + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']; + ElMessage.error(errMsg); + } +}; diff --git a/src/plugins/index.ts b/src/plugins/index.ts new file mode 100644 index 0000000..6c5e0c3 --- /dev/null +++ b/src/plugins/index.ts @@ -0,0 +1,43 @@ +import modal from './modal'; +import tab from './tab'; +import download from './download'; +import cache from './cache'; +import auth from './auth'; +// 预设动画 +import animate from '@/animate'; + +import { download as dl } from '@/utils/request'; +import { useDict } from '@/utils/dict'; +import { getConfigKey, updateConfigByKey } from '@/api/system/config'; +import { parseTime, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi'; + +import { App } from 'vue'; + +export default function installPlugin(app: App) { + // 页签操作 + app.config.globalProperties.$tab = tab; + + // 模态框对象 + app.config.globalProperties.$modal = modal; + + // 缓存对象 + app.config.globalProperties.$cache = cache; + + // 下载文件 + app.config.globalProperties.$download = download; + + // 认证对象 + app.config.globalProperties.$auth = auth; + + // 全局方法挂载 + app.config.globalProperties.useDict = useDict; + app.config.globalProperties.getConfigKey = getConfigKey; + app.config.globalProperties.updateConfigByKey = updateConfigByKey; + app.config.globalProperties.download = dl; + app.config.globalProperties.parseTime = parseTime; + app.config.globalProperties.handleTree = handleTree; + app.config.globalProperties.addDateRange = addDateRange; + app.config.globalProperties.selectDictLabel = selectDictLabel; + app.config.globalProperties.selectDictLabels = selectDictLabels; + app.config.globalProperties.animate = animate; +} diff --git a/src/plugins/modal.ts b/src/plugins/modal.ts new file mode 100644 index 0000000..a8b0548 --- /dev/null +++ b/src/plugins/modal.ts @@ -0,0 +1,81 @@ +import { MessageBoxData } from 'element-plus'; +import { LoadingInstance } from 'element-plus/es/components/loading/src/loading'; +let loadingInstance: LoadingInstance; +export default { + // 消息提示 + msg(content: any) { + ElMessage.info(content); + }, + // 错误消息 + msgError(content: any) { + ElMessage.error(content); + }, + // 成功消息 + msgSuccess(content: any) { + ElMessage.success(content); + }, + // 警告消息 + msgWarning(content: any) { + ElMessage.warning(content); + }, + // 弹出提示 + alert(content: any) { + ElMessageBox.alert(content, '系统提示'); + }, + // 错误提示 + alertError(content: any) { + ElMessageBox.alert(content, '系统提示', { type: 'error' }); + }, + // 成功提示 + alertSuccess(content: any) { + ElMessageBox.alert(content, '系统提示', { type: 'success' }); + }, + // 警告提示 + alertWarning(content: any) { + ElMessageBox.alert(content, '系统提示', { type: 'warning' }); + }, + // 通知提示 + notify(content: any) { + ElNotification.info(content); + }, + // 错误通知 + notifyError(content: any) { + ElNotification.error(content); + }, + // 成功通知 + notifySuccess(content: any) { + ElNotification.success(content); + }, + // 警告通知 + notifyWarning(content: any) { + ElNotification.warning(content); + }, + // 确认窗体 + confirm(content: any): Promise { + return ElMessageBox.confirm(content, '系统提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }); + }, + // 提交内容 + prompt(content: any) { + return ElMessageBox.prompt(content, '系统提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }); + }, + // 打开遮罩层 + loading(content: string) { + loadingInstance = ElLoading.service({ + lock: true, + text: content, + background: 'rgba(0, 0, 0, 0.7)' + }); + }, + // 关闭遮罩层 + closeLoading() { + loadingInstance.close(); + } +}; diff --git a/src/plugins/svgicon.ts b/src/plugins/svgicon.ts new file mode 100644 index 0000000..8c68609 --- /dev/null +++ b/src/plugins/svgicon.ts @@ -0,0 +1,10 @@ +import * as ElementPlusIconsVue from '@element-plus/icons-vue'; +import { App } from 'vue'; + +export default { + install: (app: App) => { + for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component); + } + } +}; diff --git a/src/plugins/tab.ts b/src/plugins/tab.ts new file mode 100644 index 0000000..1f673b3 --- /dev/null +++ b/src/plugins/tab.ts @@ -0,0 +1,96 @@ +import router from '@/router'; +import { RouteLocationMatched, RouteLocationNormalized, RouteLocationRaw } from 'vue-router'; +import { useTagsViewStore } from '@/store/modules/tagsView'; + +export default { + /** + * 刷新当前tab页签 + * @param obj 标签对象 + */ + async refreshPage(obj?: RouteLocationNormalized): Promise { + const { path, query, matched } = router.currentRoute.value; + if (obj === undefined) { + matched.forEach((m: RouteLocationMatched) => { + if (m.components && m.components.default && m.components.default.name) { + if (!['Layout', 'ParentView'].includes(m.components.default.name)) { + obj = { + name: m.components.default.name, + path: path, + query: query, + matched: undefined, + fullPath: undefined, + hash: undefined, + params: undefined, + redirectedFrom: undefined, + meta: undefined + }; + } + } + }); + } + let query1: undefined | {} = {}; + let path1: undefined | string = ''; + if (obj) { + query1 = obj.query; + path1 = obj.path; + } + await useTagsViewStore().delCachedView(obj); + await router.replace({ + path: '/redirect' + path1, + query: query1 + }); + }, + // 关闭当前tab页签,打开新页签 + closeOpenPage(obj: RouteLocationRaw): void { + useTagsViewStore().delView(router.currentRoute.value); + if (obj !== undefined) { + router.push(obj); + } + }, + // 关闭指定tab页签 + async closePage(obj?: RouteLocationNormalized): Promise<{ visitedViews: RouteLocationNormalized[]; cachedViews: string[] } | any> { + if (obj === undefined) { + // prettier-ignore + const { visitedViews } = await useTagsViewStore().delView(router.currentRoute.value) + const latestView = visitedViews.slice(-1)[0]; + if (latestView) { + return router.push(latestView.fullPath); + } + return router.push('/'); + } + return useTagsViewStore().delView(obj); + }, + // 关闭所有tab页签 + closeAllPage() { + return useTagsViewStore().delAllViews(); + }, + // 关闭左侧tab页签 + closeLeftPage(obj?: RouteLocationNormalized) { + return useTagsViewStore().delLeftTags(obj || router.currentRoute.value); + }, + // 关闭右侧tab页签 + closeRightPage(obj?: RouteLocationNormalized) { + return useTagsViewStore().delRightTags(obj || router.currentRoute.value); + }, + // 关闭其他tab页签 + closeOtherPage(obj?: RouteLocationNormalized) { + return useTagsViewStore().delOthersViews(obj || router.currentRoute.value); + }, + /** + * 打开tab页签 + * @param url 路由地址 + * @param title 标题 + * @param query 参数 + */ + openPage(url: string, title?: string, query?: any) { + const obj = { path: url, query: { ...query, title } }; + return router.push(obj); + }, + /** + * 修改tab页签 + * @param obj 标签对象 + */ + updatePage(obj: RouteLocationNormalized) { + return useTagsViewStore().updateVisitedView(obj); + } +}; diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100644 index 0000000..a6497db --- /dev/null +++ b/src/router/index.ts @@ -0,0 +1,114 @@ +import { createWebHistory, createRouter, RouteRecordRaw } from 'vue-router'; +/* Layout */ +import Layout from '@/layout/index.vue'; + +/** + * Note: 路由配置项 + * + * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1 + * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 + * // 若你想不管路由下面的 children 声明的个数都显示你的根路由 + * // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由 + * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + * name:'router-name' // 设定路由的名字,一定要填写不然使用时会出现各种问题 + * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数 + * roles: ['admin', 'common'] // 访问路由的角色权限 + * permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限 + * meta : { + noCache: true // 如果设置为true,则不会被 缓存(默认 false) + title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 + icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg + breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 + activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 + } + */ + +// 公共路由 +export const constantRoutes: RouteRecordRaw[] = [ + { + path: '/redirect', + component: Layout, + hidden: true, + children: [ + { + path: '/redirect/:path(.*)', + component: () => import('@/views/redirect/index.vue') + } + ] + }, + { + path: '/social-callback', + hidden: true, + component: () => import('@/layout/components/SocialCallback/index.vue') + }, + { + path: '/login', + component: () => import('@/views/login.vue'), + hidden: true + }, + { + path: '/register', + component: () => import('@/views/register.vue'), + hidden: true + }, + { + path: '/:pathMatch(.*)*', + component: () => import('@/views/error/404.vue'), + hidden: true + }, + { + path: '/401', + component: () => import('@/views/error/401.vue'), + hidden: true + }, + { + path: '', + component: Layout, + redirect: '/index', + children: [ + { + path: '/index', + component: () => import('@/views/index.vue'), + name: 'Index', + meta: { title: '首页', icon: 'dashboard', affix: true } + } + ] + }, + { + path: '/user', + component: Layout, + hidden: true, + redirect: 'noredirect', + children: [ + { + path: 'profile', + component: () => import('@/views/system/user/profile/index.vue'), + name: 'Profile', + meta: { title: '个人中心', icon: 'user' } + } + ] + } +]; + +// 动态路由,基于用户权限动态去加载 +export const dynamicRoutes: RouteRecordRaw[] = [ + +]; + +/** + * 创建路由 + */ +const router = createRouter({ + history: createWebHistory(import.meta.env.VITE_APP_CONTEXT_PATH), + routes: constantRoutes, + // 刷新时,滚动条位置还原 + scrollBehavior(to, from, savedPosition) { + if (savedPosition) { + return savedPosition; + } + return { top: 0 }; + } +}); + +export default router; diff --git a/src/settings.ts b/src/settings.ts new file mode 100644 index 0000000..5d53a23 --- /dev/null +++ b/src/settings.ts @@ -0,0 +1,75 @@ +import { LanguageEnum } from '@/enums/LanguageEnum'; + +const setting: DefaultSettings = { + /** + * 网页标题 + */ + title: import.meta.env.VITE_APP_TITLE, + + theme: '#409EFF', + + /** + * 侧边栏主题 深色主题theme-dark,浅色主题theme-light + */ + sideTheme: 'theme-dark', + /** + * 是否系统布局配置 + */ + showSettings: true, + + /** + * 是否显示顶部导航 + */ + topNav: false, + + /** + * 是否显示 tagsView + */ + tagsView: true, + + /** + * 显示页签图标 + */ + tagsIcon: false, + + /** + * 是否固定头部 + */ + fixedHeader: false, + + /** + * 是否显示logo + */ + sidebarLogo: true, + + /** + * 是否显示动态标题 + */ + dynamicTitle: false, + + /** + * 是否开启动画 开启随机 关闭渐进渐出 + */ + animationEnable: false, + + /** + * 是否暗黑模式 + */ + dark: false, + + /** + * 默认语言 + */ + language: LanguageEnum.zh_CN, + + /** + * 默认大小 + */ + size: 'default', + + /** + * 默认布局 + */ + layout: '' +}; +export default setting; diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..02ae96a --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,5 @@ +import { createPinia } from 'pinia'; + +const store = createPinia(); + +export default store; diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts new file mode 100644 index 0000000..54edc36 --- /dev/null +++ b/src/store/modules/app.ts @@ -0,0 +1,73 @@ +import zhCN from 'element-plus/es/locale/lang/zh-cn'; +import enUS from 'element-plus/es/locale/lang/en'; +import { defineStore } from 'pinia'; +import { useStorage } from '@vueuse/core'; +import { ref, reactive, computed } from 'vue'; + +export const useAppStore = defineStore('app', () => { + const sidebarStatus = useStorage('sidebarStatus', '1'); + const sidebar = reactive({ + opened: sidebarStatus.value ? !!+sidebarStatus.value : true, + withoutAnimation: false, + hide: false + }); + const device = ref('desktop'); + const size = useStorage<'large' | 'default' | 'small'>('size', 'default'); + + // 语言 + const language = useStorage('language', 'zh_CN'); + const languageObj: any = { + en_US: enUS, + zh_CN: zhCN + }; + const locale = computed(() => { + return languageObj[language.value]; + }); + + const toggleSideBar = (withoutAnimation: boolean) => { + if (sidebar.hide) { + return false; + } + + sidebar.opened = !sidebar.opened; + sidebar.withoutAnimation = withoutAnimation; + if (sidebar.opened) { + sidebarStatus.value = '1'; + } else { + sidebarStatus.value = '0'; + } + }; + + const closeSideBar = ({ withoutAnimation }: any): void => { + sidebarStatus.value = '0'; + sidebar.opened = false; + sidebar.withoutAnimation = withoutAnimation; + }; + const toggleDevice = (d: string): void => { + device.value = d; + }; + const setSize = (s: 'large' | 'default' | 'small'): void => { + size.value = s; + }; + const toggleSideBarHide = (status: boolean): void => { + sidebar.hide = status; + }; + + const changeLanguage = (val: string): void => { + language.value = val; + }; + + return { + device, + sidebar, + language, + locale, + size, + changeLanguage, + toggleSideBar, + closeSideBar, + toggleDevice, + setSize, + toggleSideBarHide + }; +}); diff --git a/src/store/modules/dict.ts b/src/store/modules/dict.ts new file mode 100644 index 0000000..742f900 --- /dev/null +++ b/src/store/modules/dict.ts @@ -0,0 +1,65 @@ +import { defineStore } from 'pinia'; + +export const useDictStore = defineStore('dict', () => { + const dict = ref>(new Map()); + + /** + * 获取字典 + * @param _key 字典key + */ + const getDict = (_key: string): DictDataOption[] | null => { + if (!_key) { + return null; + } + return dict.value.get(_key) || null; + }; + + /** + * 设置字典 + * @param _key 字典key + * @param _value 字典value + */ + const setDict = (_key: string, _value: DictDataOption[]) => { + if (!_key) { + return false; + } + try { + dict.value.set(_key, _value); + return true; + } catch (e) { + console.error('Error in setDict:', e); + return false; + } + }; + + /** + * 删除字典 + * @param _key + */ + const removeDict = (_key: string): boolean => { + if (!_key) { + return false; + } + try { + return dict.value.delete(_key); + } catch (e) { + console.error('Error in removeDict:', e); + return false; + } + }; + + /** + * 清空字典 + */ + const cleanDict = (): void => { + dict.value.clear(); + }; + + return { + dict, + getDict, + setDict, + removeDict, + cleanDict + }; +}); diff --git a/src/store/modules/notice.ts b/src/store/modules/notice.ts new file mode 100644 index 0000000..ff1e8d2 --- /dev/null +++ b/src/store/modules/notice.ts @@ -0,0 +1,41 @@ +import { defineStore } from 'pinia'; +import { reactive } from 'vue'; + +interface NoticeItem { + title?: string; + read: boolean; + message: any; + time: string; +} + +export const useNoticeStore = defineStore('notice', () => { + const state = reactive({ + notices: [] as NoticeItem[] + }); + + const addNotice = (notice: NoticeItem) => { + state.notices.push(notice); + }; + + const removeNotice = (notice: NoticeItem) => { + state.notices.splice(state.notices.indexOf(notice), 1); + }; + + //实现全部已读 + const readAll = () => { + state.notices.forEach((item: any) => { + item.read = true; + }); + }; + + const clearNotice = () => { + state.notices = []; + }; + return { + state, + addNotice, + removeNotice, + readAll, + clearNotice + }; +}); diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts new file mode 100644 index 0000000..1169cc8 --- /dev/null +++ b/src/store/modules/permission.ts @@ -0,0 +1,207 @@ +import { defineStore } from 'pinia'; +import router, { constantRoutes, dynamicRoutes } from '@/router'; +import store from '@/store'; +import { getRouters } from '@/api/menu'; +import auth from '@/plugins/auth'; +import { RouteRecordRaw } from 'vue-router'; +import Layout from '@/layout/index.vue'; +import ParentView from '@/components/ParentView/index.vue'; +import InnerLink from '@/layout/components/InnerLink/index.vue'; +import { ref } from 'vue'; +import { createCustomNameComponent } from '@/utils/createCustomNameComponent'; + +// 匹配views里面所有的.vue文件 +const modules = import.meta.glob('./../../views/**/*.vue'); +export const usePermissionStore = defineStore('permission', () => { + const routes = ref([]); + const addRoutes = ref([]); + const defaultRoutes = ref([]); + const topbarRouters = ref([]); + const sidebarRouters = ref([]); + + const getRoutes = (): RouteRecordRaw[] => { + return routes.value as RouteRecordRaw[]; + }; + const getDefaultRoutes = (): RouteRecordRaw[] => { + return defaultRoutes.value as RouteRecordRaw[]; + }; + const getSidebarRoutes = (): RouteRecordRaw[] => { + return sidebarRouters.value as RouteRecordRaw[]; + }; + const getTopbarRoutes = (): RouteRecordRaw[] => { + return topbarRouters.value as RouteRecordRaw[]; + }; + + const setRoutes = (newRoutes: RouteRecordRaw[]): void => { + addRoutes.value = newRoutes; + routes.value = constantRoutes.concat(newRoutes); + }; + const setDefaultRoutes = (routes: RouteRecordRaw[]): void => { + defaultRoutes.value = constantRoutes.concat(routes); + }; + const setTopbarRoutes = (routes: RouteRecordRaw[]): void => { + topbarRouters.value = routes; + }; + const setSidebarRouters = (routes: RouteRecordRaw[]): void => { + sidebarRouters.value = routes; + }; + const generateRoutes = async (): Promise => { + const res = await getRouters(); + const { data } = res; + const sdata = JSON.parse(JSON.stringify(data)); + const rdata = JSON.parse(JSON.stringify(data)); + const defaultData = JSON.parse(JSON.stringify(data)); + const sidebarRoutes = filterAsyncRouter(sdata); + const rewriteRoutes = filterAsyncRouter(rdata, undefined, true); + const defaultRoutes = filterAsyncRouter(defaultData); + const asyncRoutes = filterDynamicRoutes(dynamicRoutes); + asyncRoutes.forEach((route) => { + router.addRoute(route); + }); + setRoutes(rewriteRoutes); + setSidebarRouters(constantRoutes.concat(sidebarRoutes)); + setDefaultRoutes(sidebarRoutes); + setTopbarRoutes(defaultRoutes); + // 路由name重复检查 + duplicateRouteChecker(asyncRoutes, sidebarRoutes); + return new Promise((resolve) => resolve(rewriteRoutes)); + }; + + /** + * 遍历后台传来的路由字符串,转换为组件对象 + * @param asyncRouterMap 后台传来的路由字符串 + * @param lastRouter 上一级路由 + * @param type 是否是重写路由 + */ + const filterAsyncRouter = (asyncRouterMap: RouteRecordRaw[], lastRouter?: RouteRecordRaw, type = false): RouteRecordRaw[] => { + return asyncRouterMap.filter((route) => { + if (type && route.children) { + route.children = filterChildren(route.children, undefined); + } + // Layout ParentView 组件特殊处理 + if (route.component?.toString() === 'Layout') { + route.component = Layout; + } else if (route.component?.toString() === 'ParentView') { + route.component = ParentView; + } else if (route.component?.toString() === 'InnerLink') { + route.component = InnerLink; + } else { + route.component = loadView(route.component, route.name as string); + } + if (route.children != null && route.children && route.children.length) { + route.children = filterAsyncRouter(route.children, route, type); + } else { + delete route.children; + delete route.redirect; + } + return true; + }); + }; + const filterChildren = (childrenMap: RouteRecordRaw[], lastRouter?: RouteRecordRaw): RouteRecordRaw[] => { + let children: RouteRecordRaw[] = []; + childrenMap.forEach((el) => { + el.path = lastRouter ? lastRouter.path + '/' + el.path : el.path; + if (el.children && el.children.length && el.component?.toString() === 'ParentView') { + children = children.concat(filterChildren(el.children, el)); + } else { + children.push(el); + } + }); + return children; + }; + return { + routes, + topbarRouters, + sidebarRouters, + defaultRoutes, + + getRoutes, + getDefaultRoutes, + getSidebarRoutes, + getTopbarRoutes, + + setRoutes, + generateRoutes, + setSidebarRouters + }; +}); + +// 动态路由遍历,验证是否具备权限 +export const filterDynamicRoutes = (routes: RouteRecordRaw[]) => { + const res: RouteRecordRaw[] = []; + routes.forEach((route) => { + if (route.permissions) { + if (auth.hasPermiOr(route.permissions)) { + res.push(route); + } + } else if (route.roles) { + if (auth.hasRoleOr(route.roles)) { + res.push(route); + } + } + }); + return res; +}; + +export const loadView = (view: any, name: string) => { + let res; + for (const path in modules) { + const viewsIndex = path.indexOf('/views/'); + let dir = path.substring(viewsIndex + 7); + dir = dir.substring(0, dir.lastIndexOf('.vue')); + if (dir === view) { + res = createCustomNameComponent(modules[path], { name }); + return res; + } + } + return res; +}; + +// 非setup +export const usePermissionStoreHook = () => { + return usePermissionStore(store); +}; + +interface Route { + name?: string | symbol; + path: string; + children?: Route[]; +} + +/** + * 检查路由name是否重复 + * @param localRoutes 本地路由 + * @param routes 动态路由 + */ +function duplicateRouteChecker(localRoutes: Route[], routes: Route[]) { + // 展平 + function flatRoutes(routes: Route[]) { + const res: Route[] = []; + routes.forEach((route) => { + if (route.children) { + res.push(...flatRoutes(route.children)); + } else { + res.push(route); + } + }); + return res; + } + + const allRoutes = flatRoutes([...localRoutes, ...routes]); + + const nameList: string[] = []; + allRoutes.forEach((route) => { + const name = route.name.toString(); + if (name && nameList.includes(name)) { + const message = `路由名称: [${name}] 重复, 会造成 404`; + console.error(message); + ElNotification({ + title: '路由名称重复', + message, + type: 'error' + }); + return; + } + nameList.push(route.name.toString()); + }); +} diff --git a/src/store/modules/settings.ts b/src/store/modules/settings.ts new file mode 100644 index 0000000..7d0a4c9 --- /dev/null +++ b/src/store/modules/settings.ts @@ -0,0 +1,50 @@ +import { defineStore } from 'pinia'; +import defaultSettings from '@/settings'; +import { useDynamicTitle } from '@/utils/dynamicTitle'; +import { useStorage } from '@vueuse/core'; +import { ref } from 'vue'; + +export const useSettingsStore = defineStore('setting', () => { + const storageSetting = useStorage('layout-setting', { + topNav: defaultSettings.topNav, + tagsView: defaultSettings.tagsView, + tagsIcon: defaultSettings.tagsIcon, + fixedHeader: defaultSettings.fixedHeader, + sidebarLogo: defaultSettings.sidebarLogo, + dynamicTitle: defaultSettings.dynamicTitle, + sideTheme: defaultSettings.sideTheme, + theme: defaultSettings.theme + }); + const title = ref(defaultSettings.title); + const theme = ref(storageSetting.value.theme); + const sideTheme = ref(storageSetting.value.sideTheme); + const showSettings = ref(defaultSettings.showSettings); + const topNav = ref(storageSetting.value.topNav); + const tagsView = ref(storageSetting.value.tagsView); + const tagsIcon = ref(storageSetting.value.tagsIcon); + const fixedHeader = ref(storageSetting.value.fixedHeader); + const sidebarLogo = ref(storageSetting.value.sidebarLogo); + const dynamicTitle = ref(storageSetting.value.dynamicTitle); + const animationEnable = ref(defaultSettings.animationEnable); + const dark = ref(defaultSettings.dark); + + const setTitle = (value: string) => { + title.value = value; + useDynamicTitle(); + }; + return { + title, + theme, + sideTheme, + showSettings, + topNav, + tagsView, + tagsIcon, + fixedHeader, + sidebarLogo, + dynamicTitle, + animationEnable, + dark, + setTitle + }; +}); diff --git a/src/store/modules/tagsView.ts b/src/store/modules/tagsView.ts new file mode 100644 index 0000000..dc8850c --- /dev/null +++ b/src/store/modules/tagsView.ts @@ -0,0 +1,234 @@ +import { RouteLocationNormalized } from 'vue-router'; +import { defineStore } from 'pinia'; +import { ref } from 'vue'; + +export const useTagsViewStore = defineStore('tagsView', () => { + const visitedViews = ref([]); + const cachedViews = ref([]); + const iframeViews = ref([]); + + const getVisitedViews = (): RouteLocationNormalized[] => { + return visitedViews.value as RouteLocationNormalized[]; + }; + const getIframeViews = (): RouteLocationNormalized[] => { + return iframeViews.value as RouteLocationNormalized[]; + }; + const getCachedViews = (): string[] => { + return cachedViews.value; + }; + + const addView = (view: RouteLocationNormalized) => { + addVisitedView(view); + addCachedView(view); + }; + + const addIframeView = (view: RouteLocationNormalized): void => { + if (iframeViews.value.some((v: RouteLocationNormalized) => v.path === view.path)) return; + iframeViews.value.push( + Object.assign({}, view, { + title: view.meta?.title || 'no-name' + }) + ); + }; + const delIframeView = (view: RouteLocationNormalized): Promise => { + return new Promise((resolve) => { + iframeViews.value = iframeViews.value.filter((item: RouteLocationNormalized) => item.path !== view.path); + resolve([...(iframeViews.value as RouteLocationNormalized[])]); + }); + }; + const addVisitedView = (view: RouteLocationNormalized): void => { + if (visitedViews.value.some((v: RouteLocationNormalized) => v.path === view.path)) return; + visitedViews.value.push( + Object.assign({}, view, { + title: view.meta?.title || 'no-name' + }) + ); + }; + const delView = ( + view: RouteLocationNormalized + ): Promise<{ + visitedViews: RouteLocationNormalized[]; + cachedViews: string[]; + }> => { + return new Promise((resolve) => { + delVisitedView(view); + if (!isDynamicRoute(view)) { + delCachedView(view); + } + resolve({ + visitedViews: [...(visitedViews.value as RouteLocationNormalized[])], + cachedViews: [...cachedViews.value] + }); + }); + }; + + const delVisitedView = (view: RouteLocationNormalized): Promise => { + return new Promise((resolve) => { + for (const [i, v] of visitedViews.value.entries()) { + if (v.path === view.path) { + visitedViews.value.splice(i, 1); + break; + } + } + resolve([...(visitedViews.value as RouteLocationNormalized[])]); + }); + }; + const delCachedView = (view?: RouteLocationNormalized): Promise => { + let viewName = ''; + if (view) { + viewName = view.name as string; + } + return new Promise((resolve) => { + const index = cachedViews.value.indexOf(viewName); + index > -1 && cachedViews.value.splice(index, 1); + resolve([...cachedViews.value]); + }); + }; + const delOthersViews = ( + view: RouteLocationNormalized + ): Promise<{ + visitedViews: RouteLocationNormalized[]; + cachedViews: string[]; + }> => { + return new Promise((resolve) => { + delOthersVisitedViews(view); + delOthersCachedViews(view); + resolve({ + visitedViews: [...(visitedViews.value as RouteLocationNormalized[])], + cachedViews: [...cachedViews.value] + }); + }); + }; + + const delOthersVisitedViews = (view: RouteLocationNormalized): Promise => { + return new Promise((resolve) => { + visitedViews.value = visitedViews.value.filter((v: RouteLocationNormalized) => { + return v.meta?.affix || v.path === view.path; + }); + resolve([...(visitedViews.value as RouteLocationNormalized[])]); + }); + }; + const delOthersCachedViews = (view: RouteLocationNormalized): Promise => { + const viewName = view.name as string; + return new Promise((resolve) => { + const index = cachedViews.value.indexOf(viewName); + if (index > -1) { + cachedViews.value = cachedViews.value.slice(index, index + 1); + } else { + cachedViews.value = []; + } + resolve([...cachedViews.value]); + }); + }; + + const delAllViews = (): Promise<{ visitedViews: RouteLocationNormalized[]; cachedViews: string[] }> => { + return new Promise((resolve) => { + delAllVisitedViews(); + delAllCachedViews(); + resolve({ + visitedViews: [...(visitedViews.value as RouteLocationNormalized[])], + cachedViews: [...cachedViews.value] + }); + }); + }; + const delAllVisitedViews = (): Promise => { + return new Promise((resolve) => { + visitedViews.value = visitedViews.value.filter((tag: RouteLocationNormalized) => tag.meta?.affix); + resolve([...(visitedViews.value as RouteLocationNormalized[])]); + }); + }; + + const delAllCachedViews = (): Promise => { + return new Promise((resolve) => { + cachedViews.value = []; + resolve([...cachedViews.value]); + }); + }; + + const updateVisitedView = (view: RouteLocationNormalized): void => { + for (let v of visitedViews.value) { + if (v.path === view.path) { + v = Object.assign(v, view); + break; + } + } + }; + const delRightTags = (view: RouteLocationNormalized): Promise => { + return new Promise((resolve) => { + const index = visitedViews.value.findIndex((v: RouteLocationNormalized) => v.path === view.path); + if (index === -1) { + return; + } + visitedViews.value = visitedViews.value.filter((item: RouteLocationNormalized, idx: number) => { + if (idx <= index || (item.meta && item.meta.affix)) { + return true; + } + const i = cachedViews.value.indexOf(item.name as string); + if (i > -1) { + cachedViews.value.splice(i, 1); + } + return false; + }); + resolve([...(visitedViews.value as RouteLocationNormalized[])]); + }); + }; + const delLeftTags = (view: RouteLocationNormalized): Promise => { + return new Promise((resolve) => { + const index = visitedViews.value.findIndex((v: RouteLocationNormalized) => v.path === view.path); + if (index === -1) { + return; + } + visitedViews.value = visitedViews.value.filter((item: RouteLocationNormalized, idx: number) => { + if (idx >= index || (item.meta && item.meta.affix)) { + return true; + } + const i = cachedViews.value.indexOf(item.name as string); + if (i > -1) { + cachedViews.value.splice(i, 1); + } + return false; + }); + resolve([...(visitedViews.value as RouteLocationNormalized[])]); + }); + }; + + const addCachedView = (view: RouteLocationNormalized): void => { + const viewName = view.name as string; + if (!viewName) return; + if (cachedViews.value.includes(viewName)) return; + if (!view.meta?.noCache) { + cachedViews.value.push(viewName); + } + }; + + const isDynamicRoute = (view: RouteLocationNormalized): boolean => { + // 检查匹配的路由记录中是否有动态段 + return view.matched.some((m) => m.path.includes(':')); + }; + + return { + visitedViews, + cachedViews, + iframeViews, + + getVisitedViews, + getIframeViews, + getCachedViews, + + addVisitedView, + addCachedView, + delVisitedView, + delCachedView, + updateVisitedView, + addView, + delView, + delAllViews, + delAllVisitedViews, + delAllCachedViews, + delOthersViews, + delRightTags, + delLeftTags, + addIframeView, + delIframeView + }; +}); diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts new file mode 100644 index 0000000..93f9bc8 --- /dev/null +++ b/src/store/modules/user.ts @@ -0,0 +1,86 @@ +import { to } from 'await-to-js'; +import { getToken, removeToken, setToken } from '@/utils/auth'; +import { login as loginApi, logout as logoutApi, getInfo as getUserInfo } from '@/api/login'; +import { LoginData } from '@/api/types'; +import defAva from '@/assets/images/profile.png'; +import { defineStore } from 'pinia'; +import { ref } from 'vue'; + +export const useUserStore = defineStore('user', () => { + const token = ref(getToken()); + const name = ref(''); + const nickname = ref(''); + const userId = ref(''); + const tenantId = ref(''); + const avatar = ref(''); + const roles = ref>([]); // 用户角色编码集合 → 判断路由权限 + const permissions = ref>([]); // 用户权限编码集合 → 判断按钮权限 + + /** + * 登录 + * @param userInfo + * @returns + */ + const login = async (userInfo: LoginData): Promise => { + const [err, res] = await to(loginApi(userInfo)); + if (res) { + const data = res.data; + setToken(data.access_token); + token.value = data.access_token; + return Promise.resolve(); + } + return Promise.reject(err); + }; + + // 获取用户信息 + const getInfo = async (): Promise => { + const [err, res] = await to(getUserInfo()); + if (res) { + const data = res.data; + const user = data.user; + const profile = user.avatar == '' || user.avatar == null ? defAva : user.avatar; + + if (data.roles && data.roles.length > 0) { + // 验证返回的roles是否是一个非空数组 + roles.value = data.roles; + permissions.value = data.permissions; + } else { + roles.value = ['ROLE_DEFAULT']; + } + name.value = user.userName; + nickname.value = user.nickName; + avatar.value = profile; + userId.value = user.userId; + tenantId.value = user.tenantId; + return Promise.resolve(); + } + return Promise.reject(err); + }; + + // 注销 + const logout = async (): Promise => { + await logoutApi(); + token.value = ''; + roles.value = []; + permissions.value = []; + removeToken(); + }; + + const setAvatar = (value: string) => { + avatar.value = value; + }; + + return { + userId, + tenantId, + token, + nickname, + avatar, + roles, + permissions, + login, + getInfo, + logout, + setAvatar + }; +}); diff --git a/src/types/auto-imports.d.ts b/src/types/auto-imports.d.ts new file mode 100644 index 0000000..800d698 --- /dev/null +++ b/src/types/auto-imports.d.ts @@ -0,0 +1,629 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +// biome-ignore lint: disable +export {} +declare global { + const EffectScope: typeof import('vue')['EffectScope'] + const ElLoading: typeof import('element-plus/es')['ElLoading'] + const ElMessage: typeof import('element-plus/es')['ElMessage'] + const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] + const ElNotification: typeof import('element-plus/es')['ElNotification'] + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] + const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] + const computed: typeof import('vue')['computed'] + const computedAsync: typeof import('@vueuse/core')['computedAsync'] + const computedEager: typeof import('@vueuse/core')['computedEager'] + const computedInject: typeof import('@vueuse/core')['computedInject'] + const computedWithControl: typeof import('@vueuse/core')['computedWithControl'] + const controlledComputed: typeof import('@vueuse/core')['controlledComputed'] + const controlledRef: typeof import('@vueuse/core')['controlledRef'] + const createApp: typeof import('vue')['createApp'] + const createEventHook: typeof import('@vueuse/core')['createEventHook'] + const createGlobalState: typeof import('@vueuse/core')['createGlobalState'] + const createInjectionState: typeof import('@vueuse/core')['createInjectionState'] + const createPinia: typeof import('pinia')['createPinia'] + const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn'] + const createRef: typeof import('@vueuse/core')['createRef'] + const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate'] + const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] + const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise'] + const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn'] + const customRef: typeof import('vue')['customRef'] + const debouncedRef: typeof import('@vueuse/core')['debouncedRef'] + const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const defineStore: typeof import('pinia')['defineStore'] + const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] + const effectScope: typeof import('vue')['effectScope'] + const extendRef: typeof import('@vueuse/core')['extendRef'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] + const inject: typeof import('vue')['inject'] + const injectLocal: typeof import('@vueuse/core')['injectLocal'] + const isDefined: typeof import('@vueuse/core')['isDefined'] + const isProxy: typeof import('vue')['isProxy'] + const isReactive: typeof import('vue')['isReactive'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onClickOutside: typeof import('@vueuse/core')['onClickOutside'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onElementRemoval: typeof import('@vueuse/core')['onElementRemoval'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke'] + const onLongPress: typeof import('@vueuse/core')['onLongPress'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] + const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] + const provide: typeof import('vue')['provide'] + const provideLocal: typeof import('@vueuse/core')['provideLocal'] + const reactify: typeof import('@vueuse/core')['reactify'] + const reactifyObject: typeof import('@vueuse/core')['reactifyObject'] + const reactive: typeof import('vue')['reactive'] + const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed'] + const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit'] + const reactivePick: typeof import('@vueuse/core')['reactivePick'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const refAutoReset: typeof import('@vueuse/core')['refAutoReset'] + const refDebounced: typeof import('@vueuse/core')['refDebounced'] + const refDefault: typeof import('@vueuse/core')['refDefault'] + const refThrottled: typeof import('@vueuse/core')['refThrottled'] + const refWithControl: typeof import('@vueuse/core')['refWithControl'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const resolveRef: typeof import('@vueuse/core')['resolveRef'] + const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const syncRef: typeof import('@vueuse/core')['syncRef'] + const syncRefs: typeof import('@vueuse/core')['syncRefs'] + const templateRef: typeof import('@vueuse/core')['templateRef'] + const throttledRef: typeof import('@vueuse/core')['throttledRef'] + const throttledWatch: typeof import('@vueuse/core')['throttledWatch'] + const toRaw: typeof import('vue')['toRaw'] + const toReactive: typeof import('@vueuse/core')['toReactive'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const toValue: typeof import('vue')['toValue'] + const triggerRef: typeof import('vue')['triggerRef'] + const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] + const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] + const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted'] + const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose'] + const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted'] + const unref: typeof import('vue')['unref'] + const unrefElement: typeof import('@vueuse/core')['unrefElement'] + const until: typeof import('@vueuse/core')['until'] + const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] + const useAnimate: typeof import('@vueuse/core')['useAnimate'] + const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference'] + const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery'] + const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter'] + const useArrayFind: typeof import('@vueuse/core')['useArrayFind'] + const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex'] + const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast'] + const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes'] + const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin'] + const useArrayMap: typeof import('@vueuse/core')['useArrayMap'] + const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce'] + const useArraySome: typeof import('@vueuse/core')['useArraySome'] + const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique'] + const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue'] + const useAsyncState: typeof import('@vueuse/core')['useAsyncState'] + const useAttrs: typeof import('vue')['useAttrs'] + const useBase64: typeof import('@vueuse/core')['useBase64'] + const useBattery: typeof import('@vueuse/core')['useBattery'] + const useBluetooth: typeof import('@vueuse/core')['useBluetooth'] + const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints'] + const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel'] + const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] + const useCached: typeof import('@vueuse/core')['useCached'] + const useClipboard: typeof import('@vueuse/core')['useClipboard'] + const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems'] + const useCloned: typeof import('@vueuse/core')['useCloned'] + const useColorMode: typeof import('@vueuse/core')['useColorMode'] + const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog'] + const useCountdown: typeof import('@vueuse/core')['useCountdown'] + const useCounter: typeof import('@vueuse/core')['useCounter'] + const useCssModule: typeof import('vue')['useCssModule'] + const useCssVar: typeof import('@vueuse/core')['useCssVar'] + const useCssVars: typeof import('vue')['useCssVars'] + const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement'] + const useCycleList: typeof import('@vueuse/core')['useCycleList'] + const useDark: typeof import('@vueuse/core')['useDark'] + const useDateFormat: typeof import('@vueuse/core')['useDateFormat'] + const useDebounce: typeof import('@vueuse/core')['useDebounce'] + const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn'] + const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory'] + const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion'] + const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation'] + const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio'] + const useDevicesList: typeof import('@vueuse/core')['useDevicesList'] + const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia'] + const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility'] + const useDraggable: typeof import('@vueuse/core')['useDraggable'] + const useDropZone: typeof import('@vueuse/core')['useDropZone'] + const useElementBounding: typeof import('@vueuse/core')['useElementBounding'] + const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint'] + const useElementHover: typeof import('@vueuse/core')['useElementHover'] + const useElementSize: typeof import('@vueuse/core')['useElementSize'] + const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility'] + const useEventBus: typeof import('@vueuse/core')['useEventBus'] + const useEventListener: typeof import('@vueuse/core')['useEventListener'] + const useEventSource: typeof import('@vueuse/core')['useEventSource'] + const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper'] + const useFavicon: typeof import('@vueuse/core')['useFavicon'] + const useFetch: typeof import('@vueuse/core')['useFetch'] + const useFileDialog: typeof import('@vueuse/core')['useFileDialog'] + const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess'] + const useFocus: typeof import('@vueuse/core')['useFocus'] + const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin'] + const useFps: typeof import('@vueuse/core')['useFps'] + const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] + const useGamepad: typeof import('@vueuse/core')['useGamepad'] + const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] + const useId: typeof import('vue')['useId'] + const useIdle: typeof import('@vueuse/core')['useIdle'] + const useImage: typeof import('@vueuse/core')['useImage'] + const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] + const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver'] + const useInterval: typeof import('@vueuse/core')['useInterval'] + const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn'] + const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier'] + const useLastChanged: typeof import('@vueuse/core')['useLastChanged'] + const useLink: typeof import('vue-router')['useLink'] + const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage'] + const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys'] + const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory'] + const useMediaControls: typeof import('@vueuse/core')['useMediaControls'] + const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] + const useMemoize: typeof import('@vueuse/core')['useMemoize'] + const useMemory: typeof import('@vueuse/core')['useMemory'] + const useModel: typeof import('vue')['useModel'] + const useMounted: typeof import('@vueuse/core')['useMounted'] + const useMouse: typeof import('@vueuse/core')['useMouse'] + const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] + const useMousePressed: typeof import('@vueuse/core')['useMousePressed'] + const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] + const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] + const useNetwork: typeof import('@vueuse/core')['useNetwork'] + const useNow: typeof import('@vueuse/core')['useNow'] + const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl'] + const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] + const useOnline: typeof import('@vueuse/core')['useOnline'] + const usePageLeave: typeof import('@vueuse/core')['usePageLeave'] + const useParallax: typeof import('@vueuse/core')['useParallax'] + const useParentElement: typeof import('@vueuse/core')['useParentElement'] + const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver'] + const usePermission: typeof import('@vueuse/core')['usePermission'] + const usePointer: typeof import('@vueuse/core')['usePointer'] + const usePointerLock: typeof import('@vueuse/core')['usePointerLock'] + const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe'] + const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme'] + const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast'] + const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark'] + const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages'] + const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion'] + const usePreferredReducedTransparency: typeof import('@vueuse/core')['usePreferredReducedTransparency'] + const usePrevious: typeof import('@vueuse/core')['usePrevious'] + const useRafFn: typeof import('@vueuse/core')['useRafFn'] + const useRefHistory: typeof import('@vueuse/core')['useRefHistory'] + const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver'] + const useRoute: typeof import('vue-router')['useRoute'] + const useRouter: typeof import('vue-router')['useRouter'] + const useSSRWidth: typeof import('@vueuse/core')['useSSRWidth'] + const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation'] + const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea'] + const useScriptTag: typeof import('@vueuse/core')['useScriptTag'] + const useScroll: typeof import('@vueuse/core')['useScroll'] + const useScrollLock: typeof import('@vueuse/core')['useScrollLock'] + const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage'] + const useShare: typeof import('@vueuse/core')['useShare'] + const useSlots: typeof import('vue')['useSlots'] + const useSorted: typeof import('@vueuse/core')['useSorted'] + const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition'] + const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis'] + const useStepper: typeof import('@vueuse/core')['useStepper'] + const useStorage: typeof import('@vueuse/core')['useStorage'] + const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync'] + const useStyleTag: typeof import('@vueuse/core')['useStyleTag'] + const useSupported: typeof import('@vueuse/core')['useSupported'] + const useSwipe: typeof import('@vueuse/core')['useSwipe'] + const useTemplateRef: typeof import('vue')['useTemplateRef'] + const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] + const useTextDirection: typeof import('@vueuse/core')['useTextDirection'] + const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] + const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize'] + const useThrottle: typeof import('@vueuse/core')['useThrottle'] + const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn'] + const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory'] + const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo'] + const useTimeout: typeof import('@vueuse/core')['useTimeout'] + const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn'] + const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll'] + const useTimestamp: typeof import('@vueuse/core')['useTimestamp'] + const useTitle: typeof import('@vueuse/core')['useTitle'] + const useToNumber: typeof import('@vueuse/core')['useToNumber'] + const useToString: typeof import('@vueuse/core')['useToString'] + const useToggle: typeof import('@vueuse/core')['useToggle'] + const useTransition: typeof import('@vueuse/core')['useTransition'] + const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams'] + const useUserMedia: typeof import('@vueuse/core')['useUserMedia'] + const useVModel: typeof import('@vueuse/core')['useVModel'] + const useVModels: typeof import('@vueuse/core')['useVModels'] + const useVibrate: typeof import('@vueuse/core')['useVibrate'] + const useVirtualList: typeof import('@vueuse/core')['useVirtualList'] + const useWakeLock: typeof import('@vueuse/core')['useWakeLock'] + const useWebNotification: typeof import('@vueuse/core')['useWebNotification'] + const useWebSocket: typeof import('@vueuse/core')['useWebSocket'] + const useWebWorker: typeof import('@vueuse/core')['useWebWorker'] + const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn'] + const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus'] + const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll'] + const useWindowSize: typeof import('@vueuse/core')['useWindowSize'] + const watch: typeof import('vue')['watch'] + const watchArray: typeof import('@vueuse/core')['watchArray'] + const watchAtMost: typeof import('@vueuse/core')['watchAtMost'] + const watchDebounced: typeof import('@vueuse/core')['watchDebounced'] + const watchDeep: typeof import('@vueuse/core')['watchDeep'] + const watchEffect: typeof import('vue')['watchEffect'] + const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] + const watchImmediate: typeof import('@vueuse/core')['watchImmediate'] + const watchOnce: typeof import('@vueuse/core')['watchOnce'] + const watchPausable: typeof import('@vueuse/core')['watchPausable'] + const watchPostEffect: typeof import('vue')['watchPostEffect'] + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] + const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] + const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable'] + const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] + const whenever: typeof import('@vueuse/core')['whenever'] +} +// for type re-export +declare global { + // @ts-ignore + export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' + import('vue') +} + +// for vue template auto import +import { UnwrapRef } from 'vue' +declare module 'vue' { + interface GlobalComponents {} + interface ComponentCustomProperties { + readonly EffectScope: UnwrapRef + readonly ElLoading: UnwrapRef + readonly ElMessage: UnwrapRef + readonly ElMessageBox: UnwrapRef + readonly ElNotification: UnwrapRef + readonly acceptHMRUpdate: UnwrapRef + readonly asyncComputed: UnwrapRef + readonly autoResetRef: UnwrapRef + readonly computed: UnwrapRef + readonly computedAsync: UnwrapRef + readonly computedEager: UnwrapRef + readonly computedInject: UnwrapRef + readonly computedWithControl: UnwrapRef + readonly controlledComputed: UnwrapRef + readonly controlledRef: UnwrapRef + readonly createApp: UnwrapRef + readonly createEventHook: UnwrapRef + readonly createGlobalState: UnwrapRef + readonly createInjectionState: UnwrapRef + readonly createPinia: UnwrapRef + readonly createReactiveFn: UnwrapRef + readonly createRef: UnwrapRef + readonly createReusableTemplate: UnwrapRef + readonly createSharedComposable: UnwrapRef + readonly createTemplatePromise: UnwrapRef + readonly createUnrefFn: UnwrapRef + readonly customRef: UnwrapRef + readonly debouncedRef: UnwrapRef + readonly debouncedWatch: UnwrapRef + readonly defineAsyncComponent: UnwrapRef + readonly defineComponent: UnwrapRef + readonly defineStore: UnwrapRef + readonly eagerComputed: UnwrapRef + readonly effectScope: UnwrapRef + readonly extendRef: UnwrapRef + readonly getActivePinia: UnwrapRef + readonly getCurrentInstance: UnwrapRef + readonly getCurrentScope: UnwrapRef + readonly h: UnwrapRef + readonly ignorableWatch: UnwrapRef + readonly inject: UnwrapRef + readonly injectLocal: UnwrapRef + readonly isDefined: UnwrapRef + readonly isProxy: UnwrapRef + readonly isReactive: UnwrapRef + readonly isReadonly: UnwrapRef + readonly isRef: UnwrapRef + readonly makeDestructurable: UnwrapRef + readonly mapActions: UnwrapRef + readonly mapGetters: UnwrapRef + readonly mapState: UnwrapRef + readonly mapStores: UnwrapRef + readonly mapWritableState: UnwrapRef + readonly markRaw: UnwrapRef + readonly nextTick: UnwrapRef + readonly onActivated: UnwrapRef + readonly onBeforeMount: UnwrapRef + readonly onBeforeRouteLeave: UnwrapRef + readonly onBeforeRouteUpdate: UnwrapRef + readonly onBeforeUnmount: UnwrapRef + readonly onBeforeUpdate: UnwrapRef + readonly onClickOutside: UnwrapRef + readonly onDeactivated: UnwrapRef + readonly onElementRemoval: UnwrapRef + readonly onErrorCaptured: UnwrapRef + readonly onKeyStroke: UnwrapRef + readonly onLongPress: UnwrapRef + readonly onMounted: UnwrapRef + readonly onRenderTracked: UnwrapRef + readonly onRenderTriggered: UnwrapRef + readonly onScopeDispose: UnwrapRef + readonly onServerPrefetch: UnwrapRef + readonly onStartTyping: UnwrapRef + readonly onUnmounted: UnwrapRef + readonly onUpdated: UnwrapRef + readonly onWatcherCleanup: UnwrapRef + readonly pausableWatch: UnwrapRef + readonly provide: UnwrapRef + readonly provideLocal: UnwrapRef + readonly reactify: UnwrapRef + readonly reactifyObject: UnwrapRef + readonly reactive: UnwrapRef + readonly reactiveComputed: UnwrapRef + readonly reactiveOmit: UnwrapRef + readonly reactivePick: UnwrapRef + readonly readonly: UnwrapRef + readonly ref: UnwrapRef + readonly refAutoReset: UnwrapRef + readonly refDebounced: UnwrapRef + readonly refDefault: UnwrapRef + readonly refThrottled: UnwrapRef + readonly refWithControl: UnwrapRef + readonly resolveComponent: UnwrapRef + readonly resolveRef: UnwrapRef + readonly resolveUnref: UnwrapRef + readonly setActivePinia: UnwrapRef + readonly setMapStoreSuffix: UnwrapRef + readonly shallowReactive: UnwrapRef + readonly shallowReadonly: UnwrapRef + readonly shallowRef: UnwrapRef + readonly storeToRefs: UnwrapRef + readonly syncRef: UnwrapRef + readonly syncRefs: UnwrapRef + readonly templateRef: UnwrapRef + readonly throttledRef: UnwrapRef + readonly throttledWatch: UnwrapRef + readonly toRaw: UnwrapRef + readonly toReactive: UnwrapRef + readonly toRef: UnwrapRef + readonly toRefs: UnwrapRef + readonly toValue: UnwrapRef + readonly triggerRef: UnwrapRef + readonly tryOnBeforeMount: UnwrapRef + readonly tryOnBeforeUnmount: UnwrapRef + readonly tryOnMounted: UnwrapRef + readonly tryOnScopeDispose: UnwrapRef + readonly tryOnUnmounted: UnwrapRef + readonly unref: UnwrapRef + readonly unrefElement: UnwrapRef + readonly until: UnwrapRef + readonly useActiveElement: UnwrapRef + readonly useAnimate: UnwrapRef + readonly useArrayDifference: UnwrapRef + readonly useArrayEvery: UnwrapRef + readonly useArrayFilter: UnwrapRef + readonly useArrayFind: UnwrapRef + readonly useArrayFindIndex: UnwrapRef + readonly useArrayFindLast: UnwrapRef + readonly useArrayIncludes: UnwrapRef + readonly useArrayJoin: UnwrapRef + readonly useArrayMap: UnwrapRef + readonly useArrayReduce: UnwrapRef + readonly useArraySome: UnwrapRef + readonly useArrayUnique: UnwrapRef + readonly useAsyncQueue: UnwrapRef + readonly useAsyncState: UnwrapRef + readonly useAttrs: UnwrapRef + readonly useBase64: UnwrapRef + readonly useBattery: UnwrapRef + readonly useBluetooth: UnwrapRef + readonly useBreakpoints: UnwrapRef + readonly useBroadcastChannel: UnwrapRef + readonly useBrowserLocation: UnwrapRef + readonly useCached: UnwrapRef + readonly useClipboard: UnwrapRef + readonly useClipboardItems: UnwrapRef + readonly useCloned: UnwrapRef + readonly useColorMode: UnwrapRef + readonly useConfirmDialog: UnwrapRef + readonly useCountdown: UnwrapRef + readonly useCounter: UnwrapRef + readonly useCssModule: UnwrapRef + readonly useCssVar: UnwrapRef + readonly useCssVars: UnwrapRef + readonly useCurrentElement: UnwrapRef + readonly useCycleList: UnwrapRef + readonly useDark: UnwrapRef + readonly useDateFormat: UnwrapRef + readonly useDebounce: UnwrapRef + readonly useDebounceFn: UnwrapRef + readonly useDebouncedRefHistory: UnwrapRef + readonly useDeviceMotion: UnwrapRef + readonly useDeviceOrientation: UnwrapRef + readonly useDevicePixelRatio: UnwrapRef + readonly useDevicesList: UnwrapRef + readonly useDisplayMedia: UnwrapRef + readonly useDocumentVisibility: UnwrapRef + readonly useDraggable: UnwrapRef + readonly useDropZone: UnwrapRef + readonly useElementBounding: UnwrapRef + readonly useElementByPoint: UnwrapRef + readonly useElementHover: UnwrapRef + readonly useElementSize: UnwrapRef + readonly useElementVisibility: UnwrapRef + readonly useEventBus: UnwrapRef + readonly useEventListener: UnwrapRef + readonly useEventSource: UnwrapRef + readonly useEyeDropper: UnwrapRef + readonly useFavicon: UnwrapRef + readonly useFetch: UnwrapRef + readonly useFileDialog: UnwrapRef + readonly useFileSystemAccess: UnwrapRef + readonly useFocus: UnwrapRef + readonly useFocusWithin: UnwrapRef + readonly useFps: UnwrapRef + readonly useFullscreen: UnwrapRef + readonly useGamepad: UnwrapRef + readonly useGeolocation: UnwrapRef + readonly useId: UnwrapRef + readonly useIdle: UnwrapRef + readonly useImage: UnwrapRef + readonly useInfiniteScroll: UnwrapRef + readonly useIntersectionObserver: UnwrapRef + readonly useInterval: UnwrapRef + readonly useIntervalFn: UnwrapRef + readonly useKeyModifier: UnwrapRef + readonly useLastChanged: UnwrapRef + readonly useLink: UnwrapRef + readonly useLocalStorage: UnwrapRef + readonly useMagicKeys: UnwrapRef + readonly useManualRefHistory: UnwrapRef + readonly useMediaControls: UnwrapRef + readonly useMediaQuery: UnwrapRef + readonly useMemoize: UnwrapRef + readonly useMemory: UnwrapRef + readonly useModel: UnwrapRef + readonly useMounted: UnwrapRef + readonly useMouse: UnwrapRef + readonly useMouseInElement: UnwrapRef + readonly useMousePressed: UnwrapRef + readonly useMutationObserver: UnwrapRef + readonly useNavigatorLanguage: UnwrapRef + readonly useNetwork: UnwrapRef + readonly useNow: UnwrapRef + readonly useObjectUrl: UnwrapRef + readonly useOffsetPagination: UnwrapRef + readonly useOnline: UnwrapRef + readonly usePageLeave: UnwrapRef + readonly useParallax: UnwrapRef + readonly useParentElement: UnwrapRef + readonly usePerformanceObserver: UnwrapRef + readonly usePermission: UnwrapRef + readonly usePointer: UnwrapRef + readonly usePointerLock: UnwrapRef + readonly usePointerSwipe: UnwrapRef + readonly usePreferredColorScheme: UnwrapRef + readonly usePreferredContrast: UnwrapRef + readonly usePreferredDark: UnwrapRef + readonly usePreferredLanguages: UnwrapRef + readonly usePreferredReducedMotion: UnwrapRef + readonly usePreferredReducedTransparency: UnwrapRef + readonly usePrevious: UnwrapRef + readonly useRafFn: UnwrapRef + readonly useRefHistory: UnwrapRef + readonly useResizeObserver: UnwrapRef + readonly useRoute: UnwrapRef + readonly useRouter: UnwrapRef + readonly useSSRWidth: UnwrapRef + readonly useScreenOrientation: UnwrapRef + readonly useScreenSafeArea: UnwrapRef + readonly useScriptTag: UnwrapRef + readonly useScroll: UnwrapRef + readonly useScrollLock: UnwrapRef + readonly useSessionStorage: UnwrapRef + readonly useShare: UnwrapRef + readonly useSlots: UnwrapRef + readonly useSorted: UnwrapRef + readonly useSpeechRecognition: UnwrapRef + readonly useSpeechSynthesis: UnwrapRef + readonly useStepper: UnwrapRef + readonly useStorage: UnwrapRef + readonly useStorageAsync: UnwrapRef + readonly useStyleTag: UnwrapRef + readonly useSupported: UnwrapRef + readonly useSwipe: UnwrapRef + readonly useTemplateRef: UnwrapRef + readonly useTemplateRefsList: UnwrapRef + readonly useTextDirection: UnwrapRef + readonly useTextSelection: UnwrapRef + readonly useTextareaAutosize: UnwrapRef + readonly useThrottle: UnwrapRef + readonly useThrottleFn: UnwrapRef + readonly useThrottledRefHistory: UnwrapRef + readonly useTimeAgo: UnwrapRef + readonly useTimeout: UnwrapRef + readonly useTimeoutFn: UnwrapRef + readonly useTimeoutPoll: UnwrapRef + readonly useTimestamp: UnwrapRef + readonly useTitle: UnwrapRef + readonly useToNumber: UnwrapRef + readonly useToString: UnwrapRef + readonly useToggle: UnwrapRef + readonly useTransition: UnwrapRef + readonly useUrlSearchParams: UnwrapRef + readonly useUserMedia: UnwrapRef + readonly useVModel: UnwrapRef + readonly useVModels: UnwrapRef + readonly useVibrate: UnwrapRef + readonly useVirtualList: UnwrapRef + readonly useWakeLock: UnwrapRef + readonly useWebNotification: UnwrapRef + readonly useWebSocket: UnwrapRef + readonly useWebWorker: UnwrapRef + readonly useWebWorkerFn: UnwrapRef + readonly useWindowFocus: UnwrapRef + readonly useWindowScroll: UnwrapRef + readonly useWindowSize: UnwrapRef + readonly watch: UnwrapRef + readonly watchArray: UnwrapRef + readonly watchAtMost: UnwrapRef + readonly watchDebounced: UnwrapRef + readonly watchDeep: UnwrapRef + readonly watchEffect: UnwrapRef + readonly watchIgnorable: UnwrapRef + readonly watchImmediate: UnwrapRef + readonly watchOnce: UnwrapRef + readonly watchPausable: UnwrapRef + readonly watchPostEffect: UnwrapRef + readonly watchSyncEffect: UnwrapRef + readonly watchThrottled: UnwrapRef + readonly watchTriggerable: UnwrapRef + readonly watchWithFilter: UnwrapRef + readonly whenever: UnwrapRef + } +} \ No newline at end of file diff --git a/src/types/axios.d.ts b/src/types/axios.d.ts new file mode 100644 index 0000000..9f2c6d2 --- /dev/null +++ b/src/types/axios.d.ts @@ -0,0 +1,9 @@ +export {}; +declare module 'axios' { + interface AxiosResponse { + code: number; + msg: string; + rows: T; + total: number; + } +} diff --git a/src/types/components.d.ts b/src/types/components.d.ts new file mode 100644 index 0000000..736cf03 --- /dev/null +++ b/src/types/components.d.ts @@ -0,0 +1,98 @@ +/* eslint-disable */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +// biome-ignore lint: disable +export {} + +/* prettier-ignore */ +declare module 'vue' { + export interface GlobalComponents { + ApprovalButton: typeof import('./../components/Process/approvalButton.vue')['default'] + ApprovalRecord: typeof import('./../components/Process/approvalRecord.vue')['default'] + Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default'] + DictTag: typeof import('./../components/DictTag/index.vue')['default'] + Editor: typeof import('./../components/Editor/index.vue')['default'] + ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete'] + ElBadge: typeof import('element-plus/es')['ElBadge'] + ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] + ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] + ElButton: typeof import('element-plus/es')['ElButton'] + ElCard: typeof import('element-plus/es')['ElCard'] + ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] + ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] + ElCol: typeof import('element-plus/es')['ElCol'] + ElColorPicker: typeof import('element-plus/es')['ElColorPicker'] + ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] + ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] + ElDescriptions: typeof import('element-plus/es')['ElDescriptions'] + ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem'] + ElDialog: typeof import('element-plus/es')['ElDialog'] + ElDivider: typeof import('element-plus/es')['ElDivider'] + ElDrawer: typeof import('element-plus/es')['ElDrawer'] + ElDropdown: typeof import('element-plus/es')['ElDropdown'] + ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] + ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] + ElEmpty: typeof import('element-plus/es')['ElEmpty'] + ElForm: typeof import('element-plus/es')['ElForm'] + ElFormItem: typeof import('element-plus/es')['ElFormItem'] + ElIcon: typeof import('element-plus/es')['ElIcon'] + ElImage: typeof import('element-plus/es')['ElImage'] + ElInput: typeof import('element-plus/es')['ElInput'] + ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] + ElLink: typeof import('element-plus/es')['ElLink'] + ElMenu: typeof import('element-plus/es')['ElMenu'] + ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] + ElOption: typeof import('element-plus/es')['ElOption'] + ElPagination: typeof import('element-plus/es')['ElPagination'] + ElPopover: typeof import('element-plus/es')['ElPopover'] + ElRadio: typeof import('element-plus/es')['ElRadio'] + ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] + ElRow: typeof import('element-plus/es')['ElRow'] + ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] + ElSelect: typeof import('element-plus/es')['ElSelect'] + ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] + ElSwitch: typeof import('element-plus/es')['ElSwitch'] + ElTable: typeof import('element-plus/es')['ElTable'] + ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] + ElTabPane: typeof import('element-plus/es')['ElTabPane'] + ElTabs: typeof import('element-plus/es')['ElTabs'] + ElTag: typeof import('element-plus/es')['ElTag'] + ElText: typeof import('element-plus/es')['ElText'] + ElTooltip: typeof import('element-plus/es')['ElTooltip'] + ElTree: typeof import('element-plus/es')['ElTree'] + ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect'] + ElUpload: typeof import('element-plus/es')['ElUpload'] + FileUpload: typeof import('./../components/FileUpload/index.vue')['default'] + FlowChart: typeof import('./../components/Process/flowChart.vue')['default'] + FlowChartImg: typeof import('./../components/Process/flowChartImg.vue')['default'] + Hamburger: typeof import('./../components/Hamburger/index.vue')['default'] + IconSelect: typeof import('./../components/IconSelect/index.vue')['default'] + IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default'] + IEpCaretTop: typeof import('~icons/ep/caret-top')['default'] + IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default'] + IFrame: typeof import('./../components/iFrame/index.vue')['default'] + ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default'] + ImageUpload: typeof import('./../components/ImageUpload/index.vue')['default'] + LangSelect: typeof import('./../components/LangSelect/index.vue')['default'] + MessageType: typeof import('./../components/Process/MessageType.vue')['default'] + Pagination: typeof import('./../components/Pagination/index.vue')['default'] + ParentView: typeof import('./../components/ParentView/index.vue')['default'] + ProcessMeddle: typeof import('./../components/Process/processMeddle.vue')['default'] + RightToolbar: typeof import('./../components/RightToolbar/index.vue')['default'] + RoleSelect: typeof import('./../components/RoleSelect/index.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + RuoYiDoc: typeof import('./../components/RuoYiDoc/index.vue')['default'] + RuoYiGit: typeof import('./../components/RuoYiGit/index.vue')['default'] + Screenfull: typeof import('./../components/Screenfull/index.vue')['default'] + SizeSelect: typeof import('./../components/SizeSelect/index.vue')['default'] + SubmitVerify: typeof import('./../components/Process/submitVerify.vue')['default'] + SvgIcon: typeof import('./../components/SvgIcon/index.vue')['default'] + TopNav: typeof import('./../components/TopNav/index.vue')['default'] + UserSelect: typeof import('./../components/UserSelect/index.vue')['default'] + } + export interface ComponentCustomProperties { + vLoading: typeof import('element-plus/es')['ElLoadingDirective'] + } +} diff --git a/src/types/element.d.ts b/src/types/element.d.ts new file mode 100644 index 0000000..ae6ecfc --- /dev/null +++ b/src/types/element.d.ts @@ -0,0 +1,35 @@ +import type * as ep from 'element-plus'; +declare global { + declare type ElTagType = 'primary' | 'success' | 'info' | 'warning' | 'danger'; + declare type ElFormInstance = ep.FormInstance; + declare type ElTableInstance = ep.TableInstance; + declare type ElUploadInstance = ep.UploadInstance; + declare type ElScrollbarInstance = ep.ScrollbarInstance; + declare type ElInputInstance = ep.InputInstance; + declare type ElInputNumberInstance = ep.InputNumberInstance; + declare type ElRadioInstance = ep.RadioInstance; + declare type ElRadioGroupInstance = ep.RadioGroupInstance; + declare type ElRadioButtonInstance = ep.RadioButtonInstance; + declare type ElCheckboxInstance = ep.CheckboxInstance; + declare type ElSwitchInstance = ep.SwitchInstance; + declare type ElCascaderInstance = ep.CascaderInstance; + declare type ElColorPickerInstance = ep.ColorPickerInstance; + declare type ElRateInstance = ep.RateInstance; + declare type ElSliderInstance = ep.SliderInstance; + + declare type ElTreeInstance = InstanceType; + declare type ElTreeSelectInstance = InstanceType; + declare type ElSelectInstance = InstanceType; + declare type ElCardInstance = InstanceType; + declare type ElDialogInstance = InstanceType; + declare type ElCheckboxGroupInstance = InstanceType; + declare type ElDatePickerInstance = InstanceType; + declare type ElTimePickerInstance = InstanceType; + declare type ElTimeSelectInstance = InstanceType; + + declare type TransferKey = ep.TransferKey; + declare type CheckboxValueType = ep.CheckboxValueType; + declare type ElFormRules = ep.FormRules; + declare type DateModelType = ep.DateModelType; + declare type UploadFile = ep.UploadFile; +} diff --git a/src/types/env.d.ts b/src/types/env.d.ts new file mode 100644 index 0000000..1fb9f62 --- /dev/null +++ b/src/types/env.d.ts @@ -0,0 +1,27 @@ +declare module '*.vue' { + import { DefineComponent } from 'vue'; + const Component: DefineComponent<{}, {}, any>; + export default Component; +} + +// 环境变量 +interface ImportMetaEnv { + VITE_APP_TITLE: string; + VITE_APP_PORT: number; + VITE_APP_BASE_API: string; + VITE_APP_BASE_URL: string; + VITE_APP_CONTEXT_PATH: string; + VITE_APP_MONITOR_ADMIN: string; + VITE_APP_SNAILJOB_ADMIN: string; + VITE_APP_ENV: string; + VITE_APP_ENCRYPT: string; + VITE_APP_RSA_PUBLIC_KEY: string; + VITE_APP_RSA_PRIVATE_KEY: string; + VITE_APP_CLIENT_ID: string; + VITE_APP_WEBSOCKET: string; + VITE_APP_SSE: string; +} +interface ImportMeta { + readonly env: ImportMetaEnv; + // readonly glob: any; +} diff --git a/src/types/global.d.ts b/src/types/global.d.ts new file mode 100644 index 0000000..a31f87c --- /dev/null +++ b/src/types/global.d.ts @@ -0,0 +1,166 @@ +import type { PropType as VuePropType, ComponentInternalInstance as ComponentInstance } from 'vue'; +import { LanguageEnum } from '@/enums/LanguageEnum'; + +declare global { + /** vue Instance */ + declare type ComponentInternalInstance = ComponentInstance; + + /** + * 界面字段隐藏属性 + */ + declare interface FieldOption { + key: number; + label: string; + visible: boolean; + children?: Array; + } + + /** + * 弹窗属性 + */ + declare interface DialogOption { + /** + * 弹窗标题 + */ + title?: string; + /** + * 是否显示 + */ + visible: boolean; + } + + declare interface UploadOption { + /** 设置上传的请求头部 */ + headers: { [key: string]: any }; + + /** 上传的地址 */ + url: string; + } + + /** + * 导入属性 + */ + declare interface ImportOption extends UploadOption { + /** 是否显示弹出层 */ + open: boolean; + /** 弹出层标题 */ + title: string; + /** 是否禁用上传 */ + isUploading: boolean; + + updateSupport: number; + + /** 其他参数 */ + [key: string]: any; + } + /** + * 字典数据 数据配置 + */ + declare interface DictDataOption { + label: string; + value: string; + elTagType?: ElTagType; + elTagClass?: string; + } + + declare interface BaseEntity { + createBy?: any; + createDept?: any; + createTime?: string; + updateBy?: any; + updateTime?: any; + } + + /** + * 分页数据 + * T : 表单数据 + * D : 查询参数 + */ + declare interface PageData { + form: T; + queryParams: D; + rules: ElFormRules; + } + /** + * 分页查询参数 + */ + declare interface PageQuery { + pageNum: number; + pageSize: number; + } + declare interface LayoutSetting { + /** + * 是否显示顶部导航 + */ + topNav: boolean; + + /** + * 是否显示多标签导航 + */ + tagsView: boolean; + /** + * 显示页签图标 + */ + tagsIcon: boolean; + /** + * 是否固定头部 + */ + fixedHeader: boolean; + /** + * 是否显示侧边栏Logo + */ + sidebarLogo: boolean; + /** + * 是否显示动态标题 + */ + dynamicTitle: boolean; + /** + * 侧边栏主题 theme-dark | theme-light + */ + sideTheme: string; + /** + * 主题模式 + */ + theme: string; + } + + declare interface DefaultSettings extends LayoutSetting { + /** + * 网页标题 + */ + title: string; + + /** + * 是否显示系统布局设置 + */ + showSettings: boolean; + + /** + * 导航栏布局 + */ + layout: string; + + /** + * 布局大小 + */ + size: 'large' | 'default' | 'small'; + + /** + * 语言 + */ + language: LanguageEnum; + + /** + * 是否启用动画效果 + */ + animationEnable: boolean; + /** + * 是否启用暗黑模式 + * + * true:暗黑模式 + * false: 明亮模式 + */ + dark: boolean; + } +} +export {}; diff --git a/src/types/module.d.ts b/src/types/module.d.ts new file mode 100644 index 0000000..3b2f378 --- /dev/null +++ b/src/types/module.d.ts @@ -0,0 +1,50 @@ +import modal from '@/plugins/modal'; +import tab from '@/plugins/tab'; +import download from '@/plugins/download'; +import auth from '@/plugins/auth'; +import cache from '@/plugins/cache'; +import animate from '@/animate'; +import { useDict } from '@/utils/dict'; +import { handleTree, addDateRange, selectDictLabel, selectDictLabels, parseTime } from '@/utils/ruoyi'; +import { getConfigKey, updateConfigByKey } from '@/api/system/config'; +import { download as rd } from '@/utils/request'; +import type { LanguageType } from '@/lang'; + +export {}; + +declare module '@vue/runtime-core' { + interface ComponentCustomProperties { + // 全局方法声明 + $modal: typeof modal; + $tab: typeof tab; + $download: typeof download; + $auth: typeof auth; + $cache: typeof cache; + animate: typeof animate; + /** + * i18n $t方法支持ts类型提示 + * @param key i18n key + */ + $t(key: ObjKeysToUnion): string; + + useDict: typeof useDict; + addDateRange: typeof addDateRange; + download: typeof rd; + handleTree: typeof handleTree; + getConfigKey: typeof getConfigKey; + updateConfigByKey: typeof updateConfigByKey; + selectDictLabel: typeof selectDictLabel; + selectDictLabels: typeof selectDictLabels; + parseTime: typeof parseTime; + } +} + +/** + * { a: 1, b: { ba: { baa: 1, bab: 2 }, bb: 2} } ---> a | b.ba.baa | b.ba.bab | b.bb + * https://juejin.cn/post/7280062870670606397 + */ +export type ObjKeysToUnion = T extends object + ? { + [K in keyof T]: ObjKeysToUnion; + }[keyof T] + : P; diff --git a/src/types/router.d.ts b/src/types/router.d.ts new file mode 100644 index 0000000..11a60a0 --- /dev/null +++ b/src/types/router.d.ts @@ -0,0 +1,38 @@ +import { LocationQuery, type RouteMeta as VRouteMeta } from 'vue-router'; +declare module 'vue-router' { + interface RouteMeta extends VRouteMeta { + link?: string; + title?: string; + affix?: boolean; + noCache?: boolean; + activeMenu?: string; + icon?: string; + breadcrumb?: boolean; + } + + interface _RouteRecordBase { + hidden?: boolean | string | number; + permissions?: string[]; + roles?: string[]; + alwaysShow?: boolean; + query?: string; + parentPath?: string; + } + + interface _RouteLocationBase { + children?: _RouteRecordBase[]; + path?: string; + title?: string; + } + + interface TagView { + fullPath?: string; + name?: string; + path?: string; + title?: string; + meta?: RouteMeta; + query?: LocationQuery; + } +} + +export {}; diff --git a/src/utils/auth.ts b/src/utils/auth.ts new file mode 100644 index 0000000..db50ac9 --- /dev/null +++ b/src/utils/auth.ts @@ -0,0 +1,9 @@ +const TokenKey = 'Admin-Token'; + +const tokenStorage = useStorage(TokenKey, null); + +export const getToken = () => tokenStorage.value; + +export const setToken = (access_token: string) => (tokenStorage.value = access_token); + +export const removeToken = () => (tokenStorage.value = null); diff --git a/src/utils/createCustomNameComponent.tsx b/src/utils/createCustomNameComponent.tsx new file mode 100644 index 0000000..daf5866 --- /dev/null +++ b/src/utils/createCustomNameComponent.tsx @@ -0,0 +1,39 @@ +/** + * 后台返回的路由动态生成name 解决缓存问题 + * 感谢 @fourteendp + * 详见 https://github.com/vbenjs/vue-vben-admin/issues/3927 + */ +import { Component, defineComponent, h } from 'vue'; + +interface Options { + name?: string; +} + +export function createCustomNameComponent(loader: () => Promise, options: Options = {}): () => Promise { + const { name } = options; + let component: Component | null = null; + + const load = async () => { + try { + const { default: loadedComponent } = await loader(); + component = loadedComponent; + } catch (error) { + console.error(`Cannot resolve component ${name}, error:`, error); + } + }; + + return async () => { + if (!component) { + await load(); + } + + return Promise.resolve( + defineComponent({ + name, + render() { + return h(component as Component); + } + }) + ); + }; +} diff --git a/src/utils/crypto.ts b/src/utils/crypto.ts new file mode 100644 index 0000000..8217146 --- /dev/null +++ b/src/utils/crypto.ts @@ -0,0 +1,66 @@ +import CryptoJS from 'crypto-js'; + +/** + * 随机生成32位的字符串 + * @returns {string} + */ +const generateRandomString = () => { + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result = ''; + const charactersLength = characters.length; + for (let i = 0; i < 32; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +}; + +/** + * 随机生成aes 密钥 + * @returns {string} + */ +export const generateAesKey = () => { + return CryptoJS.enc.Utf8.parse(generateRandomString()); +}; + +/** + * 加密base64 + * @returns {string} + */ +export const encryptBase64 = (str: CryptoJS.lib.WordArray) => { + return CryptoJS.enc.Base64.stringify(str); +}; + +/** + * 解密base64 + */ +export const decryptBase64 = (str: string) => { + return CryptoJS.enc.Base64.parse(str); +}; + +/** + * 使用密钥对数据进行加密 + * @param message + * @param aesKey + * @returns {string} + */ +export const encryptWithAes = (message: string, aesKey: CryptoJS.lib.WordArray) => { + const encrypted = CryptoJS.AES.encrypt(message, aesKey, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }); + return encrypted.toString(); +}; + +/** + * 使用密钥对数据进行解密 + * @param message + * @param aesKey + * @returns {string} + */ +export const decryptWithAes = (message: string, aesKey: CryptoJS.lib.WordArray) => { + const decrypted = CryptoJS.AES.decrypt(message, aesKey, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }); + return decrypted.toString(CryptoJS.enc.Utf8); +}; diff --git a/src/utils/dict.ts b/src/utils/dict.ts new file mode 100644 index 0000000..eb43d65 --- /dev/null +++ b/src/utils/dict.ts @@ -0,0 +1,26 @@ +import { getDicts } from '@/api/system/dict/data'; +import { useDictStore } from '@/store/modules/dict'; +/** + * 获取字典数据 + */ +export const useDict = (...args: string[]): { [key: string]: DictDataOption[] } => { + const res = ref<{ + [key: string]: DictDataOption[]; + }>({}); + + args.forEach(async (dictType) => { + res.value[dictType] = []; + const dicts = useDictStore().getDict(dictType); + if (dicts) { + res.value[dictType] = dicts; + } else { + await getDicts(dictType).then((resp) => { + res.value[dictType] = resp.data.map( + (p): DictDataOption => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass }) + ); + useDictStore().setDict(dictType, res.value[dictType]); + }); + } + }); + return res.value; +}; diff --git a/src/utils/dynamicTitle.ts b/src/utils/dynamicTitle.ts new file mode 100644 index 0000000..8e23ef8 --- /dev/null +++ b/src/utils/dynamicTitle.ts @@ -0,0 +1,14 @@ +import defaultSettings from '@/settings'; +import { useSettingsStore } from '@/store/modules/settings'; + +/** + * 动态修改标题 + */ +export const useDynamicTitle = () => { + const settingsStore = useSettingsStore(); + if (settingsStore.dynamicTitle) { + document.title = settingsStore.title + ' - ' + import.meta.env.VITE_APP_TITLE; + } else { + document.title = defaultSettings.title as string; + } +}; diff --git a/src/utils/errorCode.ts b/src/utils/errorCode.ts new file mode 100644 index 0000000..d85914e --- /dev/null +++ b/src/utils/errorCode.ts @@ -0,0 +1,7 @@ +export const errorCode: any = { + '401': '认证失败,无法访问系统资源', + '403': '当前操作没有权限', + '404': '访问资源不存在', + default: '系统未知错误,请反馈给管理员' +}; +export default errorCode; diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts new file mode 100644 index 0000000..ab77af0 --- /dev/null +++ b/src/utils/i18n.ts @@ -0,0 +1,16 @@ +// translate router.meta.title, be used in breadcrumb sidebar tagsview +import i18n from '@/lang/index'; + +/** + * 获取国际化路由,如果不存在则原生返回 + * @param title 路由名称 + * @returns {string} + */ +export const translateRouteTitle = (title: string): string => { + const hasKey = i18n.global.te('route.' + title); + if (hasKey) { + const translatedTitle = i18n.global.t('route.' + title); + return translatedTitle; + } + return title; +}; diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..2b0aad5 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,318 @@ +import { parseTime } from '@/utils/ruoyi'; + +/** + * 表格时间格式化 + */ +export const formatDate = (cellValue: string) => { + if (cellValue == null || cellValue == '') return ''; + const date = new Date(cellValue); + const year = date.getFullYear(); + const month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1; + const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate(); + const hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + const minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + const seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds(); + return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds; +}; + +/** + * @param {number} time + * @param {string} option + * @returns {string} + */ +export const formatTime = (time: string, option: string) => { + let t: number; + if (('' + time).length === 10) { + t = parseInt(time) * 1000; + } else { + t = +time; + } + const d: any = new Date(t); + const now = Date.now(); + + const diff = (now - d) / 1000; + + if (diff < 30) { + return '刚刚'; + } else if (diff < 3600) { + // less 1 hour + return Math.ceil(diff / 60) + '分钟前'; + } else if (diff < 3600 * 24) { + return Math.ceil(diff / 3600) + '小时前'; + } else if (diff < 3600 * 24 * 2) { + return '1天前'; + } + if (option) { + return parseTime(t, option); + } else { + return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分'; + } +}; + +/** + * @param {string} url + * @returns {Object} + */ +export const getQueryObject = (url: string) => { + url = url == null ? window.location.href : url; + const search = url.substring(url.lastIndexOf('?') + 1); + const obj: { [key: string]: string } = {}; + const reg = /([^?&=]+)=([^?&=]*)/g; + search.replace(reg, (rs, $1, $2) => { + const name = decodeURIComponent($1); + let val = decodeURIComponent($2); + val = String(val); + obj[name] = val; + return rs; + }); + return obj; +}; + +/** + * @param {string} input value + * @returns {number} output value + */ +export const byteLength = (str: string) => { + // returns the byte length of an utf8 string + let s = str.length; + for (let i = str.length - 1; i >= 0; i--) { + const code = str.charCodeAt(i); + if (code > 0x7f && code <= 0x7ff) s++; + else if (code > 0x7ff && code <= 0xffff) s += 2; + if (code >= 0xdc00 && code <= 0xdfff) i--; + } + return s; +}; + +/** + * @param {Array} actual + * @returns {Array} + */ +export const cleanArray = (actual: Array) => { + const newArray: any[] = []; + for (let i = 0; i < actual.length; i++) { + if (actual[i]) { + newArray.push(actual[i]); + } + } + return newArray; +}; + +/** + * @param {Object} json + * @returns {Array} + */ +export const param = (json: any) => { + if (!json) return ''; + return cleanArray( + Object.keys(json).map((key) => { + if (json[key] === undefined) return ''; + return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]); + }) + ).join('&'); +}; + +/** + * @param {string} url + * @returns {Object} + */ +export const param2Obj = (url: string) => { + const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' '); + if (!search) { + return {}; + } + const obj: any = {}; + const searchArr = search.split('&'); + searchArr.forEach((v) => { + const index = v.indexOf('='); + if (index !== -1) { + const name = v.substring(0, index); + const val = v.substring(index + 1, v.length); + obj[name] = val; + } + }); + return obj; +}; + +/** + * @param {string} val + * @returns {string} + */ +export const html2Text = (val: string) => { + const div = document.createElement('div'); + div.innerHTML = val; + return div.textContent || div.innerText; +}; + +/** + * Merges two objects, giving the last one precedence + * @param {Object} target + * @param {(Object|Array)} source + * @returns {Object} + */ +export const objectMerge = (target: any, source: any | any[]) => { + if (typeof target !== 'object') { + target = {}; + } + if (Array.isArray(source)) { + return source.slice(); + } + Object.keys(source).forEach((property) => { + const sourceProperty = source[property]; + if (typeof sourceProperty === 'object') { + target[property] = objectMerge(target[property], sourceProperty); + } else { + target[property] = sourceProperty; + } + }); + return target; +}; + +/** + * @param {HTMLElement} element + * @param {string} className + */ +export const toggleClass = (element: HTMLElement, className: string) => { + if (!element || !className) { + return; + } + let classString = element.className; + const nameIndex = classString.indexOf(className); + if (nameIndex === -1) { + classString += '' + className; + } else { + classString = classString.substring(0, nameIndex) + classString.substring(nameIndex + className.length); + } + element.className = classString; +}; + +/** + * @param {string} type + * @returns {Date} + */ +export const getTime = (type: string) => { + if (type === 'start') { + return new Date().getTime() - 3600 * 1000 * 24 * 90; + } else { + return new Date(new Date().toDateString()); + } +}; + +/** + * @param {Function} func + * @param {number} wait + * @param {boolean} immediate + * @return {*} + */ +export const debounce = (func: any, wait: number, immediate: boolean) => { + let timeout: any, args: any, context: any, timestamp: any, result: any; + + const later = function () { + // 据上一次触发时间间隔 + const last = +new Date() - timestamp; + + // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait + if (last < wait && last > 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return (...args: any) => { + context = this; + timestamp = +new Date(); + const callNow = immediate && !timeout; + // 如果延时不存在,重新设定延时 + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + return result; + }; +}; + +/** + * This is just a simple version of deep copy + * Has a lot of edge cases bug + * If you want to use a perfect deep copy, use lodash's _.cloneDeep + * @param {Object} source + * @returns {Object} + */ +export const deepClone = (source: any) => { + if (!source && typeof source !== 'object') { + throw new Error('error arguments', 'deepClone' as any); + } + const targetObj: any = source.constructor === Array ? [] : {}; + Object.keys(source).forEach((keys) => { + if (source[keys] && typeof source[keys] === 'object') { + targetObj[keys] = deepClone(source[keys]); + } else { + targetObj[keys] = source[keys]; + } + }); + return targetObj; +}; + +/** + * @param {Array} arr + * @returns {Array} + */ +export const uniqueArr = (arr: any) => { + return Array.from(new Set(arr)); +}; + +/** + * @returns {string} + */ +export const createUniqueString = (): string => { + const timestamp = +new Date() + ''; + const num = (1 + Math.random()) * 65536; + const randomNum = parseInt(num + ''); + return (+(randomNum + timestamp)).toString(32); +}; + +/** + * Check if an element has a class + * @param ele + * @param {string} cls + * @returns {boolean} + */ +export const hasClass = (ele: HTMLElement, cls: string): boolean => { + return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')); +}; + +/** + * Add class to element + * @param ele + * @param {string} cls + */ +export const addClass = (ele: HTMLElement, cls: string) => { + if (!hasClass(ele, cls)) ele.className += ' ' + cls; +}; + +/** + * Remove class from element + * @param ele + * @param {string} cls + */ +export const removeClass = (ele: HTMLElement, cls: string) => { + if (hasClass(ele, cls)) { + const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)'); + ele.className = ele.className.replace(reg, ' '); + } +}; + +/** + * @param {string} path + * @returns {Boolean} + */ +export const isExternal = (path: string) => { + return /^(https?:|http?:|mailto:|tel:)/.test(path); +}; diff --git a/src/utils/jsencrypt.ts b/src/utils/jsencrypt.ts new file mode 100644 index 0000000..6df068e --- /dev/null +++ b/src/utils/jsencrypt.ts @@ -0,0 +1,21 @@ +import JSEncrypt from 'jsencrypt/bin/jsencrypt.min.js'; +// 密钥对生成 http://web.chacuo.net/netrsakeypair + +const publicKey = import.meta.env.VITE_APP_RSA_PUBLIC_KEY; + +// 前端不建议存放私钥 不建议解密数据 因为都是透明的意义不大 +const privateKey = import.meta.env.VITE_APP_RSA_PRIVATE_KEY; + +// 加密 +export const encrypt = (txt: string) => { + const encryptor = new JSEncrypt(); + encryptor.setPublicKey(publicKey); // 设置公钥 + return encryptor.encrypt(txt); // 对数据进行加密 +}; + +// 解密 +export const decrypt = (txt: string) => { + const encryptor = new JSEncrypt(); + encryptor.setPrivateKey(privateKey); // 设置私钥 + return encryptor.decrypt(txt); // 对数据进行解密 +}; diff --git a/src/utils/permission.ts b/src/utils/permission.ts new file mode 100644 index 0000000..e9a0f7f --- /dev/null +++ b/src/utils/permission.ts @@ -0,0 +1,51 @@ +import { useUserStore } from '@/store/modules/user'; + +/** + * 字符权限校验 + * @param {Array} value 校验值 + * @returns {Boolean} + */ +export const checkPermi = (value: any) => { + if (value && value instanceof Array && value.length > 0) { + const permissions = useUserStore().permissions; + const permissionDatas = value; + const all_permission = '*:*:*'; + + const hasPermission = permissions.some((permission) => { + return all_permission === permission || permissionDatas.includes(permission); + }); + + if (!hasPermission) { + return false; + } + return true; + } else { + console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`); + return false; + } +}; + +/** + * 角色权限校验 + * @param {Array} value 校验值 + * @returns {Boolean} + */ +export const checkRole = (value: any): boolean => { + if (value && value instanceof Array && value.length > 0) { + const roles = useUserStore().roles; + const permissionRoles = value; + const super_admin = 'admin'; + + const hasRole = roles.some((role) => { + return super_admin === role || permissionRoles.includes(role); + }); + + if (!hasRole) { + return false; + } + return true; + } else { + console.error(`need roles! Like checkRole="['admin','editor']"`); + return false; + } +}; diff --git a/src/utils/propTypes.ts b/src/utils/propTypes.ts new file mode 100644 index 0000000..24d861d --- /dev/null +++ b/src/utils/propTypes.ts @@ -0,0 +1,26 @@ +import { CSSProperties } from 'vue'; +import VueTypes, { createTypes, toValidableType, VueTypeValidableDef, VueTypesInterface } from 'vue-types'; + +type PropTypes = VueTypesInterface & { + readonly style: VueTypeValidableDef; + readonly fieldOption: VueTypeValidableDef>; +}; + +const propTypes = createTypes({ + func: undefined, + bool: undefined, + string: undefined, + number: undefined, + object: undefined, + integer: undefined +}) as PropTypes; + +export default class ProjectTypes extends VueTypes { + static get style() { + return toValidableType('style', { + type: [String, Object], + default: undefined + }); + } +} +export { propTypes }; diff --git a/src/utils/request.ts b/src/utils/request.ts new file mode 100644 index 0000000..f3b06ad --- /dev/null +++ b/src/utils/request.ts @@ -0,0 +1,208 @@ +import axios, { AxiosResponse, InternalAxiosRequestConfig } from 'axios'; +import { useUserStore } from '@/store/modules/user'; +import { getToken } from '@/utils/auth'; +import { tansParams, blobValidate } from '@/utils/ruoyi'; +import cache from '@/plugins/cache'; +import { HttpStatus } from '@/enums/RespEnum'; +import { errorCode } from '@/utils/errorCode'; +import { LoadingInstance } from 'element-plus/es/components/loading/src/loading'; +import FileSaver from 'file-saver'; +import { getLanguage } from '@/lang'; +import { encryptBase64, encryptWithAes, generateAesKey, decryptWithAes, decryptBase64 } from '@/utils/crypto'; +import { encrypt, decrypt } from '@/utils/jsencrypt'; +import router from '@/router'; + +const encryptHeader = 'encrypt-key'; +let downloadLoadingInstance: LoadingInstance; +// 是否显示重新登录 +export const isRelogin = { show: false }; +export const globalHeaders = () => { + return { + Authorization: 'Bearer ' + getToken(), + clientid: import.meta.env.VITE_APP_CLIENT_ID + }; +}; + +axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'; +axios.defaults.headers['clientid'] = import.meta.env.VITE_APP_CLIENT_ID; +// 创建 axios 实例 +const service = axios.create({ + baseURL: import.meta.env.VITE_APP_BASE_API, + timeout: 50000 +}); + +// 请求拦截器 +service.interceptors.request.use( + (config: InternalAxiosRequestConfig) => { + // 对应国际化资源文件后缀 + config.headers['Content-Language'] = getLanguage(); + + const isToken = config.headers?.isToken === false; + // 是否需要防止数据重复提交 + const isRepeatSubmit = config.headers?.repeatSubmit === false; + // 是否需要加密 + const isEncrypt = config.headers?.isEncrypt === 'true'; + + if (getToken() && !isToken) { + config.headers['Authorization'] = 'Bearer ' + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改 + } + // get请求映射params参数 + if (config.method === 'get' && config.params) { + let url = config.url + '?' + tansParams(config.params); + url = url.slice(0, -1); + config.params = {}; + config.url = url; + } + + if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { + const requestObj = { + url: config.url, + data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, + time: new Date().getTime() + }; + const sessionObj = cache.session.getJSON('sessionObj'); + if (sessionObj === undefined || sessionObj === null || sessionObj === '') { + cache.session.setJSON('sessionObj', requestObj); + } else { + const s_url = sessionObj.url; // 请求地址 + const s_data = sessionObj.data; // 请求数据 + const s_time = sessionObj.time; // 请求时间 + const interval = 500; // 间隔时间(ms),小于此时间视为重复提交 + if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { + const message = '数据正在处理,请勿重复提交'; + console.warn(`[${s_url}]: ` + message); + return Promise.reject(new Error(message)); + } else { + cache.session.setJSON('sessionObj', requestObj); + } + } + } + if (import.meta.env.VITE_APP_ENCRYPT === 'true') { + // 当开启参数加密 + if (isEncrypt && (config.method === 'post' || config.method === 'put')) { + // 生成一个 AES 密钥 + const aesKey = generateAesKey(); + config.headers[encryptHeader] = encrypt(encryptBase64(aesKey)); + config.data = typeof config.data === 'object' ? encryptWithAes(JSON.stringify(config.data), aesKey) : encryptWithAes(config.data, aesKey); + } + } + // FormData数据去请求头Content-Type + if (config.data instanceof FormData) { + delete config.headers['Content-Type']; + } + return config; + }, + (error: any) => { + return Promise.reject(error); + } +); + +// 响应拦截器 +service.interceptors.response.use( + (res: AxiosResponse) => { + if (import.meta.env.VITE_APP_ENCRYPT === 'true') { + // 加密后的 AES 秘钥 + const keyStr = res.headers[encryptHeader]; + // 加密 + if (keyStr != null && keyStr != '') { + const data = res.data; + // 请求体 AES 解密 + const base64Str = decrypt(keyStr); + // base64 解码 得到请求头的 AES 秘钥 + const aesKey = decryptBase64(base64Str.toString()); + // aesKey 解码 data + const decryptData = decryptWithAes(data, aesKey); + // 将结果 (得到的是 JSON 字符串) 转为 JSON + res.data = JSON.parse(decryptData); + } + } + // 未设置状态码则默认成功状态 + const code = res.data.code || HttpStatus.SUCCESS; + // 获取错误信息 + const msg = errorCode[code] || res.data.msg || errorCode['default']; + // 二进制数据则直接返回 + if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { + return res.data; + } + if (code === 401) { + // prettier-ignore + if (!isRelogin.show) { + isRelogin.show = true; + ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { + confirmButtonText: '重新登录', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + isRelogin.show = false; + useUserStore().logout().then(() => { + router.replace({ + path: '/login', + query: { + redirect: encodeURIComponent(router.currentRoute.value.fullPath || '/') + } + }) + }); + }).catch(() => { + isRelogin.show = false; + }); + } + return Promise.reject('无效的会话,或者会话已过期,请重新登录。'); + } else if (code === HttpStatus.SERVER_ERROR) { + ElMessage({ message: msg, type: 'error' }); + return Promise.reject(new Error(msg)); + } else if (code === HttpStatus.WARN) { + ElMessage({ message: msg, type: 'warning' }); + return Promise.reject(new Error(msg)); + } else if (code !== HttpStatus.SUCCESS) { + ElNotification.error({ title: msg }); + return Promise.reject('error'); + } else { + return Promise.resolve(res.data); + } + }, + (error: any) => { + let { message } = error; + if (message == 'Network Error') { + message = '后端接口连接异常'; + } else if (message.includes('timeout')) { + message = '系统接口请求超时'; + } else if (message.includes('Request failed with status code')) { + message = '系统接口' + message.substr(message.length - 3) + '异常'; + } + ElMessage({ message: message, type: 'error', duration: 5 * 1000 }); + return Promise.reject(error); + } +); +// 通用下载方法 +export function download(url: string, params: any, fileName: string) { + downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' }); + // prettier-ignore + return service.post(url, params, { + transformRequest: [ + (params: any) => { + return tansParams(params); + } + ], + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + responseType: 'blob' + }).then(async (resp: any) => { + const isLogin = blobValidate(resp); + if (isLogin) { + const blob = new Blob([resp]); + FileSaver.saveAs(blob, fileName); + } else { + const blob = new Blob([resp]); + const resText = await blob.text(); + const rspObj = JSON.parse(resText); + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']; + ElMessage.error(errMsg); + } + downloadLoadingInstance.close(); + }).catch((r: any) => { + console.error(r); + ElMessage.error('下载文件出现错误,请联系管理员!'); + downloadLoadingInstance.close(); + }); +} +// 导出 axios 实例 +export default service; diff --git a/src/utils/ruoyi.ts b/src/utils/ruoyi.ts new file mode 100644 index 0000000..8cb9f97 --- /dev/null +++ b/src/utils/ruoyi.ts @@ -0,0 +1,236 @@ +// 日期格式化 +export function parseTime(time: any, pattern?: string) { + if (arguments.length === 0 || !time) { + return null; + } + const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'; + let date; + if (typeof time === 'object') { + date = time; + } else { + if (typeof time === 'string' && /^[0-9]+$/.test(time)) { + time = parseInt(time); + } else if (typeof time === 'string') { + time = time + .replace(new RegExp(/-/gm), '/') + .replace('T', ' ') + .replace(new RegExp(/\.[\d]{3}/gm), ''); + } + if (typeof time === 'number' && time.toString().length === 10) { + time = time * 1000; + } + date = new Date(time); + } + const formatObj: { [key: string]: any } = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() + }; + return format.replace(/{(y|m|d|h|i|s|a)+}/g, (result: string, key: string) => { + let value = formatObj[key]; + // Note: getDay() returns 0 on Sunday + if (key === 'a') { + return ['日', '一', '二', '三', '四', '五', '六'][value]; + } + if (result.length > 0 && value < 10) { + value = '0' + value; + } + return value || 0; + }); +} + +/** + * 添加日期范围 + * @param params + * @param dateRange + * @param propName + */ +export const addDateRange = (params: any, dateRange: any[], propName?: string) => { + const search = params; + search.params = typeof search.params === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {}; + dateRange = Array.isArray(dateRange) ? dateRange : []; + if (typeof propName === 'undefined') { + search.params['beginTime'] = dateRange[0]; + search.params['endTime'] = dateRange[1]; + } else { + search.params['begin' + propName] = dateRange[0]; + search.params['end' + propName] = dateRange[1]; + } + return search; +}; + +// 回显数据字典 +export const selectDictLabel = (datas: any, value: number | string) => { + if (value === undefined) { + return ''; + } + const actions: Array = []; + Object.keys(datas).some((key) => { + if (datas[key].value == '' + value) { + actions.push(datas[key].label); + return true; + } + }); + if (actions.length === 0) { + actions.push(value); + } + return actions.join(''); +}; + +// 回显数据字典(字符串数组) +export const selectDictLabels = (datas: any, value: any, separator: any) => { + if (value === undefined || value.length === 0) { + return ''; + } + if (Array.isArray(value)) { + value = value.join(','); + } + const actions: any[] = []; + const currentSeparator = undefined === separator ? ',' : separator; + const temp = value.split(currentSeparator); + Object.keys(value.split(currentSeparator)).some((val) => { + let match = false; + Object.keys(datas).some((key) => { + if (datas[key].value == '' + temp[val]) { + actions.push(datas[key].label + currentSeparator); + match = true; + } + }); + if (!match) { + actions.push(temp[val] + currentSeparator); + } + }); + return actions.join('').substring(0, actions.join('').length - 1); +}; + +// 字符串格式化(%s ) +export function sprintf(str: string) { + if (arguments.length !== 0) { + let flag = true, + i = 1; + str = str.replace(/%s/g, function () { + const arg = arguments[i++]; + if (typeof arg === 'undefined') { + flag = false; + return ''; + } + return arg; + }); + return flag ? str : ''; + } +} + +// 转换字符串,undefined,null等转化为"" +export const parseStrEmpty = (str: any) => { + if (!str || str == 'undefined' || str == 'null') { + return ''; + } + return str; +}; + +// 数据合并 +export const mergeRecursive = (source: any, target: any) => { + for (const p in target) { + try { + if (target[p].constructor == Object) { + source[p] = mergeRecursive(source[p], target[p]); + } else { + source[p] = target[p]; + } + } catch (e) { + source[p] = target[p]; + } + } + return source; +}; + +/** + * 构造树型结构数据 + * @param {*} data 数据源 + * @param {*} id id字段 默认 'id' + * @param {*} parentId 父节点字段 默认 'parentId' + * @param {*} children 孩子节点字段 默认 'children' + */ +export const handleTree = (data: any[], id?: string, parentId?: string, children?: string): T[] => { + const config: { + id: string; + parentId: string; + childrenList: string; + } = { + id: id || 'id', + parentId: parentId || 'parentId', + childrenList: children || 'children' + }; + + const childrenListMap: any = {}; + const tree: T[] = []; + for (const d of data) { + const id = d[config.id]; + childrenListMap[id] = d; + if (!d[config.childrenList]) { + d[config.childrenList] = []; + } + } + + for (const d of data) { + const parentId = d[config.parentId]; + const parentObj = childrenListMap[parentId]; + if (!parentObj) { + tree.push(d); + } else { + parentObj[config.childrenList].push(d); + } + } + return tree; +}; + +/** + * 参数处理 + * @param {*} params 参数 + */ +export const tansParams = (params: any) => { + let result = ''; + for (const propName of Object.keys(params)) { + const value = params[propName]; + const part = encodeURIComponent(propName) + '='; + if (value !== null && value !== '' && typeof value !== 'undefined') { + if (typeof value === 'object') { + for (const key of Object.keys(value)) { + if (value[key] !== null && value[key] !== '' && typeof value[key] !== 'undefined') { + const params = propName + '[' + key + ']'; + const subPart = encodeURIComponent(params) + '='; + result += subPart + encodeURIComponent(value[key]) + '&'; + } + } + } else { + result += part + encodeURIComponent(value) + '&'; + } + } + } + return result; +}; + +// 返回项目路径 +export const getNormalPath = (p: string): string => { + if (p.length === 0 || !p || p === 'undefined') { + return p; + } + const res = p.replace('//', '/'); + if (res[res.length - 1] === '/') { + return res.slice(0, res.length - 1); + } + return res; +}; + +// 验证是否为blob格式 +export const blobValidate = (data: any) => { + return data.type !== 'application/json'; +}; + +export default { + handleTree +}; diff --git a/src/utils/scroll-to.ts b/src/utils/scroll-to.ts new file mode 100644 index 0000000..c2fa379 --- /dev/null +++ b/src/utils/scroll-to.ts @@ -0,0 +1,65 @@ +const easeInOutQuad = (t: number, b: number, c: number, d: number) => { + t /= d / 2; + if (t < 1) { + return (c / 2) * t * t + b; + } + t--; + return (-c / 2) * (t * (t - 2) - 1) + b; +}; + +// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts +const requestAnimFrame = (function () { + return ( + window.requestAnimationFrame || + (window as any).webkitRequestAnimationFrame || + (window as any).mozRequestAnimationFrame || + function (callback) { + window.setTimeout(callback, 1000 / 60); + } + ); +})(); + +/** + * Because it's so fucking difficult to detect the scrolling element, just move them all + * @param {number} amount + */ +const move = (amount: number) => { + document.documentElement.scrollTop = amount; + (document.body.parentNode as HTMLElement).scrollTop = amount; + document.body.scrollTop = amount; +}; + +const position = () => { + return document.documentElement.scrollTop || (document.body.parentNode as HTMLElement).scrollTop || document.body.scrollTop; +}; + +/** + * @param {number} to + * @param {number} duration + * @param {Function} callback + */ +export const scrollTo = (to: number, duration: number, callback?: any) => { + const start = position(); + const change = to - start; + const increment = 20; + let currentTime = 0; + duration = typeof duration === 'undefined' ? 500 : duration; + const animateScroll = function () { + // increment the time + currentTime += increment; + // find the value with the quadratic in-out easing function + const val = easeInOutQuad(currentTime, start, change, duration); + // move the document.body + move(val); + // do the animation unless its over + if (currentTime < duration) { + requestAnimFrame(animateScroll); + } else { + if (callback && typeof callback === 'function') { + // the animation is done so lets callback + callback(); + } + } + }; + animateScroll(); +}; diff --git a/src/utils/sse.ts b/src/utils/sse.ts new file mode 100644 index 0000000..059c8f8 --- /dev/null +++ b/src/utils/sse.ts @@ -0,0 +1,42 @@ +import { getToken } from '@/utils/auth'; +import { ElNotification } from 'element-plus'; +import { useNoticeStore } from '@/store/modules/notice'; + +// 初始化 +export const initSSE = (url: any) => { + if (import.meta.env.VITE_APP_SSE === 'false') { + return; + } + + url = url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID; + const { data, error } = useEventSource(url, [], { + autoReconnect: { + retries: 5, + delay: 5000, + onFailed() { + console.log('Failed to connect after 5 retries'); + } + } + }); + + watch(error, () => { + console.log('SSE connection error:', error.value); + error.value = null; + }); + + watch(data, () => { + if (!data.value) return; + useNoticeStore().addNotice({ + message: data.value, + read: false, + time: new Date().toLocaleString() + }); + ElNotification({ + title: '消息', + message: data.value, + type: 'success', + duration: 3000 + }); + data.value = null; + }); +}; diff --git a/src/utils/theme.ts b/src/utils/theme.ts new file mode 100644 index 0000000..3936248 --- /dev/null +++ b/src/utils/theme.ts @@ -0,0 +1,52 @@ +// 处理主题样式 +export const handleThemeStyle = (theme: string) => { + document.documentElement.style.setProperty('--el-color-primary', theme); + for (let i = 1; i <= 9; i++) { + document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(theme, i / 10)}`); + } + for (let i = 1; i <= 9; i++) { + document.documentElement.style.setProperty(`--el-color-primary-dark-${i}`, `${getDarkColor(theme, i / 10)}`); + } +}; + +// hex颜色转rgb颜色 +export const hexToRgb = (str: string): string[] => { + str = str.replace('#', ''); + const hexs = str.match(/../g); + for (let i = 0; i < 3; i++) { + if (hexs) { + hexs[i] = String(parseInt(hexs[i], 16)); + } + } + return hexs ? hexs : []; +}; + +// rgb颜色转Hex颜色 +export const rgbToHex = (r: string, g: string, b: string) => { + const hexs = [Number(r).toString(16), Number(g).toString(16), Number(b).toString(16)]; + for (let i = 0; i < 3; i++) { + if (hexs[i].length == 1) { + hexs[i] = `0${hexs[i]}`; + } + } + return `#${hexs.join('')}`; +}; + +// 变浅颜色值 +export const getLightColor = (color: string, level: number) => { + const rgb = hexToRgb(color); + for (let i = 0; i < 3; i++) { + const s = (255 - Number(rgb[i])) * level + Number(rgb[i]); + rgb[i] = String(Math.floor(s)); + } + return rgbToHex(rgb[0], rgb[1], rgb[2]); +}; + +// 变深颜色值 +export const getDarkColor = (color: string, level: number) => { + const rgb = hexToRgb(color); + for (let i = 0; i < 3; i++) { + rgb[i] = String(Math.floor(Number(rgb[i]) * (1 - level))); + } + return rgbToHex(rgb[0], rgb[1], rgb[2]); +}; diff --git a/src/utils/validate.ts b/src/utils/validate.ts new file mode 100644 index 0000000..e2886e4 --- /dev/null +++ b/src/utils/validate.ts @@ -0,0 +1,108 @@ +/** + * 路径匹配器 + * @param {string} pattern + * @param {string} path + * @returns {Boolean} + */ +export function isPathMatch(pattern: string, path: string) { + const regexPattern = pattern + .replace(/\//g, '\\/') + .replace(/\*\*/g, '__DOUBLE_STAR__') + .replace(/\*/g, '[^\\/]*') + .replace(/__DOUBLE_STAR__/g, '.*'); + const regex = new RegExp(`^${regexPattern}$`); + return regex.test(path); +} + +/** + * 判断url是否是http或https + * @returns {Boolean} + * @param url + */ +export const isHttp = (url: string): boolean => { + return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1; +}; + +/** + * 判断path是否为外链 + * @param {string} path + * @returns {Boolean} + */ +export const isExternal = (path: string) => { + return /^(https?:|mailto:|tel:)/.test(path); +}; + +/** + * @param {string} str + * @returns {Boolean} + */ +export const validUsername = (str: string) => { + const valid_map = ['admin', 'editor']; + return valid_map.indexOf(str.trim()) >= 0; +}; + +/** + * @param {string} url + * @returns {Boolean} + */ +export const validURL = (url: string) => { + const reg = + /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/; + return reg.test(url); +}; + +/** + * @param {string} str + * @returns {Boolean} + */ +export const validLowerCase = (str: string) => { + const reg = /^[a-z]+$/; + return reg.test(str); +}; + +/** + * @param {string} str + * @returns {Boolean} + */ +export const validUpperCase = (str: string) => { + const reg = /^[A-Z]+$/; + return reg.test(str); +}; + +/** + * @param {string} str + * @returns {Boolean} + */ +export const validAlphabets = (str: string) => { + const reg = /^[A-Za-z]+$/; + return reg.test(str); +}; + +/** + * @param {string} email + * @returns {Boolean} + */ +export const validEmail = (email: string) => { + const reg = + /^(([^<>()\]\\.,;:\s@"]+(\.[^<>()\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return reg.test(email); +}; + +/** + * @param {string} str + * @returns {Boolean} + */ +export const isString = (str: any) => { + return typeof str === 'string' || str instanceof String; +}; + +/** + * @param {Array} arg + * @returns {Boolean} + */ +export const isArray = (arg: string | string[]) => { + if (typeof Array.isArray === 'undefined') { + return Object.prototype.toString.call(arg) === '[object Array]'; + } + return Array.isArray(arg); +}; diff --git a/src/utils/websocket.ts b/src/utils/websocket.ts new file mode 100644 index 0000000..d8e3efc --- /dev/null +++ b/src/utils/websocket.ts @@ -0,0 +1,51 @@ +import { getToken } from '@/utils/auth'; +import { ElNotification } from 'element-plus'; +import { useNoticeStore } from '@/store/modules/notice'; + +// 初始化socket +export const initWebSocket = (url: any) => { + if (import.meta.env.VITE_APP_WEBSOCKET === 'false') { + return; + } + url = url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID; + useWebSocket(url, { + autoReconnect: { + // 重连最大次数 + retries: 3, + // 重连间隔 + delay: 1000, + onFailed() { + console.log('websocket重连失败'); + } + }, + heartbeat: { + message: JSON.stringify({ type: 'ping' }), + // 发送心跳的间隔 + interval: 10000, + // 接收到心跳response的超时时间 + pongTimeout: 2000 + }, + onConnected() { + console.log('websocket已经连接'); + }, + onDisconnected() { + console.log('websocket已经断开'); + }, + onMessage: (_, e) => { + if (e.data.indexOf('ping') > 0) { + return; + } + useNoticeStore().addNotice({ + message: e.data, + read: false, + time: new Date().toLocaleString() + }); + ElNotification({ + title: '消息', + message: e.data, + type: 'success', + duration: 3000 + }); + } + }); +}; diff --git a/src/views/demo/demo/index.vue b/src/views/demo/demo/index.vue new file mode 100644 index 0000000..e064f40 --- /dev/null +++ b/src/views/demo/demo/index.vue @@ -0,0 +1,245 @@ + + + diff --git a/src/views/demo/tree/index.vue b/src/views/demo/tree/index.vue new file mode 100644 index 0000000..ef923be --- /dev/null +++ b/src/views/demo/tree/index.vue @@ -0,0 +1,259 @@ + + + diff --git a/src/views/error/401.vue b/src/views/error/401.vue new file mode 100644 index 0000000..f90f50b --- /dev/null +++ b/src/views/error/401.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/views/error/404.vue b/src/views/error/404.vue new file mode 100644 index 0000000..0b20053 --- /dev/null +++ b/src/views/error/404.vue @@ -0,0 +1,223 @@ + + + + + diff --git a/src/views/fishery/aquUser/index.vue b/src/views/fishery/aquUser/index.vue new file mode 100644 index 0000000..16a6b32 --- /dev/null +++ b/src/views/fishery/aquUser/index.vue @@ -0,0 +1,304 @@ + + + diff --git a/src/views/fishery/deviceThreshold/index.vue b/src/views/fishery/deviceThreshold/index.vue new file mode 100644 index 0000000..eb31946 --- /dev/null +++ b/src/views/fishery/deviceThreshold/index.vue @@ -0,0 +1,257 @@ + + + diff --git a/src/views/fishery/fish/index.vue b/src/views/fishery/fish/index.vue new file mode 100644 index 0000000..5b7c997 --- /dev/null +++ b/src/views/fishery/fish/index.vue @@ -0,0 +1,238 @@ + + + diff --git a/src/views/fishery/pond/index.vue b/src/views/fishery/pond/index.vue new file mode 100644 index 0000000..7618662 --- /dev/null +++ b/src/views/fishery/pond/index.vue @@ -0,0 +1,288 @@ + + + diff --git a/src/views/index.vue b/src/views/index.vue new file mode 100644 index 0000000..bfda3f2 --- /dev/null +++ b/src/views/index.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/src/views/login.vue b/src/views/login.vue new file mode 100644 index 0000000..d8727ae --- /dev/null +++ b/src/views/login.vue @@ -0,0 +1,329 @@ + + + + + diff --git a/src/views/monitor/admin/index.vue b/src/views/monitor/admin/index.vue new file mode 100644 index 0000000..b71a5cc --- /dev/null +++ b/src/views/monitor/admin/index.vue @@ -0,0 +1,9 @@ + + + diff --git a/src/views/monitor/cache/index.vue b/src/views/monitor/cache/index.vue new file mode 100644 index 0000000..f894586 --- /dev/null +++ b/src/views/monitor/cache/index.vue @@ -0,0 +1,192 @@ + + + diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue new file mode 100644 index 0000000..da928cc --- /dev/null +++ b/src/views/monitor/logininfor/index.vue @@ -0,0 +1,209 @@ + + + diff --git a/src/views/monitor/online/index.vue b/src/views/monitor/online/index.vue new file mode 100644 index 0000000..b93325c --- /dev/null +++ b/src/views/monitor/online/index.vue @@ -0,0 +1,117 @@ + + + diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue new file mode 100644 index 0000000..dc66371 --- /dev/null +++ b/src/views/monitor/operlog/index.vue @@ -0,0 +1,261 @@ + + + diff --git a/src/views/monitor/operlog/oper-info-dialog.vue b/src/views/monitor/operlog/oper-info-dialog.vue new file mode 100644 index 0000000..8d06b86 --- /dev/null +++ b/src/views/monitor/operlog/oper-info-dialog.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/src/views/monitor/snailjob/index.vue b/src/views/monitor/snailjob/index.vue new file mode 100644 index 0000000..89e3b23 --- /dev/null +++ b/src/views/monitor/snailjob/index.vue @@ -0,0 +1,9 @@ + + + diff --git a/src/views/redirect/index.vue b/src/views/redirect/index.vue new file mode 100644 index 0000000..2de999f --- /dev/null +++ b/src/views/redirect/index.vue @@ -0,0 +1,14 @@ + + + diff --git a/src/views/register.vue b/src/views/register.vue new file mode 100644 index 0000000..8b3d6dc --- /dev/null +++ b/src/views/register.vue @@ -0,0 +1,263 @@ + + + + + diff --git a/src/views/system/client/index.vue b/src/views/system/client/index.vue new file mode 100644 index 0000000..0354d0d --- /dev/null +++ b/src/views/system/client/index.vue @@ -0,0 +1,316 @@ + + + diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue new file mode 100644 index 0000000..7401494 --- /dev/null +++ b/src/views/system/config/index.vue @@ -0,0 +1,261 @@ + + + diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue new file mode 100644 index 0000000..6339df9 --- /dev/null +++ b/src/views/system/dept/index.vue @@ -0,0 +1,320 @@ + + + diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue new file mode 100644 index 0000000..be5c87a --- /dev/null +++ b/src/views/system/dict/data.vue @@ -0,0 +1,309 @@ + + + diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue new file mode 100644 index 0000000..c97b92e --- /dev/null +++ b/src/views/system/dict/index.vue @@ -0,0 +1,246 @@ + + + diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue new file mode 100644 index 0000000..d281091 --- /dev/null +++ b/src/views/system/menu/index.vue @@ -0,0 +1,525 @@ + + + + + diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue new file mode 100644 index 0000000..c219828 --- /dev/null +++ b/src/views/system/notice/index.vue @@ -0,0 +1,243 @@ + + + diff --git a/src/views/system/oss/config.vue b/src/views/system/oss/config.vue new file mode 100644 index 0000000..89898d6 --- /dev/null +++ b/src/views/system/oss/config.vue @@ -0,0 +1,344 @@ + + + diff --git a/src/views/system/oss/index.vue b/src/views/system/oss/index.vue new file mode 100644 index 0000000..f5966d7 --- /dev/null +++ b/src/views/system/oss/index.vue @@ -0,0 +1,333 @@ + + + diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue new file mode 100644 index 0000000..803cf05 --- /dev/null +++ b/src/views/system/post/index.vue @@ -0,0 +1,361 @@ + + + diff --git a/src/views/system/role/authUser.vue b/src/views/system/role/authUser.vue new file mode 100644 index 0000000..7c7fbeb --- /dev/null +++ b/src/views/system/role/authUser.vue @@ -0,0 +1,158 @@ + + + diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue new file mode 100644 index 0000000..c6d83b4 --- /dev/null +++ b/src/views/system/role/index.vue @@ -0,0 +1,503 @@ + + + diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue new file mode 100644 index 0000000..cf36fb0 --- /dev/null +++ b/src/views/system/role/selectUser.vue @@ -0,0 +1,130 @@ + + + diff --git a/src/views/system/tenant/index.vue b/src/views/system/tenant/index.vue new file mode 100644 index 0000000..b594546 --- /dev/null +++ b/src/views/system/tenant/index.vue @@ -0,0 +1,371 @@ + + + diff --git a/src/views/system/tenantPackage/index.vue b/src/views/system/tenantPackage/index.vue new file mode 100644 index 0000000..84a9f2b --- /dev/null +++ b/src/views/system/tenantPackage/index.vue @@ -0,0 +1,329 @@ + + + diff --git a/src/views/system/user/authRole.vue b/src/views/system/user/authRole.vue new file mode 100644 index 0000000..d322942 --- /dev/null +++ b/src/views/system/user/authRole.vue @@ -0,0 +1,146 @@ + + + diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue new file mode 100644 index 0000000..da8c5bc --- /dev/null +++ b/src/views/system/user/index.vue @@ -0,0 +1,679 @@ + + + diff --git a/src/views/system/user/profile/index.vue b/src/views/system/user/profile/index.vue new file mode 100644 index 0000000..7c1389a --- /dev/null +++ b/src/views/system/user/profile/index.vue @@ -0,0 +1,122 @@ + + + diff --git a/src/views/system/user/profile/onlineDevice.vue b/src/views/system/user/profile/onlineDevice.vue new file mode 100644 index 0000000..3ce63ba --- /dev/null +++ b/src/views/system/user/profile/onlineDevice.vue @@ -0,0 +1,57 @@ + + + diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue new file mode 100644 index 0000000..3ca5ee9 --- /dev/null +++ b/src/views/system/user/profile/resetPwd.vue @@ -0,0 +1,73 @@ + + + diff --git a/src/views/system/user/profile/thirdParty.vue b/src/views/system/user/profile/thirdParty.vue new file mode 100644 index 0000000..218b63a --- /dev/null +++ b/src/views/system/user/profile/thirdParty.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/views/system/user/profile/userAvatar.vue b/src/views/system/user/profile/userAvatar.vue new file mode 100644 index 0000000..8709289 --- /dev/null +++ b/src/views/system/user/profile/userAvatar.vue @@ -0,0 +1,182 @@ + + + + + diff --git a/src/views/system/user/profile/userInfo.vue b/src/views/system/user/profile/userInfo.vue new file mode 100644 index 0000000..2a5d1a0 --- /dev/null +++ b/src/views/system/user/profile/userInfo.vue @@ -0,0 +1,69 @@ + + + diff --git a/src/views/tool/gen/basicInfoForm.vue b/src/views/tool/gen/basicInfoForm.vue new file mode 100644 index 0000000..5412088 --- /dev/null +++ b/src/views/tool/gen/basicInfoForm.vue @@ -0,0 +1,49 @@ + + + diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue new file mode 100644 index 0000000..5f11e25 --- /dev/null +++ b/src/views/tool/gen/editTable.vue @@ -0,0 +1,198 @@ + + + diff --git a/src/views/tool/gen/genInfoForm.vue b/src/views/tool/gen/genInfoForm.vue new file mode 100644 index 0000000..95065a0 --- /dev/null +++ b/src/views/tool/gen/genInfoForm.vue @@ -0,0 +1,294 @@ + + + diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue new file mode 100644 index 0000000..f86a54f --- /dev/null +++ b/src/views/tool/gen/importTable.vue @@ -0,0 +1,122 @@ + + + diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue new file mode 100644 index 0000000..e73a3fb --- /dev/null +++ b/src/views/tool/gen/index.vue @@ -0,0 +1,259 @@ + + + + + diff --git a/src/views/workflow/category/index.vue b/src/views/workflow/category/index.vue new file mode 100644 index 0000000..cd6984e --- /dev/null +++ b/src/views/workflow/category/index.vue @@ -0,0 +1,254 @@ + + + diff --git a/src/views/workflow/leave/index.vue b/src/views/workflow/leave/index.vue new file mode 100644 index 0000000..608cf05 --- /dev/null +++ b/src/views/workflow/leave/index.vue @@ -0,0 +1,236 @@ + + + diff --git a/src/views/workflow/leave/leaveEdit.vue b/src/views/workflow/leave/leaveEdit.vue new file mode 100644 index 0000000..cbf1057 --- /dev/null +++ b/src/views/workflow/leave/leaveEdit.vue @@ -0,0 +1,286 @@ + + + diff --git a/src/views/workflow/processDefinition/design.vue b/src/views/workflow/processDefinition/design.vue new file mode 100644 index 0000000..01fa552 --- /dev/null +++ b/src/views/workflow/processDefinition/design.vue @@ -0,0 +1,46 @@ + + + diff --git a/src/views/workflow/processDefinition/index.vue b/src/views/workflow/processDefinition/index.vue new file mode 100644 index 0000000..f6f2ff3 --- /dev/null +++ b/src/views/workflow/processDefinition/index.vue @@ -0,0 +1,562 @@ + + + diff --git a/src/views/workflow/processInstance/index.vue b/src/views/workflow/processInstance/index.vue new file mode 100644 index 0000000..d4b4f3f --- /dev/null +++ b/src/views/workflow/processInstance/index.vue @@ -0,0 +1,478 @@ + + + diff --git a/src/views/workflow/spel/index.vue b/src/views/workflow/spel/index.vue new file mode 100644 index 0000000..4968901 --- /dev/null +++ b/src/views/workflow/spel/index.vue @@ -0,0 +1,360 @@ + + + + diff --git a/src/views/workflow/task/allTaskWaiting.vue b/src/views/workflow/task/allTaskWaiting.vue new file mode 100644 index 0000000..eef3c0a --- /dev/null +++ b/src/views/workflow/task/allTaskWaiting.vue @@ -0,0 +1,279 @@ + + + diff --git a/src/views/workflow/task/myDocument.vue b/src/views/workflow/task/myDocument.vue new file mode 100644 index 0000000..18f3c39 --- /dev/null +++ b/src/views/workflow/task/myDocument.vue @@ -0,0 +1,246 @@ + + + diff --git a/src/views/workflow/task/taskCopyList.vue b/src/views/workflow/task/taskCopyList.vue new file mode 100644 index 0000000..f66d098 --- /dev/null +++ b/src/views/workflow/task/taskCopyList.vue @@ -0,0 +1,138 @@ + + + diff --git a/src/views/workflow/task/taskFinish.vue b/src/views/workflow/task/taskFinish.vue new file mode 100644 index 0000000..38925b4 --- /dev/null +++ b/src/views/workflow/task/taskFinish.vue @@ -0,0 +1,186 @@ + + + diff --git a/src/views/workflow/task/taskWaiting.vue b/src/views/workflow/task/taskWaiting.vue new file mode 100644 index 0000000..434c674 --- /dev/null +++ b/src/views/workflow/task/taskWaiting.vue @@ -0,0 +1,185 @@ + + + diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c5e5ca3 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "baseUrl": ".", + // https://vite.dev/config/build-options.html#build-target + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + // This setting lets you specify a file for storing incremental compilation information as a part of composite projects which enables faster building of larger TypeScript codebases. + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo", + "strict": true, + "allowJs": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "noEmit": true, + "paths": { + "@/*": ["./src/*"] + }, + "types": ["node", "vite/client"], + // 自定义配置 + "noImplicitAny": false, // 禁用 隐式的any错误 + "removeComments": true, // 移除 ts注释 + "experimentalDecorators": true, // 启用实验性的装饰器支持 + "strictFunctionTypes": false, // 禁用严格函数类型检查 + "strictNullChecks": false, // 禁用严格的空值检查 + "allowSyntheticDefaultImports": true, // 允许默认导入 + "forceConsistentCasingInFileNames": true // 强制在文件名中使用一致的大小写 + }, + "include": [ + "src/**/*.ts", + "src/**/*.vue", + "vite.config.ts", + "vitest.config.ts", + "eslint.config.ts", + "src/**/*.d.ts" + ], + "exclude": ["node_modules", "dist", "src/**/__tests__/*"] +} diff --git a/uno.config.ts b/uno.config.ts new file mode 100644 index 0000000..0c60a22 --- /dev/null +++ b/uno.config.ts @@ -0,0 +1,33 @@ +import { + defineConfig, + presetAttributify, + presetIcons, + presetTypography, + presetUno, + presetWebFonts, + transformerDirectives, + transformerVariantGroup +} from 'unocss'; + +export default defineConfig({ + shortcuts: { + 'panel-title': + 'pb-[5px] font-sans leading-[1.1] font-medium text-base text-[#6379bb] border-b border-b-solid border-[var(--el-border-color-light)] mb-5 mt-0' + }, + theme: { + colors: { + primary: 'var(--el-color-primary)', + primary_dark: 'var(--el-color-primary-light-5)' + } + }, + presets: [ + presetUno(), + presetAttributify(), + presetIcons(), + presetTypography(), + presetWebFonts({ + fonts: {} + }) + ], + transformers: [transformerDirectives(), transformerVariantGroup()] +}); diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..58ca5f2 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,73 @@ +import { defineConfig, loadEnv } from 'vite'; +import createPlugins from './vite/plugins'; +import autoprefixer from 'autoprefixer'; // css自动添加兼容性前缀 +import path from 'path'; + +export default defineConfig(({ mode, command }) => { + const env = loadEnv(mode, process.cwd()); + return { + // 部署生产环境和开发环境下的URL。 + // 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上 + // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。 + base: env.VITE_APP_CONTEXT_PATH, + resolve: { + alias: { + '@': path.resolve(__dirname, './src') + }, + extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'] + }, + // https://cn.vitejs.dev/config/#resolve-extensions + plugins: createPlugins(env, command === 'build'), + server: { + host: '0.0.0.0', + port: Number(env.VITE_APP_PORT), + open: true, + proxy: { + [env.VITE_APP_BASE_API]: { + target: 'http://localhost:8080', + changeOrigin: true, + ws: true, + rewrite: (path) => path.replace(new RegExp('^' + env.VITE_APP_BASE_API), '') + } + } + }, + css: { + preprocessorOptions: { + scss: { + // additionalData: '@use "@/assets/styles/variables.module.scss as *";' + // javascriptEnabled: true + api: 'modern-compiler' + } + }, + postcss: { + plugins: [ + // 浏览器兼容性 + autoprefixer(), + { + postcssPlugin: 'internal:charset-removal', + AtRule: { + charset: (atRule) => { + atRule.remove(); + } + } + } + ] + } + }, + // 预编译 + optimizeDeps: { + include: [ + 'vue', + 'vue-router', + 'pinia', + 'axios', + '@vueuse/core', + 'echarts', + 'vue-i18n', + '@vueup/vue-quill', + 'image-conversion', + 'element-plus/es/components/**/css' + ] + } + }; +}); diff --git a/vite/plugins/auto-import.ts b/vite/plugins/auto-import.ts new file mode 100644 index 0000000..a271829 --- /dev/null +++ b/vite/plugins/auto-import.ts @@ -0,0 +1,20 @@ +import AutoImport from 'unplugin-auto-import/vite'; +import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'; + +export default (path: any) => { + return AutoImport({ + // 自动导入 Vue 相关函数 + imports: ['vue', 'vue-router', '@vueuse/core', 'pinia'], + eslintrc: { + enabled: true, + filepath: './.eslintrc-auto-import.json', + globalsPropValue: true + }, + resolvers: [ + // 自动导入 Element Plus 相关函数ElMessage, ElMessageBox... (带样式) + ElementPlusResolver() + ], + vueTemplate: true, // 是否在 vue 模板中自动导入 + dts: path.resolve(path.resolve(__dirname, '../../src'), 'types', 'auto-imports.d.ts') + }); +}; diff --git a/vite/plugins/components.ts b/vite/plugins/components.ts new file mode 100644 index 0000000..336f5cf --- /dev/null +++ b/vite/plugins/components.ts @@ -0,0 +1,17 @@ +import Components from 'unplugin-vue-components/vite'; +import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'; +import IconsResolver from 'unplugin-icons/resolver'; + +export default (path: any) => { + return Components({ + resolvers: [ + // 自动导入 Element Plus 组件 + ElementPlusResolver(), + // 自动注册图标组件 + IconsResolver({ + enabledCollections: ['ep'] + }) + ], + dts: path.resolve(path.resolve(__dirname, '../../src'), 'types', 'components.d.ts') + }); +}; diff --git a/vite/plugins/compression.ts b/vite/plugins/compression.ts new file mode 100644 index 0000000..aa8c779 --- /dev/null +++ b/vite/plugins/compression.ts @@ -0,0 +1,28 @@ +import compression from 'vite-plugin-compression'; + +export default (env: any) => { + const { VITE_BUILD_COMPRESS } = env; + const plugin: any[] = []; + if (VITE_BUILD_COMPRESS) { + const compressList = VITE_BUILD_COMPRESS.split(','); + if (compressList.includes('gzip')) { + // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件 + plugin.push( + compression({ + ext: '.gz', + deleteOriginFile: false + }) + ); + } + if (compressList.includes('brotli')) { + plugin.push( + compression({ + ext: '.br', + algorithm: 'brotliCompress', + deleteOriginFile: false + }) + ); + } + } + return plugin; +}; diff --git a/vite/plugins/icons.ts b/vite/plugins/icons.ts new file mode 100644 index 0000000..883f230 --- /dev/null +++ b/vite/plugins/icons.ts @@ -0,0 +1,8 @@ +import Icons from 'unplugin-icons/vite'; + +export default () => { + return Icons({ + // 自动安装图标库 + autoInstall: true + }); +}; diff --git a/vite/plugins/index.ts b/vite/plugins/index.ts new file mode 100644 index 0000000..9ef8faf --- /dev/null +++ b/vite/plugins/index.ts @@ -0,0 +1,25 @@ +import vue from '@vitejs/plugin-vue'; +import vueDevTools from 'vite-plugin-vue-devtools'; + +import createUnoCss from './unocss'; +import createAutoImport from './auto-import'; +import createComponents from './components'; +import createIcons from './icons'; +import createSvgIconsPlugin from './svg-icon'; +import createCompression from './compression'; +import createSetupExtend from './setup-extend'; +import path from 'path'; + +export default (viteEnv: any, isBuild = false): [] => { + const vitePlugins: any = []; + vitePlugins.push(vue()); + vitePlugins.push(vueDevTools()); + vitePlugins.push(createUnoCss()); + vitePlugins.push(createAutoImport(path)); + vitePlugins.push(createComponents(path)); + vitePlugins.push(createCompression(viteEnv)); + vitePlugins.push(createIcons()); + vitePlugins.push(createSvgIconsPlugin(path)); + vitePlugins.push(createSetupExtend()); + return vitePlugins; +}; diff --git a/vite/plugins/setup-extend.ts b/vite/plugins/setup-extend.ts new file mode 100644 index 0000000..ed3423f --- /dev/null +++ b/vite/plugins/setup-extend.ts @@ -0,0 +1,5 @@ +import setupExtend from 'unplugin-vue-setup-extend-plus/vite'; + +export default () => { + return setupExtend({}); +}; diff --git a/vite/plugins/svg-icon.ts b/vite/plugins/svg-icon.ts new file mode 100644 index 0000000..3ad93fb --- /dev/null +++ b/vite/plugins/svg-icon.ts @@ -0,0 +1,10 @@ +import { createSvgIconsPlugin } from 'vite-plugin-svg-icons-ng'; + +export default (path: any) => { + return createSvgIconsPlugin({ + // 指定需要缓存的图标文件夹 + iconDirs: [path.resolve(path.resolve(__dirname, '../../src'), 'assets/icons/svg')], + // 指定symbolId格式 + symbolId: 'icon-[dir]-[name]' + }); +}; diff --git a/vite/plugins/unocss.ts b/vite/plugins/unocss.ts new file mode 100644 index 0000000..08e186b --- /dev/null +++ b/vite/plugins/unocss.ts @@ -0,0 +1,7 @@ +import UnoCss from 'unocss/vite'; + +export default () => { + return UnoCss({ + hmrTopLevelAwait: false // unocss默认是true,低版本浏览器是不支持的,启动后会报错 + }); +};