已添加7个文件
已删除7个文件
已修改181个文件
| | |
| | | { |
| | | "globals": { |
| | | "useRouter": true, |
| | | "useRoute": true, |
| | | "EffectScope": true, |
| | | "ElTable": true, |
| | | "ElSelect": true, |
| | | "ElUpload": true, |
| | | "ElForm": true, |
| | | "ElTree": true, |
| | | "ElMessage": true, |
| | | "ElMessageBox": 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, |
| | | "createReactiveFn": true, |
| | | "createSharedComposable": true, |
| | | "createUnrefFn": true, |
| | | "customRef": true, |
| | | "debouncedRef": true, |
| | | "debouncedWatch": true, |
| | | "defineAsyncComponent": true, |
| | | "defineComponent": true, |
| | | "eagerComputed": true, |
| | | "effectScope": true, |
| | | "extendRef": true, |
| | | "getCurrentInstance": true, |
| | | "getCurrentScope": true, |
| | | "h": true, |
| | | "ignorableWatch": true, |
| | | "inject": true, |
| | | "isDefined": true, |
| | | "isProxy": true, |
| | | "isReactive": true, |
| | | "isReadonly": true, |
| | | "isRef": true, |
| | | "makeDestructurable": true, |
| | | "markRaw": true, |
| | | "nextTick": true, |
| | | "onActivated": true, |
| | | "onBeforeMount": true, |
| | | "onBeforeUnmount": true, |
| | | "onBeforeUpdate": true, |
| | | "onClickOutside": true, |
| | | "onDeactivated": true, |
| | | "onErrorCaptured": true, |
| | | "onKeyStroke": true, |
| | | "onLongPress": true, |
| | | "onMounted": true, |
| | | "onRenderTracked": true, |
| | | "onRenderTriggered": true, |
| | | "onScopeDispose": true, |
| | | "onServerPrefetch": true, |
| | | "onStartTyping": true, |
| | | "onUnmounted": true, |
| | | "onUpdated": true, |
| | | "pausableWatch": true, |
| | | "provide": 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, |
| | | "resolveDirective": true, |
| | | "resolveRef": true, |
| | | "resolveUnref": true, |
| | | "shallowReactive": true, |
| | | "shallowReadonly": true, |
| | | "shallowRef": true, |
| | | "syncRef": true, |
| | | "syncRefs": true, |
| | | "templateRef": true, |
| | | "throttledRef": true, |
| | | "throttledWatch": true, |
| | | "toRaw": true, |
| | | "toReactive": true, |
| | | "toRef": true, |
| | | "toRefs": true, |
| | | "triggerRef": true, |
| | | "tryOnBeforeMount": true, |
| | | "tryOnBeforeUnmount": true, |
| | | "tryOnMounted": true, |
| | | "tryOnScopeDispose": true, |
| | | "tryOnUnmounted": true, |
| | | "unref": true, |
| | | "unrefElement": true, |
| | | "until": true, |
| | | "useActiveElement": true, |
| | | "useArrayEvery": true, |
| | | "useArrayFilter": true, |
| | | "useArrayFind": true, |
| | | "useArrayFindIndex": true, |
| | | "useArrayFindLast": 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, |
| | | "useCloned": true, |
| | | "useColorMode": true, |
| | | "useConfirmDialog": 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, |
| | | "useIdle": true, |
| | | "useImage": true, |
| | | "useInfiniteScroll": true, |
| | | "useIntersectionObserver": true, |
| | | "useInterval": true, |
| | | "useIntervalFn": true, |
| | | "useKeyModifier": true, |
| | | "useLastChanged": true, |
| | | "useLocalStorage": true, |
| | | "useMagicKeys": true, |
| | | "useManualRefHistory": true, |
| | | "useMediaControls": true, |
| | | "useMediaQuery": true, |
| | | "useMemoize": true, |
| | | "useMemory": 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, |
| | | "usePermission": true, |
| | | "usePointer": true, |
| | | "usePointerLock": true, |
| | | "usePointerSwipe": true, |
| | | "usePreferredColorScheme": true, |
| | | "usePreferredContrast": true, |
| | | "usePreferredDark": true, |
| | | "usePreferredLanguages": true, |
| | | "usePreferredReducedMotion": true, |
| | | "usePrevious": true, |
| | | "useRafFn": true, |
| | | "useRefHistory": true, |
| | | "useResizeObserver": 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, |
| | | "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, |
| | | "watchEffect": true, |
| | | "watchIgnorable": true, |
| | | "watchOnce": true, |
| | | "watchPausable": true, |
| | | "watchPostEffect": true, |
| | | "watchSyncEffect": true, |
| | | "watchThrottled": true, |
| | | "watchTriggerable": true, |
| | | "watchWithFilter": true, |
| | | "whenever": true, |
| | | "ImportOption": true, |
| | | "TreeType": true, |
| | | "FieldOption": true, |
| | | "PageData": true, |
| | | "storeToRefs": true, |
| | | "DictDataOption": true, |
| | | "UploadOption": true |
| | | } |
| | | "globals": { |
| | | "useRouter": true, |
| | | "useRoute": true, |
| | | "EffectScope": true, |
| | | "ElTable": true, |
| | | "ElSelect": true, |
| | | "ElUpload": true, |
| | | "ElForm": true, |
| | | "ElTree": true, |
| | | "ElMessage": true, |
| | | "ElMessageBox": 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, |
| | | "createReactiveFn": true, |
| | | "createSharedComposable": true, |
| | | "createUnrefFn": true, |
| | | "customRef": true, |
| | | "debouncedRef": true, |
| | | "debouncedWatch": true, |
| | | "defineAsyncComponent": true, |
| | | "defineComponent": true, |
| | | "eagerComputed": true, |
| | | "effectScope": true, |
| | | "extendRef": true, |
| | | "getCurrentInstance": true, |
| | | "getCurrentScope": true, |
| | | "h": true, |
| | | "ignorableWatch": true, |
| | | "inject": true, |
| | | "isDefined": true, |
| | | "isProxy": true, |
| | | "isReactive": true, |
| | | "isReadonly": true, |
| | | "isRef": true, |
| | | "makeDestructurable": true, |
| | | "markRaw": true, |
| | | "nextTick": true, |
| | | "onActivated": true, |
| | | "onBeforeMount": true, |
| | | "onBeforeUnmount": true, |
| | | "onBeforeUpdate": true, |
| | | "onClickOutside": true, |
| | | "onDeactivated": true, |
| | | "onErrorCaptured": true, |
| | | "onKeyStroke": true, |
| | | "onLongPress": true, |
| | | "onMounted": true, |
| | | "onRenderTracked": true, |
| | | "onRenderTriggered": true, |
| | | "onScopeDispose": true, |
| | | "onServerPrefetch": true, |
| | | "onStartTyping": true, |
| | | "onUnmounted": true, |
| | | "onUpdated": true, |
| | | "pausableWatch": true, |
| | | "provide": 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, |
| | | "resolveDirective": true, |
| | | "resolveRef": true, |
| | | "resolveUnref": true, |
| | | "shallowReactive": true, |
| | | "shallowReadonly": true, |
| | | "shallowRef": true, |
| | | "syncRef": true, |
| | | "syncRefs": true, |
| | | "templateRef": true, |
| | | "throttledRef": true, |
| | | "throttledWatch": true, |
| | | "toRaw": true, |
| | | "toReactive": true, |
| | | "toRef": true, |
| | | "toRefs": true, |
| | | "triggerRef": true, |
| | | "tryOnBeforeMount": true, |
| | | "tryOnBeforeUnmount": true, |
| | | "tryOnMounted": true, |
| | | "tryOnScopeDispose": true, |
| | | "tryOnUnmounted": true, |
| | | "unref": true, |
| | | "unrefElement": true, |
| | | "until": true, |
| | | "useActiveElement": true, |
| | | "useArrayEvery": true, |
| | | "useArrayFilter": true, |
| | | "useArrayFind": true, |
| | | "useArrayFindIndex": true, |
| | | "useArrayFindLast": 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, |
| | | "useCloned": true, |
| | | "useColorMode": true, |
| | | "useConfirmDialog": 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, |
| | | "useIdle": true, |
| | | "useImage": true, |
| | | "useInfiniteScroll": true, |
| | | "useIntersectionObserver": true, |
| | | "useInterval": true, |
| | | "useIntervalFn": true, |
| | | "useKeyModifier": true, |
| | | "useLastChanged": true, |
| | | "useLocalStorage": true, |
| | | "useMagicKeys": true, |
| | | "useManualRefHistory": true, |
| | | "useMediaControls": true, |
| | | "useMediaQuery": true, |
| | | "useMemoize": true, |
| | | "useMemory": 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, |
| | | "usePermission": true, |
| | | "usePointer": true, |
| | | "usePointerLock": true, |
| | | "usePointerSwipe": true, |
| | | "usePreferredColorScheme": true, |
| | | "usePreferredContrast": true, |
| | | "usePreferredDark": true, |
| | | "usePreferredLanguages": true, |
| | | "usePreferredReducedMotion": true, |
| | | "usePrevious": true, |
| | | "useRafFn": true, |
| | | "useRefHistory": true, |
| | | "useResizeObserver": 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, |
| | | "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, |
| | | "watchEffect": true, |
| | | "watchIgnorable": true, |
| | | "watchOnce": true, |
| | | "watchPausable": true, |
| | | "watchPostEffect": true, |
| | | "watchSyncEffect": true, |
| | | "watchThrottled": true, |
| | | "watchTriggerable": true, |
| | | "watchWithFilter": true, |
| | | "whenever": true, |
| | | "ImportOption": true, |
| | | "TreeType": true, |
| | | "FieldOption": true, |
| | | "PageData": true, |
| | | "storeToRefs": true, |
| | | "DictDataOption": true, |
| | | "UploadOption": true |
| | | } |
| | | } |
| | |
| | | module.exports = { |
| | | env: { |
| | | browser: true, |
| | | es2021: true, |
| | | node: true |
| | | }, |
| | | parser: 'vue-eslint-parser', |
| | | extends: [ |
| | | 'eslint:recommended', |
| | | 'plugin:vue/vue3-essential', |
| | | 'plugin:@typescript-eslint/recommended', |
| | | './.eslintrc-auto-import.json', |
| | | 'plugin:prettier/recommended' |
| | | ], |
| | | parserOptions: { |
| | | ecmaVersion: '2020', |
| | | sourceType: 'module', |
| | | parser: '@typescript-eslint/parser' |
| | | }, |
| | | plugins: ['vue', '@typescript-eslint'], |
| | | rules: { |
| | | 'vue/multi-word-component-names': 'off', |
| | | '@typescript-eslint/no-empty-function': 'off', |
| | | '@typescript-eslint/no-explicit-any': 'off', |
| | | 'vue/no-v-model-argument': 'off', |
| | | '@typescript-eslint/ban-types': [ |
| | | 'error', |
| | | { |
| | | // å
³éç©ºç±»åæ£æ¥ {} |
| | | extendDefaults: true, |
| | | types: { |
| | | '{}': false |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | globals: { |
| | | DialogOption: 'readonly', |
| | | OptionType: 'readonly' |
| | | } |
| | | env: { |
| | | browser: true, |
| | | es2021: true, |
| | | node: true |
| | | }, |
| | | parser: 'vue-eslint-parser', |
| | | extends: [ |
| | | 'eslint:recommended', |
| | | 'plugin:vue/vue3-essential', |
| | | 'plugin:@typescript-eslint/recommended', |
| | | './.eslintrc-auto-import.json', |
| | | 'plugin:prettier/recommended' |
| | | ], |
| | | parserOptions: { |
| | | ecmaVersion: '2020', |
| | | sourceType: 'module', |
| | | parser: '@typescript-eslint/parser' |
| | | }, |
| | | plugins: ['vue', '@typescript-eslint'], |
| | | rules: { |
| | | 'vue/multi-word-component-names': 'off', |
| | | '@typescript-eslint/no-empty-function': 'off', |
| | | '@typescript-eslint/no-explicit-any': 'off', |
| | | 'vue/no-v-model-argument': 'off', |
| | | '@typescript-eslint/ban-types': [ |
| | | 'error', |
| | | { |
| | | // å
³éç©ºç±»åæ£æ¥ {} |
| | | extendDefaults: true, |
| | | types: { |
| | | '{}': false |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | globals: { |
| | | DialogOption: 'readonly', |
| | | OptionType: 'readonly' |
| | | } |
| | | }; |
| | |
| | | * ä»£ç æ ¼å¼åé
ç½® |
| | | */ |
| | | module.exports = { |
| | | // ä¸è¡æå¤å¤å°ä¸ªå符 |
| | | printWidth: 150, |
| | | // æå®æ¯ä¸ªç¼©è¿çº§å«çç©ºæ ¼æ° |
| | | tabWidth: 2, |
| | | // 使ç¨å¶è¡¨ç¬¦è䏿¯ç©ºæ ¼ç¼©è¿è¡ |
| | | useTabs: true, |
| | | // å¨è¯å¥æ«å°¾æ¯å¦éè¦åå· |
| | | semi: true, |
| | | // æ¯å¦ä½¿ç¨åå¼å· |
| | | singleQuote: true, |
| | | // æ´æ¹å¼ç¨å¯¹è±¡å±æ§çæ¶é´ å¯éå¼"<as-needed|consistent|preserve>" |
| | | quoteProps: 'as-needed', |
| | | // å¨JSXä¸ä½¿ç¨åå¼å·è䏿¯åå¼å· |
| | | jsxSingleQuote: false, |
| | | // å¤è¡æ¶å°½å¯è½æå°å°¾ééå·ãï¼ä¾å¦ï¼åè¡æ°ç»æ°¸è¿ä¸ä¼åºç°éå·ç»å°¾ãï¼ å¯éå¼"<none|es5|all>"ï¼é»è®¤none |
| | | trailingComma: 'none', |
| | | // å¨å¯¹è±¡æåä¸çæ¬å·ä¹é´æå°ç©ºæ ¼ |
| | | bracketSpacing: true, |
| | | // jsx æ ç¾çåå°æ¬å·éè¦æ¢è¡ |
| | | jsxBracketSameLine: false, |
| | | embeddedLanguageFormatting: 'off', |
| | | // å¨åç¬çç®å¤´å½æ°åæ°å¨å´å
æ¬æ¬å· alwaysï¼(x) => x \ avoidï¼x => x |
| | | arrowParens: 'always', |
| | | // è¿ä¸¤ä¸ªé项å¯ç¨äºæ ¼å¼å以ç»å®å符åç§»éï¼åå«å
æ¬åä¸å
æ¬ï¼å¼å§åç»æç代ç |
| | | rangeStart: 0, |
| | | rangeEnd: Infinity, |
| | | // æå®è¦ä½¿ç¨çè§£æå¨ï¼ä¸éè¦åæä»¶å¼å¤´ç @prettier |
| | | requirePragma: false, |
| | | // ä¸éè¦èªå¨å¨æä»¶å¼å¤´æå
¥ @prettier |
| | | insertPragma: false, |
| | | // 使ç¨é»è®¤çæè¡æ å always\never\preserve |
| | | proseWrap: 'preserve', |
| | | // æå®HTMLæä»¶çå
¨å±ç©ºæ ¼ææåº¦ css\strict\ignore |
| | | htmlWhitespaceSensitivity: 'css', |
| | | // Vueæä»¶èæ¬åæ ·å¼æ ç¾ç¼©è¿ |
| | | vueIndentScriptAndStyle: false, |
| | | //å¨ windows æä½ç³»ç»ä¸æ¢è¡ç¬¦é常æ¯å车 (CR) å æ¢è¡åé符 (LF)ï¼ä¹å°±æ¯å车æ¢è¡(CRLF)ï¼ |
| | | //ç¶èå¨ Linux å Unix ä¸åªä½¿ç¨ç®åçæ¢è¡åé符 (LF)ã |
| | | //对åºçæ§å¶å符为 "\n" (LF) å "\r\n"(CRLF)ãautoæä¸ºä¿æç°æçè¡å°¾ |
| | | // æ¢è¡ç¬¦ä½¿ç¨ lf ç»å°¾æ¯ å¯éå¼"<auto|lf|crlf|cr>" |
| | | endOfLine: 'auto' |
| | | // ä¸è¡æå¤å¤å°ä¸ªå符 |
| | | printWidth: 150, |
| | | // æå®æ¯ä¸ªç¼©è¿çº§å«çç©ºæ ¼æ° |
| | | tabWidth: 2, |
| | | // 使ç¨å¶è¡¨ç¬¦è䏿¯ç©ºæ ¼ç¼©è¿è¡ |
| | | useTabs: false, |
| | | // å¨è¯å¥æ«å°¾æ¯å¦éè¦åå· |
| | | semi: true, |
| | | // æ¯å¦ä½¿ç¨åå¼å· |
| | | singleQuote: true, |
| | | // æ´æ¹å¼ç¨å¯¹è±¡å±æ§çæ¶é´ å¯éå¼"<as-needed|consistent|preserve>" |
| | | quoteProps: 'as-needed', |
| | | // å¨JSXä¸ä½¿ç¨åå¼å·è䏿¯åå¼å· |
| | | jsxSingleQuote: false, |
| | | // å¤è¡æ¶å°½å¯è½æå°å°¾ééå·ãï¼ä¾å¦ï¼åè¡æ°ç»æ°¸è¿ä¸ä¼åºç°éå·ç»å°¾ãï¼ å¯éå¼"<none|es5|all>"ï¼é»è®¤none |
| | | trailingComma: 'none', |
| | | // å¨å¯¹è±¡æåä¸çæ¬å·ä¹é´æå°ç©ºæ ¼ |
| | | bracketSpacing: true, |
| | | // jsx æ ç¾çåå°æ¬å·éè¦æ¢è¡ |
| | | jsxBracketSameLine: false, |
| | | embeddedLanguageFormatting: 'off', |
| | | // å¨åç¬çç®å¤´å½æ°åæ°å¨å´å
æ¬æ¬å· alwaysï¼(x) => x \ avoidï¼x => x |
| | | arrowParens: 'always', |
| | | // è¿ä¸¤ä¸ªé项å¯ç¨äºæ ¼å¼å以ç»å®å符åç§»éï¼åå«å
æ¬åä¸å
æ¬ï¼å¼å§åç»æç代ç |
| | | rangeStart: 0, |
| | | rangeEnd: Infinity, |
| | | // æå®è¦ä½¿ç¨çè§£æå¨ï¼ä¸éè¦åæä»¶å¼å¤´ç @prettier |
| | | requirePragma: false, |
| | | // ä¸éè¦èªå¨å¨æä»¶å¼å¤´æå
¥ @prettier |
| | | insertPragma: false, |
| | | // 使ç¨é»è®¤çæè¡æ å always\never\preserve |
| | | proseWrap: 'preserve', |
| | | // æå®HTMLæä»¶çå
¨å±ç©ºæ ¼ææåº¦ css\strict\ignore |
| | | htmlWhitespaceSensitivity: 'css', |
| | | // Vueæä»¶èæ¬åæ ·å¼æ ç¾ç¼©è¿ |
| | | vueIndentScriptAndStyle: false, |
| | | //å¨ windows æä½ç³»ç»ä¸æ¢è¡ç¬¦é常æ¯å车 (CR) å æ¢è¡åé符 (LF)ï¼ä¹å°±æ¯å车æ¢è¡(CRLF)ï¼ |
| | | //ç¶èå¨ Linux å Unix ä¸åªä½¿ç¨ç®åçæ¢è¡åé符 (LF)ã |
| | | //对åºçæ§å¶å符为 "\n" (LF) å "\r\n"(CRLF)ãautoæä¸ºä¿æç°æçè¡å°¾ |
| | | // æ¢è¡ç¬¦ä½¿ç¨ lf ç»å°¾æ¯ å¯éå¼"<auto|lf|crlf|cr>" |
| | | endOfLine: 'auto' |
| | | }; |
| | |
| | | ## å¹³å°ç®ä» |
| | | |
| | | ## å¹³å°ç®ä» |
| | | |
| | | - æ¬ä»åºä¸ºåç«¯ææ¯æ [Vue3](https://v3.cn.vuejs.org) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) çæ¬ã |
| | | - é
å¥å端代ç ä»åºå°å |
| | | - [RuoYi-Vue-Plus 5.X(注æçæ¬å·)](https://gitee.com/dromara/RuoYi-Vue-Plus) |
| | | - [RuoYi-Cloud-Plus 2.X(注æçæ¬å·)](https://gitee.com/dromara/RuoYi-Cloud-Plus) |
| | | * æ¬ä»åºä¸ºåç«¯ææ¯æ [Vue3](https://v3.cn.vuejs.org) + [TS](https://www.typescriptlang.org/) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) çæ¬ã |
| | | * é
å¥å端代ç ä»åºå°å |
| | | * [RuoYi-Vue-Plus 5.X(注æçæ¬å·)](https://gitee.com/dromara/RuoYi-Vue-Plus) |
| | | * [RuoYi-Cloud-Plus 2.X(注æçæ¬å·)](https://gitee.com/dromara/RuoYi-Cloud-Plus) |
| | | |
| | | ## å端è¿è¡ |
| | | |
| | |
| | | # å¯å¨æå¡ |
| | | npm run dev |
| | | |
| | | # æå»ºæµè¯ç¯å¢ yarn build:stage |
| | | # æå»ºç产ç¯å¢ yarn build:prod |
| | | # å端访é®å°å http://localhost:80 |
| | | ``` |
| | | |
| | | ## æ¬æ¡æ¶ä¸ RuoYi çä¸å¡å·®å¼ |
| | | ## æ¬æ¡æ¶ä¸RuoYiçä¸å¡å·®å¼ |
| | | |
| | | | ä¸å¡ | åè½è¯´æ | æ¬æ¡æ¶ | RuoYi | |
| | | | ------------ | --------------------------------------------------------------- | ------ | ------------------------------ | |
| | | | ç§æ·ç®¡ç | ç³»ç»å
ç§æ·ç管ç å¦:ç§æ·å¥é¤ãè¿ææ¶é´ãç¨æ·æ°éãä¼ä¸ä¿¡æ¯ç | æ¯æ | æ | |
| | | | ç§æ·å¥é¤ç®¡ç | ç³»ç»å
ç§æ·æè½ä½¿ç¨çå¥é¤ç®¡ç å¦:å¥é¤å
æå
å«çèåç | æ¯æ | æ | |
| | | | ç¨æ·ç®¡ç | ç¨æ·ç管çé
ç½® å¦:æ°å¢ç¨æ·ãåé
ç¨æ·æå±é¨é¨ãè§è²ãå²ä½ç | æ¯æ | æ¯æ | |
| | | | é¨é¨ç®¡ç | é
置系ç»ç»ç»æºæï¼å
¬å¸ãé¨é¨ãå°ç»ï¼ æ ç»æå±ç°æ¯ææ°æ®æé | æ¯æ | æ¯æ | |
| | | | å²ä½ç®¡ç | é
置系ç»ç¨æ·æå±æ
ä»»èå¡ | æ¯æ | æ¯æ | |
| | | | èå管ç | é
置系ç»èåãæä½æéãæé®æéæ è¯ç | æ¯æ | æ¯æ | |
| | | | è§è²ç®¡ç | è§è²èåæéåé
ã设置è§è²ææºæè¿è¡æ°æ®èå´æéåå | æ¯æ | æ¯æ | |
| | | | åå
¸ç®¡ç | 对系ç»ä¸ç»å¸¸ä½¿ç¨çä¸äºè¾ä¸ºåºå®çæ°æ®è¿è¡ç»´æ¤ | æ¯æ | æ¯æ | |
| | | | åæ°ç®¡ç | 对系ç»å¨æé
置常ç¨åæ° | æ¯æ | æ¯æ | |
| | | | éç¥å
¬å | ç³»ç»éç¥å
¬åä¿¡æ¯åå¸ç»´æ¤ | æ¯æ | æ¯æ | |
| | | | æä½æ¥å¿ | ç³»ç»æ£å¸¸æä½æ¥å¿è®°å½åæ¥è¯¢ ç³»ç»å¼å¸¸ä¿¡æ¯æ¥å¿è®°å½åæ¥è¯¢ | æ¯æ | æ¯æ | |
| | | | ç»å½æ¥å¿ | ç³»ç»ç»å½æ¥å¿è®°å½æ¥è¯¢å
å«ç»å½å¼å¸¸ | æ¯æ | æ¯æ | |
| | | | æä»¶ç®¡ç | ç³»ç»æä»¶å±ç¤ºãä¸ä¼ ãä¸è½½ãå é¤ç管ç | æ¯æ | æ | |
| | | | æä»¶é
置管ç | ç³»ç»æä»¶ä¸ä¼ ãä¸è½½æéè¦çé
置信æ¯å¨ææ·»å ãä¿®æ¹ãå é¤ç管ç | æ¯æ | æ | |
| | | | å¨çº¿ç¨æ·ç®¡ç | å·²ç»å½ç³»ç»çå¨çº¿ç¨æ·ä¿¡æ¯çæ§ä¸å¼ºå¶è¸¢åºæä½ | æ¯æ | æ¯æ | |
| | | | 宿¶ä»»å¡ | è¿è¡æ¥è¡¨ãä»»å¡ç®¡ç(æ·»å ãä¿®æ¹ãå é¤)ãæ¥å¿ç®¡çãæ§è¡å¨ç®¡çç | æ¯æ | ä»
æ¯æä»»å¡ä¸æ¥å¿ç®¡ç | |
| | | | 代ç çæ | 夿°æ®æºåå端代ç ççæï¼javaãhtmlãxmlãsqlï¼æ¯æ CRUD ä¸è½½ | æ¯æ | ä»
æ¯æåæ°æ®æº | |
| | | | ç³»ç»æ¥å£ | æ ¹æ®ä¸å¡ä»£ç èªå¨çæç¸å
³ç api æ¥å£ææ¡£ | æ¯æ | æ¯æ | |
| | | | æå¡çæ§ | çè§éç¾¤ç³»ç» CPUãå
åãç£çãå æ ãå¨çº¿æ¥å¿ãSpring ç¸å
³é
ç½®ç | æ¯æ | ä»
æ¯æåæº CPUãå
åãç£ççæ§ | |
| | | | ç¼åçæ§ | 对系ç»çç¼åä¿¡æ¯æ¥è¯¢ï¼å½ä»¤ç»è®¡çã | æ¯æ | æ¯æ | |
| | | | å¨çº¿æå»ºå¨ | æå¨è¡¨åå
ç´ çæç¸åºç HTML 代ç ã | æ¯æ | æ¯æ | |
| | | | ä½¿ç¨æ¡ä¾ | ç³»ç»çä¸äºåè½æ¡ä¾ | æ¯æ | 䏿¯æ | |
| | | | ä¸å¡ | åè½è¯´æ | æ¬æ¡æ¶ | RuoYi | |
| | | |--------|-----------------------------------------|-----|------------------| |
| | | | ç§æ·ç®¡ç | ç³»ç»å
ç§æ·ç管ç å¦:ç§æ·å¥é¤ãè¿ææ¶é´ãç¨æ·æ°éãä¼ä¸ä¿¡æ¯ç | æ¯æ | æ | |
| | | | ç§æ·å¥é¤ç®¡ç | ç³»ç»å
ç§æ·æè½ä½¿ç¨çå¥é¤ç®¡ç å¦:å¥é¤å
æå
å«çèåç | æ¯æ | æ | |
| | | | ç¨æ·ç®¡ç | ç¨æ·ç管çé
ç½® å¦:æ°å¢ç¨æ·ãåé
ç¨æ·æå±é¨é¨ãè§è²ãå²ä½ç | æ¯æ | æ¯æ | |
| | | | é¨é¨ç®¡ç | é
置系ç»ç»ç»æºæï¼å
¬å¸ãé¨é¨ãå°ç»ï¼ æ ç»æå±ç°æ¯ææ°æ®æé | æ¯æ | æ¯æ | |
| | | | å²ä½ç®¡ç | é
置系ç»ç¨æ·æå±æ
ä»»èå¡ | æ¯æ | æ¯æ | |
| | | | èå管ç | é
置系ç»èåãæä½æéãæé®æéæ è¯ç | æ¯æ | æ¯æ | |
| | | | è§è²ç®¡ç | è§è²èåæéåé
ã设置è§è²ææºæè¿è¡æ°æ®èå´æéåå | æ¯æ | æ¯æ | |
| | | | åå
¸ç®¡ç | 对系ç»ä¸ç»å¸¸ä½¿ç¨çä¸äºè¾ä¸ºåºå®çæ°æ®è¿è¡ç»´æ¤ | æ¯æ | æ¯æ | |
| | | | åæ°ç®¡ç | 对系ç»å¨æé
置常ç¨åæ° | æ¯æ | æ¯æ | |
| | | | éç¥å
¬å | ç³»ç»éç¥å
¬åä¿¡æ¯åå¸ç»´æ¤ | æ¯æ | æ¯æ | |
| | | | æä½æ¥å¿ | ç³»ç»æ£å¸¸æä½æ¥å¿è®°å½åæ¥è¯¢ ç³»ç»å¼å¸¸ä¿¡æ¯æ¥å¿è®°å½åæ¥è¯¢ | æ¯æ | æ¯æ | |
| | | | ç»å½æ¥å¿ | ç³»ç»ç»å½æ¥å¿è®°å½æ¥è¯¢å
å«ç»å½å¼å¸¸ | æ¯æ | æ¯æ | |
| | | | æä»¶ç®¡ç | ç³»ç»æä»¶å±ç¤ºãä¸ä¼ ãä¸è½½ãå é¤ç管ç | æ¯æ | æ | |
| | | | æä»¶é
置管ç | ç³»ç»æä»¶ä¸ä¼ ãä¸è½½æéè¦çé
置信æ¯å¨ææ·»å ãä¿®æ¹ãå é¤ç管ç | æ¯æ | æ | |
| | | | å¨çº¿ç¨æ·ç®¡ç | å·²ç»å½ç³»ç»çå¨çº¿ç¨æ·ä¿¡æ¯çæ§ä¸å¼ºå¶è¸¢åºæä½ | æ¯æ | æ¯æ | |
| | | | 宿¶ä»»å¡ | è¿è¡æ¥è¡¨ãä»»å¡ç®¡ç(æ·»å ãä¿®æ¹ãå é¤)ãæ¥å¿ç®¡çãæ§è¡å¨ç®¡çç | æ¯æ | ä»
æ¯æä»»å¡ä¸æ¥å¿ç®¡ç | |
| | | | 代ç çæ | 夿°æ®æºåå端代ç ççæï¼javaãhtmlãxmlãsqlï¼æ¯æCRUDä¸è½½ | æ¯æ | ä»
æ¯æåæ°æ®æº | |
| | | | ç³»ç»æ¥å£ | æ ¹æ®ä¸å¡ä»£ç èªå¨çæç¸å
³çapiæ¥å£ææ¡£ | æ¯æ | æ¯æ | |
| | | | æå¡çæ§ | çè§é群系ç»CPUãå
åãç£çãå æ ãå¨çº¿æ¥å¿ãSpringç¸å
³é
ç½®ç | æ¯æ | ä»
æ¯æåæºCPUãå
åãç£ççæ§ | |
| | | | ç¼åçæ§ | 对系ç»çç¼åä¿¡æ¯æ¥è¯¢ï¼å½ä»¤ç»è®¡çã | æ¯æ | æ¯æ | |
| | | | å¨çº¿æå»ºå¨ | æå¨è¡¨åå
ç´ çæç¸åºçHTML代ç ã | æ¯æ | æ¯æ | |
| | | | ä½¿ç¨æ¡ä¾ | ç³»ç»çä¸äºåè½æ¡ä¾ | æ¯æ | 䏿¯æ | |
| | | |
| | | ## æ¼ç¤ºå¾ |
| | | ## æ¼ç¤ºå¾ä¾ |
| | | |
| | | - æ¬ä»åºä¸ºåç«¯ææ¯æ [Vue3](https://v3.cn.vuejs.org) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) çæ¬ã |
| | | - é
å¥å端代ç ä»åºå°å |
| | | - [RuoYi-Vue-Plus 5.X(注æçæ¬å·)](https://gitee.com/dromara/RuoYi-Vue-Plus) |
| | | - [RuoYi-Cloud-Plus 2.X(注æçæ¬å·)](https://gitee.com/dromara/RuoYi-Cloud-Plus) |
| | | |
| | | ## å端è¿è¡ |
| | | |
| | | ```bash |
| | | # å
éé¡¹ç® |
| | | git clone https://gitee.com/JavaLionLi/plus-ui.git |
| | | |
| | | # å®è£
ä¾èµ |
| | | npm install --registry=https://registry.npmmirror.com |
| | | |
| | | # å¯å¨æå¡ |
| | | npm run dev |
| | | |
| | | # æå»ºæµè¯ç¯å¢ yarn build:stage |
| | | # æå»ºç产ç¯å¢ yarn build:prod |
| | | # å端访é®å°å http://localhost:80 |
| | | ``` |
| | | |
| | | ## å端æ¹é |
| | | |
| | | åèå端代ç å
`ruoyi-gen/resources/vm/vue/v3/readme.txt` 说æ |
| | | |
| | | ## å
ç½®åè½ |
| | | |
| | | 1. ç§æ·ç®¡çï¼é
置系ç»ç§æ·ï¼æ¯æ SaaS åºæ¯ä¸çå¤ç§æ·åè½ã |
| | | 2. ç¨æ·ç®¡çï¼ç¨æ·æ¯ç³»ç»æä½è
ï¼è¯¥åè½ä¸»è¦å®æç³»ç»ç¨æ·é
ç½®ã |
| | | 3. é¨é¨ç®¡çï¼é
置系ç»ç»ç»æºæï¼å
¬å¸ãé¨é¨ãå°ç»ï¼ï¼æ ç»æå±ç°æ¯ææ°æ®æéã |
| | | 4. å²ä½ç®¡çï¼é
置系ç»ç¨æ·æå±æ
ä»»èå¡ã |
| | | 5. èå管çï¼é
置系ç»èåï¼æä½æéï¼æé®æéæ è¯çã |
| | | 6. è§è²ç®¡çï¼è§è²èåæéåé
ã设置è§è²ææºæè¿è¡æ°æ®èå´æéååã |
| | | 7. åå
¸ç®¡çï¼å¯¹ç³»ç»ä¸ç»å¸¸ä½¿ç¨çä¸äºè¾ä¸ºåºå®çæ°æ®è¿è¡ç»´æ¤ã |
| | | 8. åæ°ç®¡çï¼å¯¹ç³»ç»å¨æé
置常ç¨åæ°ã |
| | | 9. éç¥å
¬åï¼ç³»ç»éç¥å
¬åä¿¡æ¯åå¸ç»´æ¤ã |
| | | 10. æä½æ¥å¿ï¼ç³»ç»æ£å¸¸æä½æ¥å¿è®°å½åæ¥è¯¢ï¼ç³»ç»å¼å¸¸ä¿¡æ¯æ¥å¿è®°å½åæ¥è¯¢ã |
| | | 11. ç»å½æ¥å¿ï¼ç³»ç»ç»å½æ¥å¿è®°å½æ¥è¯¢å
å«ç»å½å¼å¸¸ã |
| | | 12. å¨çº¿ç¨æ·ï¼å½åç³»ç»ä¸æ´»è·ç¨æ·ç¶æçæ§ã |
| | | 13. 宿¶ä»»å¡ï¼å¨çº¿ï¼æ·»å ãä¿®æ¹ãå é¤)ä»»å¡è°åº¦å
嫿§è¡ç»ææ¥å¿ã |
| | | 14. 代ç çæï¼åå端代ç ççæï¼javaãhtmlãxmlãsqlï¼æ¯æ CRUD ä¸è½½ ã |
| | | 15. ç³»ç»æ¥å£ï¼æ ¹æ®ä¸å¡ä»£ç èªå¨çæç¸å
³ç api æ¥å£ææ¡£ã |
| | | 16. æå¡çæ§ï¼çè§å½åç³»ç» CPUãå
åãç£çãå æ çç¸å
³ä¿¡æ¯ã |
| | | 17. ç¼åçæ§ï¼å¯¹ç³»ç»çç¼åä¿¡æ¯æ¥è¯¢ï¼å½ä»¤ç»è®¡çã |
| | | 18. å¨çº¿æå»ºå¨ï¼æå¨è¡¨åå
ç´ çæç¸åºç HTML 代ç ã |
| | | |
| | | ## æ¼ç¤ºå¾ |
| | | |
| | | <table> |
| | | <tr> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td> |
| | | </tr> |
| | | <tr> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td> |
| | | </tr> |
| | | <tr> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td> |
| | | </tr> |
| | | <tr> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td> |
| | | </tr> |
| | | <tr> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td> |
| | | </tr> |
| | | <tr> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td> |
| | | </tr> |
| | | <tr> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td> |
| | | </tr> |
| | | <tr> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td> |
| | | <td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td> |
| | | </tr> |
| | | </table> |
| | | | | | |
| | | |--------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------| |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | | |  |  | |
| | |
| | | module.exports = { |
| | | extends: ['@commitlint/config-conventional'], |
| | | rules: { |
| | | 'type-enum': [ |
| | | 2, |
| | | 'always', |
| | | [ |
| | | 'feat', // æ°åè½ feature |
| | | 'fix', // ä¿®å¤ bug |
| | | 'docs', // ææ¡£æ³¨é |
| | | 'style', // ä»£ç æ ¼å¼ |
| | | 'refactor', // éæ |
| | | 'perf', // æ§è½ä¼å |
| | | 'test', // å¢å æµè¯ |
| | | 'chore', // æå»ºè¿ç¨æè¾
å©å·¥å
·çåå¨ |
| | | 'revert', // åé |
| | | 'build' // æå
|
| | | ] |
| | | ], |
| | | 'subject-case': [0] |
| | | } |
| | | extends: ['@commitlint/config-conventional'], |
| | | rules: { |
| | | 'type-enum': [ |
| | | 2, |
| | | 'always', |
| | | [ |
| | | 'feat', // æ°åè½ feature |
| | | 'fix', // ä¿®å¤ bug |
| | | 'docs', // ææ¡£æ³¨é |
| | | 'style', // ä»£ç æ ¼å¼ |
| | | 'refactor', // éæ |
| | | 'perf', // æ§è½ä¼å |
| | | 'test', // å¢å æµè¯ |
| | | 'chore', // æå»ºè¿ç¨æè¾
å©å·¥å
·çåå¨ |
| | | 'revert', // åé |
| | | 'build' // æå
|
| | | ] |
| | | ], |
| | | 'subject-case': [0] |
| | | } |
| | | }; |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="zh-CN"> |
| | | <head> |
| | | <meta charset="UTF-8" /> |
| | | <title>请å级æ¨çæµè§å¨</title> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" /> |
| | | <meta name="renderer" content="webkit" /> |
| | | <base target="_blank" /> |
| | | <style type="text/css"> |
| | | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0} |
| | | a{text-decoration:none;color:#0072c6;}a:hover{text-decoration:none;color:#004d8c;} |
| | | body{width:960px;margin:0 auto;padding:10px;font-size:14px;line-height:24px;color:#454545;font-family:'Microsoft YaHei UI','Microsoft YaHei',DengXian,SimSun,'Segoe UI',Tahoma,Helvetica,sans-serif;overflow-y:scroll} |
| | | h1{font-size:40px;line-height:80px;font-weight:100;margin-bottom:10px;} |
| | | h2{font-size:20px;line-height:25px;font-weight:100;margin:10px 0;} |
| | | em{color:red} |
| | | p{margin-bottom:10px;} |
| | | hr{margin:20px 0;border:0;border-top:1px solid #dadada} |
| | | span{display:block;font-size:12px;line-height:12px;} |
| | | .clean{clear:both;} |
| | | .browser{padding:10px 10px;} |
| | | .browser li{width:auto;padding:0 80px;margin-top:30px;height:34px;line-height:22px;float:left;list-style:none;background:url(data:image/png;base64,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) no-repeat;padding-left:40px} |
| | | .browser .browser-firefox{background-position:0 -34px} |
| | | .browser .browser-ie{background-position:0 -68px;margin-left:0px} |
| | | .browser .browser-360{background-position:0 -170px;margin-left: -27px} |
| | | </style> |
| | | </head> |
| | | <body style="margin-top:50px"> |
| | | <h1>请å级æ¨çæµè§å¨ï¼ä»¥ä¾¿æä»¬æ´å¥½çä¸ºæ¨æä¾æå¡ï¼</h1> |
| | | <p>æ¨æ£å¨ä½¿ç¨ Internet Explorer çæ©æçæ¬ï¼IE11以ä¸çæ¬æä½¿ç¨è¯¥å
æ ¸çæµè§å¨ï¼ãè¿æå³çå¨å级æµè§å¨åï¼æ¨å°æ æ³è®¿é®æ¤ç½ç«ã</p> |
| | | <hr /> |
| | | <h2>请注æï¼å¾®è½¯å
¬å¸å¯¹Windows XP å Internet Explorer æ©æçæ¬çæ¯æå·²ç»ç»æ</h2> |
| | | <p> |
| | | èª 2016 å¹´ 1 æ 12 æ¥èµ·ï¼Microsoft ä¸å为 IE 11 |
| | | 以ä¸çæ¬æä¾ç¸åºæ¯æåæ´æ°ã没æå
³é®çæµè§å¨å®å
¨æ´æ°ï¼æ¨ççµèå¯è½æåæå®³ç
æ¯ãé´è°è½¯ä»¶åå
¶ä»æ¶æè½¯ä»¶çæ»å»ï¼å®ä»¬å¯ä»¥çªåææå®³æ¨çä¸å¡æ°æ®åä¿¡æ¯ã请åé
|
| | | <a href="https://www.microsoft.com/zh-cn/WindowsForBusiness/End-of-IE-support" |
| | | >微软对 Internet Explorer æ©æçæ¬çæ¯æå°äº 2016 å¹´ 1 æ 12 æ¥ç»æç说æ</a |
| | | > |
| | | ã |
| | | </p> |
| | | <hr /> |
| | | <h2>æ¨å¯ä»¥éæ©æ´å
è¿çæµè§å¨</h2> |
| | | <p>æ¨è使ç¨ä»¥ä¸æµè§å¨çææ°çæ¬ã妿æ¨ççµèå·²æä»¥ä¸æµè§å¨çææ°çæ¬åç´æ¥ä½¿ç¨è¯¥æµè§å¨è®¿é®å³å¯ã</p> |
| | | <ul class="browser"> |
| | | <li class="browser-chrome"> |
| | | <a href="https://www.google.cn/chrome/browser/desktop/index.html?hl=zh-CN&standalone=1"> è°·ææµè§å¨<span>Google Chrome</span></a> |
| | | </li> |
| | | <li class="browser-firefox"> |
| | | <a href="https://www.mozilla.org/zh-CN/firefox/new/"> ç«çæµè§å¨<span>Mozilla Firefox</span></a> |
| | | </li> |
| | | <li class="browser-ie"> |
| | | <a href="https://windows.microsoft.com/zh-cn/internet-explorer/download-ie"> IE 11 æµè§å¨<span>Internet Explorer</span></a> |
| | | </li> |
| | | <li class="browser-360"> |
| | | <a href="http://se.360.cn/"> 360å®å
¨æµè§å¨<span>360 Chrome</span></a> |
| | | </li> |
| | | <div class="clean"></div> |
| | | </ul> |
| | | <hr /> |
| | | </body> |
| | | <head> |
| | | <meta charset="UTF-8" /> |
| | | <title>请å级æ¨çæµè§å¨</title> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" /> |
| | | <meta name="renderer" content="webkit" /> |
| | | <base target="_blank" /> |
| | | <style type="text/css"> |
| | | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0} |
| | | a{text-decoration:none;color:#0072c6;}a:hover{text-decoration:none;color:#004d8c;} |
| | | body{width:960px;margin:0 auto;padding:10px;font-size:14px;line-height:24px;color:#454545;font-family:'Microsoft YaHei UI','Microsoft YaHei',DengXian,SimSun,'Segoe UI',Tahoma,Helvetica,sans-serif;overflow-y:scroll} |
| | | h1{font-size:40px;line-height:80px;font-weight:100;margin-bottom:10px;} |
| | | h2{font-size:20px;line-height:25px;font-weight:100;margin:10px 0;} |
| | | em{color:red} |
| | | p{margin-bottom:10px;} |
| | | hr{margin:20px 0;border:0;border-top:1px solid #dadada} |
| | | span{display:block;font-size:12px;line-height:12px;} |
| | | .clean{clear:both;} |
| | | .browser{padding:10px 10px;} |
| | | .browser li{width:auto;padding:0 80px;margin-top:30px;height:34px;line-height:22px;float:left;list-style:none;background:url(data:image/png;base64,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) no-repeat;padding-left:40px} |
| | | .browser .browser-firefox{background-position:0 -34px} |
| | | .browser .browser-ie{background-position:0 -68px;margin-left:0px} |
| | | .browser .browser-360{background-position:0 -170px;margin-left: -27px} |
| | | </style> |
| | | </head> |
| | | <body style="margin-top:50px"> |
| | | <h1>请å级æ¨çæµè§å¨ï¼ä»¥ä¾¿æä»¬æ´å¥½çä¸ºæ¨æä¾æå¡ï¼</h1> |
| | | <p>æ¨æ£å¨ä½¿ç¨ Internet Explorer çæ©æçæ¬ï¼IE11以ä¸çæ¬æä½¿ç¨è¯¥å
æ ¸çæµè§å¨ï¼ãè¿æå³çå¨å级æµè§å¨åï¼æ¨å°æ æ³è®¿é®æ¤ç½ç«ã</p> |
| | | <hr /> |
| | | <h2>请注æï¼å¾®è½¯å
¬å¸å¯¹Windows XP å Internet Explorer æ©æçæ¬çæ¯æå·²ç»ç»æ</h2> |
| | | <p> |
| | | èª 2016 å¹´ 1 æ 12 æ¥èµ·ï¼Microsoft ä¸å为 IE 11 |
| | | 以ä¸çæ¬æä¾ç¸åºæ¯æåæ´æ°ã没æå
³é®çæµè§å¨å®å
¨æ´æ°ï¼æ¨ççµèå¯è½æåæå®³ç
æ¯ãé´è°è½¯ä»¶åå
¶ä»æ¶æè½¯ä»¶çæ»å»ï¼å®ä»¬å¯ä»¥çªåææå®³æ¨çä¸å¡æ°æ®åä¿¡æ¯ã请åé
|
| | | <a href="https://www.microsoft.com/zh-cn/WindowsForBusiness/End-of-IE-support" |
| | | >微软对 Internet Explorer æ©æçæ¬çæ¯æå°äº 2016 å¹´ 1 æ 12 æ¥ç»æç说æ</a |
| | | > |
| | | ã |
| | | </p> |
| | | <hr /> |
| | | <h2>æ¨å¯ä»¥éæ©æ´å
è¿çæµè§å¨</h2> |
| | | <p>æ¨è使ç¨ä»¥ä¸æµè§å¨çææ°çæ¬ã妿æ¨ççµèå·²æä»¥ä¸æµè§å¨çææ°çæ¬åç´æ¥ä½¿ç¨è¯¥æµè§å¨è®¿é®å³å¯ã</p> |
| | | <ul class="browser"> |
| | | <li class="browser-chrome"> |
| | | <a href="https://www.google.cn/chrome/browser/desktop/index.html?hl=zh-CN&standalone=1"> è°·ææµè§å¨<span>Google Chrome</span></a> |
| | | </li> |
| | | <li class="browser-firefox"> |
| | | <a href="https://www.mozilla.org/zh-CN/firefox/new/"> ç«çæµè§å¨<span>Mozilla Firefox</span></a> |
| | | </li> |
| | | <li class="browser-ie"> |
| | | <a href="https://windows.microsoft.com/zh-cn/internet-explorer/download-ie"> IE 11 æµè§å¨<span>Internet Explorer</span></a> |
| | | </li> |
| | | <li class="browser-360"> |
| | | <a href="http://se.360.cn/"> 360å®å
¨æµè§å¨<span>360 Chrome</span></a> |
| | | </li> |
| | | <div class="clean"></div> |
| | | </ul> |
| | | <hr /> |
| | | </body> |
| | | </html> |
| | |
| | | <!DOCTYPE html> |
| | | <html> |
| | | <head> |
| | | <meta charset="utf-8" /> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> |
| | | <meta name="renderer" content="webkit" /> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> |
| | | <link rel="icon" href="/favicon.ico" /> |
| | | <title>RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»</title> |
| | | <!--[if lt IE 11 |
| | | ]><script> |
| | | window.location.href='/html/ie.html'; |
| | | </script><! |
| | | [endif]--> |
| | | <style> |
| | | html, |
| | | body, |
| | | #app { |
| | | height: 100%; |
| | | margin: 0px; |
| | | padding: 0px; |
| | | } |
| | | <head> |
| | | <meta charset="utf-8" /> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> |
| | | <meta name="renderer" content="webkit" /> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> |
| | | <link rel="icon" href="/favicon.ico" /> |
| | | <title>RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»</title> |
| | | <!--[if lt IE 11 |
| | | ]><script> |
| | | window.location.href='/html/ie.html'; |
| | | </script><! |
| | | [endif]--> |
| | | <style> |
| | | html, |
| | | body, |
| | | #app { |
| | | height: 100%; |
| | | margin: 0px; |
| | | padding: 0px; |
| | | } |
| | | |
| | | .chromeframe { |
| | | margin: 0.2em 0; |
| | | background: #ccc; |
| | | color: #000; |
| | | padding: 0.2em 0; |
| | | } |
| | | .chromeframe { |
| | | margin: 0.2em 0; |
| | | background: #ccc; |
| | | color: #000; |
| | | padding: 0.2em 0; |
| | | } |
| | | |
| | | #loader-wrapper { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | z-index: 999999; |
| | | } |
| | | #loader-wrapper { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | z-index: 999999; |
| | | } |
| | | |
| | | #loader { |
| | | display: block; |
| | | position: relative; |
| | | left: 50%; |
| | | top: 50%; |
| | | width: 150px; |
| | | height: 150px; |
| | | margin: -75px 0 0 -75px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -webkit-animation: spin 2s linear infinite; |
| | | -ms-animation: spin 2s linear infinite; |
| | | -moz-animation: spin 2s linear infinite; |
| | | -o-animation: spin 2s linear infinite; |
| | | animation: spin 2s linear infinite; |
| | | z-index: 1001; |
| | | } |
| | | #loader { |
| | | display: block; |
| | | position: relative; |
| | | left: 50%; |
| | | top: 50%; |
| | | width: 150px; |
| | | height: 150px; |
| | | margin: -75px 0 0 -75px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -webkit-animation: spin 2s linear infinite; |
| | | -ms-animation: spin 2s linear infinite; |
| | | -moz-animation: spin 2s linear infinite; |
| | | -o-animation: spin 2s linear infinite; |
| | | animation: spin 2s linear infinite; |
| | | z-index: 1001; |
| | | } |
| | | |
| | | #loader:before { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 5px; |
| | | left: 5px; |
| | | right: 5px; |
| | | bottom: 5px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -webkit-animation: spin 3s linear infinite; |
| | | -moz-animation: spin 3s linear infinite; |
| | | -o-animation: spin 3s linear infinite; |
| | | -ms-animation: spin 3s linear infinite; |
| | | animation: spin 3s linear infinite; |
| | | } |
| | | #loader:before { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 5px; |
| | | left: 5px; |
| | | right: 5px; |
| | | bottom: 5px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -webkit-animation: spin 3s linear infinite; |
| | | -moz-animation: spin 3s linear infinite; |
| | | -o-animation: spin 3s linear infinite; |
| | | -ms-animation: spin 3s linear infinite; |
| | | animation: spin 3s linear infinite; |
| | | } |
| | | |
| | | #loader:after { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 15px; |
| | | left: 15px; |
| | | right: 15px; |
| | | bottom: 15px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -moz-animation: spin 1.5s linear infinite; |
| | | -o-animation: spin 1.5s linear infinite; |
| | | -ms-animation: spin 1.5s linear infinite; |
| | | -webkit-animation: spin 1.5s linear infinite; |
| | | animation: spin 1.5s linear infinite; |
| | | } |
| | | #loader:after { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 15px; |
| | | left: 15px; |
| | | right: 15px; |
| | | bottom: 15px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -moz-animation: spin 1.5s linear infinite; |
| | | -o-animation: spin 1.5s linear infinite; |
| | | -ms-animation: spin 1.5s linear infinite; |
| | | -webkit-animation: spin 1.5s linear infinite; |
| | | animation: spin 1.5s linear infinite; |
| | | } |
| | | |
| | | |
| | | @-webkit-keyframes spin { |
| | | 0% { |
| | | -webkit-transform: rotate(0deg); |
| | | -ms-transform: rotate(0deg); |
| | | transform: rotate(0deg); |
| | | } |
| | | @-webkit-keyframes spin { |
| | | 0% { |
| | | -webkit-transform: rotate(0deg); |
| | | -ms-transform: rotate(0deg); |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 100% { |
| | | -webkit-transform: rotate(360deg); |
| | | -ms-transform: rotate(360deg); |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | 100% { |
| | | -webkit-transform: rotate(360deg); |
| | | -ms-transform: rotate(360deg); |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | @keyframes spin { |
| | | 0% { |
| | | -webkit-transform: rotate(0deg); |
| | | -ms-transform: rotate(0deg); |
| | | transform: rotate(0deg); |
| | | } |
| | | @keyframes spin { |
| | | 0% { |
| | | -webkit-transform: rotate(0deg); |
| | | -ms-transform: rotate(0deg); |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 100% { |
| | | -webkit-transform: rotate(360deg); |
| | | -ms-transform: rotate(360deg); |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | 100% { |
| | | -webkit-transform: rotate(360deg); |
| | | -ms-transform: rotate(360deg); |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | |
| | | #loader-wrapper .loader-section { |
| | | position: fixed; |
| | | top: 0; |
| | | width: 51%; |
| | | height: 100%; |
| | | background: #7171C6; |
| | | z-index: 1000; |
| | | -webkit-transform: translateX(0); |
| | | -ms-transform: translateX(0); |
| | | transform: translateX(0); |
| | | } |
| | | #loader-wrapper .loader-section { |
| | | position: fixed; |
| | | top: 0; |
| | | width: 51%; |
| | | height: 100%; |
| | | background: #7171C6; |
| | | z-index: 1000; |
| | | -webkit-transform: translateX(0); |
| | | -ms-transform: translateX(0); |
| | | transform: translateX(0); |
| | | } |
| | | |
| | | #loader-wrapper .loader-section.section-left { |
| | | left: 0; |
| | | } |
| | | #loader-wrapper .loader-section.section-left { |
| | | left: 0; |
| | | } |
| | | |
| | | #loader-wrapper .loader-section.section-right { |
| | | right: 0; |
| | | } |
| | | #loader-wrapper .loader-section.section-right { |
| | | right: 0; |
| | | } |
| | | |
| | | |
| | | .loaded #loader-wrapper .loader-section.section-left { |
| | | -webkit-transform: translateX(-100%); |
| | | -ms-transform: translateX(-100%); |
| | | transform: translateX(-100%); |
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | } |
| | | .loaded #loader-wrapper .loader-section.section-left { |
| | | -webkit-transform: translateX(-100%); |
| | | -ms-transform: translateX(-100%); |
| | | transform: translateX(-100%); |
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | } |
| | | |
| | | .loaded #loader-wrapper .loader-section.section-right { |
| | | -webkit-transform: translateX(100%); |
| | | -ms-transform: translateX(100%); |
| | | transform: translateX(100%); |
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | } |
| | | .loaded #loader-wrapper .loader-section.section-right { |
| | | -webkit-transform: translateX(100%); |
| | | -ms-transform: translateX(100%); |
| | | transform: translateX(100%); |
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | } |
| | | |
| | | .loaded #loader { |
| | | opacity: 0; |
| | | -webkit-transition: all 0.3s ease-out; |
| | | transition: all 0.3s ease-out; |
| | | } |
| | | .loaded #loader { |
| | | opacity: 0; |
| | | -webkit-transition: all 0.3s ease-out; |
| | | transition: all 0.3s ease-out; |
| | | } |
| | | |
| | | .loaded #loader-wrapper { |
| | | visibility: hidden; |
| | | -webkit-transform: translateY(-100%); |
| | | -ms-transform: translateY(-100%); |
| | | transform: translateY(-100%); |
| | | -webkit-transition: all 0.3s 1s ease-out; |
| | | transition: all 0.3s 1s ease-out; |
| | | } |
| | | .loaded #loader-wrapper { |
| | | visibility: hidden; |
| | | -webkit-transform: translateY(-100%); |
| | | -ms-transform: translateY(-100%); |
| | | transform: translateY(-100%); |
| | | -webkit-transition: all 0.3s 1s ease-out; |
| | | transition: all 0.3s 1s ease-out; |
| | | } |
| | | |
| | | .no-js #loader-wrapper { |
| | | display: none; |
| | | } |
| | | .no-js #loader-wrapper { |
| | | display: none; |
| | | } |
| | | |
| | | .no-js h1 { |
| | | color: #222222; |
| | | } |
| | | .no-js h1 { |
| | | color: #222222; |
| | | } |
| | | |
| | | #loader-wrapper .load_title { |
| | | font-family: 'Open Sans'; |
| | | color: #FFF; |
| | | font-size: 19px; |
| | | width: 100%; |
| | | text-align: center; |
| | | z-index: 9999999999999; |
| | | position: absolute; |
| | | top: 60%; |
| | | opacity: 1; |
| | | line-height: 30px; |
| | | } |
| | | #loader-wrapper .load_title { |
| | | font-family: 'Open Sans'; |
| | | color: #FFF; |
| | | font-size: 19px; |
| | | width: 100%; |
| | | text-align: center; |
| | | z-index: 9999999999999; |
| | | position: absolute; |
| | | top: 60%; |
| | | opacity: 1; |
| | | line-height: 30px; |
| | | } |
| | | |
| | | #loader-wrapper .load_title span { |
| | | font-weight: normal; |
| | | font-style: italic; |
| | | font-size: 13px; |
| | | color: #FFF; |
| | | opacity: 0.5; |
| | | } |
| | | </style> |
| | | </head> |
| | | #loader-wrapper .load_title span { |
| | | font-weight: normal; |
| | | font-style: italic; |
| | | font-size: 13px; |
| | | color: #FFF; |
| | | opacity: 0.5; |
| | | } |
| | | </style> |
| | | </head> |
| | | |
| | | <body> |
| | | <div id="app"> |
| | | <div id="loader-wrapper"> |
| | | <div id="loader"></div> |
| | | <div class="loader-section section-left"></div> |
| | | <div class="loader-section section-right"></div> |
| | | <div class="load_title">æ£å¨å 载系ç»èµæºï¼è¯·èå¿çå¾
</div> |
| | | </div> |
| | | </div> |
| | | <script type="module" src="/src/main.ts"></script> |
| | | </body> |
| | | <body> |
| | | <div id="app"> |
| | | <div id="loader-wrapper"> |
| | | <div id="loader"></div> |
| | | <div class="loader-section section-left"></div> |
| | | <div class="loader-section section-right"></div> |
| | | <div class="load_title">æ£å¨å 载系ç»èµæºï¼è¯·èå¿çå¾
</div> |
| | | </div> |
| | | </div> |
| | | <script type="module" src="/src/main.ts"></script> |
| | | </body> |
| | | </html> |
| | |
| | | { |
| | | "name": "ruoyi-vue-plus", |
| | | "version": "5.0.0-SNAPSHOT", |
| | | "description": "RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»", |
| | | "author": "LionLi", |
| | | "license": "MIT", |
| | | "scripts": { |
| | | "dev": "vite serve --mode development", |
| | | "build:prod": "vite build --mode production &&vue-tsc --noEmit", |
| | | "preview": "vite preview", |
| | | "lint": "eslint src/**/*.{ts,js,vue} --fix", |
| | | "prepare": "husky install", |
| | | "prettier": "prettier --write ." |
| | | }, |
| | | "repository": { |
| | | "type": "git", |
| | | "url": "https://gitee.com/JavaLionLi/plus-ui.git" |
| | | }, |
| | | "dependencies": { |
| | | "@element-plus/icons-vue": "2.1.0", |
| | | "@vueup/vue-quill": "1.1.0", |
| | | "@vueuse/core": "9.5.0", |
| | | "animate.css": "4.1.1", |
| | | "await-to-js": "^3.0.0", |
| | | "axios": "^1.3.4", |
| | | "echarts": "5.4.0", |
| | | "element-plus": "2.2.27", |
| | | "file-saver": "2.0.5", |
| | | "fuse.js": "6.6.2", |
| | | "js-cookie": "3.0.1", |
| | | "jsencrypt": "3.3.1", |
| | | "nprogress": "0.2.0", |
| | | "path-browserify": "1.0.1", |
| | | "path-to-regexp": "6.2.0", |
| | | "pinia": "2.0.22", |
| | | "screenfull": "6.0.0", |
| | | "vue": "3.2.45", |
| | | "vue-cropper": "1.0.3", |
| | | "vue-i18n": "9.2.2", |
| | | "vue-router": "4.1.4" |
| | | }, |
| | | "devDependencies": { |
| | | "@iconify/json": "^2.2.40", |
| | | "@intlify/unplugin-vue-i18n": "0.8.2", |
| | | "@types/file-saver": "2.0.5", |
| | | "@types/js-cookie": "3.0.3", |
| | | "@types/node": "18.14.2", |
| | | "@types/nprogress": "0.2.0", |
| | | "@types/path-browserify": "^1.0.0", |
| | | "@typescript-eslint/eslint-plugin": "5.56.0", |
| | | "@typescript-eslint/parser": "5.56.0", |
| | | "@unocss/preset-attributify": "^0.50.6", |
| | | "@unocss/preset-icons": "^0.50.6", |
| | | "@unocss/preset-uno": "^0.50.6", |
| | | "@vitejs/plugin-vue": "4.0.0", |
| | | "@vue/compiler-sfc": "3.2.45", |
| | | "autoprefixer": "10.4.14", |
| | | "eslint": "8.36.0", |
| | | "eslint-config-prettier": "8.8.0", |
| | | "eslint-plugin-prettier": "4.2.1", |
| | | "eslint-plugin-vue": "9.9.0", |
| | | "fast-glob": "^3.2.11", |
| | | "husky": "7.0.4", |
| | | "postcss": "^8.4.21", |
| | | "prettier": "2.8.6", |
| | | "sass": "1.56.1", |
| | | "typescript": "4.9.5", |
| | | "unocss": "^0.50.6", |
| | | "unplugin-auto-import": "0.13.0", |
| | | "unplugin-icons": "0.15.1", |
| | | "unplugin-vue-components": "0.23.0", |
| | | "vite": "4.1.4", |
| | | "vite-plugin-compression": "0.5.1", |
| | | "vite-plugin-svg-icons": "2.0.1", |
| | | "vite-plugin-vue-setup-extend": "0.4.0", |
| | | "vitest": "^0.29.7", |
| | | "vue-eslint-parser": "9.1.0", |
| | | "vue-tsc": "0.35.0" |
| | | } |
| | | "name": "ruoyi-vue-plus", |
| | | "version": "5.0.0-SNAPSHOT", |
| | | "description": "RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»", |
| | | "author": "LionLi", |
| | | "license": "MIT", |
| | | "scripts": { |
| | | "dev": "vite serve --mode development", |
| | | "build:prod": "vite build --mode production &&vue-tsc --noEmit", |
| | | "preview": "vite preview", |
| | | "lint": "eslint src/**/*.{ts,js,vue} --fix", |
| | | "prepare": "husky install", |
| | | "prettier": "prettier --write ." |
| | | }, |
| | | "repository": { |
| | | "type": "git", |
| | | "url": "https://gitee.com/JavaLionLi/plus-ui.git" |
| | | }, |
| | | "dependencies": { |
| | | "@element-plus/icons-vue": "2.1.0", |
| | | "@vueup/vue-quill": "1.1.0", |
| | | "@vueuse/core": "9.5.0", |
| | | "animate.css": "4.1.1", |
| | | "await-to-js": "^3.0.0", |
| | | "axios": "^1.3.4", |
| | | "echarts": "5.4.0", |
| | | "element-plus": "2.2.27", |
| | | "file-saver": "2.0.5", |
| | | "fuse.js": "6.6.2", |
| | | "js-cookie": "3.0.1", |
| | | "jsencrypt": "3.3.1", |
| | | "nprogress": "0.2.0", |
| | | "path-browserify": "1.0.1", |
| | | "path-to-regexp": "6.2.0", |
| | | "pinia": "2.0.22", |
| | | "screenfull": "6.0.0", |
| | | "vue": "3.2.45", |
| | | "vue-cropper": "1.0.3", |
| | | "vue-i18n": "9.2.2", |
| | | "vue-router": "4.1.4" |
| | | }, |
| | | "devDependencies": { |
| | | "@iconify/json": "^2.2.40", |
| | | "@intlify/unplugin-vue-i18n": "0.8.2", |
| | | "@types/file-saver": "2.0.5", |
| | | "@types/js-cookie": "3.0.3", |
| | | "@types/node": "18.14.2", |
| | | "@types/nprogress": "0.2.0", |
| | | "@types/path-browserify": "^1.0.0", |
| | | "@typescript-eslint/eslint-plugin": "5.56.0", |
| | | "@typescript-eslint/parser": "5.56.0", |
| | | "@unocss/preset-attributify": "^0.50.6", |
| | | "@unocss/preset-icons": "^0.50.6", |
| | | "@unocss/preset-uno": "^0.50.6", |
| | | "@vitejs/plugin-vue": "4.0.0", |
| | | "@vue/compiler-sfc": "3.2.45", |
| | | "autoprefixer": "10.4.14", |
| | | "eslint": "8.36.0", |
| | | "eslint-config-prettier": "8.8.0", |
| | | "eslint-plugin-prettier": "4.2.1", |
| | | "eslint-plugin-vue": "9.9.0", |
| | | "fast-glob": "^3.2.11", |
| | | "husky": "7.0.4", |
| | | "postcss": "^8.4.21", |
| | | "prettier": "2.8.6", |
| | | "sass": "1.56.1", |
| | | "typescript": "4.9.5", |
| | | "unocss": "^0.50.6", |
| | | "unplugin-auto-import": "0.13.0", |
| | | "unplugin-icons": "0.15.1", |
| | | "unplugin-vue-components": "0.23.0", |
| | | "vite": "4.1.4", |
| | | "vite-plugin-compression": "0.5.1", |
| | | "vite-plugin-svg-icons": "2.0.1", |
| | | "vite-plugin-vue-setup-extend": "0.4.0", |
| | | "vitest": "^0.29.7", |
| | | "vue-eslint-parser": "9.1.0", |
| | | "vue-tsc": "0.35.0" |
| | | } |
| | | } |
| | |
| | | <template> |
| | | <el-config-provider :locale="appStore.locale" :size="size"> |
| | | <router-view /> |
| | | </el-config-provider> |
| | | <el-config-provider :locale="appStore.locale" :size="size"> |
| | | <router-view /> |
| | | </el-config-provider> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | |
| | | 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' |
| | | 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: '' |
| | | enter: '', |
| | | leave: '' |
| | | }; |
| | | |
| | | // èåæç´¢å¨ç» |
| | | const menuSearchAnimate = { |
| | | enter: animatePrefix + 'animate__fadeIn', |
| | | leave: animatePrefix + 'animate__fadeOut' |
| | | enter: animatePrefix + 'animate__fadeIn', |
| | | leave: animatePrefix + 'animate__fadeOut' |
| | | }; |
| | | // logoå¨ç» |
| | | const logoAnimate = { |
| | | enter: animatePrefix + 'animate__fadeIn', |
| | | leave: animatePrefix + 'animate__fadeOut' |
| | | enter: animatePrefix + 'animate__fadeIn', |
| | | leave: animatePrefix + 'animate__fadeOut' |
| | | }; |
| | | |
| | | export default { |
| | | animateList, |
| | | defaultAnimate, |
| | | searchAnimate, |
| | | menuSearchAnimate, |
| | | logoAnimate |
| | | animateList, |
| | | defaultAnimate, |
| | | searchAnimate, |
| | | menuSearchAnimate, |
| | | logoAnimate |
| | | }; |
| | |
| | | |
| | | // æ¥è¯¢æµè¯å表å表 |
| | | export function listDemo(query: DemoQuery): AxiosPromise<DemoVO[]> { |
| | | return request({ |
| | | url: '/demo/demo/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/demo/demo/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // èªå®ä¹å页æ¥å£ |
| | | export function pageDemo(query: DemoQuery): AxiosPromise<DemoVO[]> { |
| | | return request({ |
| | | url: '/demo/demo/page', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/demo/demo/page', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢æµè¯åè¡¨è¯¦ç» |
| | | export function getDemo(id: string | number): AxiosPromise<DemoVO> { |
| | | return request({ |
| | | url: '/demo/demo/' + id, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/demo/demo/' + id, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢æµè¯å表 |
| | | export function addDemo(data: DemoForm) { |
| | | return request({ |
| | | url: '/demo/demo', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/demo/demo', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹æµè¯å表 |
| | | export function updateDemo(data: DemoForm) { |
| | | return request({ |
| | | url: '/demo/demo', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/demo/demo', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å 餿µè¯å表 |
| | | export function delDemo(id: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/demo/demo/' + id, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/demo/demo/' + id, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢æµè¯æ 表å表 |
| | | export function listTree(query?: DemoTreeQuery): AxiosPromise<DemoTreeVO[]> { |
| | | return request({ |
| | | url: '/demo/tree/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/demo/tree/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢æµè¯æ è¡¨è¯¦ç» |
| | | export function getTree(id: string | number): AxiosPromise<DemoTreeVO> { |
| | | return request({ |
| | | url: '/demo/tree/' + id, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/demo/tree/' + id, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢æµè¯æ 表 |
| | | export function addTree(data: DemoTreeForm) { |
| | | return request({ |
| | | url: '/demo/tree', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/demo/tree', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹æµè¯æ 表 |
| | | export function updateTree(data: DemoTreeForm) { |
| | | return request({ |
| | | url: '/demo/tree', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/demo/tree', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å 餿µè¯æ 表 |
| | | export function delTree(id: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/demo/tree/' + id, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/demo/tree/' + id, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface DemoVO extends BaseEntity { |
| | | id: number | string; |
| | | deptId: number | string; |
| | | userId: number | string; |
| | | orderNum: number; |
| | | testKey: string; |
| | | value: string; |
| | | createByName: string; |
| | | updateByName?: any; |
| | | id: number | string; |
| | | deptId: number | string; |
| | | userId: number | string; |
| | | orderNum: number; |
| | | testKey: string; |
| | | value: string; |
| | | createByName: string; |
| | | updateByName?: any; |
| | | } |
| | | |
| | | export interface DemoQuery extends PageQuery { |
| | | testKey: string; |
| | | value: string; |
| | | createTime: string; |
| | | testKey: string; |
| | | value: string; |
| | | createTime: string; |
| | | } |
| | | export interface DemoForm { |
| | | id: string | number | undefined; |
| | | deptId: string | number | undefined; |
| | | userId: string | number | undefined; |
| | | orderNum: number; |
| | | testKey: string; |
| | | value: string; |
| | | version: string; |
| | | ossConfigId: string | number | undefined; |
| | | createTime?: string; |
| | | id: string | number | undefined; |
| | | deptId: string | number | undefined; |
| | | userId: string | number | undefined; |
| | | orderNum: number; |
| | | testKey: string; |
| | | value: string; |
| | | version: string; |
| | | ossConfigId: string | number | undefined; |
| | | createTime?: string; |
| | | } |
| | | |
| | | export interface DemoTreeVO extends BaseEntity { |
| | | id: number | string; |
| | | parentId: number | string; |
| | | deptId: number | string; |
| | | userId: number | string; |
| | | treeName: string; |
| | | children?: DemoTreeVO[]; |
| | | id: number | string; |
| | | parentId: number | string; |
| | | deptId: number | string; |
| | | userId: number | string; |
| | | treeName: string; |
| | | children?: DemoTreeVO[]; |
| | | } |
| | | |
| | | export interface DemoTreeQuery { |
| | | treeName: string; |
| | | createTime: string; |
| | | treeName: string; |
| | | createTime: string; |
| | | } |
| | | |
| | | export interface DemoTreeForm { |
| | | id: string | number | undefined; |
| | | parentId: string | number | undefined; |
| | | deptId: string | number | undefined; |
| | | userId: string | number | undefined; |
| | | treeName: string; |
| | | id: string | number | undefined; |
| | | parentId: string | number | undefined; |
| | | deptId: string | number | undefined; |
| | | userId: string | number | undefined; |
| | | treeName: string; |
| | | } |
| | | |
| | | export interface DemoTreeOptionsType { |
| | | id: string | number; |
| | | treeName: string; |
| | | children?: DemoTreeOptionsType[]; |
| | | id: string | number; |
| | | treeName: string; |
| | | children?: DemoTreeOptionsType[]; |
| | | } |
| | |
| | | * @returns |
| | | */ |
| | | export function login(data: LoginData): AxiosPromise<LoginResult> { |
| | | const params = { |
| | | tenantId: data.tenantId, |
| | | username: data.username.trim(), |
| | | password: data.password, |
| | | code: data.code, |
| | | uuid: data.uuid |
| | | }; |
| | | return request({ |
| | | url: '/auth/login', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'post', |
| | | data: params |
| | | }); |
| | | const params = { |
| | | tenantId: data.tenantId, |
| | | username: data.username.trim(), |
| | | password: data.password, |
| | | code: data.code, |
| | | uuid: data.uuid |
| | | }; |
| | | return request({ |
| | | url: '/auth/login', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'post', |
| | | data: params |
| | | }); |
| | | } |
| | | |
| | | // æ³¨åæ¹æ³ |
| | | export function register(data: any) { |
| | | return request({ |
| | | url: '/auth/register', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/auth/register', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 注é |
| | | */ |
| | | export function logout() { |
| | | return request({ |
| | | url: '/auth/logout', |
| | | method: 'post' |
| | | }); |
| | | return request({ |
| | | url: '/auth/logout', |
| | | method: 'post' |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * è·åéªè¯ç |
| | | */ |
| | | export function getCodeImg(): AxiosPromise<VerifyCodeResult> { |
| | | return request({ |
| | | url: '/code', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'get', |
| | | timeout: 20000 |
| | | }); |
| | | return request({ |
| | | url: '/code', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'get', |
| | | timeout: 20000 |
| | | }); |
| | | } |
| | | |
| | | // è·åç¨æ·è¯¦ç»ä¿¡æ¯ |
| | | export function getInfo(): AxiosPromise<UserInfo> { |
| | | return request({ |
| | | url: '/system/user/getInfo', |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/user/getInfo', |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // è·åç§æ·å表 |
| | | export function getTenantList(): AxiosPromise<TenantInfo> { |
| | | return request({ |
| | | url: '/auth/tenant/list', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/auth/tenant/list', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'get' |
| | | }); |
| | | } |
| | |
| | | |
| | | // è·åè·¯ç± |
| | | export function getRouters(): AxiosPromise<RouteRecordRaw[]> { |
| | | return request({ |
| | | url: '/system/menu/getRouters', |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/menu/getRouters', |
| | | method: 'get' |
| | | }); |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢ç¼åè¯¦ç» |
| | | export function getCache(): AxiosPromise<CacheVO> { |
| | | return request({ |
| | | url: '/monitor/cache', |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/cache', |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢ç¼ååç§°å表 |
| | | export function listCacheName() { |
| | | return request({ |
| | | url: '/monitor/cache/getNames', |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/cache/getNames', |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢ç¼åé®åå表 |
| | | export function listCacheKey(cacheName: string) { |
| | | return request({ |
| | | url: '/monitor/cache/getKeys/' + cacheName, |
| | | method: 'get' |
| | | }); |
| | | 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' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ¸
çæå®åç§°ç¼å |
| | | export function clearCacheName(cacheName: string) { |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheName/' + cacheName, |
| | | method: 'delete' |
| | | }); |
| | | 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' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheKey/' + cacheName + '/' + cacheKey, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | |
| | | // æ¸
çå
¨é¨ç¼å |
| | | export function clearCacheAll() { |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheAll', |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheAll', |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface CacheVO { |
| | | commandStats: Array<{ name: string; value: string }>; |
| | | commandStats: Array<{ name: string; value: string }>; |
| | | |
| | | dbSize: number; |
| | | dbSize: number; |
| | | |
| | | info: { [key: string]: string }; |
| | | info: { [key: string]: string }; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢ç»å½æ¥å¿å表 |
| | | export function list(query: LoginInfoQuery): AxiosPromise<LoginInfoVO[]> { |
| | | return request({ |
| | | url: '/monitor/logininfor/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/monitor/logininfor/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // å é¤ç»å½æ¥å¿ |
| | | export function delLoginInfo(infoId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/monitor/logininfor/' + infoId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/logininfor/' + infoId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | |
| | | // è§£éç¨æ·ç»å½ç¶æ |
| | | export function unlockLoginInfo(userName: string | Array<string>) { |
| | | return request({ |
| | | url: '/monitor/logininfor/unlock/' + userName, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/logininfor/unlock/' + userName, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ¸
空ç»å½æ¥å¿ |
| | | export function cleanLoginInfo() { |
| | | return request({ |
| | | url: '/monitor/logininfor/clean', |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/logininfor/clean', |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | 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; |
| | | 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; |
| | | ipaddr: string; |
| | | userName: string; |
| | | status: string; |
| | | orderByColumn: string; |
| | | isAsc: string; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢å¨çº¿ç¨æ·å表 |
| | | export function list(query: OnlineQuery): AxiosPromise<OnlineVO[]> { |
| | | return request({ |
| | | url: '/monitor/online/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/monitor/online/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // 强éç¨æ· |
| | | export function forceLogout(tokenId: string) { |
| | | return request({ |
| | | url: '/monitor/online/' + tokenId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/online/' + tokenId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface OnlineQuery extends PageQuery { |
| | | ipaddr: string; |
| | | userName: string; |
| | | 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; |
| | | tokenId: string; |
| | | deptName: string; |
| | | userName: string; |
| | | ipaddr: string; |
| | | loginLocation: string; |
| | | browser: string; |
| | | os: string; |
| | | loginTime: number; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢æä½æ¥å¿å表 |
| | | export function list(query: OperLogQuery): AxiosPromise<OperLogVO[]> { |
| | | return request({ |
| | | url: '/monitor/operlog/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/monitor/operlog/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // å 餿使¥å¿ |
| | | export function delOperlog(operId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/monitor/operlog/' + operId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/operlog/' + operId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | |
| | | // æ¸
空æä½æ¥å¿ |
| | | export function cleanOperlog() { |
| | | return request({ |
| | | url: '/monitor/operlog/clean', |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/monitor/operlog/clean', |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface OperLogQuery extends PageQuery { |
| | | title: string; |
| | | operName: string; |
| | | businessType: string; |
| | | status: string; |
| | | orderByColumn: string; |
| | | isAsc: 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; |
| | | 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; |
| | | 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; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢åæ°å表 |
| | | export function listConfig(query: ConfigQuery): AxiosPromise<ConfigVO[]> { |
| | | return request({ |
| | | url: '/system/config/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/config/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢åæ°è¯¦ç» |
| | | export function getConfig(configId: string | number): AxiosPromise<ConfigVO> { |
| | | return request({ |
| | | url: '/system/config/' + configId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/config/' + configId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ ¹æ®åæ°é®åæ¥è¯¢åæ°å¼ |
| | | export function getConfigKey(configKey: string): AxiosPromise<ConfigVO> { |
| | | return request({ |
| | | url: '/system/config/configKey/' + configKey, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/config/configKey/' + configKey, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢åæ°é
ç½® |
| | | export function addConfig(data: ConfigForm) { |
| | | return request({ |
| | | url: '/system/config', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/config', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹åæ°é
ç½® |
| | | export function updateConfig(data: ConfigForm) { |
| | | return request({ |
| | | url: '/system/config', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | 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 |
| | | } |
| | | }); |
| | | return request({ |
| | | url: '/system/config/updateByKey', |
| | | method: 'put', |
| | | data: { |
| | | configKey: key, |
| | | configValue: value |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // å é¤åæ°é
ç½® |
| | | export function delConfig(configId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/config/' + configId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/config/' + configId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | |
| | | // å·æ°åæ°ç¼å |
| | | export function refreshCache() { |
| | | return request({ |
| | | url: '/system/config/refreshCache', |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/config/refreshCache', |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface ConfigVO extends BaseEntity { |
| | | configId: number | string; |
| | | configName: string; |
| | | configKey: string; |
| | | configValue: string; |
| | | configType: string; |
| | | remark: string; |
| | | 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; |
| | | 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; |
| | | configName: string; |
| | | configKey: string; |
| | | configType: string; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢é¨é¨å表 |
| | | export const listDept = (query?: DeptQuery) => { |
| | | return request({ |
| | | url: '/system/dept/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/dept/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢é¨é¨åè¡¨ï¼æé¤èç¹ï¼ |
| | | export const listDeptExcludeChild = (deptId: string | number): AxiosPromise<DeptVO[]> => { |
| | | return request({ |
| | | url: '/system/dept/list/exclude/' + deptId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/dept/list/exclude/' + deptId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢é¨é¨è¯¦ç» |
| | | export const getDept = (deptId: string | number): AxiosPromise<DeptVO> => { |
| | | return request({ |
| | | url: '/system/dept/' + deptId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/dept/' + deptId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢é¨é¨ä¸ææ ç»æ |
| | | export const treeselect = (): AxiosPromise<DeptVO[]> => { |
| | | return request({ |
| | | url: '/system/dept/treeselect', |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/dept/treeselect', |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // æ°å¢é¨é¨ |
| | | export const addDept = (data: DeptForm) => { |
| | | return request({ |
| | | url: '/system/dept', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/dept', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | // ä¿®æ¹é¨é¨ |
| | | export const updateDept = (data: DeptForm) => { |
| | | return request({ |
| | | url: '/system/dept', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/dept', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | // å é¤é¨é¨ |
| | | export const delDept = (deptId: number | string) => { |
| | | return request({ |
| | | url: '/system/dept/' + deptId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/dept/' + deptId, |
| | | method: 'delete' |
| | | }); |
| | | }; |
| | |
| | | * é¨é¨æ¥è¯¢åæ° |
| | | */ |
| | | export interface DeptQuery extends PageQuery { |
| | | deptName?: string; |
| | | status?: number; |
| | | deptName?: string; |
| | | status?: number; |
| | | } |
| | | |
| | | /** |
| | | * é¨é¨ç±»å |
| | | */ |
| | | export interface DeptVO extends BaseEntity { |
| | | id: number | string; |
| | | parentName: string; |
| | | parentId: number | string; |
| | | children: DeptVO[]; |
| | | deptId: number | string; |
| | | deptName: string; |
| | | orderNum: number; |
| | | leader: string; |
| | | phone: string; |
| | | email: string; |
| | | status: string; |
| | | delFlag: string; |
| | | ancestors: string; |
| | | menuId: string | number; |
| | | id: number | string; |
| | | parentName: string; |
| | | parentId: number | string; |
| | | children: DeptVO[]; |
| | | deptId: number | string; |
| | | deptName: string; |
| | | orderNum: number; |
| | | leader: string; |
| | | phone: string; |
| | | email: string; |
| | | status: string; |
| | | delFlag: string; |
| | | ancestors: string; |
| | | menuId: string | number; |
| | | } |
| | | |
| | | /** |
| | | * é¨é¨è¡¨åç±»å |
| | | */ |
| | | export interface DeptForm { |
| | | parentName?: string; |
| | | parentId?: number | string; |
| | | children?: DeptForm[]; |
| | | deptId?: number | string; |
| | | deptName?: string; |
| | | orderNum?: number; |
| | | leader?: string; |
| | | phone?: string; |
| | | email?: string; |
| | | status?: string; |
| | | delFlag?: string; |
| | | ancestors?: string; |
| | | parentName?: string; |
| | | parentId?: number | string; |
| | | children?: DeptForm[]; |
| | | deptId?: number | string; |
| | | deptName?: string; |
| | | orderNum?: number; |
| | | leader?: string; |
| | | phone?: string; |
| | | email?: string; |
| | | status?: string; |
| | | delFlag?: string; |
| | | ancestors?: string; |
| | | } |
| | |
| | | import { DictDataForm, DictDataQuery, DictDataVO } from './types'; |
| | | // æ ¹æ®åå
¸ç±»åæ¥è¯¢åå
¸æ°æ®ä¿¡æ¯ |
| | | export function getDicts(dictType: string): AxiosPromise<DictDataVO[]> { |
| | | return request({ |
| | | url: '/system/dict/data/type/' + dictType, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/data/type/' + dictType, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢åå
¸æ°æ®å表 |
| | | export function listData(query: DictDataQuery): AxiosPromise<DictDataVO[]> { |
| | | return request({ |
| | | url: '/system/dict/data/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/data/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢åå
¸æ°æ®è¯¦ç» |
| | | export function getData(dictCode: string | number): AxiosPromise<DictDataVO> { |
| | | return request({ |
| | | url: '/system/dict/data/' + dictCode, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/data/' + dictCode, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢åå
¸æ°æ® |
| | | export function addData(data: DictDataForm) { |
| | | return request({ |
| | | url: '/system/dict/data', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | 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 |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/data', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å é¤åå
¸æ°æ® |
| | | export function delData(dictCode: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/dict/data/' + dictCode, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/data/' + dictCode, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface DictDataQuery extends PageQuery { |
| | | dictName: string; |
| | | dictType: string; |
| | | status: string; |
| | | dictLabel: string; |
| | | dictName: string; |
| | | dictType: string; |
| | | status: string; |
| | | dictLabel: string; |
| | | } |
| | | |
| | | export interface DictDataVO extends BaseEntity { |
| | | dictCode: string; |
| | | dictLabel: string; |
| | | dictValue: string; |
| | | cssClass: string; |
| | | listClass: ElTagType; |
| | | dictSort: number; |
| | | status: string; |
| | | remark: string; |
| | | dictCode: string; |
| | | dictLabel: string; |
| | | dictValue: string; |
| | | cssClass: string; |
| | | listClass: ElTagType; |
| | | dictSort: number; |
| | | status: string; |
| | | remark: string; |
| | | } |
| | | |
| | | export interface DictDataForm { |
| | | dictType?: string; |
| | | dictCode: string | undefined; |
| | | dictLabel: string; |
| | | dictValue: string; |
| | | cssClass: string; |
| | | listClass: ElTagType; |
| | | dictSort: number; |
| | | status: string; |
| | | remark: string; |
| | | dictType?: string; |
| | | dictCode: string | undefined; |
| | | dictLabel: string; |
| | | dictValue: string; |
| | | cssClass: string; |
| | | listClass: ElTagType; |
| | | dictSort: number; |
| | | status: string; |
| | | remark: string; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢åå
¸ç±»åå表 |
| | | export function listType(query: DictTypeQuery): AxiosPromise<DictTypeVO[]> { |
| | | return request({ |
| | | url: '/system/dict/type/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/type/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢åå
¸ç±»åè¯¦ç» |
| | | export function getType(dictId: number | string): AxiosPromise<DictTypeVO> { |
| | | return request({ |
| | | url: '/system/dict/type/' + dictId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/type/' + dictId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢åå
¸ç±»å |
| | | export function addType(data: DictTypeForm) { |
| | | return request({ |
| | | url: '/system/dict/type', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | 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 |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/type', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å é¤åå
¸ç±»å |
| | | export function delType(dictId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/dict/type/' + dictId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/type/' + dictId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | |
| | | // å·æ°åå
¸ç¼å |
| | | export function refreshCache() { |
| | | return request({ |
| | | url: '/system/dict/type/refreshCache', |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/type/refreshCache', |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | |
| | | // è·ååå
¸éæ©æ¡å表 |
| | | export function optionselect(): AxiosPromise<DictTypeVO[]> { |
| | | return request({ |
| | | url: '/system/dict/type/optionselect', |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/dict/type/optionselect', |
| | | method: 'get' |
| | | }); |
| | | } |
| | |
| | | export interface DictTypeVO extends BaseEntity { |
| | | dictId: number | string; |
| | | dictName: string; |
| | | dictType: string; |
| | | status: string; |
| | | remark: string; |
| | | dictId: number | string; |
| | | dictName: string; |
| | | dictType: string; |
| | | status: string; |
| | | remark: string; |
| | | } |
| | | |
| | | export interface DictTypeForm { |
| | | dictId: number | string | undefined; |
| | | dictName: string; |
| | | dictType: string; |
| | | status: string; |
| | | remark: string; |
| | | dictId: number | string | undefined; |
| | | dictName: string; |
| | | dictType: string; |
| | | status: string; |
| | | remark: string; |
| | | } |
| | | |
| | | export interface DictTypeQuery extends PageQuery { |
| | | dictName: string; |
| | | dictType: string; |
| | | status: string; |
| | | dictName: string; |
| | | dictType: string; |
| | | status: string; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢èåå表 |
| | | export const listMenu = (query?: MenuQuery): AxiosPromise<MenuVO[]> => { |
| | | return request({ |
| | | url: '/system/menu/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/menu/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢èåè¯¦ç» |
| | | export const getMenu = (menuId: string | number): AxiosPromise<MenuVO> => { |
| | | return request({ |
| | | url: '/system/menu/' + menuId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/menu/' + menuId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢èå䏿æ ç»æ |
| | | export const treeselect = (): AxiosPromise<MenuTreeOption[]> => { |
| | | return request({ |
| | | url: '/system/menu/treeselect', |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/menu/treeselect', |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // æ ¹æ®è§è²IDæ¥è¯¢èå䏿æ ç»æ |
| | | export const roleMenuTreeselect = (roleId: string | number): AxiosPromise<RoleMenuTree> => { |
| | | return request({ |
| | | url: '/system/menu/roleMenuTreeselect/' + roleId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/menu/roleMenuTreeselect/' + roleId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // æ ¹æ®è§è²IDæ¥è¯¢èå䏿æ ç»æ |
| | | export const tenantPackageMenuTreeselect = (packageId: string | number): AxiosPromise<RoleMenuTree> => { |
| | | return request({ |
| | | url: '/system/menu/tenantPackageMenuTreeselect/' + packageId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/menu/tenantPackageMenuTreeselect/' + packageId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // æ°å¢èå |
| | | export const addMenu = (data: MenuForm) => { |
| | | return request({ |
| | | url: '/system/menu', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/menu', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | // ä¿®æ¹èå |
| | | export const updateMenu = (data: MenuForm) => { |
| | | return request({ |
| | | url: '/system/menu', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/menu', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | // å é¤èå |
| | | export const delMenu = (menuId: string | number) => { |
| | | return request({ |
| | | url: '/system/menu/' + menuId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/menu/' + menuId, |
| | | method: 'delete' |
| | | }); |
| | | }; |
| | |
| | | * èåæ å½¢ç»æç±»å |
| | | */ |
| | | export interface MenuTreeOption { |
| | | id: string | number; |
| | | label: string; |
| | | parentId: string | number; |
| | | weight: number; |
| | | children?: MenuTreeOption[]; |
| | | id: string | number; |
| | | label: string; |
| | | parentId: string | number; |
| | | weight: number; |
| | | children?: MenuTreeOption[]; |
| | | } |
| | | |
| | | export interface RoleMenuTree { |
| | | menus: MenuTreeOption[]; |
| | | checkedKeys: string[]; |
| | | menus: MenuTreeOption[]; |
| | | checkedKeys: string[]; |
| | | } |
| | | |
| | | /** |
| | | * èåæ¥è¯¢åæ°ç±»å |
| | | */ |
| | | export interface MenuQuery { |
| | | keywords?: string; |
| | | menuName?: string; |
| | | status?: string; |
| | | 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; |
| | | 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; |
| | | 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; |
| | | } |
| | |
| | | import { AxiosPromise } from 'axios'; |
| | | // æ¥è¯¢å
¬åå表 |
| | | export function listNotice(query: NoticeQuery): AxiosPromise<NoticeVO[]> { |
| | | return request({ |
| | | url: '/system/notice/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/notice/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢å
¬åè¯¦ç» |
| | | export function getNotice(noticeId: string | number): AxiosPromise<NoticeVO> { |
| | | return request({ |
| | | url: '/system/notice/' + noticeId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/notice/' + noticeId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢å
Œ |
| | | export function addNotice(data: NoticeForm) { |
| | | return request({ |
| | | url: '/system/notice', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/notice', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹å
Œ |
| | | export function updateNotice(data: NoticeForm) { |
| | | return request({ |
| | | url: '/system/notice', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/notice', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å é¤å
Œ |
| | | export function delNotice(noticeId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/notice/' + noticeId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/notice/' + noticeId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface NoticeVO extends BaseEntity { |
| | | noticeId: number; |
| | | noticeTitle: string; |
| | | noticeType: string; |
| | | noticeContent: string; |
| | | status: string; |
| | | remark: string; |
| | | createByName: string; |
| | | 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; |
| | | 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; |
| | | noticeId: number | string | undefined; |
| | | noticeTitle: string; |
| | | noticeType: string; |
| | | noticeContent: string; |
| | | status: string; |
| | | remark: string; |
| | | createByName: string; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢OSS对象åå¨å表 |
| | | export function listOss(query: OssQuery): AxiosPromise<OssVO[]> { |
| | | return request({ |
| | | url: '/system/oss/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/oss/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢OSS对象åºäºid串 |
| | | export function listByIds(ossId: string | number): AxiosPromise<OssVO[]> { |
| | | return request({ |
| | | url: '/system/oss/listByIds/' + ossId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/oss/listByIds/' + ossId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // å é¤OSS对象åå¨ |
| | | export function delOss(ossId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/oss/' + ossId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/oss/' + ossId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface OssVO extends BaseEntity { |
| | | ossId: string | number; |
| | | fileName: string; |
| | | originalName: string; |
| | | fileSuffix: string; |
| | | url: string; |
| | | createByName: string; |
| | | service: string; |
| | | 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; |
| | | fileName: string; |
| | | originalName: string; |
| | | fileSuffix: string; |
| | | createTime: string; |
| | | service: string; |
| | | orderByColumn: string; |
| | | isAsc: string; |
| | | } |
| | | export interface OssForm { |
| | | file: undefined | string; |
| | | file: undefined | string; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢å¯¹è±¡åå¨é
ç½®å表 |
| | | export function listOssConfig(query: OssConfigQuery): AxiosPromise<OssConfigVO[]> { |
| | | return request({ |
| | | url: '/system/oss/config/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/oss/config/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢å¯¹è±¡åå¨é
ç½®è¯¦ç» |
| | | export function getOssConfig(ossConfigId: string | number): AxiosPromise<OssConfigVO> { |
| | | return request({ |
| | | url: '/system/oss/config/' + ossConfigId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/oss/config/' + ossConfigId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢å¯¹è±¡åå¨é
ç½® |
| | | export function addOssConfig(data: OssConfigForm) { |
| | | return request({ |
| | | url: '/system/oss/config', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/oss/config', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹å¯¹è±¡åå¨é
ç½® |
| | | export function updateOssConfig(data: OssConfigForm) { |
| | | return request({ |
| | | url: '/system/oss/config', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/oss/config', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å é¤å¯¹è±¡åå¨é
ç½® |
| | | export function delOssConfig(ossConfigId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/oss/config/' + ossConfigId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/oss/config/' + ossConfigId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | |
| | | // 对象åå¨ç¶æä¿®æ¹ |
| | | export function changeOssConfigStatus(ossConfigId: string | number, status: string, configKey: string) { |
| | | const data = { |
| | | ossConfigId, |
| | | status, |
| | | configKey |
| | | }; |
| | | return request({ |
| | | url: '/system/oss/config/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | const data = { |
| | | ossConfigId, |
| | | status, |
| | | configKey |
| | | }; |
| | | return request({ |
| | | url: '/system/oss/config/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | |
| | | 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; |
| | | 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; |
| | | 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; |
| | | 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; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢å²ä½å表 |
| | | export function listPost(query: PostQuery): AxiosPromise<PostVO[]> { |
| | | return request({ |
| | | url: '/system/post/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/post/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢å²ä½è¯¦ç» |
| | | export function getPost(postId: string | number): AxiosPromise<PostVO> { |
| | | return request({ |
| | | url: '/system/post/' + postId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/post/' + postId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢å²ä½ |
| | | export function addPost(data: PostForm) { |
| | | return request({ |
| | | url: '/system/post', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/post', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹å²ä½ |
| | | export function updatePost(data: PostForm) { |
| | | return request({ |
| | | url: '/system/post', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | 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' |
| | | }); |
| | | return request({ |
| | | url: '/system/post/' + postId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface PostVO extends BaseEntity { |
| | | postId: number | string; |
| | | postCode: string; |
| | | postName: string; |
| | | postSort: number; |
| | | status: string; |
| | | remark: string; |
| | | postId: number | string; |
| | | postCode: string; |
| | | postName: string; |
| | | postSort: number; |
| | | status: string; |
| | | remark: string; |
| | | } |
| | | |
| | | export interface PostForm { |
| | | postId: number | string | undefined; |
| | | postCode: string; |
| | | postName: string; |
| | | postSort: number; |
| | | status: string; |
| | | remark: string; |
| | | postId: number | string | undefined; |
| | | postCode: string; |
| | | postName: string; |
| | | postSort: number; |
| | | status: string; |
| | | remark: string; |
| | | } |
| | | |
| | | export interface PostQuery extends PageQuery { |
| | | postCode: string; |
| | | postName: string; |
| | | status: string; |
| | | postCode: string; |
| | | postName: string; |
| | | status: string; |
| | | } |
| | |
| | | import request from '@/utils/request'; |
| | | |
| | | export const listRole = (query: RoleQuery): AxiosPromise<RoleVO[]> => { |
| | | return request({ |
| | | url: '/system/role/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/role/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢è§è²è¯¦ç» |
| | | */ |
| | | export const getRole = (roleId: string | number): AxiosPromise<RoleVO> => { |
| | | return request({ |
| | | url: '/system/role/' + roleId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/role/' + roleId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ°å¢è§è² |
| | | */ |
| | | export const addRole = (data: any) => { |
| | | return request({ |
| | | url: '/system/role', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | 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 |
| | | }); |
| | | return request({ |
| | | url: '/system/role', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * è§è²æ°æ®æé |
| | | */ |
| | | export const dataScope = (data: any) => { |
| | | return request({ |
| | | url: '/system/role/dataScope', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | 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 |
| | | }); |
| | | const data = { |
| | | roleId, |
| | | status |
| | | }; |
| | | return request({ |
| | | url: '/system/role/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * å é¤è§è² |
| | | */ |
| | | export const delRole = (roleId: Array<string | number> | string | number) => { |
| | | return request({ |
| | | url: '/system/role/' + roleId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/role/' + roleId, |
| | | method: 'delete' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢è§è²å·²ææç¨æ·å表 |
| | | */ |
| | | export const allocatedUserList = (query: UserQuery): AxiosPromise<UserVO[]> => { |
| | | return request({ |
| | | url: '/system/role/authUser/allocatedList', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/role/authUser/allocatedList', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢è§è²æªææç¨æ·å表 |
| | | */ |
| | | export const unallocatedUserList = (query: UserQuery): AxiosPromise<UserVO[]> => { |
| | | return request({ |
| | | url: '/system/role/authUser/unallocatedList', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | 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 |
| | | }); |
| | | 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 |
| | | }); |
| | | 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 |
| | | }); |
| | | return request({ |
| | | url: '/system/role/authUser/selectAll', |
| | | method: 'put', |
| | | params: data |
| | | }); |
| | | }; |
| | | // æ ¹æ®è§è²IDæ¥è¯¢é¨é¨æ ç»æ |
| | | export const deptTreeSelect = (roleId: string | number): AxiosPromise<RoleDeptTree> => { |
| | | return request({ |
| | | url: '/system/role/deptTree/' + roleId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/role/deptTree/' + roleId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | |
| | | * èåæ å½¢ç»æç±»å |
| | | */ |
| | | export interface DeptTreeOption { |
| | | id: string; |
| | | label: string; |
| | | parentId: string; |
| | | weight: number; |
| | | children?: DeptTreeOption[]; |
| | | id: string; |
| | | label: string; |
| | | parentId: string; |
| | | weight: number; |
| | | children?: DeptTreeOption[]; |
| | | } |
| | | |
| | | export interface RoleDeptTree { |
| | | checkedKeys: string[]; |
| | | depts: DeptTreeOption[]; |
| | | 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<string | number>; |
| | | deptIds?: Array<string | number>; |
| | | admin: boolean; |
| | | 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<string | number>; |
| | | deptIds?: Array<string | number>; |
| | | admin: boolean; |
| | | } |
| | | |
| | | export interface RoleQuery extends PageQuery { |
| | | roleName: string; |
| | | roleKey: string; |
| | | status: string; |
| | | roleName: string; |
| | | roleKey: string; |
| | | status: string; |
| | | } |
| | | |
| | | export interface RoleForm { |
| | | roleName: string; |
| | | roleKey: string; |
| | | roleSort: number; |
| | | status: string; |
| | | menuCheckStrictly: boolean; |
| | | deptCheckStrictly: boolean; |
| | | remark: string; |
| | | dataScope?: number; |
| | | roleId: string | undefined; |
| | | menuIds: Array<string | number>; |
| | | deptIds: Array<string | number>; |
| | | roleName: string; |
| | | roleKey: string; |
| | | roleSort: number; |
| | | status: string; |
| | | menuCheckStrictly: boolean; |
| | | deptCheckStrictly: boolean; |
| | | remark: string; |
| | | dataScope?: number; |
| | | roleId: string | undefined; |
| | | menuIds: Array<string | number>; |
| | | deptIds: Array<string | number>; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢ç§æ·å表 |
| | | export function listTenant(query: TenantQuery): AxiosPromise<TenantVO[]> { |
| | | return request({ |
| | | url: '/system/tenant/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/tenant/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢ç§æ·è¯¦ç» |
| | | export function getTenant(id: string | number): AxiosPromise<TenantVO> { |
| | | return request({ |
| | | url: '/system/tenant/' + id, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/tenant/' + id, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ç§æ· |
| | | export function addTenant(data: TenantForm) { |
| | | return request({ |
| | | url: '/system/tenant', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/tenant', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // ä¿®æ¹ç§æ· |
| | | export function updateTenant(data: TenantForm) { |
| | | return request({ |
| | | url: '/system/tenant', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | 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 |
| | | }); |
| | | const data = { |
| | | id, |
| | | tenantId, |
| | | status |
| | | }; |
| | | return request({ |
| | | url: '/system/tenant/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å é¤ç§æ· |
| | | export function delTenant(id: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/tenant/' + id, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/tenant/' + id, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | |
| | | // å¨æåæ¢ç§æ· |
| | | export function dynamicTenant(tenantId: string | number) { |
| | | return request({ |
| | | url: '/system/tenant/dynamic/' + tenantId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/tenant/dynamic/' + tenantId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ¸
é¤å¨æç§æ· |
| | | export function dynamicClear() { |
| | | return request({ |
| | | url: '/system/tenant/dynamic/clear', |
| | | method: 'get' |
| | | }); |
| | | 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 |
| | | }); |
| | | const data = { |
| | | tenantId, |
| | | packageId |
| | | }; |
| | | return request({ |
| | | url: '/system/tenant/syncTenantPackage', |
| | | method: 'get', |
| | | params: data |
| | | }); |
| | | } |
| | |
| | | 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; |
| | | 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; |
| | | tenantId: string | number; |
| | | |
| | | contactUserName: string; |
| | | contactUserName: string; |
| | | |
| | | contactPhone: string; |
| | | contactPhone: string; |
| | | |
| | | companyName: 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; |
| | | 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; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢ç§æ·å¥é¤å表 |
| | | export function listTenantPackage(query?: TenantPkgQuery): AxiosPromise<TenantPkgVO[]> { |
| | | return request({ |
| | | url: '/system/tenant/package/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/tenant/package/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢ç§æ·å¥é¤è¯¦ç» |
| | | export function getTenantPackage(packageId: string | number): AxiosPromise<TenantPkgVO> { |
| | | return request({ |
| | | url: '/system/tenant/package/' + packageId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/tenant/package/' + packageId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢ç§æ·å¥é¤ |
| | | export function addTenantPackage(data: TenantPkgForm) { |
| | | return request({ |
| | | url: '/system/tenant/package', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | 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 |
| | | }); |
| | | 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 |
| | | }); |
| | | const data = { |
| | | packageId, |
| | | status |
| | | }; |
| | | return request({ |
| | | url: '/system/tenant/package/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | // å é¤ç§æ·å¥é¤ |
| | | export function delTenantPackage(packageId: string | number | Array<string | number>) { |
| | | return request({ |
| | | url: '/system/tenant/package/' + packageId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/tenant/package/' + packageId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | |
| | | export interface TenantPkgVO extends BaseEntity { |
| | | packageId: string | number; |
| | | packageName: string; |
| | | menuIds: string; |
| | | remark: string; |
| | | menuCheckStrictly: boolean; |
| | | status: string; |
| | | packageId: string | number; |
| | | packageName: string; |
| | | menuIds: string; |
| | | remark: string; |
| | | menuCheckStrictly: boolean; |
| | | status: string; |
| | | } |
| | | |
| | | export interface TenantPkgQuery extends PageQuery { |
| | | packageName: string; |
| | | status: string; |
| | | packageName: string; |
| | | status: string; |
| | | } |
| | | |
| | | export interface TenantPkgForm { |
| | | packageId: string | number | undefined; |
| | | packageName: string; |
| | | menuIds: string; |
| | | remark: string; |
| | | menuCheckStrictly: boolean; |
| | | status: string; |
| | | packageId: string | number | undefined; |
| | | packageName: string; |
| | | menuIds: string; |
| | | remark: string; |
| | | menuCheckStrictly: boolean; |
| | | status: string; |
| | | } |
| | |
| | | * @param query |
| | | */ |
| | | export function listUser(query: UserQuery): AxiosPromise<UserVO[]> { |
| | | return request({ |
| | | url: '/system/user/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | url: '/system/user/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param userId |
| | | */ |
| | | export function getUser(userId?: string | number): AxiosPromise<UserInfoVO> { |
| | | return request({ |
| | | url: '/system/user/' + parseStrEmpty(userId), |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/user/' + parseStrEmpty(userId), |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * æ°å¢ç¨æ· |
| | | */ |
| | | export function addUser(data: UserForm) { |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¨æ· |
| | | */ |
| | | export function updateUser(data: UserForm) { |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param userId ç¨æ·ID |
| | | */ |
| | | export function delUser(userId: Array<string | number> | string | number) { |
| | | return request({ |
| | | url: '/system/user/' + userId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | url: '/system/user/' + userId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param password å¯ç |
| | | */ |
| | | export function resetUserPwd(userId: string | number, password: string) { |
| | | const data = { |
| | | userId, |
| | | password |
| | | }; |
| | | return request({ |
| | | url: '/system/user/resetPwd', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | const data = { |
| | | userId, |
| | | password |
| | | }; |
| | | return request({ |
| | | url: '/system/user/resetPwd', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param status ç¨æ·ç¶æ |
| | | */ |
| | | export function changeUserStatus(userId: number | string, status: string) { |
| | | const data = { |
| | | userId, |
| | | status |
| | | }; |
| | | return request({ |
| | | url: '/system/user/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | const data = { |
| | | userId, |
| | | status |
| | | }; |
| | | return request({ |
| | | url: '/system/user/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¨æ·ä¸ªäººä¿¡æ¯ |
| | | */ |
| | | export function getUserProfile(): AxiosPromise<UserInfoVO> { |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param data ç¨æ·ä¿¡æ¯ |
| | | */ |
| | | export function updateUserProfile(data: UserForm) { |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param newPassword æ°å¯ç |
| | | */ |
| | | export function updateUserPwd(oldPassword: string, newPassword: string) { |
| | | const data = { |
| | | oldPassword, |
| | | newPassword |
| | | }; |
| | | return request({ |
| | | url: '/system/user/profile/updatePwd', |
| | | method: 'put', |
| | | params: data |
| | | }); |
| | | const data = { |
| | | oldPassword, |
| | | newPassword |
| | | }; |
| | | return request({ |
| | | url: '/system/user/profile/updatePwd', |
| | | method: 'put', |
| | | params: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param data 头åæä»¶ |
| | | */ |
| | | export function uploadAvatar(data: FormData) { |
| | | return request({ |
| | | url: '/system/user/profile/avatar', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | url: '/system/user/profile/avatar', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param userId ç¨æ·ID |
| | | */ |
| | | export function getAuthRole(userId: string | number): AxiosPromise<{ user: UserVO; roles: RoleVO[] }> { |
| | | return request({ |
| | | url: '/system/user/authRole/' + userId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/user/authRole/' + userId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param data ç¨æ·ID |
| | | */ |
| | | export function updateAuthRole(data: { userId: string; roleIds: string }) { |
| | | return request({ |
| | | url: '/system/user/authRole', |
| | | method: 'put', |
| | | params: data |
| | | }); |
| | | return request({ |
| | | url: '/system/user/authRole', |
| | | method: 'put', |
| | | params: data |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢é¨é¨ä¸ææ ç»æ |
| | | */ |
| | | export function deptTreeSelect(): AxiosPromise<DeptVO[]> { |
| | | return request({ |
| | | url: '/system/user/deptTree', |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | url: '/system/user/deptTree', |
| | | method: 'get' |
| | | }); |
| | | } |
| | |
| | | * ç¨æ·ä¿¡æ¯ |
| | | */ |
| | | export interface UserInfo { |
| | | user: UserVO; |
| | | roles: string[]; |
| | | permissions: string[]; |
| | | user: UserVO; |
| | | roles: string[]; |
| | | permissions: string[]; |
| | | } |
| | | |
| | | /** |
| | | * ç¨æ·æ¥è¯¢å¯¹è±¡ç±»å |
| | | */ |
| | | export interface UserQuery extends PageQuery { |
| | | userName?: string; |
| | | phonenumber?: string; |
| | | status?: string; |
| | | deptId?: string | number; |
| | | roleId?: string | number; |
| | | userName?: string; |
| | | phonenumber?: string; |
| | | status?: string; |
| | | deptId?: string | number; |
| | | roleId?: string | number; |
| | | } |
| | | |
| | | /** |
| | | * ç¨æ·è¿å对象 |
| | | */ |
| | | export interface UserVO extends BaseEntity { |
| | | userId: string | number; |
| | | 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; |
| | | dept: DeptVO; |
| | | roles: RoleVO[]; |
| | | roleIds: any; |
| | | postIds: any; |
| | | roleId: any; |
| | | admin: boolean; |
| | | userId: string | number; |
| | | 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; |
| | | dept: DeptVO; |
| | | 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[]; |
| | | 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; |
| | | user: UserVO; |
| | | roles: RoleVO[]; |
| | | roleIds: string[]; |
| | | posts: PostVO[]; |
| | | postIds: string[]; |
| | | roleGroup: string; |
| | | postGroup: string; |
| | | } |
| | | |
| | | export interface ResetPwdForm { |
| | | oldPassword: string; |
| | | newPassword: string; |
| | | confirmPassword: string; |
| | | oldPassword: string; |
| | | newPassword: string; |
| | | confirmPassword: string; |
| | | } |
| | |
| | | |
| | | // æ¥è¯¢çæè¡¨æ°æ® |
| | | export const listTable = (query: TableQuery): AxiosPromise<TableVO[]> => { |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | // æ¥è¯¢dbæ°æ®åºå表 |
| | | export const listDbTable = (query: DbTableQuery): AxiosPromise<DbTableVO[]> => { |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/db/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/db/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | // æ¥è¯¢è¡¨è¯¦ç»ä¿¡æ¯ |
| | | export const getGenTable = (tableId: string | number): AxiosPromise<GenTableVO> => { |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/' + tableId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/' + tableId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // ä¿®æ¹ä»£ç çæä¿¡æ¯ |
| | | export const updateGenTable = (data: DbTableForm) => { |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | // 导å
¥è¡¨ |
| | | export const importTable = (data: { tables: string }) => { |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/importTable', |
| | | method: 'post', |
| | | params: data |
| | | }); |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/importTable', |
| | | method: 'post', |
| | | params: data |
| | | }); |
| | | }; |
| | | |
| | | // é¢è§çæä»£ç |
| | | export const previewTable = (tableId: string | number) => { |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/preview/' + tableId, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/preview/' + tableId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // å é¤è¡¨æ°æ® |
| | | export const delTable = (tableId: string | number | Array<string | number>) => { |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/' + tableId, |
| | | method: 'delete' |
| | | }); |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/' + tableId, |
| | | method: 'delete' |
| | | }); |
| | | }; |
| | | |
| | | // çæä»£ç ï¼èªå®ä¹è·¯å¾ï¼ |
| | | export const genCode = (tableName: string) => { |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/genCode/' + tableName, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/genCode/' + tableName, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | // åæ¥æ°æ®åº |
| | | export const synchDb = (tableName: string) => { |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/synchDb/' + tableName, |
| | | method: 'get' |
| | | }); |
| | | return request({ |
| | | headers: { datasource: localStorage.getItem('dataName') }, |
| | | url: '/tool/gen/synchDb/' + tableName, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | |
| | | export interface TableVO extends BaseEntity { |
| | | createDept: number | string; |
| | | tableId: string | number; |
| | | 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; |
| | | createDept: number | string; |
| | | tableId: string | number; |
| | | 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; |
| | | 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; |
| | | 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; |
| | | 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 { |
| | | tableName: string; |
| | | tableComment: string; |
| | | tableName: string; |
| | | tableComment: string; |
| | | } |
| | | |
| | | export interface GenTableVO { |
| | | info: DbTableVO; |
| | | rows: DbColumnVO[]; |
| | | tables: DbTableVO[]; |
| | | 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; |
| | | 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; |
| | | 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; |
| | | 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; |
| | | } |
| | |
| | | * 注å |
| | | */ |
| | | export type RegisterForm = { |
| | | tenantId: string; |
| | | username: string; |
| | | password: string; |
| | | confirmPassword?: string; |
| | | code?: string; |
| | | uuid?: string; |
| | | userType?: string; |
| | | 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; |
| | | code?: string; |
| | | uuid?: string; |
| | | tenantId: string; |
| | | username: string; |
| | | password: string; |
| | | rememberMe?: boolean; |
| | | code?: string; |
| | | uuid?: string; |
| | | } |
| | | |
| | | /** |
| | | * ç»å½ååº |
| | | */ |
| | | export interface LoginResult { |
| | | token: string; |
| | | token: string; |
| | | } |
| | | |
| | | /** |
| | | * éªè¯ç è¿å |
| | | */ |
| | | export interface VerifyCodeResult { |
| | | captchaEnabled: boolean; |
| | | uuid?: string; |
| | | img?: string; |
| | | captchaEnabled: boolean; |
| | | uuid?: string; |
| | | img?: string; |
| | | } |
| | | |
| | | /** |
| | | * ç§æ· |
| | | */ |
| | | export interface TenantVO { |
| | | companyName: string; |
| | | domain: any; |
| | | tenantId: string; |
| | | companyName: string; |
| | | domain: any; |
| | | tenantId: string; |
| | | } |
| | | |
| | | export interface TenantInfo { |
| | | tenantEnabled: boolean; |
| | | voList: TenantVO[]; |
| | | tenantEnabled: boolean; |
| | | voList: TenantVO[]; |
| | | } |
| | |
| | | @import './variables.module.scss'; |
| | | |
| | | @mixin colorBtn($color) { |
| | | background: $color; |
| | | background: $color; |
| | | |
| | | &:hover { |
| | | color: $color; |
| | | &:hover { |
| | | color: $color; |
| | | |
| | | &:before, |
| | | &:after { |
| | | background: $color; |
| | | } |
| | | } |
| | | &:before, |
| | | &:after { |
| | | background: $color; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .blue-btn { |
| | | @include colorBtn($blue); |
| | | @include colorBtn($blue); |
| | | } |
| | | |
| | | .light-blue-btn { |
| | | @include colorBtn($light-blue); |
| | | @include colorBtn($light-blue); |
| | | } |
| | | |
| | | .red-btn { |
| | | @include colorBtn($red); |
| | | @include colorBtn($red); |
| | | } |
| | | |
| | | .pink-btn { |
| | | @include colorBtn($pink); |
| | | @include colorBtn($pink); |
| | | } |
| | | |
| | | .green-btn { |
| | | @include colorBtn($green); |
| | | @include colorBtn($green); |
| | | } |
| | | |
| | | .tiffany-btn { |
| | | @include colorBtn($tiffany); |
| | | @include colorBtn($tiffany); |
| | | } |
| | | |
| | | .yellow-btn { |
| | | @include colorBtn($yellow); |
| | | @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; |
| | | 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; |
| | | &:hover { |
| | | background: #fff; |
| | | |
| | | &:before, |
| | | &:after { |
| | | width: 100%; |
| | | transition: 600ms ease all; |
| | | } |
| | | } |
| | | &: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; |
| | | } |
| | | &: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; |
| | | } |
| | | &::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; |
| | | 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; |
| | | } |
| | |
| | | // cover some element-ui styles |
| | | |
| | | .el-divider--horizontal { |
| | | margin-bottom: 10px; |
| | | margin-top: 10px; |
| | | margin-bottom: 10px; |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .el-breadcrumb__inner, |
| | | .el-breadcrumb__inner a { |
| | | font-weight: 400 !important; |
| | | font-weight: 400 !important; |
| | | } |
| | | |
| | | .el-upload { |
| | | input[type='file'] { |
| | | display: none !important; |
| | | } |
| | | input[type='file'] { |
| | | display: none !important; |
| | | } |
| | | } |
| | | |
| | | .el-upload__input { |
| | | display: none; |
| | | display: none; |
| | | } |
| | | |
| | | .cell { |
| | | .el-tag { |
| | | margin-right: 0px; |
| | | } |
| | | .el-tag { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | |
| | | .small-padding { |
| | | .cell { |
| | | padding-left: 5px; |
| | | padding-right: 5px; |
| | | } |
| | | .cell { |
| | | padding-left: 5px; |
| | | padding-right: 5px; |
| | | } |
| | | } |
| | | |
| | | .fixed-width { |
| | | .el-button--mini { |
| | | padding: 7px 10px; |
| | | width: 60px; |
| | | } |
| | | .el-button--mini { |
| | | padding: 7px 10px; |
| | | width: 60px; |
| | | } |
| | | } |
| | | |
| | | .status-col { |
| | | .cell { |
| | | padding: 0 10px; |
| | | text-align: center; |
| | | .cell { |
| | | padding: 0 10px; |
| | | text-align: center; |
| | | |
| | | .el-tag { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | .el-tag { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // to fixed https://github.com/ElemeFE/element/issues/2461 |
| | | .el-dialog { |
| | | transform: none; |
| | | left: 0; |
| | | position: relative; |
| | | margin: 0 auto; |
| | | transform: none; |
| | | left: 0; |
| | | position: relative; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | // refine element ui upload |
| | | .upload-container { |
| | | .el-upload { |
| | | width: 100%; |
| | | .el-upload { |
| | | width: 100%; |
| | | |
| | | .el-upload-dragger { |
| | | width: 100%; |
| | | height: 200px; |
| | | } |
| | | } |
| | | .el-upload-dragger { |
| | | width: 100%; |
| | | height: 200px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // dropdown |
| | | .el-dropdown-menu { |
| | | a { |
| | | display: block; |
| | | } |
| | | a { |
| | | display: block; |
| | | } |
| | | } |
| | | |
| | | // fix date-picker ui bug in filter-item |
| | | .el-range-editor.el-input__inner { |
| | | display: inline-flex !important; |
| | | display: inline-flex !important; |
| | | } |
| | | |
| | | // to fix el-date-picker css style |
| | | .el-range-separator { |
| | | box-sizing: content-box; |
| | | box-sizing: content-box; |
| | | } |
| | | |
| | | .el-menu--collapse>div>.el-submenu>.el-submenu__title .el-submenu__icon-arrow { |
| | | display: none; |
| | | display: none; |
| | | } |
| | | |
| | | .el-dropdown .el-dropdown-link { |
| | | color: var(--el-color-primary) !important; |
| | | color: var(--el-color-primary) !important; |
| | | } |
| | |
| | | @import '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; |
| | | 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; |
| | | font-weight: 700; |
| | | } |
| | | |
| | | html { |
| | | height: 100%; |
| | | box-sizing: border-box; |
| | | height: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | #app { |
| | | height: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | *, |
| | | *:before, |
| | | *:after { |
| | | box-sizing: inherit; |
| | | box-sizing: inherit; |
| | | } |
| | | |
| | | .no-padding { |
| | | padding: 0px !important; |
| | | padding: 0px !important; |
| | | } |
| | | |
| | | .padding-content { |
| | | padding: 4px 0; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | a:focus, |
| | | a:active { |
| | | outline: none; |
| | | outline: none; |
| | | } |
| | | |
| | | a, |
| | | a:focus, |
| | | a:hover { |
| | | cursor: pointer; |
| | | color: inherit; |
| | | text-decoration: none; |
| | | cursor: pointer; |
| | | color: inherit; |
| | | text-decoration: none; |
| | | } |
| | | |
| | | div:focus { |
| | | outline: none; |
| | | outline: none; |
| | | } |
| | | |
| | | .fr { |
| | | float: right; |
| | | float: right; |
| | | } |
| | | |
| | | .fl { |
| | | float: left; |
| | | float: left; |
| | | } |
| | | |
| | | .pr-5 { |
| | | padding-right: 5px; |
| | | padding-right: 5px; |
| | | } |
| | | |
| | | .pl-5 { |
| | | padding-left: 5px; |
| | | padding-left: 5px; |
| | | } |
| | | |
| | | .block { |
| | | display: block; |
| | | display: block; |
| | | } |
| | | |
| | | .pointer { |
| | | cursor: pointer; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .inlineBlock { |
| | | display: block; |
| | | display: block; |
| | | } |
| | | |
| | | .clearfix { |
| | | &:after { |
| | | visibility: hidden; |
| | | display: block; |
| | | font-size: 0; |
| | | content: ' '; |
| | | clear: both; |
| | | height: 0; |
| | | } |
| | | &: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; |
| | | 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; |
| | | a { |
| | | color: #337ab7; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | color: rgb(32, 160, 255); |
| | | } |
| | | } |
| | | &:hover { |
| | | color: rgb(32, 160, 255); |
| | | } |
| | | } |
| | | } |
| | | |
| | | //main-containerå
¨å±æ ·å¼ |
| | | .app-container { |
| | | padding: 20px; |
| | | 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; |
| | | --tw-shadow: var(--el-box-shadow-light); |
| | | --tw-shadow-colored: var(--el-box-shadow-light); |
| | | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); |
| | | 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; |
| | | --tw-shadow: var(--el-box-shadow-light); |
| | | --tw-shadow-colored: var(--el-box-shadow-light); |
| | | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); |
| | | } |
| | | |
| | | .components-container { |
| | | margin: 30px 50px; |
| | | position: relative; |
| | | margin: 30px 50px; |
| | | position: relative; |
| | | } |
| | | |
| | | .pagination-container { |
| | | margin-top: 30px; |
| | | margin-top: 30px; |
| | | } |
| | | |
| | | .text-center { |
| | | text-align: 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%); |
| | | 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; |
| | | } |
| | | .subtitle { |
| | | font-size: 20px; |
| | | color: #fff; |
| | | } |
| | | |
| | | &.draft { |
| | | background: #d0d0d0; |
| | | } |
| | | &.draft { |
| | | background: #d0d0d0; |
| | | } |
| | | |
| | | &.deleted { |
| | | background: #d0d0d0; |
| | | } |
| | | &.deleted { |
| | | background: #d0d0d0; |
| | | } |
| | | } |
| | | |
| | | .link-type, |
| | | .link-type:focus { |
| | | color: #337ab7; |
| | | cursor: pointer; |
| | | color: #337ab7; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | color: rgb(32, 160, 255); |
| | | } |
| | | &:hover { |
| | | color: rgb(32, 160, 255); |
| | | } |
| | | } |
| | | |
| | | .filter-container { |
| | | padding-bottom: 10px; |
| | | padding-bottom: 10px; |
| | | |
| | | .filter-item { |
| | | display: inline-block; |
| | | vertical-align: middle; |
| | | margin-bottom: 10px; |
| | | } |
| | | .filter-item { |
| | | display: inline-block; |
| | | vertical-align: middle; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | |
| | | //refine vue-multiselect plugin |
| | | .multiselect { |
| | | line-height: 16px; |
| | | line-height: 16px; |
| | | } |
| | | |
| | | .multiselect--active { |
| | | z-index: 1000 !important; |
| | | z-index: 1000 !important; |
| | | } |
| | |
| | | @mixin clearfix { |
| | | &:after { |
| | | content: ''; |
| | | display: table; |
| | | clear: both; |
| | | } |
| | | &:after { |
| | | content: ''; |
| | | display: table; |
| | | clear: both; |
| | | } |
| | | } |
| | | |
| | | @mixin scrollBar { |
| | | &::-webkit-scrollbar-track-piece { |
| | | background: #d3dce6; |
| | | } |
| | | &::-webkit-scrollbar-track-piece { |
| | | background: #d3dce6; |
| | | } |
| | | |
| | | &::-webkit-scrollbar { |
| | | width: 6px; |
| | | } |
| | | &::-webkit-scrollbar { |
| | | width: 6px; |
| | | } |
| | | |
| | | &::-webkit-scrollbar-thumb { |
| | | background: #99a9bf; |
| | | border-radius: 20px; |
| | | } |
| | | &::-webkit-scrollbar-thumb { |
| | | background: #99a9bf; |
| | | border-radius: 20px; |
| | | } |
| | | } |
| | | |
| | | @mixin relative { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | @mixin pct($pct) { |
| | | width: #{$pct}; |
| | | position: relative; |
| | | margin: 0 auto; |
| | | 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; |
| | | $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; |
| | | } |
| | | @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; |
| | | } |
| | | } |
| | |
| | | |
| | | /** åºç¡éç¨ **/ |
| | | .pt5 { |
| | | padding-top: 5px; |
| | | padding-top: 5px; |
| | | } |
| | | .pr5 { |
| | | padding-right: 5px; |
| | | padding-right: 5px; |
| | | } |
| | | .pb5 { |
| | | padding-bottom: 5px; |
| | | padding-bottom: 5px; |
| | | } |
| | | .mt5 { |
| | | margin-top: 5px; |
| | | margin-top: 5px; |
| | | } |
| | | .mr5 { |
| | | margin-right: 5px; |
| | | margin-right: 5px; |
| | | } |
| | | .mb5 { |
| | | margin-bottom: 5px; |
| | | margin-bottom: 5px; |
| | | } |
| | | .mb8 { |
| | | margin-bottom: 8px; |
| | | margin-bottom: 8px; |
| | | } |
| | | .ml5 { |
| | | margin-left: 5px; |
| | | margin-left: 5px; |
| | | } |
| | | .mt10 { |
| | | margin-top: 10px; |
| | | margin-top: 10px; |
| | | } |
| | | .mr10 { |
| | | margin-right: 10px; |
| | | margin-right: 10px; |
| | | } |
| | | .mb10 { |
| | | margin-bottom: 10px; |
| | | margin-bottom: 10px; |
| | | } |
| | | .ml10 { |
| | | margin-left: 10px; |
| | | margin-left: 10px; |
| | | } |
| | | .mt20 { |
| | | margin-top: 20px; |
| | | margin-top: 20px; |
| | | } |
| | | .mr20 { |
| | | margin-right: 20px; |
| | | margin-right: 20px; |
| | | } |
| | | .mb20 { |
| | | margin-bottom: 20px; |
| | | margin-bottom: 20px; |
| | | } |
| | | .ml20 { |
| | | margin-left: 20px; |
| | | margin-left: 20px; |
| | | } |
| | | |
| | | .h1, |
| | |
| | | h4, |
| | | h5, |
| | | h6 { |
| | | font-family: inherit; |
| | | font-weight: 500; |
| | | line-height: 1.1; |
| | | color: inherit; |
| | | font-family: inherit; |
| | | font-weight: 500; |
| | | line-height: 1.1; |
| | | color: inherit; |
| | | } |
| | | |
| | | .el-form .el-form-item__label { |
| | | font-weight: 700; |
| | | font-weight: 700; |
| | | } |
| | | .el-dialog:not(.is-fullscreen) { |
| | | margin-top: 6vh !important; |
| | | margin-top: 6vh !important; |
| | | } |
| | | |
| | | .el-dialog.scrollbar .el-dialog__body { |
| | | overflow: auto; |
| | | overflow-x: hidden; |
| | | max-height: 70vh; |
| | | padding: 10px 20px 0; |
| | | 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: #f8f8f9 !important; |
| | | color: #515a6e; |
| | | height: 40px !important; |
| | | font-size: 13px; |
| | | } |
| | | } |
| | | .el-table__body-wrapper { |
| | | .el-button [class*='el-icon-'] + span { |
| | | margin-left: 1px; |
| | | } |
| | | } |
| | | .el-table__header-wrapper, |
| | | .el-table__fixed-header-wrapper { |
| | | th { |
| | | word-break: break-word; |
| | | background-color: #f8f8f9 !important; |
| | | color: #515a6e; |
| | | 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; |
| | | font-size: 15px; |
| | | color: #6379bb; |
| | | border-bottom: 1px solid #ddd; |
| | | margin: 8px 10px 25px 10px; |
| | | padding-bottom: 5px; |
| | | } |
| | | |
| | | /** è¡¨æ ¼å¸å± **/ |
| | | .pagination-container { |
| | | // position: relative; |
| | | height: 25px; |
| | | margin-bottom: 10px; |
| | | margin-top: 15px; |
| | | padding: 10px 20px !important; |
| | | // position: relative; |
| | | height: 25px; |
| | | margin-bottom: 10px; |
| | | margin-top: 15px; |
| | | padding: 10px 20px !important; |
| | | } |
| | | |
| | | /* tree border */ |
| | | .tree-border { |
| | | margin-top: 5px; |
| | | border: 1px solid #e5e6e7; |
| | | background: #ffffff none; |
| | | border-radius: 4px; |
| | | width: 100%; |
| | | margin-top: 5px; |
| | | border: 1px solid #e5e6e7; |
| | | background: #ffffff none; |
| | | border-radius: 4px; |
| | | width: 100%; |
| | | } |
| | | |
| | | .pagination-container .el-pagination { |
| | | //right: 0; |
| | | //position: absolute; |
| | | //right: 0; |
| | | //position: absolute; |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .pagination-container .el-pagination > .el-pagination__jump { |
| | | display: none !important; |
| | | } |
| | | .pagination-container .el-pagination > .el-pagination__sizes { |
| | | display: none !important; |
| | | } |
| | | .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; |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | width: inherit; |
| | | } |
| | | |
| | | /** è¡¨æ ¼æ´å¤æä½ä¸ææ ·å¼ */ |
| | | .el-table .el-dropdown-link { |
| | | cursor: pointer; |
| | | color: #409eff; |
| | | margin-left: 10px; |
| | | cursor: pointer; |
| | | color: #409eff; |
| | | margin-left: 10px; |
| | | } |
| | | |
| | | .el-table .el-dropdown, |
| | | .el-icon-arrow-down { |
| | | font-size: 12px; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .el-tree-node__content > .el-checkbox { |
| | | margin-right: 8px; |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .list-group-striped > .list-group-item { |
| | | border-left: 0; |
| | | border-right: 0; |
| | | border-radius: 0; |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | border-left: 0; |
| | | border-right: 0; |
| | | border-radius: 0; |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | } |
| | | |
| | | .list-group { |
| | | padding-left: 0px; |
| | | list-style: none; |
| | | 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; |
| | | border-bottom: 1px solid #e7eaec; |
| | | border-top: 1px solid #e7eaec; |
| | | margin-bottom: -1px; |
| | | padding: 11px 0px; |
| | | font-size: 13px; |
| | | } |
| | | |
| | | .pull-right { |
| | | float: right !important; |
| | | float: right !important; |
| | | } |
| | | |
| | | .el-card__header { |
| | | padding: 14px 15px 7px !important; |
| | | min-height: 40px; |
| | | padding: 14px 15px 7px !important; |
| | | min-height: 40px; |
| | | } |
| | | |
| | | .el-card__body { |
| | | padding: 15px 20px 20px 20px !important; |
| | | padding: 15px 20px 20px 20px !important; |
| | | } |
| | | |
| | | .card-box { |
| | | padding-right: 15px; |
| | | padding-left: 15px; |
| | | margin-bottom: 10px; |
| | | padding-right: 15px; |
| | | padding-left: 15px; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | /* button color */ |
| | | .el-button--cyan.is-active, |
| | | .el-button--cyan:active { |
| | | background: #20b2aa; |
| | | border-color: #20b2aa; |
| | | color: #ffffff; |
| | | background: #20b2aa; |
| | | border-color: #20b2aa; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .el-button--cyan:focus, |
| | | .el-button--cyan:hover { |
| | | background: #48d1cc; |
| | | border-color: #48d1cc; |
| | | color: #ffffff; |
| | | background: #48d1cc; |
| | | border-color: #48d1cc; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .el-button--cyan { |
| | | background-color: #20b2aa; |
| | | border-color: #20b2aa; |
| | | color: #ffffff; |
| | | background-color: #20b2aa; |
| | | border-color: #20b2aa; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | /* text color */ |
| | | .text-navy { |
| | | color: #1ab394; |
| | | color: #1ab394; |
| | | } |
| | | |
| | | .text-primary { |
| | | color: inherit; |
| | | color: inherit; |
| | | } |
| | | |
| | | .text-success { |
| | | color: #1c84c6; |
| | | color: #1c84c6; |
| | | } |
| | | |
| | | .text-info { |
| | | color: #23c6c8; |
| | | color: #23c6c8; |
| | | } |
| | | |
| | | .text-warning { |
| | | color: #f8ac59; |
| | | color: #f8ac59; |
| | | } |
| | | |
| | | .text-danger { |
| | | color: #ed5565; |
| | | color: #ed5565; |
| | | } |
| | | |
| | | .text-muted { |
| | | color: #888888; |
| | | color: #888888; |
| | | } |
| | | |
| | | /* image */ |
| | | .img-circle { |
| | | border-radius: 50%; |
| | | border-radius: 50%; |
| | | } |
| | | |
| | | .img-lg { |
| | | width: 120px; |
| | | height: 120px; |
| | | 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; |
| | | 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; |
| | | opacity: 0.8; |
| | | color: #fff !important; |
| | | background: #42b983 !important; |
| | | } |
| | | |
| | | /* è¡¨æ ¼å³ä¾§å·¥å
·æ æ ·å¼ */ |
| | | .top-right-btn { |
| | | margin-left: auto; |
| | | margin-left: auto; |
| | | } |
| | |
| | | #app { |
| | | .main-container { |
| | | min-height: 100%; |
| | | transition: margin-left 0.28s; |
| | | margin-left: $base-sidebar-width; |
| | | position: relative; |
| | | } |
| | | .main-container { |
| | | min-height: 100%; |
| | | transition: margin-left 0.28s; |
| | | margin-left: $base-sidebar-width; |
| | | position: relative; |
| | | } |
| | | |
| | | .sidebarHide { |
| | | margin-left: 0 !important; |
| | | } |
| | | .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: 0px; |
| | | 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: 2px 0 6px rgba(0, 21, 41, 0.35); |
| | | .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: 0px; |
| | | 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: 2px 0 6px rgba(0, 21, 41, 0.35); |
| | | |
| | | // 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; |
| | | } |
| | | // 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; |
| | | } |
| | | .scrollbar-wrapper { |
| | | overflow-x: hidden !important; |
| | | } |
| | | |
| | | .el-scrollbar__bar.is-vertical { |
| | | right: 0px; |
| | | } |
| | | .el-scrollbar__bar.is-vertical { |
| | | right: 0px; |
| | | } |
| | | |
| | | .el-scrollbar { |
| | | height: 100%; |
| | | } |
| | | .el-scrollbar { |
| | | height: 100%; |
| | | } |
| | | |
| | | &.has-logo { |
| | | .el-scrollbar { |
| | | height: calc(100% - 50px); |
| | | } |
| | | } |
| | | &.has-logo { |
| | | .el-scrollbar { |
| | | height: calc(100% - 50px); |
| | | } |
| | | } |
| | | |
| | | .is-horizontal { |
| | | display: none; |
| | | } |
| | | .is-horizontal { |
| | | display: none; |
| | | } |
| | | |
| | | a { |
| | | display: inline-block; |
| | | width: 100%; |
| | | overflow: hidden; |
| | | } |
| | | a { |
| | | display: inline-block; |
| | | width: 100%; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .svg-icon { |
| | | margin-right: 16px; |
| | | } |
| | | .svg-icon { |
| | | margin-right: 16px; |
| | | } |
| | | |
| | | .el-menu { |
| | | border: none; |
| | | height: 100%; |
| | | width: 100% !important; |
| | | } |
| | | .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, |
| | | .menu-title { |
| | | overflow: hidden !important; |
| | | text-overflow: ellipsis !important; |
| | | white-space: nowrap !important; |
| | | } |
| | | |
| | | .el-menu-item .el-menu-tooltip__trigger { |
| | | display: inline-block !important; |
| | | } |
| | | .el-menu-item .el-menu-tooltip__trigger { |
| | | display: inline-block !important; |
| | | } |
| | | |
| | | // menu hover |
| | | .sub-menu-title-noDropdown, |
| | | .el-sub-menu__title { |
| | | &:hover { |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | } |
| | | } |
| | | // menu hover |
| | | .sub-menu-title-noDropdown, |
| | | .el-sub-menu__title { |
| | | &:hover { |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | } |
| | | } |
| | | |
| | | & .theme-dark .is-active > .el-sub-menu__title { |
| | | color: $base-menu-color-active !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: $base-sidebar-width !important; |
| | | & .nest-menu .el-sub-menu > .el-sub-menu__title, |
| | | & .el-sub-menu .el-menu-item { |
| | | min-width: $base-sidebar-width !important; |
| | | |
| | | &:hover { |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | } |
| | | } |
| | | &:hover { |
| | | background-color: rgba(0, 0, 0, 0.06) !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; |
| | | & .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; |
| | | |
| | | &:hover { |
| | | background-color: $base-sub-menu-hover !important; |
| | | } |
| | | } |
| | | } |
| | | &:hover { |
| | | background-color: $base-sub-menu-hover !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .hideSidebar { |
| | | .sidebar-container { |
| | | width: 54px !important; |
| | | } |
| | | .hideSidebar { |
| | | .sidebar-container { |
| | | width: 54px !important; |
| | | } |
| | | |
| | | .main-container { |
| | | margin-left: 54px; |
| | | } |
| | | .main-container { |
| | | margin-left: 54px; |
| | | } |
| | | |
| | | .sub-menu-title-noDropdown { |
| | | padding: 0 !important; |
| | | position: relative; |
| | | .sub-menu-title-noDropdown { |
| | | padding: 0 !important; |
| | | position: relative; |
| | | |
| | | .el-tooltip { |
| | | padding: 0 !important; |
| | | .el-tooltip { |
| | | padding: 0 !important; |
| | | |
| | | .svg-icon { |
| | | margin-left: 20px; |
| | | } |
| | | } |
| | | } |
| | | .svg-icon { |
| | | margin-left: 20px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-sub-menu { |
| | | overflow: hidden; |
| | | .el-sub-menu { |
| | | overflow: hidden; |
| | | |
| | | & > .el-sub-menu__title { |
| | | padding: 0 !important; |
| | | & > .el-sub-menu__title { |
| | | padding: 0 !important; |
| | | |
| | | .svg-icon { |
| | | margin-left: 20px; |
| | | } |
| | | } |
| | | } |
| | | .svg-icon { |
| | | margin-left: 20px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-menu--collapse { |
| | | .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-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; |
| | | } |
| | | .el-menu--collapse .el-menu .el-sub-menu { |
| | | min-width: $base-sidebar-width !important; |
| | | } |
| | | |
| | | // mobile responsive |
| | | .mobile { |
| | | .main-container { |
| | | margin-left: 0px; |
| | | } |
| | | // mobile responsive |
| | | .mobile { |
| | | .main-container { |
| | | margin-left: 0px; |
| | | } |
| | | |
| | | .sidebar-container { |
| | | transition: transform 0.28s; |
| | | width: $base-sidebar-width !important; |
| | | } |
| | | .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); |
| | | } |
| | | } |
| | | } |
| | | &.hideSidebar { |
| | | .sidebar-container { |
| | | pointer-events: none; |
| | | transition-duration: 0.3s; |
| | | transform: translate3d(-$base-sidebar-width, 0, 0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | .withoutAnimation { |
| | | .main-container, |
| | | .sidebar-container { |
| | | transition: none; |
| | | } |
| | | } |
| | | .withoutAnimation { |
| | | .main-container, |
| | | .sidebar-container { |
| | | transition: none; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // when menu collapsed |
| | | .el-menu--vertical { |
| | | & > .el-menu { |
| | | .svg-icon { |
| | | margin-right: 16px; |
| | | } |
| | | } |
| | | & > .el-menu { |
| | | .svg-icon { |
| | | margin-right: 16px; |
| | | } |
| | | } |
| | | |
| | | .nest-menu .el-sub-menu > .el-sub-menu__title, |
| | | .el-menu-item { |
| | | &:hover { |
| | | // you can use $sub-menuHover |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | } |
| | | } |
| | | .nest-menu .el-sub-menu > .el-sub-menu__title, |
| | | .el-menu-item { |
| | | &:hover { |
| | | // you can use $sub-menuHover |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | } |
| | | } |
| | | |
| | | // the scroll bar appears when the sub-menu is too long |
| | | > .el-menu--popup { |
| | | max-height: 100vh; |
| | | overflow-y: auto; |
| | | // the scroll bar appears when the sub-menu is too long |
| | | > .el-menu--popup { |
| | | max-height: 100vh; |
| | | overflow-y: auto; |
| | | |
| | | &::-webkit-scrollbar-track-piece { |
| | | background: #d3dce6; |
| | | } |
| | | &::-webkit-scrollbar-track-piece { |
| | | background: #d3dce6; |
| | | } |
| | | |
| | | &::-webkit-scrollbar { |
| | | width: 6px; |
| | | } |
| | | &::-webkit-scrollbar { |
| | | width: 6px; |
| | | } |
| | | |
| | | &::-webkit-scrollbar-thumb { |
| | | background: #99a9bf; |
| | | border-radius: 20px; |
| | | } |
| | | } |
| | | &::-webkit-scrollbar-thumb { |
| | | background: #99a9bf; |
| | | border-radius: 20px; |
| | | } |
| | | } |
| | | } |
| | |
| | | /* fade */ |
| | | .fade-enter-active, |
| | | .fade-leave-active { |
| | | transition: opacity 0.28s; |
| | | transition: opacity 0.28s; |
| | | } |
| | | |
| | | .fade-enter, |
| | | .fade-leave-active { |
| | | opacity: 0; |
| | | opacity: 0; |
| | | } |
| | | |
| | | /* fade-transform */ |
| | | .fade-transform--move, |
| | | .fade-transform-leave-active, |
| | | .fade-transform-enter-active { |
| | | transition: all 0.5s; |
| | | transition: all 0.5s; |
| | | } |
| | | |
| | | .fade-transform-leave-active { |
| | | position: absolute; |
| | | position: absolute; |
| | | } |
| | | |
| | | .fade-transform-enter { |
| | | opacity: 0; |
| | | transform: translateX(-30px); |
| | | opacity: 0; |
| | | transform: translateX(-30px); |
| | | } |
| | | |
| | | .fade-transform-leave-to { |
| | | opacity: 0; |
| | | transform: translateX(30px); |
| | | opacity: 0; |
| | | transform: translateX(30px); |
| | | } |
| | | |
| | | /* breadcrumb transition */ |
| | | .breadcrumb-enter-active, |
| | | .breadcrumb-leave-active { |
| | | transition: all 0.5s; |
| | | transition: all 0.5s; |
| | | } |
| | | |
| | | .breadcrumb-enter, |
| | | .breadcrumb-leave-active { |
| | | opacity: 0; |
| | | transform: translateX(20px); |
| | | opacity: 0; |
| | | transform: translateX(20px); |
| | | } |
| | | |
| | | .breadcrumb-move { |
| | | transition: all 0.5s; |
| | | transition: all 0.5s; |
| | | } |
| | | |
| | | .breadcrumb-leave-active { |
| | | position: absolute; |
| | | position: absolute; |
| | | } |
| | |
| | | // 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; |
| | | 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; |
| | | } |
| | |
| | | <template> |
| | | <el-breadcrumb class="app-breadcrumb" separator="/"> |
| | | <transition-group name="breadcrumb"> |
| | | <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path"> |
| | | <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ |
| | | item.meta?.title }}</span> |
| | | <a v-else @click.prevent="handleLink(item)">{{ item.meta?.title }}</a> |
| | | </el-breadcrumb-item> |
| | | </transition-group> |
| | | </el-breadcrumb> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { RouteLocationMatched } from 'vue-router' |
| | | |
| | |
| | | const levelList = ref<RouteLocationMatched[]>([]) |
| | | |
| | | const getBreadcrumb = () => { |
| | | // only show routes with meta.title |
| | | let matched = route.matched.filter(item => item.meta && item.meta.title); |
| | | const first = matched[0] |
| | | // 夿æ¯å¦ä¸ºé¦é¡µ |
| | | if (!isDashboard(first)) { |
| | | matched = ([{ path: '/index', meta: { title: 'é¦é¡µ' } }] as any).concat(matched) |
| | | } |
| | | levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) |
| | | // only show routes with meta.title |
| | | let matched = route.matched.filter(item => item.meta && item.meta.title); |
| | | const first = matched[0] |
| | | // 夿æ¯å¦ä¸ºé¦é¡µ |
| | | if (!isDashboard(first)) { |
| | | matched = ([{ path: '/index', meta: { title: 'é¦é¡µ' } }] as any).concat(matched) |
| | | } |
| | | levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) |
| | | } |
| | | const isDashboard = (route: RouteLocationMatched) => { |
| | | const name = route && route.name as string |
| | | if (!name) { |
| | | return false |
| | | } |
| | | return name.trim() === 'Index' |
| | | const name = route && route.name as string |
| | | if (!name) { |
| | | return false |
| | | } |
| | | return name.trim() === 'Index' |
| | | } |
| | | const handleLink = (item: RouteLocationMatched) => { |
| | | const { redirect, path } = item |
| | | redirect ? router.push(redirect as string) : router.push(path) |
| | | const { redirect, path } = item |
| | | redirect ? router.push(redirect as string) : router.push(path) |
| | | } |
| | | |
| | | watchEffect(() => { |
| | | // if you go to the redirect page, do not update the breadcrumbs |
| | | if (route.path.startsWith('/redirect/')) return |
| | | getBreadcrumb() |
| | | // if you go to the redirect page, do not update the breadcrumbs |
| | | if (route.path.startsWith('/redirect/')) return |
| | | getBreadcrumb() |
| | | }) |
| | | onMounted(() => { |
| | | getBreadcrumb(); |
| | | getBreadcrumb(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <el-breadcrumb class="app-breadcrumb" separator="/"> |
| | | <transition-group name="breadcrumb"> |
| | | <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path"> |
| | | <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ |
| | | item.meta?.title }}</span> |
| | | <a v-else @click.prevent="handleLink(item)">{{ item.meta?.title }}</a> |
| | | </el-breadcrumb-item> |
| | | </transition-group> |
| | | </el-breadcrumb> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | .app-breadcrumb.el-breadcrumb { |
| | |
| | | <template> |
| | | <div> |
| | | <template v-for="(item, index) in options"> |
| | | <template v-if="values.includes(item.value)"> |
| | | <span |
| | | v-if="item.elTagType == 'default' || item.elTagType == ''" |
| | | :key="item.value" |
| | | :index="index" |
| | | :class="item.elTagClass" |
| | | >{{ item.label }}</span |
| | | > |
| | | <el-tag |
| | | v-else |
| | | :disable-transitions="true" |
| | | :key="item.value + ''" |
| | | :index="index" |
| | | :type="item.elTagType === 'primary' ? '' : item.elTagType" |
| | | :class="item.elTagClass" |
| | | >{{ item.label }}</el-tag |
| | | > |
| | | </template> |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { PropType } from 'vue'; |
| | | |
| | | const props = defineProps({ |
| | | // æ°æ® |
| | | options: { |
| | | type: Array as PropType<DictDataOption[]>, |
| | | default: null, |
| | | }, |
| | | // å½åçå¼ |
| | | value: [Number, String, Array], |
| | | // æ°æ® |
| | | options: { |
| | | type: Array as PropType<DictDataOption[]>, |
| | | default: null, |
| | | }, |
| | | // å½åçå¼ |
| | | value: [Number, String, Array], |
| | | }) |
| | | |
| | | const values = computed(() => { |
| | | if (props.value !== null && typeof props.value !== 'undefined') { |
| | | return Array.isArray(props.value) ? props.value : [String(props.value)]; |
| | | } else { |
| | | return []; |
| | | } |
| | | if (props.value !== null && typeof props.value !== 'undefined') { |
| | | return Array.isArray(props.value) ? props.value : [String(props.value)]; |
| | | } else { |
| | | return []; |
| | | } |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div> |
| | | <template v-for="(item, index) in options"> |
| | | <template v-if="values.includes(item.value)"> |
| | | <span |
| | | v-if="item.elTagType == 'default' || item.elTagType == ''" |
| | | :key="item.value" |
| | | :index="index" |
| | | :class="item.elTagClass" |
| | | >{{ item.label }}</span |
| | | > |
| | | <el-tag |
| | | v-else |
| | | :disable-transitions="true" |
| | | :key="item.value + ''" |
| | | :index="index" |
| | | :type="item.elTagType === 'primary' ? '' : item.elTagType" |
| | | :class="item.elTagClass" |
| | | >{{ item.label }}</el-tag |
| | | > |
| | | </template> |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped> |
| | | .el-tag + .el-tag { |
| | |
| | | <template> |
| | | <div> |
| | | <el-upload |
| | | :action="upload.url" |
| | | :before-upload="handleBeforeUpload" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | class="editor-img-uploader" |
| | | name="file" |
| | | :show-file-list="false" |
| | | :headers="upload.headers" |
| | | style="display: none" |
| | | v-if="type === 'url'" |
| | | > |
| | | </el-upload> |
| | | <div class="editor"> |
| | | <quill-editor |
| | | ref="myQuillEditor" |
| | | v-model:content="content" |
| | | contentType="html" |
| | | @textChange="(e: any) => $emit('update:modelValue', content)" |
| | | :options="options" |
| | | :style="styles" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { QuillEditor, Quill } from '@vueup/vue-quill'; |
| | | import '@vueup/vue-quill/dist/vue-quill.snow.css'; |
| | |
| | | import { ComponentInternalInstance } from "vue"; |
| | | |
| | | const props = defineProps({ |
| | | /* ç¼è¾å¨çå
容 */ |
| | | modelValue: { |
| | | type: String, |
| | | }, |
| | | /* é«åº¦ */ |
| | | height: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | /* æå°é«åº¦ */ |
| | | minHeight: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | /* åªè¯» */ |
| | | readOnly: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | /* ä¸ä¼ æä»¶å¤§å°éå¶(MB) */ |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | /* ç±»åï¼base64æ ¼å¼ãurlæ ¼å¼ï¼ */ |
| | | type: { |
| | | type: String, |
| | | default: "url", |
| | | } |
| | | /* ç¼è¾å¨çå
容 */ |
| | | modelValue: { |
| | | type: String, |
| | | }, |
| | | /* é«åº¦ */ |
| | | height: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | /* æå°é«åº¦ */ |
| | | minHeight: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | /* åªè¯» */ |
| | | readOnly: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | /* ä¸ä¼ æä»¶å¤§å°éå¶(MB) */ |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | /* ç±»åï¼base64æ ¼å¼ãurlæ ¼å¼ï¼ */ |
| | | type: { |
| | | type: String, |
| | | default: "url", |
| | | } |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | | const upload = reactive<UploadOption>({ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | url: import.meta.env.VITE_APP_BASE_API + '/system/oss/upload' |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | url: import.meta.env.VITE_APP_BASE_API + '/system/oss/upload' |
| | | }) |
| | | const myQuillEditor = ref(); |
| | | |
| | | const options = ref({ |
| | | theme: "snow", |
| | | bounds: document.body, |
| | | debug: "warn", |
| | | modules: { |
| | | // å·¥å
·æ é
ç½® |
| | | toolbar: { |
| | | container: [ |
| | | ["bold", "italic", "underline", "strike"], // å ç² æä½ ä¸å线 å é¤çº¿ |
| | | ["blockquote", "code-block"], // å¼ç¨ 代ç å |
| | | [{ list: "ordered" }, { list: "bullet"} ], // æåºãæ åºå表 |
| | | [{ indent: "-1" }, { indent: "+1" }], // ç¼©è¿ |
| | | [{ size: ["small", false, "large", "huge"] }], // åä½å¤§å° |
| | | [{ header: [1, 2, 3, 4, 5, 6, false] }], // æ é¢ |
| | | [{ color: [] }, { background: [] }], // åä½é¢è²ãåä½èæ¯é¢è² |
| | | [{ align: [] }], // 坹齿¹å¼ |
| | | ["clean"], // æ¸
é¤ææ¬æ ¼å¼ |
| | | ["link", "image", "video"] // 龿¥ãå¾çãè§é¢ |
| | | ], |
| | | handlers: { |
| | | image: function (value: any) { |
| | | if (value) { |
| | | // è°ç¨elementå¾çä¸ä¼ |
| | | (document.querySelector(".editor-img-uploader>.el-upload") as HTMLDivElement)?.click(); |
| | | } else { |
| | | Quill.format("image", true); |
| | | } |
| | | }, |
| | | }, |
| | | } |
| | | }, |
| | | placeholder: '请è¾å
¥å
容', |
| | | readOnly: props.readOnly, |
| | | theme: "snow", |
| | | bounds: document.body, |
| | | debug: "warn", |
| | | modules: { |
| | | // å·¥å
·æ é
ç½® |
| | | toolbar: { |
| | | container: [ |
| | | ["bold", "italic", "underline", "strike"], // å ç² æä½ ä¸å线 å é¤çº¿ |
| | | ["blockquote", "code-block"], // å¼ç¨ 代ç å |
| | | [{ list: "ordered" }, { list: "bullet"} ], // æåºãæ åºå表 |
| | | [{ indent: "-1" }, { indent: "+1" }], // ç¼©è¿ |
| | | [{ size: ["small", false, "large", "huge"] }], // åä½å¤§å° |
| | | [{ header: [1, 2, 3, 4, 5, 6, false] }], // æ é¢ |
| | | [{ color: [] }, { background: [] }], // åä½é¢è²ãåä½èæ¯é¢è² |
| | | [{ align: [] }], // 坹齿¹å¼ |
| | | ["clean"], // æ¸
é¤ææ¬æ ¼å¼ |
| | | ["link", "image", "video"] // 龿¥ãå¾çãè§é¢ |
| | | ], |
| | | handlers: { |
| | | image: function (value: any) { |
| | | if (value) { |
| | | // è°ç¨elementå¾çä¸ä¼ |
| | | (document.querySelector(".editor-img-uploader>.el-upload") as HTMLDivElement)?.click(); |
| | | } else { |
| | | Quill.format("image", true); |
| | | } |
| | | }, |
| | | }, |
| | | } |
| | | }, |
| | | placeholder: '请è¾å
¥å
容', |
| | | readOnly: props.readOnly, |
| | | }); |
| | | |
| | | const styles = computed(() => { |
| | | let style: any = {}; |
| | | if (props.minHeight) { |
| | | style.minHeight = `${props.minHeight}px`; |
| | | } |
| | | if (props.height) { |
| | | style.height = `${props.height}px`; |
| | | } |
| | | return style; |
| | | let style: any = {}; |
| | | if (props.minHeight) { |
| | | style.minHeight = `${props.minHeight}px`; |
| | | } |
| | | if (props.height) { |
| | | style.height = `${props.height}px`; |
| | | } |
| | | return style; |
| | | }) |
| | | |
| | | const content = ref(""); |
| | | watch(() => props.modelValue, (v) => { |
| | | if (v !== content.value) { |
| | | content.value = v === undefined ? "<p></p>" : v; |
| | | } |
| | | if (v !== content.value) { |
| | | content.value = v === undefined ? "<p></p>" : v; |
| | | } |
| | | }, { immediate: true }); |
| | | |
| | | // å¾çä¸ä¼ æåè¿åå¾çå°å |
| | | const handleUploadSuccess = (res: any) => { |
| | | // è·å坿æ¬å®ä¾ |
| | | let quill = toRaw(myQuillEditor.value).getQuill(); |
| | | // 妿ä¸ä¼ æå |
| | | if (res.code === 200) { |
| | | // è·åå
æ ä½ç½® |
| | | let length = quill.selection.savedRange.index; |
| | | // æå
¥å¾çï¼res为æå¡å¨è¿åçå¾ç龿¥å°å |
| | | quill.insertEmbed(length, "image", res.data.url); |
| | | // è°æ´å
æ å°æå |
| | | quill.setSelection(length + 1); |
| | | proxy?.$modal.closeLoading(); |
| | | } else { |
| | | proxy?.$modal.loading(res.msg); |
| | | proxy?.$modal.closeLoading(); |
| | | } |
| | | // è·å坿æ¬å®ä¾ |
| | | let quill = toRaw(myQuillEditor.value).getQuill(); |
| | | // 妿ä¸ä¼ æå |
| | | if (res.code === 200) { |
| | | // è·åå
æ ä½ç½® |
| | | let length = quill.selection.savedRange.index; |
| | | // æå
¥å¾çï¼res为æå¡å¨è¿åçå¾ç龿¥å°å |
| | | quill.insertEmbed(length, "image", res.data.url); |
| | | // è°æ´å
æ å°æå |
| | | quill.setSelection(length + 1); |
| | | proxy?.$modal.closeLoading(); |
| | | } else { |
| | | proxy?.$modal.loading(res.msg); |
| | | proxy?.$modal.closeLoading(); |
| | | } |
| | | } |
| | | |
| | | // å¾çä¸ä¼ åæ¦æª |
| | | const handleBeforeUpload = (file: any) => { |
| | | // æ ¡æ£æä»¶å¤§å° |
| | | if (props.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < props.fileSize; |
| | | if (!isLt) { |
| | | proxy?.$modal.msgError(`ä¸ä¼ æä»¶å¤§å°ä¸è½è¶
è¿ ${props.fileSize} MB!`); |
| | | return false; |
| | | // æ ¡æ£æä»¶å¤§å° |
| | | if (props.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < props.fileSize; |
| | | if (!isLt) { |
| | | proxy?.$modal.msgError(`ä¸ä¼ æä»¶å¤§å°ä¸è½è¶
è¿ ${props.fileSize} MB!`); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | proxy?.$modal.loading('æ£å¨ä¸ä¼ æä»¶ï¼è¯·ç¨å...'); |
| | | return true; |
| | | proxy?.$modal.loading('æ£å¨ä¸ä¼ æä»¶ï¼è¯·ç¨å...'); |
| | | return true; |
| | | } |
| | | |
| | | // å¾çå¤±è´¥æ¦æª |
| | | const handleUploadError = (err: any) => { |
| | | console.error(err); |
| | | proxy?.$modal.msgError('ä¸ä¼ æä»¶å¤±è´¥'); |
| | | console.error(err); |
| | | proxy?.$modal.msgError('ä¸ä¼ æä»¶å¤±è´¥'); |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div> |
| | | <el-upload |
| | | :action="upload.url" |
| | | :before-upload="handleBeforeUpload" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | class="editor-img-uploader" |
| | | name="file" |
| | | :show-file-list="false" |
| | | :headers="upload.headers" |
| | | style="display: none" |
| | | v-if="type === 'url'" |
| | | > |
| | | </el-upload> |
| | | <div class="editor"> |
| | | <quill-editor |
| | | ref="myQuillEditor" |
| | | v-model:content="content" |
| | | contentType="html" |
| | | @textChange="(e: any) => $emit('update:modelValue', content)" |
| | | :options="options" |
| | | :style="styles" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style> |
| | | .editor, .ql-toolbar { |
| | |
| | | <template> |
| | | <div class="upload-file"> |
| | | <el-upload |
| | | multiple |
| | | :action="uploadFileUrl" |
| | | :before-upload="handleBeforeUpload" |
| | | :file-list="fileList" |
| | | :limit="limit" |
| | | :on-error="handleUploadError" |
| | | :on-exceed="handleExceed" |
| | | :on-success="handleUploadSuccess" |
| | | :show-file-list="false" |
| | | :headers="headers" |
| | | class="upload-file-uploader" |
| | | ref="fileUploadRef" |
| | | > |
| | | <!-- ä¸ä¼ æé® --> |
| | | <el-button type="primary">éåæä»¶</el-button> |
| | | </el-upload> |
| | | <!-- ä¸ä¼ æç¤º --> |
| | | <div class="el-upload__tip" v-if="showTip"> |
| | | 请ä¸ä¼ |
| | | <template v-if="fileSize"> |
| | | 大å°ä¸è¶
è¿ <b style="color: #f56c6c">{{ fileSize }}MB</b> |
| | | </template> |
| | | <template v-if="fileType"> |
| | | æ ¼å¼ä¸º <b style="color: #f56c6c">{{ fileType.join("/") }}</b> |
| | | </template> |
| | | çæä»¶ |
| | | </div> |
| | | <!-- æä»¶å表 --> |
| | | <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"> |
| | | <li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList"> |
| | | <el-link :href="`${file.url}`" :underline="false" target="_blank"> |
| | | <span class="el-icon-document"> {{ getFileName(file.name) }} </span> |
| | | </el-link> |
| | | <div class="ele-upload-list__item-content-action"> |
| | | <el-link :underline="false" @click="handleDelete(index)" type="danger">å é¤</el-link> |
| | | </div> |
| | | </li> |
| | | </transition-group> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { getToken } from "@/utils/auth"; |
| | | import { listByIds, delOss } from "@/api/system/oss"; |
| | |
| | | import { ElUpload, UploadFile } from "element-plus"; |
| | | |
| | | const props = defineProps({ |
| | | modelValue: [String, Object, Array], |
| | | // æ°ééå¶ |
| | | limit: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | // 大å°éå¶(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | // æä»¶ç±»å, ä¾å¦['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array, |
| | | default: () => ["doc", "xls", "ppt", "txt", "pdf"], |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºæç¤º |
| | | isShowTip: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | modelValue: [String, Object, Array], |
| | | // æ°ééå¶ |
| | | limit: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | // 大å°éå¶(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | // æä»¶ç±»å, ä¾å¦['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array, |
| | | default: () => ["doc", "xls", "ppt", "txt", "pdf"], |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºæç¤º |
| | | isShowTip: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | |
| | | const fileList = ref<any[]>([]); |
| | | const showTip = computed( |
| | | () => props.isShowTip && (props.fileType || props.fileSize) |
| | | () => props.isShowTip && (props.fileType || props.fileSize) |
| | | ); |
| | | |
| | | const fileUploadRef = ref(ElUpload); |
| | | |
| | | watch(() => props.modelValue, async val => { |
| | | if (val) { |
| | | let temp = 1; |
| | | // é¦å
å°å¼è½¬ä¸ºæ°ç» |
| | | let list = []; |
| | | if (Array.isArray(val)) { |
| | | list = val; |
| | | } else { |
| | | const res = await listByIds(val as string) |
| | | list = res.data.map((oss) => { |
| | | const data = { name: oss.originalName, url: oss.url, ossId: oss.ossId }; |
| | | return data; |
| | | if (val) { |
| | | let temp = 1; |
| | | // é¦å
å°å¼è½¬ä¸ºæ°ç» |
| | | let list = []; |
| | | if (Array.isArray(val)) { |
| | | list = val; |
| | | } else { |
| | | const res = await listByIds(val as string) |
| | | list = res.data.map((oss) => { |
| | | const data = { name: oss.originalName, url: oss.url, ossId: oss.ossId }; |
| | | return data; |
| | | }); |
| | | } |
| | | // ç¶åå°æ°ç»è½¬ä¸ºå¯¹è±¡æ°ç» |
| | | fileList.value = list.map(item => { |
| | | item = {name: item.name, url: item.url, ossId: item.ossId}; |
| | | item.uid = item.uid || new Date().getTime() + temp++; |
| | | return item; |
| | | }); |
| | | } else { |
| | | fileList.value = []; |
| | | return []; |
| | | } |
| | | // ç¶åå°æ°ç»è½¬ä¸ºå¯¹è±¡æ°ç» |
| | | fileList.value = list.map(item => { |
| | | item = {name: item.name, url: item.url, ossId: item.ossId}; |
| | | item.uid = item.uid || new Date().getTime() + temp++; |
| | | return item; |
| | | }); |
| | | } else { |
| | | fileList.value = []; |
| | | return []; |
| | | } |
| | | },{ deep: true, immediate: true }); |
| | | |
| | | // ä¸ä¼ åæ ¡æ£æ ¼å¼åå¤§å° |
| | | const handleBeforeUpload = (file: any) => { |
| | | // æ ¡æ£æä»¶ç±»å |
| | | if (props.fileType.length) { |
| | | const fileName = file.name.split('.'); |
| | | const fileExt = fileName[fileName.length - 1]; |
| | | const isTypeOk = props.fileType.indexOf(fileExt) >= 0; |
| | | if (!isTypeOk) { |
| | | proxy?.$modal.msgError(`æä»¶æ ¼å¼ä¸æ£ç¡®, 请ä¸ä¼ ${props.fileType.join("/")}æ ¼å¼æä»¶!`); |
| | | return false; |
| | | // æ ¡æ£æä»¶ç±»å |
| | | if (props.fileType.length) { |
| | | const fileName = file.name.split('.'); |
| | | const fileExt = fileName[fileName.length - 1]; |
| | | const isTypeOk = props.fileType.indexOf(fileExt) >= 0; |
| | | if (!isTypeOk) { |
| | | proxy?.$modal.msgError(`æä»¶æ ¼å¼ä¸æ£ç¡®, 请ä¸ä¼ ${props.fileType.join("/")}æ ¼å¼æä»¶!`); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | // æ ¡æ£æä»¶å¤§å° |
| | | if (props.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < props.fileSize; |
| | | if (!isLt) { |
| | | proxy?.$modal.msgError(`ä¸ä¼ æä»¶å¤§å°ä¸è½è¶
è¿ ${props.fileSize} MB!`); |
| | | return false; |
| | | // æ ¡æ£æä»¶å¤§å° |
| | | if (props.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < props.fileSize; |
| | | if (!isLt) { |
| | | proxy?.$modal.msgError(`ä¸ä¼ æä»¶å¤§å°ä¸è½è¶
è¿ ${props.fileSize} MB!`); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | proxy?.$modal.loading("æ£å¨ä¸ä¼ æä»¶ï¼è¯·ç¨å..."); |
| | | number.value++; |
| | | return true; |
| | | proxy?.$modal.loading("æ£å¨ä¸ä¼ æä»¶ï¼è¯·ç¨å..."); |
| | | number.value++; |
| | | return true; |
| | | } |
| | | |
| | | // æä»¶ä¸ªæ°è¶
åº |
| | | const handleExceed = () => { |
| | | proxy?.$modal.msgError(`ä¸ä¼ æä»¶æ°éä¸è½è¶
è¿ ${props.limit} 个!`); |
| | | proxy?.$modal.msgError(`ä¸ä¼ æä»¶æ°éä¸è½è¶
è¿ ${props.limit} 个!`); |
| | | } |
| | | |
| | | // ä¸ä¼ 失败 |
| | | const handleUploadError = () => { |
| | | proxy?.$modal.msgError("ä¸ä¼ æä»¶å¤±è´¥"); |
| | | proxy?.$modal.msgError("ä¸ä¼ æä»¶å¤±è´¥"); |
| | | } |
| | | |
| | | // ä¸ä¼ æååè° |
| | | const handleUploadSuccess = (res:any, file: UploadFile) => { |
| | | if (res.code === 200) { |
| | | uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId }); |
| | | uploadedSuccessfully(); |
| | | } else { |
| | | number.value--; |
| | | proxy?.$modal.closeLoading(); |
| | | proxy?.$modal.msgError(res.msg); |
| | | fileUploadRef.value.handleRemove(file); |
| | | uploadedSuccessfully(); |
| | | } |
| | | if (res.code === 200) { |
| | | uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId }); |
| | | uploadedSuccessfully(); |
| | | } else { |
| | | number.value--; |
| | | proxy?.$modal.closeLoading(); |
| | | proxy?.$modal.msgError(res.msg); |
| | | fileUploadRef.value.handleRemove(file); |
| | | uploadedSuccessfully(); |
| | | } |
| | | } |
| | | |
| | | // å 餿件 |
| | | const handleDelete = (index: number) => { |
| | | let ossId = fileList.value[index].ossId; |
| | | delOss(ossId); |
| | | fileList.value.splice(index, 1); |
| | | emit("update:modelValue", listToString(fileList.value)); |
| | | let ossId = fileList.value[index].ossId; |
| | | delOss(ossId); |
| | | fileList.value.splice(index, 1); |
| | | emit("update:modelValue", listToString(fileList.value)); |
| | | } |
| | | |
| | | // ä¸ä¼ ç»æå¤ç |
| | | const uploadedSuccessfully =() => { |
| | | if (number.value > 0 && uploadList.value.length === number.value) { |
| | | fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value); |
| | | uploadList.value = []; |
| | | number.value = 0; |
| | | emit("update:modelValue", listToString(fileList.value)); |
| | | proxy?.$modal.closeLoading(); |
| | | } |
| | | if (number.value > 0 && uploadList.value.length === number.value) { |
| | | fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value); |
| | | uploadList.value = []; |
| | | number.value = 0; |
| | | emit("update:modelValue", listToString(fileList.value)); |
| | | proxy?.$modal.closeLoading(); |
| | | } |
| | | } |
| | | |
| | | // è·åæä»¶åç§° |
| | | const getFileName = (name: string) => { |
| | | // 妿æ¯urlé£ä¹åæåçåå 妿䏿¯ç´æ¥è¿å |
| | | if (name.lastIndexOf("/") > -1) { |
| | | return name.slice(name.lastIndexOf("/") + 1); |
| | | } else { |
| | | return name; |
| | | } |
| | | // 妿æ¯urlé£ä¹åæåçåå 妿䏿¯ç´æ¥è¿å |
| | | if (name.lastIndexOf("/") > -1) { |
| | | return name.slice(name.lastIndexOf("/") + 1); |
| | | } else { |
| | | return name; |
| | | } |
| | | } |
| | | |
| | | // 对象转ææå®å符串åé |
| | | const listToString = (list: any[], separator?: string) => { |
| | | let strs = ""; |
| | | separator = separator || ","; |
| | | list.forEach(item => { |
| | | if (item.ossId) { |
| | | strs += item.ossId + separator; |
| | | } |
| | | }) |
| | | return strs != "" ? strs.substring(0, strs.length - 1) : ""; |
| | | let strs = ""; |
| | | separator = separator || ","; |
| | | list.forEach(item => { |
| | | if (item.ossId) { |
| | | strs += item.ossId + separator; |
| | | } |
| | | }) |
| | | return strs != "" ? strs.substring(0, strs.length - 1) : ""; |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="upload-file"> |
| | | <el-upload |
| | | multiple |
| | | :action="uploadFileUrl" |
| | | :before-upload="handleBeforeUpload" |
| | | :file-list="fileList" |
| | | :limit="limit" |
| | | :on-error="handleUploadError" |
| | | :on-exceed="handleExceed" |
| | | :on-success="handleUploadSuccess" |
| | | :show-file-list="false" |
| | | :headers="headers" |
| | | class="upload-file-uploader" |
| | | ref="fileUploadRef" |
| | | > |
| | | <!-- ä¸ä¼ æé® --> |
| | | <el-button type="primary">éåæä»¶</el-button> |
| | | </el-upload> |
| | | <!-- ä¸ä¼ æç¤º --> |
| | | <div class="el-upload__tip" v-if="showTip"> |
| | | 请ä¸ä¼ |
| | | <template v-if="fileSize"> |
| | | 大å°ä¸è¶
è¿ <b style="color: #f56c6c">{{ fileSize }}MB</b> |
| | | </template> |
| | | <template v-if="fileType"> |
| | | æ ¼å¼ä¸º <b style="color: #f56c6c">{{ fileType.join("/") }}</b> |
| | | </template> |
| | | çæä»¶ |
| | | </div> |
| | | <!-- æä»¶å表 --> |
| | | <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"> |
| | | <li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList"> |
| | | <el-link :href="`${file.url}`" :underline="false" target="_blank"> |
| | | <span class="el-icon-document"> {{ getFileName(file.name) }} </span> |
| | | </el-link> |
| | | <div class="ele-upload-list__item-content-action"> |
| | | <el-link :underline="false" @click="handleDelete(index)" type="danger">å é¤</el-link> |
| | | </div> |
| | | </li> |
| | | </transition-group> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .upload-file-uploader { |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <div style="padding: 0 15px;" @click="toggleClick"> |
| | | <svg :class="{'is-active':isActive}" class="hamburger" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64"> |
| | | <path |
| | | d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" |
| | | /> |
| | | </svg> |
| | | </div> |
| | | <div style="padding: 0 15px;" @click="toggleClick"> |
| | | <svg :class="{'is-active':isActive}" class="hamburger" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64"> |
| | | <path |
| | | d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" |
| | | /> |
| | | </svg> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped> |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <div :class="{ 'show': show }" class="header-search"> |
| | | <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> |
| | | <el-select |
| | | ref="headerSearchSelectRef" |
| | | v-model="search" |
| | | :remote-method="querySearch" |
| | | filterable |
| | | default-first-option |
| | | remote |
| | | placeholder="Search" |
| | | class="header-search-select" |
| | | @change="change" |
| | | > |
| | | <el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" /> |
| | | </el-select> |
| | | </div> |
| | | <div :class="{ 'show': show }" class="header-search"> |
| | | <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> |
| | | <el-select |
| | | ref="headerSearchSelectRef" |
| | | v-model="search" |
| | | :remote-method="querySearch" |
| | | filterable |
| | | default-first-option |
| | | remote |
| | | placeholder="Search" |
| | | class="header-search-select" |
| | | @change="change" |
| | | > |
| | | <el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" /> |
| | | </el-select> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="relative" :style="{ width: width }"> |
| | | <el-input v-model="modelValue" readonly @click="visible = !visible" placeholder="ç¹å»éæ©å¾æ "> |
| | | <template #prepend> |
| | | <svg-icon :icon-class="modelValue as string"></svg-icon> |
| | | </template> |
| | | </el-input> |
| | | <div class="relative" :style="{ width: width }"> |
| | | <el-input v-model="modelValue" readonly @click="visible = !visible" placeholder="ç¹å»éæ©å¾æ "> |
| | | <template #prepend> |
| | | <svg-icon :icon-class="modelValue as string"></svg-icon> |
| | | </template> |
| | | </el-input> |
| | | |
| | | <el-popover shadow="none" :visible="visible" placement="bottom-end" trigger="click" :width="450"> |
| | | <template #reference> |
| | | <div @click="visible = !visible" class="cursor-pointer text-[#999] absolute right-[10px] top-0 height-[32px] leading-[32px]"> |
| | | <i-ep-caret-top v-show="visible"></i-ep-caret-top> |
| | | <i-ep-caret-bottom v-show="!visible"></i-ep-caret-bottom> |
| | | </div> |
| | | </template> |
| | | <el-popover shadow="none" :visible="visible" placement="bottom-end" trigger="click" :width="450"> |
| | | <template #reference> |
| | | <div @click="visible = !visible" class="cursor-pointer text-[#999] absolute right-[10px] top-0 height-[32px] leading-[32px]"> |
| | | <i-ep-caret-top v-show="visible"></i-ep-caret-top> |
| | | <i-ep-caret-bottom v-show="!visible"></i-ep-caret-bottom> |
| | | </div> |
| | | </template> |
| | | |
| | | <el-input class="p-2" v-model="filterValue" placeholder="æç´¢å¾æ " clearable @input="filterIcons" /> |
| | | <el-input class="p-2" v-model="filterValue" placeholder="æç´¢å¾æ " clearable @input="filterIcons" /> |
| | | |
| | | <el-scrollbar height="w-[200px]"> |
| | | <ul class="icon-list"> |
| | | <el-tooltip v-for="(iconName, index) in iconNames" :key="index" :content="iconName" placement="bottom" effect="light"> |
| | | <li class="icon-item" @click="selectedIcon(iconName)"> |
| | | <svg-icon color="var(--el-text-color-regular)" :icon-class="iconName" /> |
| | | </li> |
| | | </el-tooltip> |
| | | </ul> |
| | | </el-scrollbar> |
| | | </el-popover> |
| | | </div> |
| | | <el-scrollbar height="w-[200px]"> |
| | | <ul class="icon-list"> |
| | | <el-tooltip v-for="(iconName, index) in iconNames" :key="index" :content="iconName" placement="bottom" effect="light"> |
| | | <li class="icon-item" @click="selectedIcon(iconName)"> |
| | | <svg-icon color="var(--el-text-color-regular)" :icon-class="iconName" /> |
| | | </li> |
| | | </el-tooltip> |
| | | </ul> |
| | | </el-scrollbar> |
| | | </el-popover> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | |
| | | 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); |
| | | const p = path.split('assets/icons/svg/')[1].split('.svg')[0]; |
| | | icons.push(p); |
| | | } |
| | | export default icons; |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList" preview-teleported> |
| | | <template #error> |
| | | <div class="image-slot"> |
| | | <el-icon><picture-filled /></el-icon> |
| | | </div> |
| | | </template> |
| | | </el-image> |
| | | <el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList" preview-teleported> |
| | | <template #error> |
| | | <div class="image-slot"> |
| | | <el-icon><picture-filled /></el-icon> |
| | | </div> |
| | | </template> |
| | | </el-image> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | <template> |
| | | <div class="component-upload-image"> |
| | | <el-upload |
| | | multiple |
| | | :action="uploadImgUrl" |
| | | list-type="picture-card" |
| | | :on-success="handleUploadSuccess" |
| | | :before-upload="handleBeforeUpload" |
| | | :limit="limit" |
| | | :on-error="handleUploadError" |
| | | :on-exceed="handleExceed" |
| | | ref="imageUpload" |
| | | :before-remove="handleDelete" |
| | | :show-file-list="true" |
| | | :headers="headers" |
| | | :file-list="fileList" |
| | | :on-preview="handlePictureCardPreview" |
| | | :class="{ hide: fileList.length >= limit }" |
| | | > |
| | | <el-icon class="avatar-uploader-icon"><plus /></el-icon> |
| | | </el-upload> |
| | | <!-- ä¸ä¼ æç¤º --> |
| | | <div class="el-upload__tip" v-if="showTip"> |
| | | 请ä¸ä¼ |
| | | <template v-if="fileSize"> |
| | | 大å°ä¸è¶
è¿ <b style="color: #f56c6c">{{ fileSize }}MB</b> |
| | | </template> |
| | | <template v-if="fileType"> |
| | | æ ¼å¼ä¸º <b style="color: #f56c6c">{{ fileType.join("/") }}</b> |
| | | </template> |
| | | çæä»¶ |
| | | </div> |
| | | |
| | | <el-dialog v-model="dialogVisible" title="é¢è§" width="800px" append-to-body> |
| | | <img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" /> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { getToken } from "@/utils/auth"; |
| | | import { listByIds, delOss } from "@/api/system/oss"; |
| | |
| | | import { ElUpload, UploadFile } from "element-plus"; |
| | | |
| | | const props = defineProps({ |
| | | modelValue: [String, Object, Array], |
| | | // å¾çæ°ééå¶ |
| | | limit: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | // 大å°éå¶(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | // æä»¶ç±»å, ä¾å¦['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array as PropType<string[]>, |
| | | default: () => ["png", "jpg", "jpeg"], |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºæç¤º |
| | | isShowTip: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | modelValue: [String, Object, Array], |
| | | // å¾çæ°ééå¶ |
| | | limit: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | // 大å°éå¶(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | // æä»¶ç±»å, ä¾å¦['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array as PropType<string[]>, |
| | | default: () => ["png", "jpg", "jpeg"], |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºæç¤º |
| | | isShowTip: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | |
| | | const fileList = ref<any[]>([]); |
| | | const showTip = computed( |
| | | () => props.isShowTip && (props.fileType || props.fileSize) |
| | | () => props.isShowTip && (props.fileType || props.fileSize) |
| | | ); |
| | | |
| | | const imageUploadRef = ref(ElUpload); |
| | | |
| | | watch(() => props.modelValue, async val => { |
| | | if (val) { |
| | | // é¦å
å°å¼è½¬ä¸ºæ°ç» |
| | | let list:OssVO[] = []; |
| | | if (Array.isArray(val)) { |
| | | list = val as OssVO[]; |
| | | if (val) { |
| | | // é¦å
å°å¼è½¬ä¸ºæ°ç» |
| | | let list:OssVO[] = []; |
| | | if (Array.isArray(val)) { |
| | | list = val as OssVO[]; |
| | | } else { |
| | | const res = await listByIds(val as string) |
| | | list = res.data |
| | | } |
| | | // ç¶åå°æ°ç»è½¬ä¸ºå¯¹è±¡æ°ç» |
| | | fileList.value = list.map(item => { |
| | | // åç¬¦ä¸²åæ¾å¤ç 妿æ¤å¤åçæ¯urlå¯ç´æ¥åæ¾ å¦æåçæ¯idéè¦è°ç¨æ¥å£æ¥åºæ¥ |
| | | let itemData; |
| | | if (typeof item === "string") { |
| | | itemData = { name: item, url: item }; |
| | | } else { |
| | | // æ¤å¤name使ç¨ossId 鲿¢å é¤åºç°éå |
| | | itemData = { name: item.ossId, url: item.url, ossId: item.ossId }; |
| | | } |
| | | return itemData; |
| | | }); |
| | | } else { |
| | | const res = await listByIds(val as string) |
| | | list = res.data |
| | | fileList.value = []; |
| | | return []; |
| | | } |
| | | // ç¶åå°æ°ç»è½¬ä¸ºå¯¹è±¡æ°ç» |
| | | fileList.value = list.map(item => { |
| | | // åç¬¦ä¸²åæ¾å¤ç 妿æ¤å¤åçæ¯urlå¯ç´æ¥åæ¾ å¦æåçæ¯idéè¦è°ç¨æ¥å£æ¥åºæ¥ |
| | | let itemData; |
| | | if (typeof item === "string") { |
| | | itemData = { name: item, url: item }; |
| | | } else { |
| | | // æ¤å¤name使ç¨ossId 鲿¢å é¤åºç°éå |
| | | itemData = { name: item.ossId, url: item.url, ossId: item.ossId }; |
| | | } |
| | | return itemData; |
| | | }); |
| | | } else { |
| | | fileList.value = []; |
| | | return []; |
| | | } |
| | | },{ deep: true, immediate: true }); |
| | | |
| | | /** ä¸ä¼ åloadingå è½½ */ |
| | | const handleBeforeUpload = (file: any) => { |
| | | let isImg = false; |
| | | if (props.fileType.length) { |
| | | let fileExtension = ""; |
| | | if (file.name.lastIndexOf(".") > -1) { |
| | | fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1); |
| | | let isImg = false; |
| | | if (props.fileType.length) { |
| | | let fileExtension = ""; |
| | | if (file.name.lastIndexOf(".") > -1) { |
| | | fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1); |
| | | } |
| | | isImg = props.fileType.some((type) => { |
| | | if (file.type.indexOf(type) > -1) return true; |
| | | if (fileExtension && fileExtension.indexOf(type) > -1) return true; |
| | | return false; |
| | | }); |
| | | } else { |
| | | isImg = file.type.indexOf("image") > -1; |
| | | } |
| | | isImg = props.fileType.some((type) => { |
| | | if (file.type.indexOf(type) > -1) return true; |
| | | if (fileExtension && fileExtension.indexOf(type) > -1) return true; |
| | | return false; |
| | | }); |
| | | } else { |
| | | isImg = file.type.indexOf("image") > -1; |
| | | } |
| | | if (!isImg) { |
| | | proxy?.$modal.msgError( |
| | | `æä»¶æ ¼å¼ä¸æ£ç¡®, 请ä¸ä¼ ${props.fileType.join("/")}å¾çæ ¼å¼æä»¶!` |
| | | ); |
| | | return false; |
| | | } |
| | | if (props.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < props.fileSize; |
| | | if (!isLt) { |
| | | proxy?.$modal.msgError(`ä¸ä¼ 头åå¾ç大å°ä¸è½è¶
è¿ ${props.fileSize} MB!`); |
| | | return false; |
| | | if (!isImg) { |
| | | proxy?.$modal.msgError( |
| | | `æä»¶æ ¼å¼ä¸æ£ç¡®, 请ä¸ä¼ ${props.fileType.join("/")}å¾çæ ¼å¼æä»¶!` |
| | | ); |
| | | return false; |
| | | } |
| | | } |
| | | proxy?.$modal.loading("æ£å¨ä¸ä¼ å¾çï¼è¯·ç¨å..."); |
| | | number.value++; |
| | | if (props.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < props.fileSize; |
| | | if (!isLt) { |
| | | proxy?.$modal.msgError(`ä¸ä¼ 头åå¾ç大å°ä¸è½è¶
è¿ ${props.fileSize} MB!`); |
| | | return false; |
| | | } |
| | | } |
| | | proxy?.$modal.loading("æ£å¨ä¸ä¼ å¾çï¼è¯·ç¨å..."); |
| | | number.value++; |
| | | } |
| | | |
| | | // æä»¶ä¸ªæ°è¶
åº |
| | | const handleExceed = () => { |
| | | proxy?.$modal.msgError(`ä¸ä¼ æä»¶æ°éä¸è½è¶
è¿ ${props.limit} 个!`); |
| | | proxy?.$modal.msgError(`ä¸ä¼ æä»¶æ°éä¸è½è¶
è¿ ${props.limit} 个!`); |
| | | } |
| | | |
| | | // ä¸ä¼ æååè° |
| | | const handleUploadSuccess = (res: any, file: UploadFile) => { |
| | | if (res.code === 200) { |
| | | uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId }); |
| | | uploadedSuccessfully(); |
| | | } else { |
| | | number.value--; |
| | | proxy?.$modal.closeLoading(); |
| | | proxy?.$modal.msgError(res.msg); |
| | | imageUploadRef.value.handleRemove(file); |
| | | uploadedSuccessfully(); |
| | | } |
| | | if (res.code === 200) { |
| | | uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId }); |
| | | uploadedSuccessfully(); |
| | | } else { |
| | | number.value--; |
| | | proxy?.$modal.closeLoading(); |
| | | proxy?.$modal.msgError(res.msg); |
| | | imageUploadRef.value.handleRemove(file); |
| | | uploadedSuccessfully(); |
| | | } |
| | | } |
| | | |
| | | // å é¤å¾ç |
| | | const handleDelete = (file: UploadFile): boolean => { |
| | | const findex = fileList.value.map(f => f.name).indexOf(file.name); |
| | | if (findex > -1 && uploadList.value.length === number.value) { |
| | | let ossId = fileList.value[findex].ossId; |
| | | delOss(ossId); |
| | | fileList.value.splice(findex, 1); |
| | | emit("update:modelValue", listToString(fileList.value)); |
| | | return false; |
| | | } |
| | | return true; |
| | | const findex = fileList.value.map(f => f.name).indexOf(file.name); |
| | | if (findex > -1 && uploadList.value.length === number.value) { |
| | | let ossId = fileList.value[findex].ossId; |
| | | delOss(ossId); |
| | | fileList.value.splice(findex, 1); |
| | | emit("update:modelValue", listToString(fileList.value)); |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | // ä¸ä¼ ç»æå¤ç |
| | | const uploadedSuccessfully = () => { |
| | | if (number.value > 0 && uploadList.value.length === number.value) { |
| | | fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value); |
| | | uploadList.value = []; |
| | | number.value = 0; |
| | | emit("update:modelValue", listToString(fileList.value)); |
| | | proxy?.$modal.closeLoading(); |
| | | } |
| | | if (number.value > 0 && uploadList.value.length === number.value) { |
| | | fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value); |
| | | uploadList.value = []; |
| | | number.value = 0; |
| | | emit("update:modelValue", listToString(fileList.value)); |
| | | proxy?.$modal.closeLoading(); |
| | | } |
| | | } |
| | | |
| | | // ä¸ä¼ 失败 |
| | | const handleUploadError = () => { |
| | | proxy?.$modal.msgError("ä¸ä¼ å¾ç失败"); |
| | | proxy?.$modal.closeLoading(); |
| | | proxy?.$modal.msgError("ä¸ä¼ å¾ç失败"); |
| | | proxy?.$modal.closeLoading(); |
| | | } |
| | | |
| | | // é¢è§ |
| | | const handlePictureCardPreview = (file: any) => { |
| | | dialogImageUrl.value = file.url; |
| | | dialogVisible.value = true; |
| | | dialogImageUrl.value = file.url; |
| | | dialogVisible.value = true; |
| | | } |
| | | |
| | | // 对象转ææå®å符串åé |
| | | const listToString = (list: any[], separator?: string) => { |
| | | let strs = ""; |
| | | separator = separator || ","; |
| | | for (let i in list) { |
| | | if(undefined !== list[i].ossId && list[i].url.indexOf("blob:") !== 0) { |
| | | strs += list[i].ossId + separator; |
| | | let strs = ""; |
| | | separator = separator || ","; |
| | | for (let i in list) { |
| | | if(undefined !== list[i].ossId && list[i].url.indexOf("blob:") !== 0) { |
| | | strs += list[i].ossId + separator; |
| | | } |
| | | } |
| | | } |
| | | return strs != "" ? strs.substring(0, strs.length - 1) : ""; |
| | | return strs != "" ? strs.substring(0, strs.length - 1) : ""; |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="component-upload-image"> |
| | | <el-upload |
| | | multiple |
| | | :action="uploadImgUrl" |
| | | list-type="picture-card" |
| | | :on-success="handleUploadSuccess" |
| | | :before-upload="handleBeforeUpload" |
| | | :limit="limit" |
| | | :on-error="handleUploadError" |
| | | :on-exceed="handleExceed" |
| | | ref="imageUpload" |
| | | :before-remove="handleDelete" |
| | | :show-file-list="true" |
| | | :headers="headers" |
| | | :file-list="fileList" |
| | | :on-preview="handlePictureCardPreview" |
| | | :class="{ hide: fileList.length >= limit }" |
| | | > |
| | | <el-icon class="avatar-uploader-icon"><plus /></el-icon> |
| | | </el-upload> |
| | | <!-- ä¸ä¼ æç¤º --> |
| | | <div class="el-upload__tip" v-if="showTip"> |
| | | 请ä¸ä¼ |
| | | <template v-if="fileSize"> |
| | | 大å°ä¸è¶
è¿ <b style="color: #f56c6c">{{ fileSize }}MB</b> |
| | | </template> |
| | | <template v-if="fileType"> |
| | | æ ¼å¼ä¸º <b style="color: #f56c6c">{{ fileType.join("/") }}</b> |
| | | </template> |
| | | çæä»¶ |
| | | </div> |
| | | |
| | | <el-dialog v-model="dialogVisible" title="é¢è§" width="800px" append-to-body> |
| | | <img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" /> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | // .el-upload--picture-card æ§å¶å å·é¨å |
| | |
| | | <template> |
| | | <div :class="{ 'hidden': hidden }" class="pagination-container"> |
| | | <el-pagination |
| | | :background="background" |
| | | v-model:current-page="currentPage" |
| | | v-model:page-size="pageSize" |
| | | :layout="layout" |
| | | :page-sizes="pageSizes" |
| | | :pager-count="pagerCount" |
| | | :total="total" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | export default { |
| | | name: 'Pagination' |
| | | name: 'Pagination' |
| | | } |
| | | </script> |
| | | |
| | |
| | | import { PropType } from "vue"; |
| | | |
| | | const props = defineProps({ |
| | | total: { |
| | | required: true, |
| | | type: Number |
| | | }, |
| | | page: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | limit: { |
| | | type: Number, |
| | | default: 20 |
| | | }, |
| | | pageSizes: { |
| | | type: Array as PropType<number[]>, |
| | | default() { |
| | | return [10, 20, 30, 50] |
| | | total: { |
| | | required: true, |
| | | type: Number |
| | | }, |
| | | page: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | limit: { |
| | | type: Number, |
| | | default: 20 |
| | | }, |
| | | pageSizes: { |
| | | type: Array as PropType<number[]>, |
| | | default() { |
| | | return [10, 20, 30, 50] |
| | | } |
| | | }, |
| | | // ç§»å¨ç«¯é¡µç æé®çæ°é端é»è®¤å¼5 |
| | | pagerCount: { |
| | | type: Number, |
| | | default: document.body.clientWidth < 992 ? 5 : 7 |
| | | }, |
| | | layout: { |
| | | type: String, |
| | | default: 'total, sizes, prev, pager, next, jumper' |
| | | }, |
| | | background: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | autoScroll: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | hidden: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | float: { |
| | | type: String, |
| | | default: 'right' |
| | | } |
| | | }, |
| | | // ç§»å¨ç«¯é¡µç æé®çæ°é端é»è®¤å¼5 |
| | | pagerCount: { |
| | | type: Number, |
| | | default: document.body.clientWidth < 992 ? 5 : 7 |
| | | }, |
| | | layout: { |
| | | type: String, |
| | | default: 'total, sizes, prev, pager, next, jumper' |
| | | }, |
| | | background: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | autoScroll: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | hidden: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | float: { |
| | | type: String, |
| | | default: 'right' |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:page', 'update:limit', 'pagination']); |
| | | const currentPage = computed({ |
| | | get() { |
| | | return props.page |
| | | }, |
| | | set(val) { |
| | | emit('update:page', val) |
| | | } |
| | | get() { |
| | | return props.page |
| | | }, |
| | | set(val) { |
| | | emit('update:page', val) |
| | | } |
| | | }) |
| | | const pageSize = computed({ |
| | | get() { |
| | | return props.limit |
| | | }, |
| | | set(val){ |
| | | emit('update:limit', val) |
| | | } |
| | | get() { |
| | | return props.limit |
| | | }, |
| | | set(val){ |
| | | emit('update:limit', val) |
| | | } |
| | | }) |
| | | function handleSizeChange(val: number) { |
| | | if (currentPage.value * val > props.total) { |
| | | currentPage.value = 1 |
| | | } |
| | | emit('pagination', { page: currentPage.value, limit: val }) |
| | | if (props.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | if (currentPage.value * val > props.total) { |
| | | currentPage.value = 1 |
| | | } |
| | | emit('pagination', { page: currentPage.value, limit: val }) |
| | | if (props.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | } |
| | | function handleCurrentChange(val: number) { |
| | | emit('pagination', { page: val, limit: pageSize.value }) |
| | | if (props.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | emit('pagination', { page: val, limit: pageSize.value }) |
| | | if (props.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div :class="{ 'hidden': hidden }" class="pagination-container"> |
| | | <el-pagination |
| | | :background="background" |
| | | v-model:current-page="currentPage" |
| | | v-model:page-size="pageSize" |
| | | :layout="layout" |
| | | :page-sizes="pageSizes" |
| | | :pager-count="pagerCount" |
| | | :total="total" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | .pagination-container { |
| | |
| | | <template> |
| | | <router-view /> |
| | | <router-view /> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="top-right-btn" :style="style"> |
| | | <el-row> |
| | | <el-tooltip class="item" effect="dark" :content="showSearch ? 'éèæç´¢' : 'æ¾ç¤ºæç´¢'" placement="top" v-if="search"> |
| | | <el-button circle icon="Search" @click="toggleSearch()" /> |
| | | </el-tooltip> |
| | | <el-tooltip class="item" effect="dark" content="å·æ°" placement="top"> |
| | | <el-button circle icon="Refresh" @click="refresh()" /> |
| | | </el-tooltip> |
| | | <el-tooltip class="item" effect="dark" content="æ¾éå" placement="top" v-if="columns"> |
| | | <el-button circle icon="Menu" @click="showColumn()" /> |
| | | </el-tooltip> |
| | | </el-row> |
| | | <el-dialog :title="title" v-model="open" append-to-body> |
| | | <el-transfer :titles="['æ¾ç¤º', 'éè']" v-model="value" :data="columns" @change="dataChange"></el-transfer> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { TransferKey } from "element-plus"; |
| | | import { PropType } from "vue"; |
| | | |
| | | const props = defineProps({ |
| | | showSearch: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | columns: { |
| | | type: Array as PropType<FieldOption[]>, |
| | | }, |
| | | search: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | gutter: { |
| | | type: Number, |
| | | default: 10, |
| | | }, |
| | | showSearch: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | columns: { |
| | | type: Array as PropType<FieldOption[]>, |
| | | }, |
| | | search: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | gutter: { |
| | | type: Number, |
| | | default: 10, |
| | | }, |
| | | }) |
| | | |
| | | const emits = defineEmits(['update:showSearch', 'queryTable']); |
| | |
| | | const open = ref(false); |
| | | |
| | | const style = computed(() => { |
| | | const ret: any = {}; |
| | | if (props.gutter) { |
| | | ret.marginRight = `${props.gutter / 2}px`; |
| | | } |
| | | return ret; |
| | | const ret: any = {}; |
| | | if (props.gutter) { |
| | | ret.marginRight = `${props.gutter / 2}px`; |
| | | } |
| | | return ret; |
| | | }); |
| | | |
| | | // æç´¢ |
| | | function toggleSearch() { |
| | | emits("update:showSearch", !props.showSearch); |
| | | emits("update:showSearch", !props.showSearch); |
| | | } |
| | | |
| | | // å·æ° |
| | | function refresh() { |
| | | emits("queryTable"); |
| | | emits("queryTable"); |
| | | } |
| | | |
| | | // å³ä¾§å表å
ç´ åå |
| | | function dataChange(data: TransferKey[]) { |
| | | props.columns?.forEach((item) => { |
| | | item.visible = !data.includes(item.key); |
| | | }) |
| | | props.columns?.forEach((item) => { |
| | | item.visible = !data.includes(item.key); |
| | | }) |
| | | } |
| | | |
| | | // æå¼æ¾éådialog |
| | | const showColumn = () => { |
| | | open.value = true; |
| | | open.value = true; |
| | | } |
| | | |
| | | // æ¾éååå§é»è®¤éèå |
| | | onMounted(() => { |
| | | props.columns?.forEach((item) => { |
| | | if (!item.visible) { |
| | | value.value.push(item.key); |
| | | } |
| | | }) |
| | | props.columns?.forEach((item) => { |
| | | if (!item.visible) { |
| | | value.value.push(item.key); |
| | | } |
| | | }) |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="top-right-btn" :style="style"> |
| | | <el-row> |
| | | <el-tooltip class="item" effect="dark" :content="showSearch ? 'éèæç´¢' : 'æ¾ç¤ºæç´¢'" placement="top" v-if="search"> |
| | | <el-button circle icon="Search" @click="toggleSearch()" /> |
| | | </el-tooltip> |
| | | <el-tooltip class="item" effect="dark" content="å·æ°" placement="top"> |
| | | <el-button circle icon="Refresh" @click="refresh()" /> |
| | | </el-tooltip> |
| | | <el-tooltip class="item" effect="dark" content="æ¾éå" placement="top" v-if="columns"> |
| | | <el-button circle icon="Menu" @click="showColumn()" /> |
| | | </el-tooltip> |
| | | </el-row> |
| | | <el-dialog :title="title" v-model="open" append-to-body> |
| | | <el-transfer :titles="['æ¾ç¤º', 'éè']" v-model="value" :data="columns" @change="dataChange"></el-transfer> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | :deep(.el-transfer__button) { |
| | |
| | | <template> |
| | | <div> |
| | | <svg-icon icon-class="question" @click="goto" /> |
| | | </div> |
| | | <div> |
| | | <svg-icon icon-class="question" @click="goto" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | |
| | | <template> |
| | | <div> |
| | | <svg-icon icon-class="github" @click="goto" /> |
| | | </div> |
| | | <div> |
| | | <svg-icon icon-class="github" @click="goto" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | |
| | | <template> |
| | | <div> |
| | | <svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'" @click="toggle" /> |
| | | </div> |
| | | <div> |
| | | <svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'" @click="toggle" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <div> |
| | | <el-dropdown trigger="click" @command="handleSetSize"> |
| | | <div class="size-icon--style"> |
| | | <svg-icon class-name="size-icon" icon-class="size" /> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size === item.value" :command="item.value"> |
| | | {{ item.label }} |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | <div> |
| | | <el-dropdown trigger="click" @command="handleSetSize"> |
| | | <div class="size-icon--style"> |
| | | <svg-icon class-name="size-icon" icon-class="size" /> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size === item.value" :command="item.value"> |
| | | {{ item.label }} |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <svg :class="svgClass" aria-hidden="true"> |
| | | <use :xlink:href="iconName" :fill="color" /> |
| | | </svg> |
| | | <svg :class="svgClass" aria-hidden="true"> |
| | | <use :xlink:href="iconName" :fill="color" /> |
| | | </svg> |
| | | </template> |
| | | |
| | | <style scope lang="scss"> |
| | |
| | | <template> |
| | | <el-menu :default-active="activeMenu" mode="horizontal" @select="handleSelect" :ellipsis="false"> |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber" |
| | | ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item |
| | | > |
| | | </template> |
| | | |
| | | <!-- é¡¶é¨èåè¶
åºæ°éæå --> |
| | | <el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber"> |
| | | <template #title>æ´å¤èå</template> |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item :index="item.path" :key="index" v-if="index >= visibleNumber" |
| | | ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item |
| | | > |
| | | </template> |
| | | </el-sub-menu> |
| | | </el-menu> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { constantRoutes } from '@/router'; |
| | | import { isHttp } from '@/utils/validate'; |
| | |
| | | setVisibleNumber() |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <el-menu :default-active="activeMenu" mode="horizontal" @select="handleSelect" :ellipsis="false"> |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber" |
| | | ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item |
| | | > |
| | | </template> |
| | | |
| | | <!-- é¡¶é¨èåè¶
åºæ°éæå --> |
| | | <el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber"> |
| | | <template #title>æ´å¤èå</template> |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item :index="item.path" :key="index" v-if="index >= visibleNumber" |
| | | ><svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> {{ item.meta?.title }}</el-menu-item |
| | | > |
| | | </template> |
| | | </el-sub-menu> |
| | | </el-menu> |
| | | </template> |
| | | |
| | | <style lang="scss"> |
| | | .topmenu-container.el-menu--horizontal > .el-menu-item { |
| | |
| | | </style> |
| | | |
| | | <template> |
| | | <div class="el-tree-select"> |
| | | <el-select |
| | | style="width: 100%" |
| | | v-model="valueId" |
| | | ref="treeSelect" |
| | | :filterable="true" |
| | | :clearable="true" |
| | | @clear="clearHandle" |
| | | :filter-method="selectFilterData" |
| | | :placeholder="placeholder" |
| | | > |
| | | <el-option :value="valueId" :label="valueTitle"> |
| | | <el-tree |
| | | id="tree-option" |
| | | ref="selectTree" |
| | | :accordion="accordion" |
| | | :data="options" |
| | | :props="objMap" |
| | | :node-key="objMap.value" |
| | | :expand-on-click-node="false" |
| | | :default-expanded-keys="defaultExpandedKey" |
| | | :filter-node-method="filterNode" |
| | | @node-click="handleNodeClick" |
| | | ></el-tree> |
| | | </el-option> |
| | | </el-select> |
| | | </div> |
| | | <div class="el-tree-select"> |
| | | <el-select |
| | | style="width: 100%" |
| | | v-model="valueId" |
| | | ref="treeSelect" |
| | | :filterable="true" |
| | | :clearable="true" |
| | | @clear="clearHandle" |
| | | :filter-method="selectFilterData" |
| | | :placeholder="placeholder" |
| | | > |
| | | <el-option :value="valueId" :label="valueTitle"> |
| | | <el-tree |
| | | id="tree-option" |
| | | ref="selectTree" |
| | | :accordion="accordion" |
| | | :data="options" |
| | | :props="objMap" |
| | | :node-key="objMap.value" |
| | | :expand-on-click-node="false" |
| | | :default-expanded-keys="defaultExpandedKey" |
| | | :filter-node-method="filterNode" |
| | | @node-click="handleNodeClick" |
| | | ></el-tree> |
| | | </el-option> |
| | | </el-select> |
| | | </div> |
| | | </template> |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <div v-loading="loading" :style="'height:' + height"> |
| | | <iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" /> |
| | | </div> |
| | | <div v-loading="loading" :style="'height:' + height"> |
| | | <iframe :src="url" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" /> |
| | | </div> |
| | | </template> |
| | |
| | | */ |
| | | |
| | | export default { |
| | | beforeMount(el: any, { value, arg }: any) { |
| | | if (arg === 'callback') { |
| | | el.$copyCallback = value; |
| | | } else { |
| | | el.$copyValue = value; |
| | | const handler = () => { |
| | | copyTextToClipboard(el.$copyValue); |
| | | if (el.$copyCallback) { |
| | | el.$copyCallback(el.$copyValue); |
| | | } |
| | | }; |
| | | el.addEventListener('click', handler); |
| | | el.$destroyCopy = () => el.removeEventListener('click', handler); |
| | | } |
| | | } |
| | | beforeMount(el: any, { value, arg }: any) { |
| | | if (arg === 'callback') { |
| | | el.$copyCallback = value; |
| | | } else { |
| | | el.$copyValue = value; |
| | | const handler = () => { |
| | | copyTextToClipboard(el.$copyValue); |
| | | if (el.$copyCallback) { |
| | | el.$copyCallback(el.$copyValue); |
| | | } |
| | | }; |
| | | el.addEventListener('click', handler); |
| | | el.$destroyCopy = () => el.removeEventListener('click', handler); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | function copyTextToClipboard(input: string, { target = document.body } = {}) { |
| | | const element = document.createElement('textarea'); |
| | | const previouslyFocusedElement = document.activeElement as HTMLInputElement; |
| | | element.value = input; |
| | | // Prevent keyboard from showing on mobile |
| | | element.setAttribute('readonly', ''); |
| | | const element = document.createElement('textarea'); |
| | | const previouslyFocusedElement = document.activeElement as HTMLInputElement; |
| | | element.value = input; |
| | | // Prevent keyboard from showing on mobile |
| | | element.setAttribute('readonly', ''); |
| | | |
| | | element.style.contain = 'strict'; |
| | | element.style.position = 'absolute'; |
| | | element.style.left = '-9999px'; |
| | | element.style.fontSize = '12pt'; // Prevent zooming on iOS |
| | | element.style.contain = 'strict'; |
| | | element.style.position = 'absolute'; |
| | | element.style.left = '-9999px'; |
| | | element.style.fontSize = '12pt'; // Prevent zooming on iOS |
| | | |
| | | const selection = document.getSelection(); |
| | | let originalRange; |
| | | if (selection) { |
| | | originalRange = selection?.rangeCount > 0 && selection.getRangeAt(0); |
| | | } |
| | | target.append(element); |
| | | element.select(); |
| | | const selection = document.getSelection(); |
| | | let originalRange; |
| | | if (selection) { |
| | | originalRange = selection?.rangeCount > 0 && selection.getRangeAt(0); |
| | | } |
| | | target.append(element); |
| | | element.select(); |
| | | |
| | | // Explicit selection workaround for iOS |
| | | element.selectionStart = 0; |
| | | element.selectionEnd = input.length; |
| | | // Explicit selection workaround for iOS |
| | | element.selectionStart = 0; |
| | | element.selectionEnd = input.length; |
| | | |
| | | let isSuccess = false; |
| | | try { |
| | | isSuccess = document.execCommand('copy'); |
| | | } catch (err) { |
| | | console.error(err); |
| | | } |
| | | element.remove(); |
| | | let isSuccess = false; |
| | | try { |
| | | isSuccess = document.execCommand('copy'); |
| | | } catch (err) { |
| | | console.error(err); |
| | | } |
| | | element.remove(); |
| | | |
| | | if (originalRange) { |
| | | selection?.removeAllRanges(); |
| | | selection?.addRange(originalRange); |
| | | } |
| | | if (originalRange) { |
| | | selection?.removeAllRanges(); |
| | | selection?.addRange(originalRange); |
| | | } |
| | | |
| | | // Get the focus back on the previously focused element, if any |
| | | if (previouslyFocusedElement) { |
| | | previouslyFocusedElement.focus(); |
| | | } |
| | | return isSuccess; |
| | | // Get the focus back on the previously focused element, if any |
| | | if (previouslyFocusedElement) { |
| | | previouslyFocusedElement.focus(); |
| | | } |
| | | return isSuccess; |
| | | } |
| | |
| | | import { App } from 'vue'; |
| | | |
| | | export default (app: App) => { |
| | | app.directive('copyText', copyText); |
| | | app.directive('hasPermi', hasPermi); |
| | | app.directive('hasRoles', hasRoles); |
| | | app.directive('copyText', copyText); |
| | | app.directive('hasPermi', hasPermi); |
| | | app.directive('hasRoles', hasRoles); |
| | | }; |
| | |
| | | * æä½æéå¤ç |
| | | */ |
| | | export const hasPermi: Directive = { |
| | | mounted(el: HTMLElement, binding: DirectiveBinding) { |
| | | const { permissions } = useUserStore(); |
| | | // ãå
¶ä»è§è²ãæé®æéæ ¡éª |
| | | const { value } = binding; |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const hasPermission = permissions.some((permi) => { |
| | | return permi === '*:*:*' || value.includes(permi); |
| | | }); |
| | | if (!hasPermission) { |
| | | el.parentNode && el.parentNode.removeChild(el); |
| | | return false; |
| | | } |
| | | } else { |
| | | throw new Error("check perms! Like v-has-permi=\"['sys:user:add','sys:user:edit']\""); |
| | | } |
| | | } |
| | | mounted(el: HTMLElement, binding: DirectiveBinding) { |
| | | const { permissions } = useUserStore(); |
| | | // ãå
¶ä»è§è²ãæé®æéæ ¡éª |
| | | const { value } = binding; |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const hasPermission = permissions.some((permi) => { |
| | | return permi === '*:*:*' || value.includes(permi); |
| | | }); |
| | | if (!hasPermission) { |
| | | el.parentNode && el.parentNode.removeChild(el); |
| | | return false; |
| | | } |
| | | } else { |
| | | throw new Error("check perms! Like v-has-permi=\"['sys:user:add','sys:user:edit']\""); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * è§è²æéå¤ç |
| | | */ |
| | | export const hasRoles: Directive = { |
| | | mounted(el: HTMLElement, binding: DirectiveBinding) { |
| | | const { value } = binding; |
| | | const { roles } = useUserStore(); |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const hasRole = roles.some((role) => { |
| | | return role === 'admin' || value.includes(role); |
| | | }); |
| | | if (!hasRole) { |
| | | el.parentNode && el.parentNode.removeChild(el); |
| | | return false; |
| | | } |
| | | } else { |
| | | throw new Error("check roles! Like v-has-roles=\"['admin','test']\""); |
| | | } |
| | | } |
| | | mounted(el: HTMLElement, binding: DirectiveBinding) { |
| | | const { value } = binding; |
| | | const { roles } = useUserStore(); |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const hasRole = roles.some((role) => { |
| | | return role === 'admin' || value.includes(role); |
| | | }); |
| | | if (!hasRole) { |
| | | el.parentNode && el.parentNode.removeChild(el); |
| | | return false; |
| | | } |
| | | } else { |
| | | throw new Error("check roles! Like v-has-roles=\"['admin','test']\""); |
| | | } |
| | | } |
| | | }; |
| | |
| | | export enum MenuTypeEnum { |
| | | /** |
| | | * ç®å½ |
| | | */ |
| | | M = 'M', |
| | | /** |
| | | * èå |
| | | */ |
| | | C = 'C', |
| | | /** |
| | | * ç®å½ |
| | | */ |
| | | M = 'M', |
| | | /** |
| | | * èå |
| | | */ |
| | | C = 'C', |
| | | |
| | | /** |
| | | * æé® |
| | | */ |
| | | F = 'F' |
| | | /** |
| | | * æé® |
| | | */ |
| | | F = 'F' |
| | | } |
| | |
| | | export enum HttpStatus { |
| | | /** |
| | | * æä½æå |
| | | */ |
| | | SUCCESS = 200, |
| | | /** |
| | | * 对象å建æå |
| | | */ |
| | | CREATED = 201, |
| | | /** |
| | | * 请æ±å·²ç»è¢«æ¥å |
| | | */ |
| | | ACCEPTED = 202, |
| | | /** |
| | | * æä½å·²ç»æ§è¡æåï¼ä½æ¯æ²¡æè¿åæ°æ® |
| | | */ |
| | | NO_CONTENT = 204, |
| | | /** |
| | | * èµæºå·²ç»è¢«ç§»é¤ |
| | | */ |
| | | MOVED_PERM = 301, |
| | | /** |
| | | * éå®å |
| | | */ |
| | | SEE_OTHER = 303, |
| | | /** |
| | | * èµæºæ²¡æè¢«ä¿®æ¹ |
| | | */ |
| | | NOT_MODIFIED = 304, |
| | | /** |
| | | * åæ°å表é误ï¼ç¼ºå°ï¼æ ¼å¼ä¸å¹é
ï¼ |
| | | */ |
| | | PARAM_ERROR = 400, |
| | | /** |
| | | * æªææ |
| | | */ |
| | | UNAUTHORIZED = 401, |
| | | /** |
| | | * 访é®åéï¼ææè¿æ |
| | | */ |
| | | FORBIDDEN = 403, |
| | | /** |
| | | * èµæºï¼æå¡æªæ¾å° |
| | | */ |
| | | NOT_FOUND = 404, |
| | | /** |
| | | * ä¸å
许çhttpæ¹æ³ |
| | | */ |
| | | BAD_METHOD = 405, |
| | | /** |
| | | * èµæºå²çªï¼æè
èµæºè¢«é |
| | | */ |
| | | CONFLICT = 409, |
| | | /** |
| | | * 䏿¯æçæ°æ®ï¼åªä½ç±»å |
| | | */ |
| | | UNSUPPORTED_TYPE = 415, |
| | | /** |
| | | * ç³»ç»å
é¨é误 |
| | | */ |
| | | SERVER_ERROR = 500, |
| | | /** |
| | | * æ¥å£æªå®ç° |
| | | */ |
| | | NOT_IMPLEMENTED = 501, |
| | | /** |
| | | * æå¡ä¸å¯ç¨ï¼è¿è½½æè
ç»´æ¤ |
| | | */ |
| | | BAD_GATEWAY = 502, |
| | | /** |
| | | * ç½å
³è¶
æ¶ |
| | | */ |
| | | GATEWAY_TIMEOUT = 504, |
| | | /** |
| | | * æªç¥é误 |
| | | */ |
| | | UNKNOWN_ERROR = 520, |
| | | /** |
| | | * æå¡æªç¥é误 |
| | | */ |
| | | SERVICE_ERROR = 521, |
| | | /** |
| | | * æ°æ®åºæªç¥é误 |
| | | */ |
| | | DATABASE_ERROR = 522, |
| | | /** |
| | | * ç³»ç»è¦åæ¶æ¯ |
| | | */ |
| | | WARN = 601 |
| | | /** |
| | | * æä½æå |
| | | */ |
| | | SUCCESS = 200, |
| | | /** |
| | | * 对象å建æå |
| | | */ |
| | | CREATED = 201, |
| | | /** |
| | | * 请æ±å·²ç»è¢«æ¥å |
| | | */ |
| | | ACCEPTED = 202, |
| | | /** |
| | | * æä½å·²ç»æ§è¡æåï¼ä½æ¯æ²¡æè¿åæ°æ® |
| | | */ |
| | | NO_CONTENT = 204, |
| | | /** |
| | | * èµæºå·²ç»è¢«ç§»é¤ |
| | | */ |
| | | MOVED_PERM = 301, |
| | | /** |
| | | * éå®å |
| | | */ |
| | | SEE_OTHER = 303, |
| | | /** |
| | | * èµæºæ²¡æè¢«ä¿®æ¹ |
| | | */ |
| | | NOT_MODIFIED = 304, |
| | | /** |
| | | * åæ°å表é误ï¼ç¼ºå°ï¼æ ¼å¼ä¸å¹é
ï¼ |
| | | */ |
| | | PARAM_ERROR = 400, |
| | | /** |
| | | * æªææ |
| | | */ |
| | | UNAUTHORIZED = 401, |
| | | /** |
| | | * 访é®åéï¼ææè¿æ |
| | | */ |
| | | FORBIDDEN = 403, |
| | | /** |
| | | * èµæºï¼æå¡æªæ¾å° |
| | | */ |
| | | NOT_FOUND = 404, |
| | | /** |
| | | * ä¸å
许çhttpæ¹æ³ |
| | | */ |
| | | BAD_METHOD = 405, |
| | | /** |
| | | * èµæºå²çªï¼æè
èµæºè¢«é |
| | | */ |
| | | CONFLICT = 409, |
| | | /** |
| | | * 䏿¯æçæ°æ®ï¼åªä½ç±»å |
| | | */ |
| | | UNSUPPORTED_TYPE = 415, |
| | | /** |
| | | * ç³»ç»å
é¨é误 |
| | | */ |
| | | SERVER_ERROR = 500, |
| | | /** |
| | | * æ¥å£æªå®ç° |
| | | */ |
| | | NOT_IMPLEMENTED = 501, |
| | | /** |
| | | * æå¡ä¸å¯ç¨ï¼è¿è½½æè
ç»´æ¤ |
| | | */ |
| | | BAD_GATEWAY = 502, |
| | | /** |
| | | * ç½å
³è¶
æ¶ |
| | | */ |
| | | GATEWAY_TIMEOUT = 504, |
| | | /** |
| | | * æªç¥é误 |
| | | */ |
| | | UNKNOWN_ERROR = 520, |
| | | /** |
| | | * æå¡æªç¥é误 |
| | | */ |
| | | SERVICE_ERROR = 521, |
| | | /** |
| | | * æ°æ®åºæªç¥é误 |
| | | */ |
| | | DATABASE_ERROR = 522, |
| | | /** |
| | | * ç³»ç»è¦åæ¶æ¯ |
| | | */ |
| | | WARN = 601 |
| | | } |
| | |
| | | export enum SettingTypeEnum { |
| | | TITLE = 'title', |
| | | THEME = 'theme', |
| | | SIDE_THEME = 'sideTheme', |
| | | SHOW_SETTINGS = 'showSettings', |
| | | TOP_NAV = 'topNav', |
| | | TAGS_VIEW = 'tagsView', |
| | | FIXED_HEADER = 'fixedHeader', |
| | | SIDEBAR_LOGO = 'sidebarLogo', |
| | | DYNAMIC_TITLE = 'dynamicTitle', |
| | | ANIMATION_ENABLE = 'animationEnable', |
| | | LAYOUT = 'layout', |
| | | DARK = 'dark', |
| | | TITLE = 'title', |
| | | THEME = 'theme', |
| | | SIDE_THEME = 'sideTheme', |
| | | SHOW_SETTINGS = 'showSettings', |
| | | TOP_NAV = 'topNav', |
| | | TAGS_VIEW = 'tagsView', |
| | | FIXED_HEADER = 'fixedHeader', |
| | | SIDEBAR_LOGO = 'sidebarLogo', |
| | | DYNAMIC_TITLE = 'dynamicTitle', |
| | | ANIMATION_ENABLE = 'animationEnable', |
| | | LAYOUT = 'layout', |
| | | DARK = 'dark', |
| | | |
| | | LAYOUT_SETTING = 'layout-setting' |
| | | LAYOUT_SETTING = 'layout-setting' |
| | | } |
| | |
| | | export enum ThemeEnum { |
| | | DARK = 'theme-dark', |
| | | LIGHT = 'theme-light' |
| | | DARK = 'theme-dark', |
| | | LIGHT = 'theme-light' |
| | | } |
| | |
| | | export default { |
| | | // è·¯ç±å½é
å |
| | | route: { |
| | | dashboard: 'Dashboard', |
| | | document: 'Document' |
| | | }, |
| | | // ç»å½é¡µé¢å½é
å |
| | | login: { |
| | | title: 'vue3-element-admin', |
| | | username: 'Username', |
| | | password: 'Password', |
| | | login: 'Login', |
| | | code: 'Verification Code', |
| | | copyright: '', |
| | | icp: '', |
| | | thirdPartyLogin: 'third-party login' |
| | | }, |
| | | // å¯¼èªæ å½é
å |
| | | navbar: { |
| | | dashboard: 'Dashboard', |
| | | logout: 'Logout', |
| | | document: 'Document', |
| | | gitee: 'Gitee' |
| | | } |
| | | // è·¯ç±å½é
å |
| | | route: { |
| | | dashboard: 'Dashboard', |
| | | document: 'Document' |
| | | }, |
| | | // ç»å½é¡µé¢å½é
å |
| | | login: { |
| | | title: 'vue3-element-admin', |
| | | username: 'Username', |
| | | password: 'Password', |
| | | login: 'Login', |
| | | code: 'Verification Code', |
| | | copyright: '', |
| | | icp: '', |
| | | thirdPartyLogin: 'third-party login' |
| | | }, |
| | | // å¯¼èªæ å½é
å |
| | | navbar: { |
| | | dashboard: 'Dashboard', |
| | | logout: 'Logout', |
| | | document: 'Document', |
| | | gitee: 'Gitee' |
| | | } |
| | | }; |
| | |
| | | import zhCnLocale from './zh-cn'; |
| | | |
| | | const messages = { |
| | | 'zh-cn': { |
| | | ...zhCnLocale |
| | | }, |
| | | en: { |
| | | ...enLocale |
| | | } |
| | | 'zh-cn': { |
| | | ...zhCnLocale |
| | | }, |
| | | en: { |
| | | ...enLocale |
| | | } |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns zh-cn|en ... |
| | | */ |
| | | export const getLanguage = () => { |
| | | // æ¬å°ç¼åè·å |
| | | let language = localStorage.getItem('language'); |
| | | if (language) { |
| | | return language; |
| | | } |
| | | // æµè§å¨ä½¿ç¨è¯è¨ |
| | | language = navigator.language.toLowerCase(); |
| | | const locales = Object.keys(messages); |
| | | for (const locale of locales) { |
| | | if (language.indexOf(locale) > -1) { |
| | | return locale; |
| | | } |
| | | } |
| | | return 'zh-cn'; |
| | | // æ¬å°ç¼åè·å |
| | | let language = localStorage.getItem('language'); |
| | | if (language) { |
| | | return language; |
| | | } |
| | | // æµè§å¨ä½¿ç¨è¯è¨ |
| | | language = navigator.language.toLowerCase(); |
| | | const locales = Object.keys(messages); |
| | | for (const locale of locales) { |
| | | if (language.indexOf(locale) > -1) { |
| | | return locale; |
| | | } |
| | | } |
| | | return 'zh-cn'; |
| | | }; |
| | | |
| | | const i18n = createI18n({ |
| | | legacy: false, |
| | | locale: getLanguage(), |
| | | messages: messages |
| | | legacy: false, |
| | | locale: getLanguage(), |
| | | messages: messages |
| | | }); |
| | | |
| | | export default i18n; |
| | |
| | | export default { |
| | | // è·¯ç±å½é
å |
| | | route: { |
| | | dashboard: 'é¦é¡µ', |
| | | document: 'é¡¹ç®ææ¡£' |
| | | }, |
| | | // ç»å½é¡µé¢å½é
å |
| | | login: { |
| | | title: 'vue3-element-admin', |
| | | username: 'ç¨æ·å', |
| | | password: 'å¯ç ', |
| | | login: 'ç» å½', |
| | | code: '请è¾å
¥éªè¯ç ', |
| | | copyright: '', |
| | | icp: '', |
| | | thirdPartyLogin: 'ç¬¬ä¸æ¹ç»å½' |
| | | }, |
| | | navbar: { |
| | | dashboard: 'é¦é¡µ', |
| | | logout: '注é', |
| | | document: 'é¡¹ç®ææ¡£', |
| | | gitee: 'ç äº' |
| | | } |
| | | // è·¯ç±å½é
å |
| | | route: { |
| | | dashboard: 'é¦é¡µ', |
| | | document: 'é¡¹ç®ææ¡£' |
| | | }, |
| | | // ç»å½é¡µé¢å½é
å |
| | | login: { |
| | | title: 'vue3-element-admin', |
| | | username: 'ç¨æ·å', |
| | | password: 'å¯ç ', |
| | | login: 'ç» å½', |
| | | code: '请è¾å
¥éªè¯ç ', |
| | | copyright: '', |
| | | icp: '', |
| | | thirdPartyLogin: 'ç¬¬ä¸æ¹ç»å½' |
| | | }, |
| | | navbar: { |
| | | dashboard: 'é¦é¡µ', |
| | | logout: '注é', |
| | | document: 'é¡¹ç®ææ¡£', |
| | | gitee: 'ç äº' |
| | | } |
| | | }; |
| | |
| | | <template> |
| | | <section class="app-main"> |
| | | <router-view v-slot="{ Component, route }"> |
| | | <transition :enter-active-class="animante" mode="out-in"> |
| | | <keep-alive :include="tagsViewStore.cachedViews"> |
| | | <component v-if="!route.meta.link" :is="Component" :key="route.path" /> |
| | | </keep-alive> |
| | | </transition> |
| | | </router-view> |
| | | <iframe-toggle /> |
| | | </section> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | export default { |
| | | name: 'AppMin' |
| | | name: 'AppMin' |
| | | } |
| | | </script> |
| | | |
| | |
| | | const animante = ref<string>(''); |
| | | const animationEnable = ref(useSettingsStore().animationEnable); |
| | | watch(()=> useSettingsStore().animationEnable, (val) => { |
| | | animationEnable.value = val; |
| | | if (val) { |
| | | animante.value = proxy?.animate.animateList[Math.round(Math.random() * proxy?.animate.animateList.length)] as string; |
| | | } else { |
| | | animante.value = proxy?.animate.defaultAnimate as string; |
| | | } |
| | | animationEnable.value = val; |
| | | if (val) { |
| | | animante.value = proxy?.animate.animateList[Math.round(Math.random() * proxy?.animate.animateList.length)] as string; |
| | | } else { |
| | | animante.value = proxy?.animate.defaultAnimate as string; |
| | | } |
| | | }, { immediate: true }); |
| | | </script> |
| | | |
| | | <template> |
| | | <section class="app-main"> |
| | | <router-view v-slot="{ Component, route }"> |
| | | <transition :enter-active-class="animante" mode="out-in"> |
| | | <keep-alive :include="tagsViewStore.cachedViews"> |
| | | <component v-if="!route.meta.link" :is="Component" :key="route.path" /> |
| | | </keep-alive> |
| | | </transition> |
| | | </router-view> |
| | | <iframe-toggle /> |
| | | </section> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | .app-main { |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <transition-group name="fade-transform" mode="out-in"> |
| | | <inner-link |
| | | v-for="(item, index) in tagsViewStore.iframeViews" |
| | | :key="item.path" |
| | | :iframeId="'iframe' + index" |
| | | v-show="route.path === item.path" |
| | | :src="item.meta ? item.meta.link : ''" |
| | | ></inner-link> |
| | | </transition-group> |
| | | <transition-group name="fade-transform" mode="out-in"> |
| | | <inner-link |
| | | v-for="(item, index) in tagsViewStore.iframeViews" |
| | | :key="item.path" |
| | | :iframeId="'iframe' + index" |
| | | v-show="route.path === item.path" |
| | | :src="item.meta ? item.meta.link : ''" |
| | | ></inner-link> |
| | | </transition-group> |
| | | </template> |
| | |
| | | <template> |
| | | <div :style="'height:' + height"> |
| | | <iframe :id="iframeId" style="width: 100%; height: 100%" :src="src" frameborder="no"></iframe> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | const props = defineProps({ |
| | | src: { |
| | | type: String, |
| | | default: "/" |
| | | }, |
| | | iframeId: { |
| | | type: String |
| | | } |
| | | src: { |
| | | type: String, |
| | | default: "/" |
| | | }, |
| | | iframeId: { |
| | | type: String |
| | | } |
| | | }); |
| | | const height = ref(document.documentElement.clientHeight - 94.5 + "px"); |
| | | </script> |
| | | |
| | | <template> |
| | | <div :style="'height:' + height"> |
| | | <iframe :id="iframeId" style="width: 100%; height: 100%" :src="src" frameborder="no"></iframe> |
| | | </div> |
| | | </template> |
| | | </script> |
| | |
| | | <template> |
| | | <div class="navbar"> |
| | | <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> |
| | | <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!settingsStore.topNav" /> |
| | | <top-nav id="topmenu-container" class="topmenu-container" v-if="settingsStore.topNav" /> |
| | | |
| | | <div class="right-menu flex align-center"> |
| | | <template v-if="appStore.device !== 'mobile'"> |
| | | <el-select |
| | | v-model="companyName" |
| | | clearable |
| | | filterable |
| | | reserve-keyword |
| | | placeholder="è¯·éæ©ç§æ·" |
| | | v-if="userId === 1 && tenantEnabled" |
| | | @change="dynamicTenantEvent" |
| | | @clear="dynamicClearEvent" |
| | | > |
| | | <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option> |
| | | <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template> |
| | | </el-select> |
| | | |
| | | <header-search id="header-search" class="right-menu-item" /> |
| | | |
| | | <el-tooltip content="æºç å°å" effect="dark" placement="bottom"> |
| | | <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | |
| | | <el-tooltip content="ææ¡£å°å" effect="dark" placement="bottom"> |
| | | <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | |
| | | <el-tooltip content="å
¨å±" effect="dark" placement="bottom"> |
| | | <screenfull id="screenfull" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | |
| | | <el-tooltip content="å¸å±å¤§å°" effect="dark" placement="bottom"> |
| | | <size-select id="size-select" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | </template> |
| | | <div class="avatar-container"> |
| | | <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click"> |
| | | <div class="avatar-wrapper"> |
| | | <img :src="userStore.avatar" class="user-avatar" /> |
| | | <el-icon><caret-bottom /></el-icon> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <router-link to="/user/profile" v-if="!dynamic"> |
| | | <el-dropdown-item>个人ä¸å¿</el-dropdown-item> |
| | | </router-link> |
| | | <el-dropdown-item command="setLayout"> |
| | | <span>å¸å±è®¾ç½®</span> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item divided command="logout"> |
| | | <span>éåºç»å½</span> |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import useAppStore from '@/store/modules/app' |
| | | import useUserStore from '@/store/modules/user' |
| | |
| | | |
| | | // 卿忢 |
| | | const dynamicTenantEvent = async (tenantId: string) => { |
| | | if (companyName.value != null && companyName.value !== '') { |
| | | await dynamicTenant(tenantId); |
| | | dynamic.value = true; |
| | | proxy?.$tab.closeAllPage(); |
| | | proxy?.$router.push('/'); |
| | | } |
| | | if (companyName.value != null && companyName.value !== '') { |
| | | await dynamicTenant(tenantId); |
| | | dynamic.value = true; |
| | | proxy?.$tab.closeAllPage(); |
| | | proxy?.$router.push('/'); |
| | | } |
| | | } |
| | | |
| | | const dynamicClearEvent = async () => { |
| | | await dynamicClear(); |
| | | dynamic.value = false; |
| | | proxy?.$tab.closeAllPage(); |
| | | proxy?.$router.push('/') |
| | | await dynamicClear(); |
| | | dynamic.value = false; |
| | | proxy?.$tab.closeAllPage(); |
| | | proxy?.$router.push('/') |
| | | } |
| | | |
| | | /** ç§æ·å表 */ |
| | | const initTenantList = async () => { |
| | | const { data } = await getTenantList(); |
| | | tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled; |
| | | if (tenantEnabled.value) { |
| | | tenantList.value = data.voList; |
| | | } |
| | | const { data } = await getTenantList(); |
| | | tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled; |
| | | if (tenantEnabled.value) { |
| | | tenantList.value = data.voList; |
| | | } |
| | | } |
| | | |
| | | defineExpose({ |
| | | initTenantList, |
| | | initTenantList, |
| | | }) |
| | | |
| | | const toggleSideBar = () => { |
| | | appStore.toggleSideBar() |
| | | appStore.toggleSideBar() |
| | | } |
| | | |
| | | const logout = async () => { |
| | | await ElMessageBox.confirm('ç¡®å®æ³¨éå¹¶éåºç³»ç»åï¼', 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }) |
| | | await userStore.logout() |
| | | location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index'; |
| | | await ElMessageBox.confirm('ç¡®å®æ³¨éå¹¶éåºç³»ç»åï¼', 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }) |
| | | await userStore.logout() |
| | | location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index'; |
| | | } |
| | | |
| | | const emits = defineEmits(['setLayout']) |
| | | const setLayout = () => { |
| | | emits('setLayout'); |
| | | emits('setLayout'); |
| | | } |
| | | // å®ä¹Commandæ¹æ³å¯¹è±¡ éè¿keyç´æ¥è°ç¨æ¹æ³ |
| | | const commandMap: {[key: string]: any} = { |
| | | setLayout, |
| | | logout |
| | | setLayout, |
| | | logout |
| | | }; |
| | | const handleCommand = (command: string) => { |
| | | // 夿æ¯å¦åå¨è¯¥æ¹æ³ |
| | | if (commandMap[command]) { |
| | | commandMap[command](); |
| | | } |
| | | // 夿æ¯å¦åå¨è¯¥æ¹æ³ |
| | | if (commandMap[command]) { |
| | | commandMap[command](); |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="navbar"> |
| | | <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> |
| | | <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!settingsStore.topNav" /> |
| | | <top-nav id="topmenu-container" class="topmenu-container" v-if="settingsStore.topNav" /> |
| | | |
| | | <div class="right-menu flex align-center"> |
| | | <template v-if="appStore.device !== 'mobile'"> |
| | | <el-select |
| | | v-model="companyName" |
| | | clearable |
| | | filterable |
| | | reserve-keyword |
| | | placeholder="è¯·éæ©ç§æ·" |
| | | v-if="userId === 1 && tenantEnabled" |
| | | @change="dynamicTenantEvent" |
| | | @clear="dynamicClearEvent" |
| | | > |
| | | <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option> |
| | | <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template> |
| | | </el-select> |
| | | |
| | | <header-search id="header-search" class="right-menu-item" /> |
| | | |
| | | <el-tooltip content="æºç å°å" effect="dark" placement="bottom"> |
| | | <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | |
| | | <el-tooltip content="ææ¡£å°å" effect="dark" placement="bottom"> |
| | | <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | |
| | | <el-tooltip content="å
¨å±" effect="dark" placement="bottom"> |
| | | <screenfull id="screenfull" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | |
| | | <el-tooltip content="å¸å±å¤§å°" effect="dark" placement="bottom"> |
| | | <size-select id="size-select" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | </template> |
| | | <div class="avatar-container"> |
| | | <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click"> |
| | | <div class="avatar-wrapper"> |
| | | <img :src="userStore.avatar" class="user-avatar" /> |
| | | <el-icon><caret-bottom /></el-icon> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <router-link to="/user/profile" v-if="!dynamic"> |
| | | <el-dropdown-item>个人ä¸å¿</el-dropdown-item> |
| | | </router-link> |
| | | <el-dropdown-item command="setLayout"> |
| | | <span>å¸å±è®¾ç½®</span> |
| | | </el-dropdown-item> |
| | | <el-dropdown-item divided command="logout"> |
| | | <span>éåºç»å½</span> |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <el-drawer v-model="showSettings" :withHeader="false" direction="rtl" size="300px" close-on-click-modal> |
| | | <div class="setting-drawer-title"> |
| | | <h3 class="drawer-title">主é¢é£æ ¼è®¾ç½®</h3> |
| | | </div> |
| | | <div class="setting-drawer-block-checbox"> |
| | | <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')"> |
| | | <img src="@/assets/images/dark.svg" alt="dark" /> |
| | | <div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;"> |
| | | <i aria-label="徿 : check" class="anticon anticon-check"> |
| | | <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class> |
| | | <path |
| | | d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" |
| | | /> |
| | | </svg> |
| | | </i> |
| | | </div> |
| | | </div> |
| | | <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')"> |
| | | <img src="@/assets/images/light.svg" alt="light" /> |
| | | <div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;"> |
| | | <i aria-label="徿 : check" class="anticon anticon-check"> |
| | | <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class> |
| | | <path |
| | | d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" |
| | | /> |
| | | </svg> |
| | | </i> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="drawer-item"> |
| | | <span>主é¢é¢è²</span> |
| | | <span class="comp-style"> |
| | | <el-color-picker v-model="theme" :predefine="predefineColors" @change="themeChange" /> |
| | | </span> |
| | | </div> |
| | | <el-divider /> |
| | | <el-drawer v-model="showSettings" :withHeader="false" direction="rtl" size="300px" close-on-click-modal> |
| | | <div class="setting-drawer-title"> |
| | | <h3 class="drawer-title">主é¢é£æ ¼è®¾ç½®</h3> |
| | | </div> |
| | | <div class="setting-drawer-block-checbox"> |
| | | <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')"> |
| | | <img src="@/assets/images/dark.svg" alt="dark" /> |
| | | <div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;"> |
| | | <i aria-label="徿 : check" class="anticon anticon-check"> |
| | | <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class> |
| | | <path |
| | | d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" |
| | | /> |
| | | </svg> |
| | | </i> |
| | | </div> |
| | | </div> |
| | | <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')"> |
| | | <img src="@/assets/images/light.svg" alt="light" /> |
| | | <div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;"> |
| | | <i aria-label="徿 : check" class="anticon anticon-check"> |
| | | <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class> |
| | | <path |
| | | d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" |
| | | /> |
| | | </svg> |
| | | </i> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="drawer-item"> |
| | | <span>主é¢é¢è²</span> |
| | | <span class="comp-style"> |
| | | <el-color-picker v-model="theme" :predefine="predefineColors" @change="themeChange" /> |
| | | </span> |
| | | </div> |
| | | <el-divider /> |
| | | |
| | | <h3 class="drawer-title">ç³»ç»å¸å±é
ç½®</h3> |
| | | <h3 class="drawer-title">ç³»ç»å¸å±é
ç½®</h3> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>å¼å¯ TopNav</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="topNav" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | <div class="drawer-item"> |
| | | <span>å¼å¯ TopNav</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="topNav" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>å¼å¯ Tags-Views</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="tagsView" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | <div class="drawer-item"> |
| | | <span>å¼å¯ Tags-Views</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="tagsView" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>åºå® Header</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="fixedHeader" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | <div class="drawer-item"> |
| | | <span>åºå® Header</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="fixedHeader" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>æ¾ç¤º Logo</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="sidebarLogo" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | <div class="drawer-item"> |
| | | <span>æ¾ç¤º Logo</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="sidebarLogo" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>卿æ é¢</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="dynamicTitle" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | <div class="drawer-item"> |
| | | <span>卿æ é¢</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="dynamicTitle" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <el-divider /> |
| | | <el-divider /> |
| | | |
| | | <el-button type="primary" plain icon="DocumentAdd" @click="saveSetting">ä¿åé
ç½®</el-button> |
| | | <el-button plain icon="Refresh" @click="resetSetting">éç½®é
ç½®</el-button> |
| | | </el-drawer> |
| | | <el-button type="primary" plain icon="DocumentAdd" @click="saveSetting">ä¿åé
ç½®</el-button> |
| | | <el-button plain icon="Refresh" @click="resetSetting">éç½®é
ç½®</el-button> |
| | | </el-drawer> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <component :is="type" v-bind="linkProps()"> |
| | | <slot /> |
| | | </component> |
| | | <component :is="type" v-bind="linkProps()"> |
| | | <slot /> |
| | | </component> |
| | | </template> |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <div |
| | | class="sidebar-logo-container" |
| | | :class="{ 'collapse': collapse }" |
| | | :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }" |
| | | > |
| | | <transition :enter-active-class="proxy?.animate.logoAnimate.enter" mode="out-in"> |
| | | <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }"> |
| | | {{ title }} |
| | | </h1> |
| | | </router-link> |
| | | <router-link v-else key="expand" class="sidebar-logo-link" to="/"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }"> |
| | | {{ title }} |
| | | </h1> |
| | | </router-link> |
| | | </transition> |
| | | </div> |
| | | <div |
| | | class="sidebar-logo-container" |
| | | :class="{ 'collapse': collapse }" |
| | | :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }" |
| | | > |
| | | <transition :enter-active-class="proxy?.animate.logoAnimate.enter" mode="out-in"> |
| | | <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }"> |
| | | {{ title }} |
| | | </h1> |
| | | </router-link> |
| | | <router-link v-else key="expand" class="sidebar-logo-link" to="/"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }"> |
| | | {{ title }} |
| | | </h1> |
| | | </router-link> |
| | | </transition> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | <template> |
| | | <div v-if="!item.hidden"> |
| | | <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow"> |
| | | <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)"> |
| | | <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }"> |
| | | <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" /> |
| | | <template #title> |
| | | <span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span> |
| | | </template> |
| | | </el-menu-item> |
| | | </app-link> |
| | | </template> |
| | | |
| | | <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported> |
| | | <template v-if="item.meta" #title> |
| | | <svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> |
| | | <span class="menu-title" :title="hasTitle(item.meta?.title)">{{ item.meta?.title }}</span> |
| | | </template> |
| | | |
| | | <sidebar-item |
| | | v-for="child in item.children" |
| | | :key="child.path" |
| | | :is-nest="true" |
| | | :item="child as RouteOption" |
| | | :base-path="resolvePath(child.path)" |
| | | class="nest-menu" |
| | | /> |
| | | </el-sub-menu> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { isExternal } from '@/utils/validate' |
| | | import AppLink from './Link.vue' |
| | |
| | | import { PropType } from "vue"; |
| | | |
| | | const props = defineProps({ |
| | | // route object |
| | | item: { |
| | | type: Object as PropType<RouteOption>, |
| | | required: true |
| | | }, |
| | | isNest: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | basePath: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | // route object |
| | | item: { |
| | | type: Object as PropType<RouteOption>, |
| | | required: true |
| | | }, |
| | | isNest: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | basePath: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }) |
| | | |
| | | const onlyOneChild = ref<any>({}); |
| | | |
| | | const hasOneShowingChild = (children:RouteOption[] = [], parent: RouteOption) => { |
| | | if (!children) { |
| | | children = []; |
| | | } |
| | | const showingChildren = children.filter(item => { |
| | | if (item.hidden) { |
| | | return false |
| | | } else { |
| | | // Temp set(will be used if only has one showing child) |
| | | onlyOneChild.value = item |
| | | return true |
| | | if (!children) { |
| | | children = []; |
| | | } |
| | | }) |
| | | const showingChildren = children.filter(item => { |
| | | if (item.hidden) { |
| | | return false |
| | | } else { |
| | | // Temp set(will be used if only has one showing child) |
| | | onlyOneChild.value = item |
| | | return true |
| | | } |
| | | }) |
| | | |
| | | // When there is only one child router, the child router is displayed by default |
| | | if (showingChildren.length === 1) { |
| | | return true |
| | | } |
| | | // When there is only one child router, the child router is displayed by default |
| | | if (showingChildren.length === 1) { |
| | | return true |
| | | } |
| | | |
| | | // Show parent if there are no child router to display |
| | | if (showingChildren.length === 0) { |
| | | onlyOneChild.value = { ...parent, path: '', noShowingChildren: true } |
| | | return true |
| | | } |
| | | // Show parent if there are no child router to display |
| | | if (showingChildren.length === 0) { |
| | | onlyOneChild.value = { ...parent, path: '', noShowingChildren: true } |
| | | return true |
| | | } |
| | | |
| | | return false |
| | | return false |
| | | }; |
| | | |
| | | const resolvePath = (routePath:string, routeQuery?:string): any => { |
| | | if (isExternal(routePath)) { |
| | | return routePath |
| | | } |
| | | if (isExternal(props.basePath)) { |
| | | return props.basePath |
| | | } |
| | | if (routeQuery) { |
| | | let query = JSON.parse(routeQuery); |
| | | return { path: getNormalPath(props.basePath + '/' + routePath), query: query } |
| | | } |
| | | return getNormalPath(props.basePath + '/' + routePath) |
| | | if (isExternal(routePath)) { |
| | | return routePath |
| | | } |
| | | if (isExternal(props.basePath)) { |
| | | return props.basePath |
| | | } |
| | | if (routeQuery) { |
| | | let query = JSON.parse(routeQuery); |
| | | return { path: getNormalPath(props.basePath + '/' + routePath), query: query } |
| | | } |
| | | return getNormalPath(props.basePath + '/' + routePath) |
| | | } |
| | | |
| | | const hasTitle = (title: string | undefined): string => { |
| | | if(!title || title.length <= 5) { |
| | | return ""; |
| | | } |
| | | return title; |
| | | if(!title || title.length <= 5) { |
| | | return ""; |
| | | } |
| | | return title; |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div v-if="!item.hidden"> |
| | | <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow"> |
| | | <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)"> |
| | | <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }"> |
| | | <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" /> |
| | | <template #title> |
| | | <span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span> |
| | | </template> |
| | | </el-menu-item> |
| | | </app-link> |
| | | </template> |
| | | |
| | | <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported> |
| | | <template v-if="item.meta" #title> |
| | | <svg-icon :icon-class="item.meta ? item.meta.icon : '' " /> |
| | | <span class="menu-title" :title="hasTitle(item.meta?.title)">{{ item.meta?.title }}</span> |
| | | </template> |
| | | |
| | | <sidebar-item |
| | | v-for="child in item.children" |
| | | :key="child.path" |
| | | :is-nest="true" |
| | | :item="child as RouteOption" |
| | | :base-path="resolvePath(child.path)" |
| | | class="nest-menu" |
| | | /> |
| | | </el-sub-menu> |
| | | </div> |
| | | </template> |
| | |
| | | // if set path, the sidebar will highlight the path you set |
| | | if (meta.activeMenu) { |
| | | return meta.activeMenu; |
| | | } |
| | | } |
| | | return path; |
| | | }) |
| | | |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <div :class="{ 'has-logo': showLogo }" :style="{ backgroundColor: bgColor }"> |
| | | <logo v-if="showLogo" :collapse="isCollapse" /> |
| | | <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper"> |
| | | <transition :enter-active-class="proxy?.animate.menuSearchAnimate.enter" mode="out-in"> |
| | | <el-menu |
| | | :default-active="activeMenu as string" |
| | | :collapse="isCollapse" |
| | | :background-color="bgColor" |
| | | :text-color="textColor" |
| | | :unique-opened="true" |
| | | :active-text-color="theme" |
| | | :collapse-transition="false" |
| | | mode="vertical" |
| | | > |
| | | <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" /> |
| | | </el-menu> |
| | | </transition> |
| | | </el-scrollbar> |
| | | </div> |
| | | <div :class="{ 'has-logo': showLogo }" :style="{ backgroundColor: bgColor }"> |
| | | <logo v-if="showLogo" :collapse="isCollapse" /> |
| | | <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper"> |
| | | <transition :enter-active-class="proxy?.animate.menuSearchAnimate.enter" mode="out-in"> |
| | | <el-menu |
| | | :default-active="activeMenu as string" |
| | | :collapse="isCollapse" |
| | | :background-color="bgColor" |
| | | :text-color="textColor" |
| | | :unique-opened="true" |
| | | :active-text-color="theme" |
| | | :collapse-transition="false" |
| | | mode="vertical" |
| | | > |
| | | <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" /> |
| | | </el-menu> |
| | | </transition> |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <el-scrollbar ref="scrollContainerRef" :vertical="false" class="scroll-container" @wheel.prevent="handleScroll"> |
| | | <slot /> |
| | | </el-scrollbar> |
| | | <el-scrollbar ref="scrollContainerRef" :vertical="false" class="scroll-container" @wheel.prevent="handleScroll"> |
| | | <slot /> |
| | | </el-scrollbar> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | <template> |
| | | <div id="tags-view-container" class="tags-view-container"> |
| | | <scroll-pane ref="scrollPaneRef" class="tags-view-wrapper" @scroll="handleScroll"> |
| | | <router-link |
| | | v-for="tag in visitedViews" |
| | | :key="tag.path" |
| | | :data-path="tag.path" |
| | | :class="isActive(tag) ? 'active' : ''" |
| | | :to="{ path: tag.path ? tag.path : '', query: tag.query, fullPath: tag.fullPath ? tag.fullPath : '' }" |
| | | class="tags-view-item" |
| | | :style="activeStyle(tag)" |
| | | @click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''" |
| | | @contextmenu.prevent="openMenu(tag, $event)" |
| | | > |
| | | {{ tag.title }} |
| | | <span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)"> |
| | | <close class="el-icon-close" style="width: 1em; height: 1em;vertical-align: middle;" /> |
| | | </span> |
| | | </router-link> |
| | | </scroll-pane> |
| | | <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu"> |
| | | <li @click="refreshSelectedTag(selectedTag)"><refresh-right style="width: 1em; height: 1em;" /> å·æ°é¡µé¢</li> |
| | | <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><close style="width: 1em; height: 1em;" /> å
³éå½å</li> |
| | | <li @click="closeOthersTags"><circle-close style="width: 1em; height: 1em;" /> å
³éå
¶ä»</li> |
| | | <li v-if="!isFirstView()" @click="closeLeftTags"><back style="width: 1em; height: 1em;" /> å
³é左侧</li> |
| | | <li v-if="!isLastView()" @click="closeRightTags"><right style="width: 1em; height: 1em;" /> å
³éå³ä¾§</li> |
| | | <li @click="closeAllTags(selectedTag)"><circle-close style="width: 1em; height: 1em;" /> å
¨é¨å
³é</li> |
| | | </ul> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import ScrollPane from './ScrollPane.vue' |
| | | import { getNormalPath } from '@/utils/ruoyi' |
| | |
| | | const theme = computed(() => useSettingsStore().theme); |
| | | |
| | | watch(route, () => { |
| | | addTags(); |
| | | moveToCurrentTag(); |
| | | addTags(); |
| | | moveToCurrentTag(); |
| | | }) |
| | | watch(visible, (value) => { |
| | | if (value) { |
| | | document.body.addEventListener('click', closeMenu); |
| | | } else { |
| | | document.body.removeEventListener('click', closeMenu); |
| | | } |
| | | if (value) { |
| | | document.body.addEventListener('click', closeMenu); |
| | | } else { |
| | | document.body.removeEventListener('click', closeMenu); |
| | | } |
| | | }) |
| | | |
| | | const isActive = (r: TagView): boolean => { |
| | | return r.path === route.path; |
| | | return r.path === route.path; |
| | | } |
| | | const activeStyle = (tag: TagView) => { |
| | | if (!isActive(tag)) return {}; |
| | | return { |
| | | "background-color": theme.value, |
| | | "border-color": theme.value |
| | | }; |
| | | if (!isActive(tag)) return {}; |
| | | return { |
| | | "background-color": theme.value, |
| | | "border-color": theme.value |
| | | }; |
| | | } |
| | | const isAffix = (tag: TagView) => { |
| | | return tag.meta && tag.meta.affix; |
| | | return tag.meta && tag.meta.affix; |
| | | } |
| | | const isFirstView = () => { |
| | | try { |
| | | return selectedTag.value.fullPath === '/index' || selectedTag.value.fullPath === visitedViews.value[1].fullPath; |
| | | } catch (err) { |
| | | return false; |
| | | } |
| | | try { |
| | | return selectedTag.value.fullPath === '/index' || selectedTag.value.fullPath === visitedViews.value[1].fullPath; |
| | | } catch (err) { |
| | | return false; |
| | | } |
| | | } |
| | | const isLastView = () => { |
| | | try { |
| | | return selectedTag.value.fullPath === visitedViews.value[visitedViews.value.length - 1].fullPath; |
| | | } catch (err) { |
| | | return false; |
| | | } |
| | | try { |
| | | return selectedTag.value.fullPath === visitedViews.value[visitedViews.value.length - 1].fullPath; |
| | | } catch (err) { |
| | | return false; |
| | | } |
| | | } |
| | | const filterAffixTags = (routes:RouteOption [], basePath = '') => { |
| | | let tags:TagView[] = [] |
| | | routes.forEach(route => { |
| | | if (route.meta && route.meta.affix) { |
| | | const tagPath = getNormalPath(basePath + '/' + route.path); |
| | | tags.push({ |
| | | fullPath: tagPath, |
| | | path: tagPath, |
| | | name: route.name, |
| | | meta: { ...route.meta } |
| | | }) |
| | | } |
| | | if (route.children) { |
| | | const tempTags = filterAffixTags(route.children, route.path); |
| | | if (tempTags.length >= 1) { |
| | | tags = [...tags, ...tempTags]; |
| | | } |
| | | } |
| | | }) |
| | | return tags |
| | | let tags:TagView[] = [] |
| | | routes.forEach(route => { |
| | | if (route.meta && route.meta.affix) { |
| | | const tagPath = getNormalPath(basePath + '/' + route.path); |
| | | tags.push({ |
| | | fullPath: tagPath, |
| | | path: tagPath, |
| | | name: route.name, |
| | | meta: { ...route.meta } |
| | | }) |
| | | } |
| | | if (route.children) { |
| | | const tempTags = filterAffixTags(route.children, route.path); |
| | | if (tempTags.length >= 1) { |
| | | tags = [...tags, ...tempTags]; |
| | | } |
| | | } |
| | | }) |
| | | return tags |
| | | } |
| | | const initTags = () => { |
| | | const res = filterAffixTags(routes.value); |
| | | affixTags.value = res; |
| | | for (const tag of res) { |
| | | // Must have tag name |
| | | if (tag.name) { |
| | | useTagsViewStore().addVisitedView(tag); |
| | | const res = filterAffixTags(routes.value); |
| | | affixTags.value = res; |
| | | for (const tag of res) { |
| | | // Must have tag name |
| | | if (tag.name) { |
| | | useTagsViewStore().addVisitedView(tag); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | const addTags = () => { |
| | | const { name } = route; |
| | | if (name) { |
| | | useTagsViewStore().addView(route); |
| | | if (route.meta.link) { |
| | | useTagsViewStore().addIframeView(route); |
| | | const { name } = route; |
| | | if (name) { |
| | | useTagsViewStore().addView(route); |
| | | if (route.meta.link) { |
| | | useTagsViewStore().addIframeView(route); |
| | | } |
| | | } |
| | | } |
| | | return false |
| | | return false |
| | | } |
| | | const moveToCurrentTag = () => { |
| | | nextTick(() => { |
| | | for (const r of visitedViews.value) { |
| | | if (r.path === route.path) { |
| | | scrollPaneRef.value.moveToTarget(r); |
| | | // when query is different then update |
| | | if (r.fullPath !== route.fullPath) { |
| | | useTagsViewStore().updateVisitedView(route); |
| | | nextTick(() => { |
| | | for (const r of visitedViews.value) { |
| | | if (r.path === route.path) { |
| | | scrollPaneRef.value.moveToTarget(r); |
| | | // when query is different then update |
| | | if (r.fullPath !== route.fullPath) { |
| | | useTagsViewStore().updateVisitedView(route); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | const refreshSelectedTag = (view: TagView) => { |
| | | proxy?.$tab.refreshPage(view); |
| | | if (route.meta.link) { |
| | | useTagsViewStore().delIframeView(route); |
| | | } |
| | | proxy?.$tab.refreshPage(view); |
| | | if (route.meta.link) { |
| | | useTagsViewStore().delIframeView(route); |
| | | } |
| | | } |
| | | const closeSelectedTag = (view: TagView) => { |
| | | proxy?.$tab.closePage(view).then(({ visitedViews }: any) => { |
| | | if (isActive(view)) { |
| | | toLastView(visitedViews, view); |
| | | } |
| | | }) |
| | | proxy?.$tab.closePage(view).then(({ visitedViews }: any) => { |
| | | if (isActive(view)) { |
| | | toLastView(visitedViews, view); |
| | | } |
| | | }) |
| | | } |
| | | const closeRightTags = () => { |
| | | proxy?.$tab.closeRightPage(selectedTag.value).then(visitedViews => { |
| | | if (!visitedViews.find(i => i.fullPath === route.fullPath)) { |
| | | toLastView(visitedViews); |
| | | } |
| | | }) |
| | | proxy?.$tab.closeRightPage(selectedTag.value).then(visitedViews => { |
| | | if (!visitedViews.find(i => i.fullPath === route.fullPath)) { |
| | | toLastView(visitedViews); |
| | | } |
| | | }) |
| | | } |
| | | const closeLeftTags = () => { |
| | | proxy?.$tab.closeLeftPage(selectedTag.value).then(visitedViews => { |
| | | if (!visitedViews.find(i => i.fullPath === route.fullPath)) { |
| | | toLastView(visitedViews); |
| | | } |
| | | }) |
| | | proxy?.$tab.closeLeftPage(selectedTag.value).then(visitedViews => { |
| | | if (!visitedViews.find(i => i.fullPath === route.fullPath)) { |
| | | toLastView(visitedViews); |
| | | } |
| | | }) |
| | | } |
| | | const closeOthersTags = () => { |
| | | router.push(selectedTag.value as RouteLocationRaw).catch(() => { }); |
| | | proxy?.$tab.closeOtherPage(selectedTag.value).then(() => { |
| | | moveToCurrentTag(); |
| | | }) |
| | | router.push(selectedTag.value as RouteLocationRaw).catch(() => { }); |
| | | proxy?.$tab.closeOtherPage(selectedTag.value).then(() => { |
| | | moveToCurrentTag(); |
| | | }) |
| | | } |
| | | const closeAllTags = (view: TagView) => { |
| | | proxy?.$tab.closeAllPage().then(({ visitedViews }) => { |
| | | if (affixTags.value.some(tag => tag.path === route.path)) { |
| | | return; |
| | | } |
| | | toLastView(visitedViews, view); |
| | | }) |
| | | proxy?.$tab.closeAllPage().then(({ visitedViews }) => { |
| | | if (affixTags.value.some(tag => tag.path === route.path)) { |
| | | return; |
| | | } |
| | | toLastView(visitedViews, view); |
| | | }) |
| | | } |
| | | const toLastView = (visitedViews:TagView[], view?: TagView) => { |
| | | const latestView = visitedViews.slice(-1)[0]; |
| | | if (latestView) { |
| | | router.push(latestView.fullPath as string); |
| | | } else { |
| | | // now the default is to redirect to the home page if there is no tags-view, |
| | | // you can adjust it according to your needs. |
| | | if (view?.name === 'Dashboard') { |
| | | // to reload home page |
| | | router.replace({ path: '/redirect' + view?.fullPath }); |
| | | const latestView = visitedViews.slice(-1)[0]; |
| | | if (latestView) { |
| | | router.push(latestView.fullPath as string); |
| | | } else { |
| | | router.push('/'); |
| | | // now the default is to redirect to the home page if there is no tags-view, |
| | | // you can adjust it according to your needs. |
| | | if (view?.name === 'Dashboard') { |
| | | // to reload home page |
| | | router.replace({ path: '/redirect' + view?.fullPath }); |
| | | } else { |
| | | router.push('/'); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | const openMenu = (tag: TagView, e: MouseEvent) => { |
| | | const menuMinWidth = 105; |
| | | const offsetLeft = proxy?.$el.getBoundingClientRect().left; // container margin left |
| | | const offsetWidth = proxy?.$el.offsetWidth; // container width |
| | | const maxLeft = offsetWidth - menuMinWidth; // left boundary |
| | | const l = e.clientX - offsetLeft + 15; // 15: margin right |
| | | const menuMinWidth = 105; |
| | | const offsetLeft = proxy?.$el.getBoundingClientRect().left; // container margin left |
| | | const offsetWidth = proxy?.$el.offsetWidth; // container width |
| | | const maxLeft = offsetWidth - menuMinWidth; // left boundary |
| | | const l = e.clientX - offsetLeft + 15; // 15: margin right |
| | | |
| | | if (l > maxLeft) { |
| | | left.value = maxLeft; |
| | | } else { |
| | | left.value = l; |
| | | } |
| | | if (l > maxLeft) { |
| | | left.value = maxLeft; |
| | | } else { |
| | | left.value = l; |
| | | } |
| | | |
| | | top.value = e.clientY |
| | | visible.value = true; |
| | | selectedTag.value = tag; |
| | | top.value = e.clientY |
| | | visible.value = true; |
| | | selectedTag.value = tag; |
| | | } |
| | | const closeMenu = () => { |
| | | visible.value = false; |
| | | visible.value = false; |
| | | } |
| | | const handleScroll = () => { |
| | | closeMenu(); |
| | | closeMenu(); |
| | | } |
| | | |
| | | |
| | | onMounted(() => { |
| | | initTags(); |
| | | addTags(); |
| | | initTags(); |
| | | addTags(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div id="tags-view-container" class="tags-view-container"> |
| | | <scroll-pane ref="scrollPaneRef" class="tags-view-wrapper" @scroll="handleScroll"> |
| | | <router-link |
| | | v-for="tag in visitedViews" |
| | | :key="tag.path" |
| | | :data-path="tag.path" |
| | | :class="isActive(tag) ? 'active' : ''" |
| | | :to="{ path: tag.path ? tag.path : '', query: tag.query, fullPath: tag.fullPath ? tag.fullPath : '' }" |
| | | class="tags-view-item" |
| | | :style="activeStyle(tag)" |
| | | @click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''" |
| | | @contextmenu.prevent="openMenu(tag, $event)" |
| | | > |
| | | {{ tag.title }} |
| | | <span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)"> |
| | | <close class="el-icon-close" style="width: 1em; height: 1em;vertical-align: middle;" /> |
| | | </span> |
| | | </router-link> |
| | | </scroll-pane> |
| | | <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu"> |
| | | <li @click="refreshSelectedTag(selectedTag)"><refresh-right style="width: 1em; height: 1em;" /> å·æ°é¡µé¢</li> |
| | | <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><close style="width: 1em; height: 1em;" /> å
³éå½å</li> |
| | | <li @click="closeOthersTags"><circle-close style="width: 1em; height: 1em;" /> å
³éå
¶ä»</li> |
| | | <li v-if="!isFirstView()" @click="closeLeftTags"><back style="width: 1em; height: 1em;" /> å
³é左侧</li> |
| | | <li v-if="!isLastView()" @click="closeRightTags"><right style="width: 1em; height: 1em;" /> å
³éå³ä¾§</li> |
| | | <li @click="closeAllTags(selectedTag)"><circle-close style="width: 1em; height: 1em;" /> å
¨é¨å
³é</li> |
| | | </ul> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | .tags-view-container { |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }"> |
| | | <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" /> |
| | | <side-bar v-if="!sidebar.hide" class="sidebar-container" /> |
| | | <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container"> |
| | | <div :class="{ 'fixed-header': fixedHeader }"> |
| | | <navbar ref="navbarRef" @setLayout="setLayout" /> |
| | | <tags-view v-if="needTagsView" /> |
| | | </div> |
| | | <app-main /> |
| | | <settings ref="settingRef" /> |
| | | </div> |
| | | </div> |
| | | <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }"> |
| | | <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" /> |
| | | <side-bar v-if="!sidebar.hide" class="sidebar-container" /> |
| | | <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container"> |
| | | <div :class="{ 'fixed-header': fixedHeader }"> |
| | | <navbar ref="navbarRef" @setLayout="setLayout" /> |
| | | <tags-view v-if="needTagsView" /> |
| | | </div> |
| | | <app-main /> |
| | | <settings ref="settingRef" /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | const whiteList = ['/login', '/register']; |
| | | |
| | | 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 (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); // å¨ææ·»å å¯è®¿é®è·¯ç±è¡¨ |
| | | } |
| | | }); |
| | | next({ ...to, replace: true }); // hackæ¹æ³ ç¡®ä¿addRoutes已宿 |
| | | } |
| | | } else { |
| | | next(); |
| | | } |
| | | } |
| | | } else { |
| | | // 没ætoken |
| | | if (whiteList.indexOf(to.path) !== -1) { |
| | | // å¨å
ç»å½ç½ååï¼ç´æ¥è¿å
¥ |
| | | next(); |
| | | } else { |
| | | next(`/login?redirect=${to.fullPath}`); // å¦åå
¨é¨éå®åå°ç»å½é¡µ |
| | | NProgress.done(); |
| | | } |
| | | } |
| | | 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 (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); // å¨ææ·»å å¯è®¿é®è·¯ç±è¡¨ |
| | | } |
| | | }); |
| | | next({ ...to, replace: true }); // hackæ¹æ³ ç¡®ä¿addRoutes已宿 |
| | | } |
| | | } else { |
| | | next(); |
| | | } |
| | | } |
| | | } else { |
| | | // 没ætoken |
| | | if (whiteList.indexOf(to.path) !== -1) { |
| | | // å¨å
ç»å½ç½ååï¼ç´æ¥è¿å
¥ |
| | | next(); |
| | | } else { |
| | | next(`/login?redirect=${to.fullPath}`); // å¦åå
¨é¨éå®åå°ç»å½é¡µ |
| | | NProgress.done(); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | router.afterEach(() => { |
| | | NProgress.done(); |
| | | NProgress.done(); |
| | | }); |
| | |
| | | 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 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; |
| | | } |
| | | 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); |
| | | }); |
| | | } |
| | | // éªè¯ç¨æ·æ¯å¦å
·å¤ææé |
| | | 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); |
| | | }); |
| | | } |
| | | }; |
| | |
| | | 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); |
| | | } |
| | | }, |
| | | remove(key: string) { |
| | | sessionStorage.removeItem(key); |
| | | } |
| | | 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); |
| | | } |
| | | }, |
| | | 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); |
| | | } |
| | | }, |
| | | remove(key: string) { |
| | | localStorage.removeItem(key); |
| | | } |
| | | 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); |
| | | } |
| | | }, |
| | | remove(key: string) { |
| | | localStorage.removeItem(key); |
| | | } |
| | | }; |
| | | |
| | | export default { |
| | | /** |
| | | * ä¼è¯çº§ç¼å |
| | | */ |
| | | session: sessionCache, |
| | | /** |
| | | * æ¬å°ç¼å |
| | | */ |
| | | local: localCache |
| | | /** |
| | | * ä¼è¯çº§ç¼å |
| | | */ |
| | | session: sessionCache, |
| | | /** |
| | | * æ¬å°ç¼å |
| | | */ |
| | | local: localCache |
| | | }; |
| | |
| | | const baseURL = import.meta.env.VITE_APP_BASE_API; |
| | | let downloadLoadingInstance: LoadingInstance; |
| | | export default { |
| | | async oss(ossId: string | number) { |
| | | const url = baseURL + '/system/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: { Authorization: 'Bearer ' + getToken() } |
| | | }); |
| | | 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; |
| | | const res = await axios({ |
| | | method: 'get', |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { |
| | | Authorization: 'Bearer ' + getToken(), |
| | | datasource: localStorage.getItem('dataName') |
| | | } |
| | | }); |
| | | 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); |
| | | } |
| | | }, |
| | | 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); |
| | | } |
| | | async oss(ossId: string | number) { |
| | | const url = baseURL + '/system/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: { Authorization: 'Bearer ' + getToken() } |
| | | }); |
| | | 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; |
| | | const res = await axios({ |
| | | method: 'get', |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { |
| | | Authorization: 'Bearer ' + getToken(), |
| | | datasource: localStorage.getItem('dataName') |
| | | } |
| | | }); |
| | | 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); |
| | | } |
| | | }, |
| | | 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); |
| | | } |
| | | }; |
| | |
| | | import { App } from 'vue'; |
| | | |
| | | export default function installPlugin(app: App) { |
| | | // é¡µç¾æä½ |
| | | app.config.globalProperties.$tab = tab; |
| | | // é¡µç¾æä½ |
| | | app.config.globalProperties.$tab = tab; |
| | | |
| | | // æ¨¡ææ¡å¯¹è±¡ |
| | | app.config.globalProperties.$modal = modal; |
| | | // æ¨¡ææ¡å¯¹è±¡ |
| | | app.config.globalProperties.$modal = modal; |
| | | |
| | | // ç¼å对象 |
| | | app.config.globalProperties.$cache = cache; |
| | | // ç¼å对象 |
| | | app.config.globalProperties.$cache = cache; |
| | | |
| | | // ä¸è½½æä»¶ |
| | | app.config.globalProperties.$download = download; |
| | | // ä¸è½½æä»¶ |
| | | app.config.globalProperties.$download = download; |
| | | |
| | | // 认è¯å¯¹è±¡ |
| | | app.config.globalProperties.$auth = auth; |
| | | // 认è¯å¯¹è±¡ |
| | | app.config.globalProperties.$auth = auth; |
| | | } |
| | |
| | | import { LoadingInstance } from 'element-plus/es/components/loading/src/loading'; |
| | | let loadingInstance: LoadingInstance; |
| | | export default { |
| | | // æ¶æ¯æç¤º |
| | | msg(content: string) { |
| | | ElMessage.info(content); |
| | | }, |
| | | // éè¯¯æ¶æ¯ |
| | | msgError(content: string) { |
| | | ElMessage.error(content); |
| | | }, |
| | | // æåæ¶æ¯ |
| | | msgSuccess(content: string) { |
| | | ElMessage.success(content); |
| | | }, |
| | | // è¦åæ¶æ¯ |
| | | msgWarning(content: string) { |
| | | ElMessage.warning(content); |
| | | }, |
| | | // å¼¹åºæç¤º |
| | | alert(content: string) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º'); |
| | | }, |
| | | // é误æç¤º |
| | | alertError(content: string) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º', { type: 'error' }); |
| | | }, |
| | | // æåæç¤º |
| | | alertSuccess(content: string, s: string, p: { dangerouslyUseHTMLString: boolean }) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º', { type: 'success' }); |
| | | }, |
| | | // è¦åæç¤º |
| | | alertWarning(content: string) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º', { type: 'warning' }); |
| | | }, |
| | | // éç¥æç¤º |
| | | notify(content: string) { |
| | | ElNotification.info(content); |
| | | }, |
| | | // é误éç¥ |
| | | notifyError(content: string) { |
| | | ElNotification.error(content); |
| | | }, |
| | | // æåéç¥ |
| | | notifySuccess(content: string) { |
| | | ElNotification.success(content); |
| | | }, |
| | | // è¦åéç¥ |
| | | notifyWarning(content: string) { |
| | | ElNotification.warning(content); |
| | | }, |
| | | // 确认çªä½ |
| | | confirm(content: string): Promise<MessageBoxData> { |
| | | return ElMessageBox.confirm(content, 'ç³»ç»æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }); |
| | | }, |
| | | // æäº¤å
容 |
| | | prompt(content: string) { |
| | | 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(); |
| | | } |
| | | // æ¶æ¯æç¤º |
| | | msg(content: string) { |
| | | ElMessage.info(content); |
| | | }, |
| | | // éè¯¯æ¶æ¯ |
| | | msgError(content: string) { |
| | | ElMessage.error(content); |
| | | }, |
| | | // æåæ¶æ¯ |
| | | msgSuccess(content: string) { |
| | | ElMessage.success(content); |
| | | }, |
| | | // è¦åæ¶æ¯ |
| | | msgWarning(content: string) { |
| | | ElMessage.warning(content); |
| | | }, |
| | | // å¼¹åºæç¤º |
| | | alert(content: string) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º'); |
| | | }, |
| | | // é误æç¤º |
| | | alertError(content: string) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º', { type: 'error' }); |
| | | }, |
| | | // æåæç¤º |
| | | alertSuccess(content: string, s: string, p: { dangerouslyUseHTMLString: boolean }) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º', { type: 'success' }); |
| | | }, |
| | | // è¦åæç¤º |
| | | alertWarning(content: string) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º', { type: 'warning' }); |
| | | }, |
| | | // éç¥æç¤º |
| | | notify(content: string) { |
| | | ElNotification.info(content); |
| | | }, |
| | | // é误éç¥ |
| | | notifyError(content: string) { |
| | | ElNotification.error(content); |
| | | }, |
| | | // æåéç¥ |
| | | notifySuccess(content: string) { |
| | | ElNotification.success(content); |
| | | }, |
| | | // è¦åéç¥ |
| | | notifyWarning(content: string) { |
| | | ElNotification.warning(content); |
| | | }, |
| | | // 确认çªä½ |
| | | confirm(content: string): Promise<MessageBoxData> { |
| | | return ElMessageBox.confirm(content, 'ç³»ç»æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }); |
| | | }, |
| | | // æäº¤å
容 |
| | | prompt(content: string) { |
| | | 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(); |
| | | } |
| | | }; |
| | |
| | | import { App } from 'vue'; |
| | | |
| | | export default { |
| | | install: (app: App) => { |
| | | for (const [key, component] of Object.entries(ElementPlusIconsVue)) { |
| | | app.component(key, component); |
| | | } |
| | | } |
| | | install: (app: App) => { |
| | | for (const [key, component] of Object.entries(ElementPlusIconsVue)) { |
| | | app.component(key, component); |
| | | } |
| | | } |
| | | }; |
| | |
| | | import { TagView, RouteLocationRaw } from 'vue-router'; |
| | | |
| | | export default { |
| | | // å·æ°å½åtabé¡µç¾ |
| | | async refreshPage(obj: TagView): Promise<void> { |
| | | const { path, query, matched } = router.currentRoute.value; |
| | | if (obj === undefined) { |
| | | matched.forEach((m) => { |
| | | 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 }; |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | // prettier-ignore |
| | | await useTagsViewStore().delCachedView(obj) |
| | | router.replace({ |
| | | path: '/redirect' + obj.path, |
| | | query: obj.query |
| | | }); |
| | | }, |
| | | // å
³éå½åtab页ç¾ï¼æå¼æ°é¡µç¾ |
| | | closeOpenPage(obj: RouteLocationRaw): void { |
| | | useTagsViewStore().delView(router.currentRoute.value); |
| | | if (obj !== undefined) { |
| | | router.push(obj); |
| | | } |
| | | }, |
| | | // å
³éæå®tabé¡µç¾ |
| | | async closePage(obj?: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] } | any> { |
| | | if (obj === undefined) { |
| | | // prettier-ignore |
| | | const { lastPath } = await useTagsViewStore().delView(router.currentRoute.value) as any |
| | | return router.push(lastPath || '/index'); |
| | | } |
| | | return useTagsViewStore().delView(obj); |
| | | }, |
| | | // å
³éæætabé¡µç¾ |
| | | closeAllPage() { |
| | | return useTagsViewStore().delAllViews(); |
| | | }, |
| | | // å
³é左侧tabé¡µç¾ |
| | | closeLeftPage(obj: TagView) { |
| | | return useTagsViewStore().delLeftTags(obj || router.currentRoute.value); |
| | | }, |
| | | // å
³éå³ä¾§tabé¡µç¾ |
| | | closeRightPage(obj: TagView) { |
| | | return useTagsViewStore().delRightTags(obj || router.currentRoute.value); |
| | | }, |
| | | // å
³éå
¶ä»tabé¡µç¾ |
| | | closeOtherPage(obj: TagView) { |
| | | return useTagsViewStore().delOthersViews(obj || router.currentRoute.value); |
| | | }, |
| | | // æå¼tabé¡µç¾ |
| | | openPage(url: RouteLocationRaw) { |
| | | return router.push(url); |
| | | }, |
| | | // ä¿®æ¹tabé¡µç¾ |
| | | updatePage(obj: TagView) { |
| | | return useTagsViewStore().updateVisitedView(obj); |
| | | } |
| | | // å·æ°å½åtabé¡µç¾ |
| | | async refreshPage(obj: TagView): Promise<void> { |
| | | const { path, query, matched } = router.currentRoute.value; |
| | | if (obj === undefined) { |
| | | matched.forEach((m) => { |
| | | 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 }; |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | // prettier-ignore |
| | | await useTagsViewStore().delCachedView(obj) |
| | | router.replace({ |
| | | path: '/redirect' + obj.path, |
| | | query: obj.query |
| | | }); |
| | | }, |
| | | // å
³éå½åtab页ç¾ï¼æå¼æ°é¡µç¾ |
| | | closeOpenPage(obj: RouteLocationRaw): void { |
| | | useTagsViewStore().delView(router.currentRoute.value); |
| | | if (obj !== undefined) { |
| | | router.push(obj); |
| | | } |
| | | }, |
| | | // å
³éæå®tabé¡µç¾ |
| | | async closePage(obj?: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] } | any> { |
| | | if (obj === undefined) { |
| | | // prettier-ignore |
| | | const { lastPath } = await useTagsViewStore().delView(router.currentRoute.value) as any |
| | | return router.push(lastPath || '/index'); |
| | | } |
| | | return useTagsViewStore().delView(obj); |
| | | }, |
| | | // å
³éæætabé¡µç¾ |
| | | closeAllPage() { |
| | | return useTagsViewStore().delAllViews(); |
| | | }, |
| | | // å
³é左侧tabé¡µç¾ |
| | | closeLeftPage(obj: TagView) { |
| | | return useTagsViewStore().delLeftTags(obj || router.currentRoute.value); |
| | | }, |
| | | // å
³éå³ä¾§tabé¡µç¾ |
| | | closeRightPage(obj: TagView) { |
| | | return useTagsViewStore().delRightTags(obj || router.currentRoute.value); |
| | | }, |
| | | // å
³éå
¶ä»tabé¡µç¾ |
| | | closeOtherPage(obj: TagView) { |
| | | return useTagsViewStore().delOthersViews(obj || router.currentRoute.value); |
| | | }, |
| | | // æå¼tabé¡µç¾ |
| | | openPage(url: RouteLocationRaw) { |
| | | return router.push(url); |
| | | }, |
| | | // ä¿®æ¹tabé¡µç¾ |
| | | updatePage(obj: TagView) { |
| | | return useTagsViewStore().updateVisitedView(obj); |
| | | } |
| | | }; |
| | |
| | | |
| | | // å
Œ
±è·¯ç± |
| | | export const constantRoutes: RouteOption[] = [ |
| | | { |
| | | path: '/redirect', |
| | | component: Layout, |
| | | hidden: true, |
| | | children: [ |
| | | { |
| | | path: '/redirect/:path(.*)', |
| | | component: () => import('@/views/redirect/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' } |
| | | } |
| | | ] |
| | | } |
| | | { |
| | | path: '/redirect', |
| | | component: Layout, |
| | | hidden: true, |
| | | children: [ |
| | | { |
| | | path: '/redirect/:path(.*)', |
| | | component: () => import('@/views/redirect/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: RouteOption[] = [ |
| | | { |
| | | path: '/system/user-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:user:edit'], |
| | | children: [ |
| | | { |
| | | path: 'role/:userId(\\d+)', |
| | | component: () => import('@/views/system/user/authRole.vue'), |
| | | name: 'AuthRole', |
| | | meta: { title: 'åé
è§è²', activeMenu: '/system/user', icon: '' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/role-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:role:edit'], |
| | | children: [ |
| | | { |
| | | path: 'user/:roleId(\\d+)', |
| | | component: () => import('@/views/system/role/authUser.vue'), |
| | | name: 'AuthUser', |
| | | meta: { title: 'åé
ç¨æ·', activeMenu: '/system/role', icon: '' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/dict-data', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:dict:list'], |
| | | children: [ |
| | | { |
| | | path: 'index/:dictId(\\d+)', |
| | | component: () => import('@/views/system/dict/data.vue'), |
| | | name: 'Data', |
| | | meta: { title: 'åå
¸æ°æ®', activeMenu: '/system/dict', icon: '' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/oss-config', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['monitor:job:list'], |
| | | children: [ |
| | | { |
| | | path: 'index', |
| | | component: () => import('@/views/system/oss/config.vue'), |
| | | name: 'OssConfig', |
| | | meta: { title: 'é
置管ç', activeMenu: '/system/oss', icon: '' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/tool/gen-edit', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['tool:gen:edit'], |
| | | children: [ |
| | | { |
| | | path: 'index/:tableId(\\d+)', |
| | | component: () => import('@/views/tool/gen/editTable.vue'), |
| | | name: 'GenEdit', |
| | | meta: { title: 'ä¿®æ¹çæé
ç½®', activeMenu: '/tool/gen', icon: '' } |
| | | } |
| | | ] |
| | | } |
| | | { |
| | | path: '/system/user-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:user:edit'], |
| | | children: [ |
| | | { |
| | | path: 'role/:userId(\\d+)', |
| | | component: () => import('@/views/system/user/authRole.vue'), |
| | | name: 'AuthRole', |
| | | meta: { title: 'åé
è§è²', activeMenu: '/system/user', icon: '' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/role-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:role:edit'], |
| | | children: [ |
| | | { |
| | | path: 'user/:roleId(\\d+)', |
| | | component: () => import('@/views/system/role/authUser.vue'), |
| | | name: 'AuthUser', |
| | | meta: { title: 'åé
ç¨æ·', activeMenu: '/system/role', icon: '' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/dict-data', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:dict:list'], |
| | | children: [ |
| | | { |
| | | path: 'index/:dictId(\\d+)', |
| | | component: () => import('@/views/system/dict/data.vue'), |
| | | name: 'Data', |
| | | meta: { title: 'åå
¸æ°æ®', activeMenu: '/system/dict', icon: '' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/oss-config', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['monitor:job:list'], |
| | | children: [ |
| | | { |
| | | path: 'index', |
| | | component: () => import('@/views/system/oss/config.vue'), |
| | | name: 'OssConfig', |
| | | meta: { title: 'é
置管ç', activeMenu: '/system/oss', icon: '' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/tool/gen-edit', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['tool:gen:edit'], |
| | | children: [ |
| | | { |
| | | path: 'index/:tableId(\\d+)', |
| | | component: () => import('@/views/tool/gen/editTable.vue'), |
| | | name: 'GenEdit', |
| | | meta: { title: 'ä¿®æ¹çæé
ç½®', activeMenu: '/tool/gen', icon: '' } |
| | | } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | | /** |
| | | * åå»ºè·¯ç± |
| | | */ |
| | | const router = createRouter({ |
| | | history: createWebHistory(import.meta.env.VITE_APP_CONTEXT_PATH), |
| | | routes: constantRoutes, |
| | | // å·æ°æ¶ï¼æ»å¨æ¡ä½ç½®è¿å |
| | | scrollBehavior(to, from, savedPosition) { |
| | | if (savedPosition) { |
| | | return savedPosition; |
| | | } else { |
| | | return { top: 0 }; |
| | | } |
| | | } |
| | | history: createWebHistory(import.meta.env.VITE_APP_CONTEXT_PATH), |
| | | routes: constantRoutes, |
| | | // å·æ°æ¶ï¼æ»å¨æ¡ä½ç½®è¿å |
| | | scrollBehavior(to, from, savedPosition) { |
| | | if (savedPosition) { |
| | | return savedPosition; |
| | | } else { |
| | | return { top: 0 }; |
| | | } |
| | | } |
| | | }); |
| | | |
| | | export default router; |
| | |
| | | const setting: DefaultSettings = { |
| | | /** |
| | | * ç½é¡µæ é¢ |
| | | */ |
| | | title: import.meta.env.VITE_APP_TITLE, |
| | | /** |
| | | * ç½é¡µæ é¢ |
| | | */ |
| | | title: import.meta.env.VITE_APP_TITLE, |
| | | |
| | | theme: '#409EFF', |
| | | theme: '#409EFF', |
| | | |
| | | /** |
| | | * ä¾§è¾¹æ ä¸»é¢ æ·±è²ä¸»é¢theme-darkï¼æµ
è²ä¸»é¢theme-light |
| | | */ |
| | | sideTheme: 'theme-dark', |
| | | /** |
| | | * æ¯å¦ç³»ç»å¸å±é
ç½® |
| | | */ |
| | | showSettings: false, |
| | | /** |
| | | * ä¾§è¾¹æ ä¸»é¢ æ·±è²ä¸»é¢theme-darkï¼æµ
è²ä¸»é¢theme-light |
| | | */ |
| | | sideTheme: 'theme-dark', |
| | | /** |
| | | * æ¯å¦ç³»ç»å¸å±é
ç½® |
| | | */ |
| | | showSettings: false, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºé¡¶é¨å¯¼èª |
| | | */ |
| | | topNav: false, |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºé¡¶é¨å¯¼èª |
| | | */ |
| | | topNav: false, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤º tagsView |
| | | */ |
| | | tagsView: true, |
| | | /** |
| | | * æ¯å¦æ¾ç¤º tagsView |
| | | */ |
| | | tagsView: true, |
| | | |
| | | /** |
| | | * æ¯å¦åºå®å¤´é¨ |
| | | */ |
| | | fixedHeader: false, |
| | | /** |
| | | * æ¯å¦åºå®å¤´é¨ |
| | | */ |
| | | fixedHeader: false, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºlogo |
| | | */ |
| | | sidebarLogo: true, |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºlogo |
| | | */ |
| | | sidebarLogo: true, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºå¨ææ é¢ |
| | | */ |
| | | dynamicTitle: false, |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºå¨ææ é¢ |
| | | */ |
| | | dynamicTitle: false, |
| | | |
| | | /** |
| | | * @type {string | array} 'production' | ['production', 'development'] |
| | | * @description Need show err logs component. |
| | | * The default is only used in the production env |
| | | * If you want to also use it in dev, you can pass ['production', 'development'] |
| | | */ |
| | | errorLog: 'production', |
| | | /** |
| | | * @type {string | array} 'production' | ['production', 'development'] |
| | | * @description Need show err logs component. |
| | | * The default is only used in the production env |
| | | * If you want to also use it in dev, you can pass ['production', 'development'] |
| | | */ |
| | | errorLog: 'production', |
| | | |
| | | animationEnable: false, |
| | | animationEnable: false, |
| | | |
| | | dark: false |
| | | dark: false |
| | | }; |
| | | export default setting; |
| | |
| | | import en from 'element-plus/es/locale/lang/en'; |
| | | |
| | | export const useAppStore = defineStore('app', () => { |
| | | const sidebarStatus = Cookies.get('sidebarStatus'); |
| | | const sidebar = reactive({ |
| | | opened: sidebarStatus ? !!+sidebarStatus : true, |
| | | withoutAnimation: false, |
| | | hide: false |
| | | }); |
| | | const device = ref<string>('desktop'); |
| | | const size = ref(Cookies.get('size') || 'default'); |
| | | // è¯è¨ |
| | | const language = ref(Cookies.get('language')); |
| | | const locale = computed(() => { |
| | | if (language?.value == 'en') { |
| | | return en; |
| | | } else { |
| | | return zhCn; |
| | | } |
| | | }); |
| | | const sidebarStatus = Cookies.get('sidebarStatus'); |
| | | const sidebar = reactive({ |
| | | opened: sidebarStatus ? !!+sidebarStatus : true, |
| | | withoutAnimation: false, |
| | | hide: false |
| | | }); |
| | | const device = ref<string>('desktop'); |
| | | const size = ref(Cookies.get('size') || 'default'); |
| | | // è¯è¨ |
| | | const language = ref(Cookies.get('language')); |
| | | const locale = computed(() => { |
| | | if (language?.value == 'en') { |
| | | return en; |
| | | } else { |
| | | return zhCn; |
| | | } |
| | | }); |
| | | |
| | | const toggleSideBar = (withoutAnimation?: boolean) => { |
| | | if (sidebar.hide) { |
| | | return false; |
| | | } |
| | | const toggleSideBar = (withoutAnimation?: boolean) => { |
| | | if (sidebar.hide) { |
| | | return false; |
| | | } |
| | | |
| | | sidebar.opened = !sidebar.opened; |
| | | sidebar.withoutAnimation = withoutAnimation as boolean; |
| | | if (sidebar.opened) { |
| | | Cookies.set('sidebarStatus', '1'); |
| | | } else { |
| | | Cookies.set('sidebarStatus', '0'); |
| | | } |
| | | }; |
| | | sidebar.opened = !sidebar.opened; |
| | | sidebar.withoutAnimation = withoutAnimation as boolean; |
| | | if (sidebar.opened) { |
| | | Cookies.set('sidebarStatus', '1'); |
| | | } else { |
| | | Cookies.set('sidebarStatus', '0'); |
| | | } |
| | | }; |
| | | |
| | | const closeSideBar = ({ withoutAnimation }: any): void => { |
| | | Cookies.set('sidebarStatus', '0'); |
| | | sidebar.opened = false; |
| | | sidebar.withoutAnimation = withoutAnimation; |
| | | }; |
| | | const toggleDevice = (d: string): void => { |
| | | device.value = d; |
| | | }; |
| | | const setSize = (s: string): void => { |
| | | size.value = s; |
| | | Cookies.set('size', s); |
| | | }; |
| | | const toggleSideBarHide = (status: boolean): void => { |
| | | sidebar.hide = status; |
| | | }; |
| | | const closeSideBar = ({ withoutAnimation }: any): void => { |
| | | Cookies.set('sidebarStatus', '0'); |
| | | sidebar.opened = false; |
| | | sidebar.withoutAnimation = withoutAnimation; |
| | | }; |
| | | const toggleDevice = (d: string): void => { |
| | | device.value = d; |
| | | }; |
| | | const setSize = (s: string): void => { |
| | | size.value = s; |
| | | Cookies.set('size', s); |
| | | }; |
| | | const toggleSideBarHide = (status: boolean): void => { |
| | | sidebar.hide = status; |
| | | }; |
| | | |
| | | const changeLanguage = (val: string): void => { |
| | | language.value = val; |
| | | }; |
| | | const changeLanguage = (val: string): void => { |
| | | language.value = val; |
| | | }; |
| | | |
| | | return { |
| | | device, |
| | | sidebar, |
| | | language, |
| | | locale, |
| | | size, |
| | | changeLanguage, |
| | | toggleSideBar, |
| | | closeSideBar, |
| | | toggleDevice, |
| | | setSize, |
| | | toggleSideBarHide |
| | | }; |
| | | return { |
| | | device, |
| | | sidebar, |
| | | language, |
| | | locale, |
| | | size, |
| | | changeLanguage, |
| | | toggleSideBar, |
| | | closeSideBar, |
| | | toggleDevice, |
| | | setSize, |
| | | toggleSideBarHide |
| | | }; |
| | | }); |
| | | |
| | | export default useAppStore; |
| | |
| | | export const useDictStore = defineStore('dict', () => { |
| | | const dict = ref< |
| | | Array<{ |
| | | key: string; |
| | | value: DictDataOption[]; |
| | | }> |
| | | >([]); |
| | | const dict = ref< |
| | | Array<{ |
| | | key: string; |
| | | value: DictDataOption[]; |
| | | }> |
| | | >([]); |
| | | |
| | | /** |
| | | * è·ååå
¸ |
| | | * @param _key åå
¸key |
| | | */ |
| | | const getDict = (_key: string): DictDataOption[] | null => { |
| | | if (_key == null && _key == '') { |
| | | return null; |
| | | } |
| | | try { |
| | | for (let i = 0; i < dict.value.length; i++) { |
| | | if (dict.value[i].key == _key) { |
| | | return dict.value[i].value; |
| | | } |
| | | } |
| | | } catch (e) { |
| | | return null; |
| | | } |
| | | return null; |
| | | }; |
| | | /** |
| | | * è·ååå
¸ |
| | | * @param _key åå
¸key |
| | | */ |
| | | const getDict = (_key: string): DictDataOption[] | null => { |
| | | if (_key == null && _key == '') { |
| | | return null; |
| | | } |
| | | try { |
| | | for (let i = 0; i < dict.value.length; i++) { |
| | | if (dict.value[i].key == _key) { |
| | | return dict.value[i].value; |
| | | } |
| | | } |
| | | } catch (e) { |
| | | return null; |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | /** |
| | | * 设置åå
¸ |
| | | * @param _key åå
¸key |
| | | * @param _value åå
¸value |
| | | */ |
| | | const setDict = (_key: string, _value: DictDataOption[]) => { |
| | | if (_key !== null && _key !== '') { |
| | | dict.value.push({ |
| | | key: _key, |
| | | value: _value |
| | | }); |
| | | } |
| | | }; |
| | | /** |
| | | * 设置åå
¸ |
| | | * @param _key åå
¸key |
| | | * @param _value åå
¸value |
| | | */ |
| | | const setDict = (_key: string, _value: DictDataOption[]) => { |
| | | if (_key !== null && _key !== '') { |
| | | dict.value.push({ |
| | | key: _key, |
| | | value: _value |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * å é¤åå
¸ |
| | | * @param _key |
| | | */ |
| | | const removeDict = (_key: string): boolean => { |
| | | let bln = false; |
| | | try { |
| | | for (let i = 0; i < dict.value.length; i++) { |
| | | if (dict.value[i].key == _key) { |
| | | dict.value.splice(i, 1); |
| | | return true; |
| | | } |
| | | } |
| | | } catch (e) { |
| | | bln = false; |
| | | } |
| | | return bln; |
| | | }; |
| | | /** |
| | | * å é¤åå
¸ |
| | | * @param _key |
| | | */ |
| | | const removeDict = (_key: string): boolean => { |
| | | let bln = false; |
| | | try { |
| | | for (let i = 0; i < dict.value.length; i++) { |
| | | if (dict.value[i].key == _key) { |
| | | dict.value.splice(i, 1); |
| | | return true; |
| | | } |
| | | } |
| | | } catch (e) { |
| | | bln = false; |
| | | } |
| | | return bln; |
| | | }; |
| | | |
| | | /** |
| | | * æ¸
空åå
¸ |
| | | */ |
| | | const cleanDict = (): void => { |
| | | dict.value = []; |
| | | }; |
| | | /** |
| | | * æ¸
空åå
¸ |
| | | */ |
| | | const cleanDict = (): void => { |
| | | dict.value = []; |
| | | }; |
| | | |
| | | return { |
| | | dict, |
| | | getDict, |
| | | setDict, |
| | | removeDict, |
| | | cleanDict |
| | | }; |
| | | return { |
| | | dict, |
| | | getDict, |
| | | setDict, |
| | | removeDict, |
| | | cleanDict |
| | | }; |
| | | }); |
| | | |
| | | export default useDictStore; |
| | |
| | | const modules = import.meta.glob('./../../views/**/*.vue'); |
| | | |
| | | export const usePermissionStore = defineStore('permission', () => { |
| | | const routes = ref<RouteOption[]>([]); |
| | | const addRoutes = ref<RouteOption[]>([]); |
| | | const defaultRoutes = ref<RouteOption[]>([]); |
| | | const topbarRouters = ref<RouteOption[]>([]); |
| | | const sidebarRouters = ref<RouteOption[]>([]); |
| | | const routes = ref<RouteOption[]>([]); |
| | | const addRoutes = ref<RouteOption[]>([]); |
| | | const defaultRoutes = ref<RouteOption[]>([]); |
| | | const topbarRouters = ref<RouteOption[]>([]); |
| | | const sidebarRouters = ref<RouteOption[]>([]); |
| | | |
| | | const setRoutes = (newRoutes: RouteOption[]): void => { |
| | | addRoutes.value = newRoutes; |
| | | routes.value = constantRoutes.concat(newRoutes); |
| | | }; |
| | | const setDefaultRoutes = (routes: RouteOption[]): void => { |
| | | defaultRoutes.value = constantRoutes.concat(routes); |
| | | }; |
| | | const setTopbarRoutes = (routes: RouteOption[]): void => { |
| | | topbarRouters.value = routes; |
| | | }; |
| | | const setSidebarRouters = (routes: RouteOption[]): void => { |
| | | sidebarRouters.value = routes; |
| | | }; |
| | | const generateRoutes = async (): Promise<RouteOption[]> => { |
| | | 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); |
| | | return new Promise<RouteOption[]>((resolve) => resolve(rewriteRoutes)); |
| | | }; |
| | | const setRoutes = (newRoutes: RouteOption[]): void => { |
| | | addRoutes.value = newRoutes; |
| | | routes.value = constantRoutes.concat(newRoutes); |
| | | }; |
| | | const setDefaultRoutes = (routes: RouteOption[]): void => { |
| | | defaultRoutes.value = constantRoutes.concat(routes); |
| | | }; |
| | | const setTopbarRoutes = (routes: RouteOption[]): void => { |
| | | topbarRouters.value = routes; |
| | | }; |
| | | const setSidebarRouters = (routes: RouteOption[]): void => { |
| | | sidebarRouters.value = routes; |
| | | }; |
| | | const generateRoutes = async (): Promise<RouteOption[]> => { |
| | | 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); |
| | | return new Promise<RouteOption[]>((resolve) => resolve(rewriteRoutes)); |
| | | }; |
| | | |
| | | /** |
| | | * éååå°ä¼ æ¥çè·¯ç±å符串ï¼è½¬æ¢ä¸ºç»ä»¶å¯¹è±¡ |
| | | * @param asyncRouterMap åå°ä¼ æ¥çè·¯ç±å符串 |
| | | * @param lastRouter ä¸ä¸çº§è·¯ç± |
| | | * @param type æ¯å¦æ¯éåè·¯ç± |
| | | */ |
| | | const filterAsyncRouter = (asyncRouterMap: RouteOption[], lastRouter?: RouteOption, type = false): RouteOption[] => { |
| | | return asyncRouterMap.filter((route) => { |
| | | if (type && route.children) { |
| | | route.children = filterChildren(route.children, undefined); |
| | | } |
| | | if (route.component) { |
| | | // Layout ParentView ç»ä»¶ç¹æ®å¤ç |
| | | if (route.component === 'Layout') { |
| | | route.component = Layout; |
| | | } else if (route.component === 'ParentView') { |
| | | route.component = ParentView; |
| | | } else if (route.component === 'InnerLink') { |
| | | route.component = InnerLink; |
| | | } else { |
| | | route.component = loadView(route.component); |
| | | } |
| | | } |
| | | 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: RouteOption[], lastRouter?: RouteOption): RouteOption[] => { |
| | | let children: RouteOption[] = []; |
| | | childrenMap.forEach((el) => { |
| | | if (el.children && el.children.length) { |
| | | if (el.component === 'ParentView' && !lastRouter) { |
| | | el.children.forEach((c) => { |
| | | c.path = el.path + '/' + c.path; |
| | | if (c.children && c.children.length) { |
| | | children = children.concat(filterChildren(c.children, c)); |
| | | return; |
| | | } |
| | | children.push(c); |
| | | }); |
| | | return; |
| | | } |
| | | } |
| | | if (lastRouter) { |
| | | el.path = lastRouter.path + '/' + el.path; |
| | | } |
| | | children = children.concat(el); |
| | | }); |
| | | return children; |
| | | }; |
| | | return { routes, setRoutes, generateRoutes, setSidebarRouters, topbarRouters, sidebarRouters, defaultRoutes }; |
| | | /** |
| | | * éååå°ä¼ æ¥çè·¯ç±å符串ï¼è½¬æ¢ä¸ºç»ä»¶å¯¹è±¡ |
| | | * @param asyncRouterMap åå°ä¼ æ¥çè·¯ç±å符串 |
| | | * @param lastRouter ä¸ä¸çº§è·¯ç± |
| | | * @param type æ¯å¦æ¯éåè·¯ç± |
| | | */ |
| | | const filterAsyncRouter = (asyncRouterMap: RouteOption[], lastRouter?: RouteOption, type = false): RouteOption[] => { |
| | | return asyncRouterMap.filter((route) => { |
| | | if (type && route.children) { |
| | | route.children = filterChildren(route.children, undefined); |
| | | } |
| | | if (route.component) { |
| | | // Layout ParentView ç»ä»¶ç¹æ®å¤ç |
| | | if (route.component === 'Layout') { |
| | | route.component = Layout; |
| | | } else if (route.component === 'ParentView') { |
| | | route.component = ParentView; |
| | | } else if (route.component === 'InnerLink') { |
| | | route.component = InnerLink; |
| | | } else { |
| | | route.component = loadView(route.component); |
| | | } |
| | | } |
| | | 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: RouteOption[], lastRouter?: RouteOption): RouteOption[] => { |
| | | let children: RouteOption[] = []; |
| | | childrenMap.forEach((el) => { |
| | | if (el.children && el.children.length) { |
| | | if (el.component === 'ParentView' && !lastRouter) { |
| | | el.children.forEach((c) => { |
| | | c.path = el.path + '/' + c.path; |
| | | if (c.children && c.children.length) { |
| | | children = children.concat(filterChildren(c.children, c)); |
| | | return; |
| | | } |
| | | children.push(c); |
| | | }); |
| | | return; |
| | | } |
| | | } |
| | | if (lastRouter) { |
| | | el.path = lastRouter.path + '/' + el.path; |
| | | } |
| | | children = children.concat(el); |
| | | }); |
| | | return children; |
| | | }; |
| | | return { routes, setRoutes, generateRoutes, setSidebarRouters, topbarRouters, sidebarRouters, defaultRoutes }; |
| | | }); |
| | | |
| | | // å¨æè·¯ç±éåï¼éªè¯æ¯å¦å
·å¤æé |
| | | export const filterDynamicRoutes = (routes: RouteOption[]) => { |
| | | const res: RouteOption[] = []; |
| | | 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; |
| | | const res: RouteOption[] = []; |
| | | 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) => { |
| | | let res; |
| | | for (const path in modules) { |
| | | const dir = path.split('views/')[1].split('.vue')[0]; |
| | | if (dir === view) { |
| | | res = () => modules[path](); |
| | | } |
| | | } |
| | | return res; |
| | | let res; |
| | | for (const path in modules) { |
| | | const dir = path.split('views/')[1].split('.vue')[0]; |
| | | if (dir === view) { |
| | | res = () => modules[path](); |
| | | } |
| | | } |
| | | return res; |
| | | }; |
| | | |
| | | // ésetup |
| | | export const usePermissionStoreHook = () => { |
| | | return usePermissionStore(store); |
| | | return usePermissionStore(store); |
| | | }; |
| | | |
| | | export default usePermissionStore; |
| | |
| | | import { Ref } from 'vue'; |
| | | |
| | | export const useSettingsStore = defineStore('setting', () => { |
| | | const storageSetting = JSON.parse(localStorage.getItem('layout-setting') || '{}'); |
| | | const storageSetting = JSON.parse(localStorage.getItem('layout-setting') || '{}'); |
| | | |
| | | const prop: { [key: string]: Ref<any> } = { |
| | | title: ref<string>(''), |
| | | theme: ref<string>(storageSetting.theme || defaultSettings.theme), |
| | | sideTheme: ref<string>(storageSetting.sideTheme || defaultSettings.sideTheme), |
| | | showSettings: ref<boolean>(storageSetting.showSettings), |
| | | topNav: ref<boolean>(storageSetting.topNav || defaultSettings.topNav), |
| | | tagsView: ref<boolean>(storageSetting.tagsView || defaultSettings.tagsView), |
| | | fixedHeader: ref<boolean>(storageSetting.fixedHeader || defaultSettings.fixedHeader), |
| | | sidebarLogo: ref<boolean>(storageSetting.sidebarLogo || defaultSettings.sidebarLogo), |
| | | dynamicTitle: ref<boolean>(storageSetting.dynamicTitle || defaultSettings.dynamicTitle), |
| | | animationEnable: ref<boolean>(storageSetting.animationEnable || defaultSettings.animationEnable), |
| | | dark: ref<boolean>(storageSetting.dark || defaultSettings.dark) |
| | | }; |
| | | const prop: { [key: string]: Ref<any> } = { |
| | | title: ref<string>(''), |
| | | theme: ref<string>(storageSetting.theme || defaultSettings.theme), |
| | | sideTheme: ref<string>(storageSetting.sideTheme || defaultSettings.sideTheme), |
| | | showSettings: ref<boolean>(storageSetting.showSettings), |
| | | topNav: ref<boolean>(storageSetting.topNav || defaultSettings.topNav), |
| | | tagsView: ref<boolean>(storageSetting.tagsView || defaultSettings.tagsView), |
| | | fixedHeader: ref<boolean>(storageSetting.fixedHeader || defaultSettings.fixedHeader), |
| | | sidebarLogo: ref<boolean>(storageSetting.sidebarLogo || defaultSettings.sidebarLogo), |
| | | dynamicTitle: ref<boolean>(storageSetting.dynamicTitle || defaultSettings.dynamicTitle), |
| | | animationEnable: ref<boolean>(storageSetting.animationEnable || defaultSettings.animationEnable), |
| | | dark: ref<boolean>(storageSetting.dark || defaultSettings.dark) |
| | | }; |
| | | |
| | | const { title, theme, sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle, animationEnable, dark } = prop; |
| | | const { title, theme, sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle, animationEnable, dark } = prop; |
| | | |
| | | // actions |
| | | const changeSetting = (param: { key: SettingTypeEnum; value: any }) => { |
| | | const { key, value } = param; |
| | | if (key in prop) { |
| | | prop[key].value = value; |
| | | } |
| | | }; |
| | | const setTitle = (value: string) => { |
| | | title.value = value; |
| | | useDynamicTitle(); |
| | | }; |
| | | return { |
| | | title, |
| | | theme, |
| | | sideTheme, |
| | | showSettings, |
| | | topNav, |
| | | tagsView, |
| | | fixedHeader, |
| | | sidebarLogo, |
| | | dynamicTitle, |
| | | animationEnable, |
| | | dark, |
| | | changeSetting, |
| | | setTitle |
| | | }; |
| | | // actions |
| | | const changeSetting = (param: { key: SettingTypeEnum; value: any }) => { |
| | | const { key, value } = param; |
| | | if (key in prop) { |
| | | prop[key].value = value; |
| | | } |
| | | }; |
| | | const setTitle = (value: string) => { |
| | | title.value = value; |
| | | useDynamicTitle(); |
| | | }; |
| | | return { |
| | | title, |
| | | theme, |
| | | sideTheme, |
| | | showSettings, |
| | | topNav, |
| | | tagsView, |
| | | fixedHeader, |
| | | sidebarLogo, |
| | | dynamicTitle, |
| | | animationEnable, |
| | | dark, |
| | | changeSetting, |
| | | setTitle |
| | | }; |
| | | }); |
| | | |
| | | export default useSettingsStore; |
| | |
| | | import { TagView } from 'vue-router'; |
| | | |
| | | export const useTagsViewStore = defineStore('tagsView', () => { |
| | | const visitedViews = ref<TagView[]>([]); |
| | | const cachedViews = ref<string[]>([]); |
| | | const iframeViews = ref<TagView[]>([]); |
| | | const visitedViews = ref<TagView[]>([]); |
| | | const cachedViews = ref<string[]>([]); |
| | | const iframeViews = ref<TagView[]>([]); |
| | | |
| | | const addView = (view: TagView) => { |
| | | addVisitedView(view); |
| | | addCachedView(view); |
| | | }; |
| | | const addView = (view: TagView) => { |
| | | addVisitedView(view); |
| | | addCachedView(view); |
| | | }; |
| | | |
| | | const addIframeView = (view: TagView): void => { |
| | | if (iframeViews.value.some((v) => v.path === view.path)) return; |
| | | iframeViews.value.push( |
| | | Object.assign({}, view, { |
| | | title: view.meta?.title || 'no-name' |
| | | }) |
| | | ); |
| | | }; |
| | | const delIframeView = (view: TagView): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | iframeViews.value = iframeViews.value.filter((item) => item.path !== view.path); |
| | | resolve([...iframeViews.value]); |
| | | }); |
| | | }; |
| | | const addVisitedView = (view: TagView): void => { |
| | | if (visitedViews.value.some((v) => v.path === view.path)) return; |
| | | visitedViews.value.push( |
| | | Object.assign({}, view, { |
| | | title: view.meta?.title || 'no-name' |
| | | }) |
| | | ); |
| | | }; |
| | | const delView = (view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => { |
| | | return new Promise((resolve) => { |
| | | delVisitedView(view); |
| | | delCachedView(view); |
| | | resolve({ |
| | | visitedViews: [...visitedViews.value], |
| | | cachedViews: [...cachedViews.value] |
| | | }); |
| | | }); |
| | | }; |
| | | const addIframeView = (view: TagView): void => { |
| | | if (iframeViews.value.some((v) => v.path === view.path)) return; |
| | | iframeViews.value.push( |
| | | Object.assign({}, view, { |
| | | title: view.meta?.title || 'no-name' |
| | | }) |
| | | ); |
| | | }; |
| | | const delIframeView = (view: TagView): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | iframeViews.value = iframeViews.value.filter((item) => item.path !== view.path); |
| | | resolve([...iframeViews.value]); |
| | | }); |
| | | }; |
| | | const addVisitedView = (view: TagView): void => { |
| | | if (visitedViews.value.some((v) => v.path === view.path)) return; |
| | | visitedViews.value.push( |
| | | Object.assign({}, view, { |
| | | title: view.meta?.title || 'no-name' |
| | | }) |
| | | ); |
| | | }; |
| | | const delView = (view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => { |
| | | return new Promise((resolve) => { |
| | | delVisitedView(view); |
| | | delCachedView(view); |
| | | resolve({ |
| | | visitedViews: [...visitedViews.value], |
| | | cachedViews: [...cachedViews.value] |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | const delVisitedView = (view: TagView): Promise<TagView[]> => { |
| | | 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]); |
| | | }); |
| | | }; |
| | | const delCachedView = (view: TagView): Promise<string[]> => { |
| | | const 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: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => { |
| | | return new Promise((resolve) => { |
| | | delOthersVisitedViews(view); |
| | | delOthersCachedViews(view); |
| | | resolve({ |
| | | visitedViews: [...visitedViews.value], |
| | | cachedViews: [...cachedViews.value] |
| | | }); |
| | | }); |
| | | }; |
| | | const delVisitedView = (view: TagView): Promise<TagView[]> => { |
| | | 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]); |
| | | }); |
| | | }; |
| | | const delCachedView = (view: TagView): Promise<string[]> => { |
| | | const 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: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => { |
| | | return new Promise((resolve) => { |
| | | delOthersVisitedViews(view); |
| | | delOthersCachedViews(view); |
| | | resolve({ |
| | | visitedViews: [...visitedViews.value], |
| | | cachedViews: [...cachedViews.value] |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | const delOthersVisitedViews = (view: TagView): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | visitedViews.value = visitedViews.value.filter((v) => { |
| | | return v.meta?.affix || v.path === view.path; |
| | | }); |
| | | resolve([...visitedViews.value]); |
| | | }); |
| | | }; |
| | | const delOthersCachedViews = (view: TagView): Promise<string[]> => { |
| | | 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 delOthersVisitedViews = (view: TagView): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | visitedViews.value = visitedViews.value.filter((v) => { |
| | | return v.meta?.affix || v.path === view.path; |
| | | }); |
| | | resolve([...visitedViews.value]); |
| | | }); |
| | | }; |
| | | const delOthersCachedViews = (view: TagView): Promise<string[]> => { |
| | | 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: TagView[]; cachedViews: string[] }> => { |
| | | return new Promise((resolve) => { |
| | | delAllVisitedViews(); |
| | | delAllCachedViews(); |
| | | resolve({ |
| | | visitedViews: [...visitedViews.value], |
| | | cachedViews: [...cachedViews.value] |
| | | }); |
| | | }); |
| | | }; |
| | | const delAllVisitedViews = (): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | visitedViews.value = visitedViews.value.filter((tag) => tag.meta?.affix); |
| | | resolve([...visitedViews.value]); |
| | | }); |
| | | }; |
| | | const delAllViews = (): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => { |
| | | return new Promise((resolve) => { |
| | | delAllVisitedViews(); |
| | | delAllCachedViews(); |
| | | resolve({ |
| | | visitedViews: [...visitedViews.value], |
| | | cachedViews: [...cachedViews.value] |
| | | }); |
| | | }); |
| | | }; |
| | | const delAllVisitedViews = (): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | visitedViews.value = visitedViews.value.filter((tag) => tag.meta?.affix); |
| | | resolve([...visitedViews.value]); |
| | | }); |
| | | }; |
| | | |
| | | const delAllCachedViews = (): Promise<string[]> => { |
| | | return new Promise((resolve) => { |
| | | cachedViews.value = []; |
| | | resolve([...cachedViews.value]); |
| | | }); |
| | | }; |
| | | const delAllCachedViews = (): Promise<string[]> => { |
| | | return new Promise((resolve) => { |
| | | cachedViews.value = []; |
| | | resolve([...cachedViews.value]); |
| | | }); |
| | | }; |
| | | |
| | | const updateVisitedView = (view: TagView): void => { |
| | | for (let v of visitedViews.value) { |
| | | if (v.path === view.path) { |
| | | v = Object.assign(v, view); |
| | | break; |
| | | } |
| | | } |
| | | }; |
| | | const delRightTags = (view: TagView): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | const index = visitedViews.value.findIndex((v) => v.path === view.path); |
| | | if (index === -1) { |
| | | return; |
| | | } |
| | | visitedViews.value = visitedViews.value.filter((item, idx) => { |
| | | 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]); |
| | | }); |
| | | }; |
| | | const delLeftTags = (view: TagView): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | const index = visitedViews.value.findIndex((v) => v.path === view.path); |
| | | if (index === -1) { |
| | | return; |
| | | } |
| | | visitedViews.value = visitedViews.value.filter((item, idx) => { |
| | | 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]); |
| | | }); |
| | | }; |
| | | const updateVisitedView = (view: TagView): void => { |
| | | for (let v of visitedViews.value) { |
| | | if (v.path === view.path) { |
| | | v = Object.assign(v, view); |
| | | break; |
| | | } |
| | | } |
| | | }; |
| | | const delRightTags = (view: TagView): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | const index = visitedViews.value.findIndex((v) => v.path === view.path); |
| | | if (index === -1) { |
| | | return; |
| | | } |
| | | visitedViews.value = visitedViews.value.filter((item, idx) => { |
| | | 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]); |
| | | }); |
| | | }; |
| | | const delLeftTags = (view: TagView): Promise<TagView[]> => { |
| | | return new Promise((resolve) => { |
| | | const index = visitedViews.value.findIndex((v) => v.path === view.path); |
| | | if (index === -1) { |
| | | return; |
| | | } |
| | | visitedViews.value = visitedViews.value.filter((item, idx) => { |
| | | 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]); |
| | | }); |
| | | }; |
| | | |
| | | const addCachedView = (view: TagView): void => { |
| | | const viewName = view.name as string; |
| | | if (cachedViews.value.includes(viewName)) return; |
| | | if (!view.meta?.noCache) { |
| | | cachedViews.value.push(viewName); |
| | | } |
| | | }; |
| | | const addCachedView = (view: TagView): void => { |
| | | const viewName = view.name as string; |
| | | if (cachedViews.value.includes(viewName)) return; |
| | | if (!view.meta?.noCache) { |
| | | cachedViews.value.push(viewName); |
| | | } |
| | | }; |
| | | |
| | | return { |
| | | visitedViews, |
| | | cachedViews, |
| | | iframeViews, |
| | | addVisitedView, |
| | | addCachedView, |
| | | delVisitedView, |
| | | delCachedView, |
| | | updateVisitedView, |
| | | addView, |
| | | delView, |
| | | delAllViews, |
| | | delAllVisitedViews, |
| | | delAllCachedViews, |
| | | delOthersViews, |
| | | delRightTags, |
| | | delLeftTags, |
| | | addIframeView, |
| | | delIframeView |
| | | }; |
| | | return { |
| | | visitedViews, |
| | | cachedViews, |
| | | iframeViews, |
| | | addVisitedView, |
| | | addCachedView, |
| | | delVisitedView, |
| | | delCachedView, |
| | | updateVisitedView, |
| | | addView, |
| | | delView, |
| | | delAllViews, |
| | | delAllVisitedViews, |
| | | delAllCachedViews, |
| | | delOthersViews, |
| | | delRightTags, |
| | | delLeftTags, |
| | | addIframeView, |
| | | delIframeView |
| | | }; |
| | | }); |
| | | |
| | | export default useTagsViewStore; |
| | |
| | | import { LoginData } from '@/api/types'; |
| | | |
| | | export const useUserStore = defineStore('user', () => { |
| | | const token = ref(getToken()); |
| | | const name = ref(''); |
| | | const nickname = ref(''); |
| | | const userId = ref<string | number>(''); |
| | | const avatar = ref(''); |
| | | const roles = ref<Array<string>>([]); // ç¨æ·è§è²ç¼ç éå â å¤æè·¯ç±æé |
| | | const permissions = ref<Array<string>>([]); // ç¨æ·æéç¼ç éå â 夿æé®æé |
| | | const token = ref(getToken()); |
| | | const name = ref(''); |
| | | const nickname = ref(''); |
| | | const userId = ref<string | number>(''); |
| | | const avatar = ref(''); |
| | | const roles = ref<Array<string>>([]); // ç¨æ·è§è²ç¼ç éå â å¤æè·¯ç±æé |
| | | const permissions = ref<Array<string>>([]); // ç¨æ·æéç¼ç éå â 夿æé®æé |
| | | |
| | | /** |
| | | * ç»å½ |
| | | * @param userInfo |
| | | * @returns |
| | | */ |
| | | const login = async (userInfo: LoginData): Promise<void> => { |
| | | const [err, res] = await to(loginApi(userInfo)); |
| | | if (res) { |
| | | const data = res.data; |
| | | setToken(data.token); |
| | | token.value = data.token; |
| | | return Promise.resolve(); |
| | | } |
| | | return Promise.reject(err); |
| | | }; |
| | | /** |
| | | * ç»å½ |
| | | * @param userInfo |
| | | * @returns |
| | | */ |
| | | const login = async (userInfo: LoginData): Promise<void> => { |
| | | const [err, res] = await to(loginApi(userInfo)); |
| | | if (res) { |
| | | const data = res.data; |
| | | setToken(data.token); |
| | | token.value = data.token; |
| | | return Promise.resolve(); |
| | | } |
| | | return Promise.reject(err); |
| | | }; |
| | | |
| | | // è·åç¨æ·ä¿¡æ¯ |
| | | const getInfo = async (): Promise<void> => { |
| | | 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; |
| | | // è·åç¨æ·ä¿¡æ¯ |
| | | const getInfo = async (): Promise<void> => { |
| | | 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; |
| | | return Promise.resolve(); |
| | | } |
| | | return Promise.reject(err); |
| | | }; |
| | | 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; |
| | | return Promise.resolve(); |
| | | } |
| | | return Promise.reject(err); |
| | | }; |
| | | |
| | | // 注é |
| | | const logout = async (): Promise<void> => { |
| | | await logoutApi(); |
| | | token.value = ''; |
| | | roles.value = []; |
| | | permissions.value = []; |
| | | removeToken(); |
| | | }; |
| | | // 注é |
| | | const logout = async (): Promise<void> => { |
| | | await logoutApi(); |
| | | token.value = ''; |
| | | roles.value = []; |
| | | permissions.value = []; |
| | | removeToken(); |
| | | }; |
| | | |
| | | return { |
| | | userId, |
| | | token, |
| | | nickname, |
| | | avatar, |
| | | roles, |
| | | permissions, |
| | | login, |
| | | getInfo, |
| | | logout |
| | | }; |
| | | return { |
| | | userId, |
| | | token, |
| | | nickname, |
| | | avatar, |
| | | roles, |
| | | permissions, |
| | | login, |
| | | getInfo, |
| | | logout |
| | | }; |
| | | }); |
| | | |
| | | export default useUserStore; |
| | | // ésetup |
| | | export function useUserStoreHook() { |
| | | return useUserStore(store); |
| | | return useUserStore(store); |
| | | } |
| | |
| | | export {} |
| | | declare global { |
| | | const EffectScope: typeof import('vue')['EffectScope'] |
| | | const ElForm: typeof import('element-plus/es')['ElForm'] |
| | | 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 ElSelect: typeof import('element-plus/es')['ElSelect'] |
| | | const ElTable: typeof import('element-plus/es')['ElTable'] |
| | | const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] |
| | | const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] |
| | | const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] |
| | |
| | | declare module 'vue' { |
| | | interface ComponentCustomProperties { |
| | | readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']> |
| | | readonly ElForm: UnwrapRef<typeof import('element-plus/es')['ElForm']> |
| | | readonly ElLoading: UnwrapRef<typeof import('element-plus/es')['ElLoading']> |
| | | readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']> |
| | | readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']> |
| | | readonly ElNotification: UnwrapRef<typeof import('element-plus/es')['ElNotification']> |
| | | readonly ElSelect: UnwrapRef<typeof import('element-plus/es')['ElSelect']> |
| | | readonly ElTable: UnwrapRef<typeof import('element-plus/es')['ElTable']> |
| | | readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']> |
| | | readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> |
| | | readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']> |
| | |
| | | import axios from 'axios'; |
| | | |
| | | declare module 'axios' { |
| | | export interface AxiosResponse<T = any> { |
| | | code: number; |
| | | msg: string; |
| | | rows: T; |
| | | total: number; |
| | | } |
| | | export interface AxiosResponse<T = any> { |
| | | code: number; |
| | | msg: string; |
| | | rows: T; |
| | | total: number; |
| | | } |
| | | } |
| | |
| | | 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'] |
| | | ElCol: typeof import('element-plus/es')['ElCol'] |
| | | ElColorPicker: typeof import('element-plus/es')['ElColorPicker'] |
| | | ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] |
| | |
| | | ElDropdown: typeof import('element-plus/es')['ElDropdown'] |
| | | ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] |
| | | ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] |
| | | 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'] |
| | | ElTooltip: typeof import('element-plus/es')['ElTooltip'] |
| | | ElTransfer: typeof import('element-plus/es')['ElTransfer'] |
| | | 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'] |
| | | Hamburger: typeof import('./../components/Hamburger/index.vue')['default'] |
| | | HeaderSearch: typeof import('./../components/HeaderSearch/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'] |
| | |
| | | declare module '*.vue' { |
| | | import { DefineComponent } from 'vue'; |
| | | const component: DefineComponent<{}, {}, any>; |
| | | export default component; |
| | | import { DefineComponent } from 'vue'; |
| | | const component: DefineComponent<{}, {}, any>; |
| | | export default component; |
| | | } |
| | | declare module '*.avif' { |
| | | const src: string; |
| | | export default src; |
| | | const src: string; |
| | | export default src; |
| | | } |
| | | |
| | | declare module '*.bmp' { |
| | | const src: string; |
| | | export default src; |
| | | const src: string; |
| | | export default src; |
| | | } |
| | | |
| | | declare module '*.gif' { |
| | | const src: string; |
| | | export default src; |
| | | const src: string; |
| | | export default src; |
| | | } |
| | | |
| | | declare module '*.jpg' { |
| | | const src: string; |
| | | export default src; |
| | | const src: string; |
| | | export default src; |
| | | } |
| | | |
| | | declare module '*.jpeg' { |
| | | const src: string; |
| | | export default src; |
| | | const src: string; |
| | | export default src; |
| | | } |
| | | |
| | | declare module '*.png' { |
| | | const src: string; |
| | | export default src; |
| | | const src: string; |
| | | export default src; |
| | | } |
| | | |
| | | declare module '*.webp' { |
| | | const src: string; |
| | | export default src; |
| | | const src: string; |
| | | export default src; |
| | | } |
| | | |
| | | declare module '*.svg' { |
| | | const src: string; |
| | | export default src; |
| | | const src: string; |
| | | export default src; |
| | | } |
| | | |
| | | declare module '*.module.css' { |
| | | const classes: { readonly [key: string]: string }; |
| | | export default classes; |
| | | const classes: { readonly [key: string]: string }; |
| | | export default classes; |
| | | } |
| | | |
| | | declare module '*.module.scss' { |
| | | const classes: { readonly [key: string]: string }; |
| | | export default classes; |
| | | const classes: { readonly [key: string]: string }; |
| | | export default classes; |
| | | } |
| | | |
| | | declare module '*.module.sass' { |
| | | const classes: { readonly [key: string]: string }; |
| | | export default classes; |
| | | const classes: { readonly [key: string]: string }; |
| | | export default classes; |
| | | } |
| | | // ç¯å¢åé |
| | | 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_MONITRO_ADMIN: string; |
| | | VITE_APP_XXL_JOB_ADMIN: string; |
| | | VITE_APP_ENV: string; |
| | | 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_MONITRO_ADMIN: string; |
| | | VITE_APP_XXL_JOB_ADMIN: string; |
| | | VITE_APP_ENV: string; |
| | | } |
| | | interface ImportMeta { |
| | | readonly env: ImportMetaEnv; |
| | | // readonly glob: any; |
| | | readonly env: ImportMetaEnv; |
| | | // readonly glob: any; |
| | | } |
| | |
| | | import { FormRules } from 'element-plus'; |
| | | declare global { |
| | | /** |
| | | * çé¢å段éè屿§ |
| | | */ |
| | | interface FieldOption { |
| | | key: number; |
| | | label: string; |
| | | visible: boolean; |
| | | } |
| | | /** |
| | | * çé¢å段éè屿§ |
| | | */ |
| | | interface FieldOption { |
| | | key: number; |
| | | label: string; |
| | | visible: boolean; |
| | | } |
| | | |
| | | /** |
| | | * å¼¹çªå±æ§ |
| | | */ |
| | | interface DialogOption { |
| | | /** |
| | | * å¼¹çªæ é¢ |
| | | */ |
| | | title?: string; |
| | | /** |
| | | * æ¯å¦æ¾ç¤º |
| | | */ |
| | | visible: boolean; |
| | | } |
| | | /** |
| | | * å¼¹çªå±æ§ |
| | | */ |
| | | interface DialogOption { |
| | | /** |
| | | * å¼¹çªæ é¢ |
| | | */ |
| | | title?: string; |
| | | /** |
| | | * æ¯å¦æ¾ç¤º |
| | | */ |
| | | visible: boolean; |
| | | } |
| | | |
| | | interface UploadOption { |
| | | /** 设置ä¸ä¼ ç请æ±å¤´é¨ */ |
| | | headers: { [key: string]: any }; |
| | | interface UploadOption { |
| | | /** 设置ä¸ä¼ ç请æ±å¤´é¨ */ |
| | | headers: { [key: string]: any }; |
| | | |
| | | /** ä¸ä¼ çå°å */ |
| | | url: string; |
| | | } |
| | | /** ä¸ä¼ çå°å */ |
| | | url: string; |
| | | } |
| | | |
| | | /** |
| | | * 导å
¥å±æ§ |
| | | */ |
| | | interface ImportOption extends UploadOption { |
| | | /** æ¯å¦æ¾ç¤ºå¼¹åºå± */ |
| | | open: boolean; |
| | | /** å¼¹åºå±æ é¢ */ |
| | | title: string; |
| | | /** æ¯å¦ç¦ç¨ä¸ä¼ */ |
| | | isUploading: boolean; |
| | | /** |
| | | * 导å
¥å±æ§ |
| | | */ |
| | | interface ImportOption extends UploadOption { |
| | | /** æ¯å¦æ¾ç¤ºå¼¹åºå± */ |
| | | open: boolean; |
| | | /** å¼¹åºå±æ é¢ */ |
| | | title: string; |
| | | /** æ¯å¦ç¦ç¨ä¸ä¼ */ |
| | | isUploading: boolean; |
| | | |
| | | /** å
¶ä»åæ° */ |
| | | [key: string]: any; |
| | | } |
| | | /** |
| | | * åå
¸æ°æ® æ°æ®é
ç½® |
| | | */ |
| | | interface DictDataOption { |
| | | label: string; |
| | | value: string; |
| | | elTagType?: ElTagType; |
| | | elTagClass?: string; |
| | | } |
| | | /** å
¶ä»åæ° */ |
| | | [key: string]: any; |
| | | } |
| | | /** |
| | | * åå
¸æ°æ® æ°æ®é
ç½® |
| | | */ |
| | | interface DictDataOption { |
| | | label: string; |
| | | value: string; |
| | | elTagType?: ElTagType; |
| | | elTagClass?: string; |
| | | } |
| | | |
| | | interface BaseEntity { |
| | | createBy?: any; |
| | | createTime?: string; |
| | | updateBy?: any; |
| | | updateTime?: any; |
| | | } |
| | | interface BaseEntity { |
| | | createBy?: any; |
| | | createTime?: string; |
| | | updateBy?: any; |
| | | updateTime?: any; |
| | | } |
| | | |
| | | /** |
| | | * åé¡µæ°æ® |
| | | * T : è¡¨åæ°æ® |
| | | * D : æ¥è¯¢åæ° |
| | | */ |
| | | interface PageData<T, D> { |
| | | form: T; |
| | | queryParams: D; |
| | | rules: FormRules; |
| | | } |
| | | /** |
| | | * å页æ¥è¯¢åæ° |
| | | */ |
| | | interface PageQuery { |
| | | pageNum: number; |
| | | pageSize: number; |
| | | } |
| | | /** |
| | | * åé¡µæ°æ® |
| | | * T : è¡¨åæ°æ® |
| | | * D : æ¥è¯¢åæ° |
| | | */ |
| | | interface PageData<T, D> { |
| | | form: T; |
| | | queryParams: D; |
| | | rules: FormRules; |
| | | } |
| | | /** |
| | | * å页æ¥è¯¢åæ° |
| | | */ |
| | | interface PageQuery { |
| | | pageNum: number; |
| | | pageSize: number; |
| | | } |
| | | } |
| | | export {}; |
| | |
| | | import animate from '@/animate'; |
| | | |
| | | declare module 'vue' { |
| | | export interface ComponentCustomProperties { |
| | | // å
¨å±æ¹æ³å£°æ |
| | | $modal: typeof modal; |
| | | $tab: typeof tab; |
| | | $download: typeof download; |
| | | animate: typeof animate; |
| | | export interface ComponentCustomProperties { |
| | | // å
¨å±æ¹æ³å£°æ |
| | | $modal: typeof modal; |
| | | $tab: typeof tab; |
| | | $download: typeof download; |
| | | animate: typeof animate; |
| | | |
| | | useDict: typeof useDict; |
| | | addDateRange: typeof addDateRange; |
| | | download: typeof download1; |
| | | handleTree: typeof handleTree; |
| | | getConfigKey: typeof getConfigKey; |
| | | updateConfigByKey: typeof updateConfigByKey; |
| | | selectDictLabel: typeof selectDictLabel; |
| | | selectDictLabels: typeof selectDictLabels; |
| | | parseTime: typeof parseTime; |
| | | } |
| | | useDict: typeof useDict; |
| | | addDateRange: typeof addDateRange; |
| | | download: typeof download1; |
| | | handleTree: typeof handleTree; |
| | | getConfigKey: typeof getConfigKey; |
| | | updateConfigByKey: typeof updateConfigByKey; |
| | | selectDictLabel: typeof selectDictLabel; |
| | | selectDictLabels: typeof selectDictLabels; |
| | | parseTime: typeof parseTime; |
| | | } |
| | | } |
| | |
| | | import { RouteRecordRaw } from 'vue-router'; |
| | | |
| | | declare module 'vue-router' { |
| | | type RouteOption = { |
| | | hidden?: boolean; |
| | | permissions?: string[]; |
| | | roles?: string[]; |
| | | component?: any; |
| | | children?: RouteOption[]; |
| | | alwaysShow?: boolean; |
| | | parentPath?: string; |
| | | meta?: { |
| | | title: string; |
| | | icon: string; |
| | | }; |
| | | } & RouteRecordRaw; |
| | | type RouteOption = { |
| | | hidden?: boolean; |
| | | permissions?: string[]; |
| | | roles?: string[]; |
| | | component?: any; |
| | | children?: RouteOption[]; |
| | | alwaysShow?: boolean; |
| | | parentPath?: string; |
| | | meta?: { |
| | | title: string; |
| | | icon: string; |
| | | }; |
| | | } & RouteRecordRaw; |
| | | |
| | | interface _RouteLocationBase { |
| | | children?: RouteOption[]; |
| | | } |
| | | interface _RouteLocationBase { |
| | | children?: RouteOption[]; |
| | | } |
| | | |
| | | interface RouteLocationOptions { |
| | | fullPath?: string; |
| | | } |
| | | interface RouteLocationOptions { |
| | | fullPath?: string; |
| | | } |
| | | |
| | | interface TagView extends Partial<_RouteLocationBase> { |
| | | title?: string; |
| | | meta?: { |
| | | link?: string; |
| | | title?: string; |
| | | affix?: boolean; |
| | | noCache?: boolean; |
| | | }; |
| | | } |
| | | interface TagView extends Partial<_RouteLocationBase> { |
| | | title?: string; |
| | | meta?: { |
| | | link?: string; |
| | | title?: string; |
| | | affix?: boolean; |
| | | noCache?: boolean; |
| | | }; |
| | | } |
| | | } |
| | |
| | | declare type DefaultSettings = { |
| | | /** |
| | | * ç½é¡µæ é¢ |
| | | */ |
| | | title?: string; |
| | | /** |
| | | * ç½é¡µæ é¢ |
| | | */ |
| | | title?: string; |
| | | |
| | | /** |
| | | * ä¾§è¾¹æ ä¸»é¢ theme-dark | theme-light |
| | | */ |
| | | sideTheme?: string; |
| | | /** |
| | | * ä¾§è¾¹æ ä¸»é¢ theme-dark | theme-light |
| | | */ |
| | | sideTheme?: string; |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºç³»ç»å¸å±è®¾ç½® |
| | | */ |
| | | showSettings?: boolean; |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºç³»ç»å¸å±è®¾ç½® |
| | | */ |
| | | showSettings?: boolean; |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºé¡¶é¨å¯¼èª |
| | | */ |
| | | topNav?: boolean; |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºé¡¶é¨å¯¼èª |
| | | */ |
| | | topNav?: boolean; |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºå¤æ ç¾å¯¼èª |
| | | */ |
| | | tagsView?: boolean; |
| | | /** |
| | | * æ¯å¦åºå®å¤´é¨ |
| | | */ |
| | | fixedHeader?: boolean; |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºä¾§è¾¹æ Logo |
| | | */ |
| | | sidebarLogo?: boolean; |
| | | /** |
| | | * å¯¼èªæ å¸å± |
| | | */ |
| | | layout?: string; |
| | | /** |
| | | * 䏻颿¨¡å¼ |
| | | */ |
| | | theme?: string; |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºå¤æ ç¾å¯¼èª |
| | | */ |
| | | tagsView?: boolean; |
| | | /** |
| | | * æ¯å¦åºå®å¤´é¨ |
| | | */ |
| | | fixedHeader?: boolean; |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºä¾§è¾¹æ Logo |
| | | */ |
| | | sidebarLogo?: boolean; |
| | | /** |
| | | * å¯¼èªæ å¸å± |
| | | */ |
| | | layout?: string; |
| | | /** |
| | | * 䏻颿¨¡å¼ |
| | | */ |
| | | theme?: string; |
| | | |
| | | /** |
| | | * å¸å±å¤§å° |
| | | */ |
| | | size?: string; |
| | | /** |
| | | * å¸å±å¤§å° |
| | | */ |
| | | size?: string; |
| | | |
| | | /** |
| | | * è¯è¨ |
| | | */ |
| | | language?: string; |
| | | /** |
| | | * è¯è¨ |
| | | */ |
| | | language?: string; |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºå¨ææ é¢ |
| | | */ |
| | | dynamicTitle?: boolean; |
| | | /** |
| | | * æ¯å¦å¯ç¨å¨ç»ææ |
| | | */ |
| | | animationEnable?: boolean; |
| | | /** |
| | | * æ¯å¦å¯ç¨æé»æ¨¡å¼ |
| | | * |
| | | * true:æé»æ¨¡å¼ |
| | | * false: æäº®æ¨¡å¼ |
| | | */ |
| | | dark?: boolean; |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºå¨ææ é¢ |
| | | */ |
| | | dynamicTitle?: boolean; |
| | | /** |
| | | * æ¯å¦å¯ç¨å¨ç»ææ |
| | | */ |
| | | animationEnable?: boolean; |
| | | /** |
| | | * æ¯å¦å¯ç¨æé»æ¨¡å¼ |
| | | * |
| | | * true:æé»æ¨¡å¼ |
| | | * false: æäº®æ¨¡å¼ |
| | | */ |
| | | dark?: boolean; |
| | | |
| | | errorLog?: string; |
| | | errorLog?: string; |
| | | }; |
| | |
| | | * è·ååå
¸æ°æ® |
| | | */ |
| | | export const useDict = (...args: string[]): { [key: string]: DictDataOption[] } => { |
| | | const res = ref<{ |
| | | [key: string]: DictDataOption[]; |
| | | }>({}); |
| | | return (() => { |
| | | 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; |
| | | })(); |
| | | const res = ref<{ |
| | | [key: string]: DictDataOption[]; |
| | | }>({}); |
| | | return (() => { |
| | | 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; |
| | | })(); |
| | | }; |
| | |
| | | * å¨æä¿®æ¹æ é¢ |
| | | */ |
| | | 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; |
| | | } |
| | | const settingsStore = useSettingsStore(); |
| | | if (settingsStore.dynamicTitle) { |
| | | document.title = settingsStore.title + ' - ' + import.meta.env.VITE_APP_TITLE; |
| | | } else { |
| | | document.title = defaultSettings.title as string; |
| | | } |
| | | }; |
| | |
| | | export const errorCode: any = { |
| | | '401': '认è¯å¤±è´¥ï¼æ æ³è®¿é®ç³»ç»èµæº', |
| | | '403': 'å½åæä½æ²¡ææé', |
| | | '404': '访é®èµæºä¸åå¨', |
| | | default: 'ç³»ç»æªç¥é误ï¼è¯·åé¦ç»ç®¡çå' |
| | | '401': '认è¯å¤±è´¥ï¼æ æ³è®¿é®ç³»ç»èµæº', |
| | | '403': 'å½åæä½æ²¡ææé', |
| | | '404': '访é®èµæºä¸åå¨', |
| | | default: 'ç³»ç»æªç¥é误ï¼è¯·åé¦ç»ç®¡çå' |
| | | }; |
| | | export default errorCode; |
| | |
| | | import i18n from '@/lang/index'; |
| | | |
| | | export const translateRouteTitleI18n = (title: string): string => { |
| | | // 夿æ¯å¦åå¨å½é
åé
ç½®ï¼å¦ææ²¡æåçè¿å |
| | | const hasKey = i18n.global.te('route.' + title); |
| | | if (hasKey) { |
| | | const translatedTitle = i18n.global.t('route.' + title); |
| | | return translatedTitle; |
| | | } |
| | | return title; |
| | | // 夿æ¯å¦åå¨å½é
åé
ç½®ï¼å¦ææ²¡æåçè¿å |
| | | const hasKey = i18n.global.te('route.' + title); |
| | | if (hasKey) { |
| | | const translatedTitle = i18n.global.t('route.' + title); |
| | | return translatedTitle; |
| | | } |
| | | return title; |
| | | }; |
| | |
| | | * è¡¨æ ¼æ¶é´æ ¼å¼å |
| | | */ |
| | | 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; |
| | | 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; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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(); |
| | | 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; |
| | | 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() + 'å'; |
| | | } |
| | | 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() + 'å'; |
| | | } |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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; |
| | | 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; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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; |
| | | // 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; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {Array} |
| | | */ |
| | | export const cleanArray = (actual: Array<any>) => { |
| | | const newArray = []; |
| | | for (let i = 0; i < actual.length; i++) { |
| | | if (actual[i]) { |
| | | newArray.push(actual[i]); |
| | | } |
| | | } |
| | | return newArray; |
| | | const newArray = []; |
| | | for (let i = 0; i < actual.length; i++) { |
| | | if (actual[i]) { |
| | | newArray.push(actual[i]); |
| | | } |
| | | } |
| | | return newArray; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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('&'); |
| | | if (!json) return ''; |
| | | return cleanArray( |
| | | Object.keys(json).map((key) => { |
| | | if (json[key] === undefined) return ''; |
| | | return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]); |
| | | }) |
| | | ).join('&'); |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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; |
| | | 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; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {string} |
| | | */ |
| | | export const html2Text = (val: string) => { |
| | | const div = document.createElement('div'); |
| | | div.innerHTML = val; |
| | | return div.textContent || div.innerText; |
| | | const div = document.createElement('div'); |
| | | div.innerHTML = val; |
| | | return div.textContent || div.innerText; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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; |
| | | 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 {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; |
| | | 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; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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()); |
| | | } |
| | | if (type === 'start') { |
| | | return new Date().getTime() - 3600 * 1000 * 24 * 90; |
| | | } else { |
| | | return new Date(new Date().toDateString()); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @return {*} |
| | | */ |
| | | export const debounce = (func: any, wait: number, immediate: boolean) => { |
| | | let timeout: any, args: any, context: any, timestamp: any, result: any; |
| | | let timeout: any, args: any, context: any, timestamp: any, result: any; |
| | | |
| | | const later = function () { |
| | | // æ®ä¸ä¸æ¬¡è§¦åæ¶é´é´é |
| | | const last = +new Date() - timestamp; |
| | | 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; |
| | | } |
| | | } |
| | | }; |
| | | // 䏿¬¡è¢«å
è£
彿°è¢«è°ç¨æ¶é´é´é 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; |
| | | }; |
| | | 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; |
| | | }; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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; |
| | | 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; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {Array} |
| | | */ |
| | | export const uniqueArr = (arr: any) => { |
| | | return Array.from(new Set(arr)); |
| | | 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); |
| | | const timestamp = +new Date() + ''; |
| | | const num = (1 + Math.random()) * 65536; |
| | | const randomNum = parseInt(num + ''); |
| | | return (+(randomNum + timestamp)).toString(32); |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {boolean} |
| | | */ |
| | | export const hasClass = (ele: HTMLElement, cls: string): boolean => { |
| | | return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')); |
| | | return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')); |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @param {string} cls |
| | | */ |
| | | export const addClass = (ele: HTMLElement, cls: string) => { |
| | | if (!hasClass(ele, cls)) ele.className += ' ' + cls; |
| | | if (!hasClass(ele, cls)) ele.className += ' ' + cls; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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, ' '); |
| | | } |
| | | if (hasClass(ele, cls)) { |
| | | const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)'); |
| | | ele.className = ele.className.replace(reg, ' '); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {Boolean} |
| | | */ |
| | | export const isExternal = (path: string) => { |
| | | return /^(https?:|http?:|mailto:|tel:)/.test(path); |
| | | return /^(https?:|http?:|mailto:|tel:)/.test(path); |
| | | }; |
| | |
| | | // å¯é¥å¯¹çæ http://web.chacuo.net/netrsakeypair |
| | | |
| | | const publicKey = |
| | | 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='; |
| | | 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='; |
| | | |
| | | const privateKey = |
| | | 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' + |
| | | '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' + |
| | | 'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' + |
| | | 'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' + |
| | | 'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' + |
| | | 'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' + |
| | | 'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' + |
| | | 'UP8iWi1Qw0Y='; |
| | | 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' + |
| | | '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' + |
| | | 'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' + |
| | | 'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' + |
| | | 'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' + |
| | | 'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' + |
| | | 'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' + |
| | | 'UP8iWi1Qw0Y='; |
| | | |
| | | // å å¯ |
| | | export const encrypt = (txt: string) => { |
| | | const encryptor = new JSEncrypt(); |
| | | encryptor.setPublicKey(publicKey); // 设置å
¬é¥ |
| | | return encryptor.encrypt(txt); // å¯¹æ°æ®è¿è¡å å¯ |
| | | 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); // å¯¹æ°æ®è¿è¡è§£å¯ |
| | | const encryptor = new JSEncrypt(); |
| | | encryptor.setPrivateKey(privateKey); // 设置ç§é¥ |
| | | return encryptor.decrypt(txt); // å¯¹æ°æ®è¿è¡è§£å¯ |
| | | }; |
| | |
| | | * @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 = '*:*:*'; |
| | | 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); |
| | | }); |
| | | 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; |
| | | } |
| | | if (!hasPermission) { |
| | | return false; |
| | | } |
| | | return true; |
| | | } else { |
| | | console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`); |
| | | return false; |
| | | } |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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'; |
| | | 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); |
| | | }); |
| | | 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; |
| | | } |
| | | if (!hasRole) { |
| | | return false; |
| | | } |
| | | return true; |
| | | } else { |
| | | console.error(`need roles! Like checkRole="['admin','editor']"`); |
| | | return false; |
| | | } |
| | | }; |
| | |
| | | axios.defaults.headers['Content-Language'] = 'zh_CN'; |
| | | // å建 axios å®ä¾ |
| | | const service = axios.create({ |
| | | baseURL: import.meta.env.VITE_APP_BASE_API, |
| | | timeout: 50000 |
| | | baseURL: import.meta.env.VITE_APP_BASE_API, |
| | | timeout: 50000 |
| | | }); |
| | | |
| | | // è¯·æ±æ¦æªå¨ |
| | | service.interceptors.request.use( |
| | | (config: InternalAxiosRequestConfig) => { |
| | | const isToken = (config.headers || {}).isToken === false; |
| | | // æ¯å¦éè¦é²æ¢æ°æ®éå¤æäº¤ |
| | | const isRepeatSubmit = !(config.headers || {}).repeatSubmit; |
| | | 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; |
| | | } |
| | | (config: InternalAxiosRequestConfig) => { |
| | | const isToken = (config.headers || {}).isToken === false; |
| | | // æ¯å¦éè¦é²æ¢æ°æ®éå¤æäº¤ |
| | | const isRepeatSubmit = !(config.headers || {}).repeatSubmit; |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | return config; |
| | | }, |
| | | (error: any) => { |
| | | console.log(error); |
| | | return Promise.reject(error); |
| | | } |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | return config; |
| | | }, |
| | | (error: any) => { |
| | | console.log(error); |
| | | return Promise.reject(error); |
| | | } |
| | | ); |
| | | |
| | | // ååºæ¦æªå¨ |
| | | service.interceptors.response.use( |
| | | (res) => { |
| | | // æªè®¾ç½®ç¶æç åé»è®¤æåç¶æ |
| | | 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(() => { |
| | | location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index'; |
| | | }); |
| | | }).catch(() => { |
| | | isRelogin.show = false; |
| | | }); |
| | | } |
| | | return Promise.reject('æ æçä¼è¯ï¼æè
ä¼è¯å·²è¿æï¼è¯·éæ°ç»å½ã'); |
| | | } else if (code === HttpStatus.SERVER_ERROR) { |
| | | console.log(msg); |
| | | 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) => { |
| | | 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); |
| | | } |
| | | (res) => { |
| | | // æªè®¾ç½®ç¶æç åé»è®¤æåç¶æ |
| | | 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(() => { |
| | | location.href = import.meta.env.VITE_APP_CONTEXT_PATH + 'index'; |
| | | }); |
| | | }).catch(() => { |
| | | isRelogin.show = false; |
| | | }); |
| | | } |
| | | return Promise.reject('æ æçä¼è¯ï¼æè
ä¼è¯å·²è¿æï¼è¯·éæ°ç»å½ã'); |
| | | } else if (code === HttpStatus.SERVER_ERROR) { |
| | | console.log(msg); |
| | | 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) => { |
| | | 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) => { |
| | | return tansParams(params); |
| | | } |
| | | ], |
| | | headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, |
| | | responseType: 'blob' |
| | | }).then(async (resp) => { |
| | | const isLogin = blobValidate(resp); |
| | | if (isLogin) { |
| | | const blob = new Blob([resp as any]); |
| | | downloadLoadingInstance = ElLoading.service({ text: 'æ£å¨ä¸è½½æ°æ®ï¼è¯·ç¨å', background: 'rgba(0, 0, 0, 0.7)' }); |
| | | // prettier-ignore |
| | | return service.post(url, params, { |
| | | transformRequest: [ |
| | | (params) => { |
| | | return tansParams(params); |
| | | } |
| | | ], |
| | | headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, |
| | | responseType: 'blob' |
| | | }).then(async (resp) => { |
| | | const isLogin = blobValidate(resp); |
| | | if (isLogin) { |
| | | const blob = new Blob([resp as any]); |
| | | FileSaver.saveAs(blob, fileName); |
| | | } else { |
| | | const resText = await resp.data.text(); |
| | | const rspObj = JSON.parse(resText); |
| | | const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']; |
| | | ElMessage.error(errMsg); |
| | | } |
| | | downloadLoadingInstance.close(); |
| | | }).catch((r) => { |
| | | console.error(r); |
| | | ElMessage.error('ä¸è½½æä»¶åºç°é误ï¼è¯·è系管çåï¼'); |
| | | downloadLoadingInstance.close(); |
| | | }); |
| | | } else { |
| | | const resText = await resp.data.text(); |
| | | const rspObj = JSON.parse(resText); |
| | | const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']; |
| | | ElMessage.error(errMsg); |
| | | } |
| | | downloadLoadingInstance.close(); |
| | | }).catch((r) => { |
| | | console.error(r); |
| | | ElMessage.error('ä¸è½½æä»¶åºç°é误ï¼è¯·è系管çåï¼'); |
| | | downloadLoadingInstance.close(); |
| | | }); |
| | | } |
| | | // å¯¼åº axios å®ä¾ |
| | | export default service; |
| | |
| | | // æ¥ææ ¼å¼å |
| | | 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; |
| | | }); |
| | | 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 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; |
| | | 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 = []; |
| | | 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(''); |
| | | if (value === undefined) { |
| | | return ''; |
| | | } |
| | | const actions = []; |
| | | 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); |
| | | 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 : ''; |
| | | } |
| | | 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; |
| | | 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; |
| | | 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 {*} children å©åèç¹å段 é»è®¤ 'children' |
| | | */ |
| | | export const handleTree = <T>(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 config: { |
| | | id: string; |
| | | parentId: string; |
| | | childrenList: string; |
| | | } = { |
| | | id: id || 'id', |
| | | parentId: parentId || 'parentId', |
| | | childrenList: children || 'children' |
| | | }; |
| | | |
| | | const childrenListMap: any = {}; |
| | | const nodeIds: any = {}; |
| | | const tree: T[] = []; |
| | | const childrenListMap: any = {}; |
| | | const nodeIds: any = {}; |
| | | const tree: T[] = []; |
| | | |
| | | for (const d of data) { |
| | | const parentId = d[config.parentId]; |
| | | if (childrenListMap[parentId] == null) { |
| | | childrenListMap[parentId] = []; |
| | | } |
| | | nodeIds[d[config.id]] = d; |
| | | childrenListMap[parentId].push(d); |
| | | } |
| | | for (const d of data) { |
| | | const parentId = d[config.parentId]; |
| | | if (childrenListMap[parentId] == null) { |
| | | childrenListMap[parentId] = []; |
| | | } |
| | | nodeIds[d[config.id]] = d; |
| | | childrenListMap[parentId].push(d); |
| | | } |
| | | |
| | | for (const d of data) { |
| | | const parentId = d[config.parentId]; |
| | | if (nodeIds[parentId] == null) { |
| | | tree.push(d); |
| | | } |
| | | } |
| | | const adaptToChildrenList = (o: any) => { |
| | | if (childrenListMap[o[config.id]] !== null) { |
| | | o[config.childrenList] = childrenListMap[o[config.id]]; |
| | | } |
| | | if (o[config.childrenList]) { |
| | | for (const c of o[config.childrenList]) { |
| | | adaptToChildrenList(c); |
| | | } |
| | | } |
| | | }; |
| | | for (const d of data) { |
| | | const parentId = d[config.parentId]; |
| | | if (nodeIds[parentId] == null) { |
| | | tree.push(d); |
| | | } |
| | | } |
| | | const adaptToChildrenList = (o: any) => { |
| | | if (childrenListMap[o[config.id]] !== null) { |
| | | o[config.childrenList] = childrenListMap[o[config.id]]; |
| | | } |
| | | if (o[config.childrenList]) { |
| | | for (const c of o[config.childrenList]) { |
| | | adaptToChildrenList(c); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | for (const t of tree) { |
| | | adaptToChildrenList(t); |
| | | } |
| | | for (const t of tree) { |
| | | adaptToChildrenList(t); |
| | | } |
| | | |
| | | return tree; |
| | | 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; |
| | | 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; |
| | | 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'; |
| | | return data.type !== 'application/json'; |
| | | }; |
| | |
| | | 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; |
| | | 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); |
| | | } |
| | | ); |
| | | return ( |
| | | window.requestAnimationFrame || |
| | | (window as any).webkitRequestAnimationFrame || |
| | | (window as any).mozRequestAnimationFrame || |
| | | function (callback) { |
| | | window.setTimeout(callback, 1000 / 60); |
| | | } |
| | | ); |
| | | })(); |
| | | |
| | | /** |
| | |
| | | * @param {number} amount |
| | | */ |
| | | const move = (amount: number) => { |
| | | document.documentElement.scrollTop = amount; |
| | | (document.body.parentNode as HTMLElement).scrollTop = amount; |
| | | document.body.scrollTop = amount; |
| | | 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; |
| | | return document.documentElement.scrollTop || (document.body.parentNode as HTMLElement).scrollTop || document.body.scrollTop; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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(); |
| | | 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(); |
| | | }; |
| | |
| | | // å¤ç䏻颿 ·å¼ |
| | | 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)}`); |
| | | } |
| | | 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 : []; |
| | | 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('')}`; |
| | | 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]); |
| | | 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]); |
| | | 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]); |
| | | }; |
| | |
| | | * @param url |
| | | */ |
| | | export const isHttp = (url: string): boolean => { |
| | | return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1; |
| | | return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {Boolean} |
| | | */ |
| | | export const isExternal = (path: string) => { |
| | | return /^(https?:|mailto:|tel:)/.test(path); |
| | | return /^(https?:|mailto:|tel:)/.test(path); |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {Boolean} |
| | | */ |
| | | export const validUsername = (str: string) => { |
| | | const valid_map = ['admin', 'editor']; |
| | | return valid_map.indexOf(str.trim()) >= 0; |
| | | const valid_map = ['admin', 'editor']; |
| | | return valid_map.indexOf(str.trim()) >= 0; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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); |
| | | 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); |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {Boolean} |
| | | */ |
| | | export const validLowerCase = (str: string) => { |
| | | const reg = /^[a-z]+$/; |
| | | return reg.test(str); |
| | | const reg = /^[a-z]+$/; |
| | | return reg.test(str); |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {Boolean} |
| | | */ |
| | | export const validUpperCase = (str: string) => { |
| | | const reg = /^[A-Z]+$/; |
| | | return reg.test(str); |
| | | const reg = /^[A-Z]+$/; |
| | | return reg.test(str); |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {Boolean} |
| | | */ |
| | | export const validAlphabets = (str: string) => { |
| | | const reg = /^[A-Za-z]+$/; |
| | | return reg.test(str); |
| | | const reg = /^[A-Za-z]+$/; |
| | | return reg.test(str); |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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); |
| | | 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); |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @returns {Boolean} |
| | | */ |
| | | export const isString = (str: any) => { |
| | | return typeof str === 'string' || str instanceof String; |
| | | return typeof str === 'string' || str instanceof String; |
| | | }; |
| | | |
| | | /** |
| | |
| | | * @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); |
| | | if (typeof Array.isArray === 'undefined') { |
| | | return Object.prototype.toString.call(arg) === '[object Array]'; |
| | | } |
| | | return Array.isArray(arg); |
| | | }; |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="keyé®" prop="testKey"> |
| | | <el-input v-model="queryParams.testKey" placeholder="请è¾å
¥keyé®" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¼" prop="value"> |
| | | <el-input v-model="queryParams.value" placeholder="请è¾å
¥å¼" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´"> |
| | | <el-date-picker |
| | | v-model="daterangeCreateTime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button type="primary" icon="search" @click="handlePage">æç´¢(èªå®ä¹å页æ¥å£)</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['demo:demo:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['demo:demo:edit']">ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['demo:demo:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['demo:demo:import']">导å
¥(æ ¡éª)</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['demo:demo:export']">导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" :data="demoList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="主é®" align="center" prop="id" v-if="columns[0].visible" /> |
| | | <el-table-column label="é¨é¨id" align="center" prop="deptId" v-if="columns[1].visible" /> |
| | | <el-table-column label="ç¨æ·id" align="center" prop="userId" v-if="columns[2].visible" /> |
| | | <el-table-column label="æåºå·" align="center" prop="orderNum" v-if="columns[3].visible" /> |
| | | <el-table-column label="keyé®" align="center" prop="testKey" v-if="columns[4].visible" /> |
| | | <el-table-column label="å¼" align="center" prop="value" v-if="columns[5].visible" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" v-if="columns[6].visible" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建人" align="center" prop="createByName" v-if="columns[7].visible" /> |
| | | <el-table-column label="æ´æ°æ¶é´" align="center" prop="updateTime" v-if="columns[8].visible" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æ´æ°äºº" align="center" prop="updateByName" v-if="columns[9].visible" /> |
| | | <el-table-column label="æä½" fixed="right" align="center" width="150" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:demo:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:demo:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | |
| | | <!-- æ·»å æä¿®æ¹æµè¯åè¡¨å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="demoFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="é¨é¨id" prop="deptId"> |
| | | <el-input v-model="form.deptId" placeholder="请è¾å
¥é¨é¨id" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·id" prop="userId"> |
| | | <el-input v-model="form.userId" placeholder="请è¾å
¥ç¨æ·id" /> |
| | | </el-form-item> |
| | | <el-form-item label="æåºå·" prop="orderNum"> |
| | | <el-input v-model="form.orderNum" placeholder="请è¾å
¥æåºå·" /> |
| | | </el-form-item> |
| | | <el-form-item label="keyé®" prop="testKey"> |
| | | <el-input v-model="form.testKey" placeholder="请è¾å
¥keyé®" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¼" prop="value"> |
| | | <el-input v-model="form.value" placeholder="请è¾å
¥å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" prop="createTime"> |
| | | <el-date-picker clearable v-model="form.createTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="éæ©å建æ¶é´"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button :loading="buttonLoading" type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- ç¨æ·å¯¼å
¥å¯¹è¯æ¡ --> |
| | | <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body> |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :limit="1" |
| | | accept=".xlsx, .xls" |
| | | :headers="upload.headers" |
| | | :action="upload.url + '?updateSupport=' + upload.updateSupport" |
| | | :disabled="upload.isUploading" |
| | | :on-progress="handleFileUploadProgress" |
| | | :on-success="handleFileSuccess" |
| | | :auto-upload="false" |
| | | drag |
| | | > |
| | | <i class="el-icon-upload"></i> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | </el-upload> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> |
| | | <el-button @click="upload.open = false">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Demo" lang="ts"> |
| | | import { listDemo, pageDemo, getDemo, delDemo, addDemo, updateDemo } from "@/api/demo/demo"; |
| | | import { getToken } from "@/utils/auth"; |
| | |
| | | const uploadRef = ref(ElUpload); |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: '' |
| | | visible: false, |
| | | title: '' |
| | | }); |
| | | |
| | | /** ç¨æ·å¯¼å
¥åæ° */ |
| | | const upload = reactive<ImportOption>({ |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼ç¨æ·å¯¼å
¥ï¼ |
| | | open: false, |
| | | // å¼¹åºå±æ é¢ï¼ç¨æ·å¯¼å
¥ï¼ |
| | | title: "", |
| | | // æ¯å¦ç¦ç¨ä¸ä¼ |
| | | isUploading: false, |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "demo/demo/importData" |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼ç¨æ·å¯¼å
¥ï¼ |
| | | open: false, |
| | | // å¼¹åºå±æ é¢ï¼ç¨æ·å¯¼å
¥ï¼ |
| | | title: "", |
| | | // æ¯å¦ç¦ç¨ä¸ä¼ |
| | | isUploading: false, |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "demo/demo/importData" |
| | | }) |
| | | |
| | | // åæ¾éä¿¡æ¯ |
| | | const columns = ref<FieldOption[]>([ |
| | | { key: 0, label: `主é®`, visible: false }, |
| | | { key: 1, label: `é¨é¨id`, visible: true }, |
| | | { key: 2, label: `ç¨æ·id`, visible: true }, |
| | | { key: 3, label: `æåºå·`, visible: true }, |
| | | { key: 4, label: `keyé®`, visible: true }, |
| | | { key: 5, label: `å¼`, visible: true }, |
| | | { key: 6, label: `å建æ¶é´`, visible: true }, |
| | | { key: 7, label: `å建人`, visible: true }, |
| | | { key: 8, label: `æ´æ°æ¶é´`, visible: true }, |
| | | { key: 9, label: `æ´æ°äºº`, visible: true } |
| | | { key: 0, label: `主é®`, visible: false }, |
| | | { key: 1, label: `é¨é¨id`, visible: true }, |
| | | { key: 2, label: `ç¨æ·id`, visible: true }, |
| | | { key: 3, label: `æåºå·`, visible: true }, |
| | | { key: 4, label: `keyé®`, visible: true }, |
| | | { key: 5, label: `å¼`, visible: true }, |
| | | { key: 6, label: `å建æ¶é´`, visible: true }, |
| | | { key: 7, label: `å建人`, visible: true }, |
| | | { key: 8, label: `æ´æ°æ¶é´`, visible: true }, |
| | | { key: 9, label: `æ´æ°äºº`, visible: true } |
| | | ]); |
| | | |
| | | const initDataForm: DemoForm = { |
| | | id: undefined, |
| | | deptId: undefined, |
| | | userId: undefined, |
| | | orderNum: 0, |
| | | testKey: '', |
| | | value: '', |
| | | version: '', |
| | | ossConfigId: undefined, |
| | | id: undefined, |
| | | deptId: undefined, |
| | | userId: undefined, |
| | | orderNum: 0, |
| | | testKey: '', |
| | | value: '', |
| | | version: '', |
| | | ossConfigId: undefined, |
| | | } |
| | | const data = reactive<PageData<DemoForm, DemoQuery>>({ |
| | | form: { ...initDataForm }, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | testKey: '', |
| | | value: '', |
| | | createTime: '', |
| | | }, |
| | | rules: { |
| | | testKey: [{ required: true, message: "keyé®ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | value: [{ required: true, message: "å¼ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | } |
| | | form: { ...initDataForm }, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | testKey: '', |
| | | value: '', |
| | | createTime: '', |
| | | }, |
| | | rules: { |
| | | testKey: [{ required: true, message: "keyé®ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | value: [{ required: true, message: "å¼ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | } |
| | | }); |
| | | |
| | | const { queryParams, form, rules } = toRefs(data); |
| | | |
| | | /** æ¥è¯¢OSS对象åå¨å表 */ |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const res = await listDemo(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")); |
| | | demoList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | loading.value = true; |
| | | const res = await listDemo(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")); |
| | | demoList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | } |
| | | /** èªå®ä¹å页æ¥è¯¢ */ |
| | | const getPage = async () => { |
| | | loading.value = true; |
| | | const res = await pageDemo(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")); |
| | | demoList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | loading.value = true; |
| | | const res = await pageDemo(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")); |
| | | demoList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | } |
| | | /** åæ¶æé® */ |
| | | const cancel = () => { |
| | | reset(); |
| | | dialog.visible = false; |
| | | reset(); |
| | | dialog.visible = false; |
| | | } |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = { ...initDataForm }; |
| | | demoFormRef.value.resetFields(); |
| | | form.value = { ...initDataForm }; |
| | | demoFormRef.value.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handlePage = () => { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | daterangeCreateTime.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | handleQuery(); |
| | | daterangeCreateTime.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** éæ©æ¡æ° */ |
| | | const handleSelectionChange = (selection: DemoVO[]) => { |
| | | ids.value = selection.map(item => item.id); |
| | | single.value = selection.length != 1; |
| | | multiple.value = !selection.length; |
| | | ids.value = selection.map(item => item.id); |
| | | single.value = selection.length != 1; |
| | | multiple.value = !selection.length; |
| | | } |
| | | /** æ°å¢æé®æä½ */ |
| | | const handleAdd = () => { |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å æµè¯å表"; |
| | | nextTick(() => { |
| | | reset(); |
| | | }) |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å æµè¯å表"; |
| | | nextTick(() => { |
| | | reset(); |
| | | }) |
| | | } |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | const handleUpdate = async (row?: DemoVO) => { |
| | | loading.value = true; |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹æµè¯å表"; |
| | | const _ids = row?.id || ids.value[0]; |
| | | const res = await getDemo(_ids); |
| | | nextTick(() => { |
| | | reset(); |
| | | Object.assign(form.value, res.data) |
| | | loading.value = false; |
| | | }) |
| | | loading.value = true; |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹æµè¯å表"; |
| | | const _ids = row?.id || ids.value[0]; |
| | | const res = await getDemo(_ids); |
| | | nextTick(() => { |
| | | reset(); |
| | | Object.assign(form.value, res.data) |
| | | loading.value = false; |
| | | }) |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | demoFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | if (form.value.ossConfigId) { |
| | | await updateDemo(form.value).finally(() => buttonLoading.value = false); |
| | | } else { |
| | | await addDemo(form.value).finally(() => buttonLoading.value = false); |
| | | } |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | } |
| | | }); |
| | | demoFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | if (form.value.ossConfigId) { |
| | | await updateDemo(form.value).finally(() => buttonLoading.value = false); |
| | | } else { |
| | | await addDemo(form.value).finally(() => buttonLoading.value = false); |
| | | } |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | } |
| | | }); |
| | | } |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row?: DemoVO) => { |
| | | const _ids = row?.id || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿µè¯å表ç¼å·ä¸º"' + _ids + '"çæ°æ®é¡¹?'); |
| | | await delDemo(_ids).finally(() => loading.value = false); |
| | | loading.value = false; |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | const _ids = row?.id || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿µè¯å表ç¼å·ä¸º"' + _ids + '"çæ°æ®é¡¹?'); |
| | | await delDemo(_ids).finally(() => loading.value = false); |
| | | loading.value = false; |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | /** 导å
¥æé®æä½ */ |
| | | const handleImport = () => { |
| | | upload.title = "æµè¯å¯¼å
¥"; |
| | | upload.open = true; |
| | | upload.title = "æµè¯å¯¼å
¥"; |
| | | upload.open = true; |
| | | } |
| | | /** å¯¼åºæé®æä½ */ |
| | | const handleExport = () => { |
| | | proxy?.download("demo/demo/export", { |
| | | ...queryParams.value, |
| | | }, `demo_${new Date().getTime()}.xlsx`); |
| | | proxy?.download("demo/demo/export", { |
| | | ...queryParams.value, |
| | | }, `demo_${new Date().getTime()}.xlsx`); |
| | | } |
| | | /**æä»¶ä¸ä¼ ä¸å¤ç */ |
| | | const handleFileUploadProgress = () => { |
| | | upload.isUploading = true; |
| | | upload.isUploading = true; |
| | | } |
| | | /** æä»¶ä¸ä¼ æåå¤ç */ |
| | | const handleFileSuccess = (res: any, file: UploadFile, fileList: UploadFiles) => { |
| | | upload.open = false; |
| | | upload.isUploading = false; |
| | | uploadRef.value.clearFiles(); |
| | | ElMessageBox.alert(res.msg, "导å
¥ç»æ", { dangerouslyUseHTMLString: true }); |
| | | getList(); |
| | | upload.open = false; |
| | | upload.isUploading = false; |
| | | uploadRef.value.clearFiles(); |
| | | ElMessageBox.alert(res.msg, "导å
¥ç»æ", { dangerouslyUseHTMLString: true }); |
| | | getList(); |
| | | } |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | function submitFileForm() { |
| | | uploadRef.value.submit(); |
| | | uploadRef.value.submit(); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | | getPage() |
| | | getList() |
| | | getPage() |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="keyé®" prop="testKey"> |
| | | <el-input v-model="queryParams.testKey" placeholder="请è¾å
¥keyé®" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¼" prop="value"> |
| | | <el-input v-model="queryParams.value" placeholder="请è¾å
¥å¼" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´"> |
| | | <el-date-picker |
| | | v-model="daterangeCreateTime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button type="primary" icon="search" @click="handlePage">æç´¢(èªå®ä¹å页æ¥å£)</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['demo:demo:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['demo:demo:edit']">ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['demo:demo:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['demo:demo:import']">导å
¥(æ ¡éª)</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['demo:demo:export']">导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" :data="demoList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="主é®" align="center" prop="id" v-if="columns[0].visible" /> |
| | | <el-table-column label="é¨é¨id" align="center" prop="deptId" v-if="columns[1].visible" /> |
| | | <el-table-column label="ç¨æ·id" align="center" prop="userId" v-if="columns[2].visible" /> |
| | | <el-table-column label="æåºå·" align="center" prop="orderNum" v-if="columns[3].visible" /> |
| | | <el-table-column label="keyé®" align="center" prop="testKey" v-if="columns[4].visible" /> |
| | | <el-table-column label="å¼" align="center" prop="value" v-if="columns[5].visible" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" v-if="columns[6].visible" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建人" align="center" prop="createByName" v-if="columns[7].visible" /> |
| | | <el-table-column label="æ´æ°æ¶é´" align="center" prop="updateTime" v-if="columns[8].visible" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æ´æ°äºº" align="center" prop="updateByName" v-if="columns[9].visible" /> |
| | | <el-table-column label="æä½" fixed="right" align="center" width="150" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:demo:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:demo:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | |
| | | <!-- æ·»å æä¿®æ¹æµè¯åè¡¨å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="demoFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="é¨é¨id" prop="deptId"> |
| | | <el-input v-model="form.deptId" placeholder="请è¾å
¥é¨é¨id" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·id" prop="userId"> |
| | | <el-input v-model="form.userId" placeholder="请è¾å
¥ç¨æ·id" /> |
| | | </el-form-item> |
| | | <el-form-item label="æåºå·" prop="orderNum"> |
| | | <el-input v-model="form.orderNum" placeholder="请è¾å
¥æåºå·" /> |
| | | </el-form-item> |
| | | <el-form-item label="keyé®" prop="testKey"> |
| | | <el-input v-model="form.testKey" placeholder="请è¾å
¥keyé®" /> |
| | | </el-form-item> |
| | | <el-form-item label="å¼" prop="value"> |
| | | <el-input v-model="form.value" placeholder="请è¾å
¥å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" prop="createTime"> |
| | | <el-date-picker clearable v-model="form.createTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="éæ©å建æ¶é´"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button :loading="buttonLoading" type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- ç¨æ·å¯¼å
¥å¯¹è¯æ¡ --> |
| | | <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body> |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :limit="1" |
| | | accept=".xlsx, .xls" |
| | | :headers="upload.headers" |
| | | :action="upload.url + '?updateSupport=' + upload.updateSupport" |
| | | :disabled="upload.isUploading" |
| | | :on-progress="handleFileUploadProgress" |
| | | :on-success="handleFileSuccess" |
| | | :auto-upload="false" |
| | | drag |
| | | > |
| | | <i class="el-icon-upload"></i> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | </el-upload> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> |
| | | <el-button @click="upload.open = false">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="qeuryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="æ èç¹å" prop="treeName"> |
| | | <el-input v-model="queryParams.treeName" placeholder="请è¾å
¥æ èç¹å" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´"> |
| | | <el-date-picker |
| | | v-model="daterangeCreateTime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['demo:tree:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">å±å¼/æå </el-button> |
| | | </el-col> |
| | | <right-toolbar :columns="columns" v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table |
| | | v-if="refreshTable" |
| | | v-loading="loading" |
| | | :data="treeList" |
| | | row-key="id" |
| | | :default-expand-all="isExpandAll" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | ref="demoTreeTableRef" |
| | | > |
| | | <el-table-column label="ç¶id" prop="parentId" v-if="columns[0].visible" /> |
| | | <el-table-column label="é¨é¨id" align="center" prop="deptId" v-if="columns[1].visible" /> |
| | | <el-table-column label="ç¨æ·id" align="center" prop="userId" v-if="columns[2].visible" /> |
| | | <el-table-column label="æ èç¹å" align="center" prop="treeName" v-if="columns[3].visible" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" v-if="columns[4].visible" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" fixed="right" align="center" width="150" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:tree:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="æ°å¢" placement="top"> |
| | | <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['demo:tree:add']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:tree:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | | <!-- æ·»å æä¿®æ¹æµè¯æ è¡¨å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="treeRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="ç¶id" prop="parentId"> |
| | | <el-tree-select |
| | | v-model="form.parentId" |
| | | :data="treeOptions" |
| | | :props="{ value: 'id', label: 'treeName', children: 'children' }" |
| | | value-key="id" |
| | | check-strictly |
| | | placeholder="è¯·éæ©ç¶id" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="é¨é¨id" prop="deptId"> |
| | | <el-input v-model="form.deptId" placeholder="请è¾å
¥é¨é¨id" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·id" prop="userId"> |
| | | <el-input v-model="form.userId" placeholder="请è¾å
¥ç¨æ·id" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ èç¹å" prop="treeName"> |
| | | <el-input v-model="form.treeName" placeholder="请è¾å
¥æ èç¹å" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button :loading="buttonLoading" type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Tree" lang="ts"> |
| | | import { listTree, getTree, delTree, addTree, updateTree } from '@/api/demo/tree'; |
| | | import { DemoTreeVO, DemoTreeForm, DemoTreeOptionsType, DemoTreeQuery } from '@/api/demo/types'; |
| | |
| | | const demoTreeTableRef = ref(ElTable) |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: '' |
| | | visible: false, |
| | | title: '' |
| | | }); |
| | | |
| | | // åæ¾éä¿¡æ¯ |
| | | const columns = ref<FieldOption[]>([ |
| | | { key: 0, label: `ç¶id`, visible: false }, |
| | | { key: 1, label: `é¨é¨id`, visible: true }, |
| | | { key: 2, label: `ç¨æ·id`, visible: true }, |
| | | { key: 3, label: `æ èç¹å`, visible: true }, |
| | | { key: 4, label: `å建æ¶é´`, visible: true } |
| | | { key: 0, label: `ç¶id`, visible: false }, |
| | | { key: 1, label: `é¨é¨id`, visible: true }, |
| | | { key: 2, label: `ç¨æ·id`, visible: true }, |
| | | { key: 3, label: `æ èç¹å`, visible: true }, |
| | | { key: 4, label: `å建æ¶é´`, visible: true } |
| | | ]); |
| | | |
| | | const initFormData = { |
| | | id: undefined, |
| | | parentId: undefined, |
| | | deptId: undefined, |
| | | userId: undefined, |
| | | treeName: '' |
| | | id: undefined, |
| | | parentId: undefined, |
| | | deptId: undefined, |
| | | userId: undefined, |
| | | treeName: '' |
| | | } |
| | | |
| | | const data = reactive<PageData<DemoTreeForm, DemoTreeQuery>>({ |
| | | // æ¥è¯¢åæ° |
| | | queryParams: { |
| | | treeName: '', |
| | | createTime: '', |
| | | }, |
| | | // 表ååæ° |
| | | form: {...initFormData}, |
| | | // è¡¨åæ ¡éª |
| | | rules: { |
| | | treeName: [{ required: true, message: "æ èç¹åä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | } |
| | | // æ¥è¯¢åæ° |
| | | queryParams: { |
| | | treeName: '', |
| | | createTime: '', |
| | | }, |
| | | // 表ååæ° |
| | | form: {...initFormData}, |
| | | // è¡¨åæ ¡éª |
| | | rules: { |
| | | treeName: [{ required: true, message: "æ èç¹åä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | } |
| | | }); |
| | | |
| | | const { queryParams, form, rules } = toRefs(data); |
| | | /** æ¥è¯¢æµè¯æ 表å表 */ |
| | | const getList = () => { |
| | | loading.value = true; |
| | | listTree(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")).then(res => { |
| | | const data = proxy?.handleTree<DemoTreeVO>(res.data, "id", "parentId"); |
| | | if (data) { |
| | | treeList.value = data |
| | | } |
| | | loading.value = false; |
| | | }); |
| | | loading.value = true; |
| | | listTree(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")).then(res => { |
| | | const data = proxy?.handleTree<DemoTreeVO>(res.data, "id", "parentId"); |
| | | if (data) { |
| | | treeList.value = data |
| | | } |
| | | loading.value = false; |
| | | }); |
| | | } |
| | | |
| | | /** æ¥è¯¢é¨é¨ä¸ææ ç»æ */ |
| | | const getTreeSelect = async () => { |
| | | listTree(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")).then(res => { |
| | | const topData: DemoTreeOptionsType = { id: 0, treeName: '顶级èç¹', children: [] }; |
| | | topData.children = proxy?.handleTree<DemoTreeOptionsType>(res.data, "id", "parentId"); |
| | | treeOptions.value.push(topData); |
| | | }); |
| | | listTree(proxy?.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")).then(res => { |
| | | const topData: DemoTreeOptionsType = { id: 0, treeName: '顶级èç¹', children: [] }; |
| | | topData.children = proxy?.handleTree<DemoTreeOptionsType>(res.data, "id", "parentId"); |
| | | treeOptions.value.push(topData); |
| | | }); |
| | | } |
| | | /** åæ¶æé® */ |
| | | const cancel = () => { |
| | | reset(); |
| | | dialog.visible = false; |
| | | reset(); |
| | | dialog.visible = false; |
| | | } |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = {...initFormData} |
| | | treeRef.value.resetFields(); |
| | | form.value = {...initFormData} |
| | | treeRef.value.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | getList(); |
| | | getList(); |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | daterangeCreateTime.value = ['', '']; |
| | | qeuryFormRef.value.resetFields(); |
| | | handleQuery(); |
| | | daterangeCreateTime.value = ['', '']; |
| | | qeuryFormRef.value.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** æ°å¢æé®æä½ */ |
| | | const handleAdd = (row?: DemoTreeVO) => { |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å æµè¯æ 表"; |
| | | nextTick(() => { |
| | | reset(); |
| | | getTreeSelect(); |
| | | if (row != null && row.id) { |
| | | form.value.parentId = row.id; |
| | | } else { |
| | | form.value.parentId = 0; |
| | | } |
| | | }) |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å æµè¯æ 表"; |
| | | nextTick(() => { |
| | | reset(); |
| | | getTreeSelect(); |
| | | if (row != null && row.id) { |
| | | form.value.parentId = row.id; |
| | | } else { |
| | | form.value.parentId = 0; |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** å±å¼/æå æä½ */ |
| | | const handleToggleExpandAll = () => { |
| | | isExpandAll.value = !isExpandAll.value; |
| | | toggleExpandAll(treeList.value, isExpandAll.value) |
| | | isExpandAll.value = !isExpandAll.value; |
| | | toggleExpandAll(treeList.value, isExpandAll.value) |
| | | } |
| | | /** å±å¼/æå ææ */ |
| | | const toggleExpandAll = (data: DemoTreeVO[], status: boolean) => { |
| | | data.forEach((item) => { |
| | | demoTreeTableRef.value.toggleRowExpansion(item, status) |
| | | if(item.children && item.children.length > 0) toggleExpandAll(item.children, status) |
| | | }) |
| | | data.forEach((item) => { |
| | | demoTreeTableRef.value.toggleRowExpansion(item, status) |
| | | if(item.children && item.children.length > 0) toggleExpandAll(item.children, status) |
| | | }) |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | const handleUpdate = async (row: DemoTreeVO) => { |
| | | loading.value = true; |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹æµè¯æ 表"; |
| | | nextTick(async () => { |
| | | reset(); |
| | | getTreeSelect(); |
| | | if (row) { |
| | | form.value.parentId = row.id; |
| | | } |
| | | getTree(row.id).then((response) => { |
| | | loading.value = false; |
| | | form.value = response.data; |
| | | loading.value = true; |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹æµè¯æ 表"; |
| | | nextTick(async () => { |
| | | reset(); |
| | | getTreeSelect(); |
| | | if (row) { |
| | | form.value.parentId = row.id; |
| | | } |
| | | getTree(row.id).then((response) => { |
| | | loading.value = false; |
| | | form.value = response.data; |
| | | |
| | | }); |
| | | }) |
| | | }); |
| | | }) |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | treeRef.value.validate((valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | if (form.value.id != null) { |
| | | updateTree(form.value).then(() => { |
| | | proxy?.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | }).finally(() => { |
| | | buttonLoading.value = false; |
| | | }); |
| | | } else { |
| | | addTree(form.value).then(() => { |
| | | proxy?.$modal.msgSuccess("æ°å¢æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | }).finally(() => { |
| | | buttonLoading.value = false; |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | treeRef.value.validate((valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | if (form.value.id != null) { |
| | | updateTree(form.value).then(() => { |
| | | proxy?.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | }).finally(() => { |
| | | buttonLoading.value = false; |
| | | }); |
| | | } else { |
| | | addTree(form.value).then(() => { |
| | | proxy?.$modal.msgSuccess("æ°å¢æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | }).finally(() => { |
| | | buttonLoading.value = false; |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = (row: DemoTreeVO) => { |
| | | proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿µè¯å表ç¼å·ä¸º"' + row.id + '"çæ°æ®é¡¹?').then(() => { |
| | | loading.value = true; |
| | | return delTree(row.id); |
| | | }).then(() => { |
| | | loading.value = false; |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | }).finally(() => { |
| | | loading.value = false; |
| | | }); |
| | | proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿µè¯å表ç¼å·ä¸º"' + row.id + '"çæ°æ®é¡¹?').then(() => { |
| | | loading.value = true; |
| | | return delTree(row.id); |
| | | }).then(() => { |
| | | loading.value = false; |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | }).finally(() => { |
| | | loading.value = false; |
| | | }); |
| | | } |
| | | onMounted(() => { |
| | | getList() |
| | | getList() |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="qeuryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="æ èç¹å" prop="treeName"> |
| | | <el-input v-model="queryParams.treeName" placeholder="请è¾å
¥æ èç¹å" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´"> |
| | | <el-date-picker |
| | | v-model="daterangeCreateTime" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['demo:tree:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">å±å¼/æå </el-button> |
| | | </el-col> |
| | | <right-toolbar :columns="columns" v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table |
| | | v-if="refreshTable" |
| | | v-loading="loading" |
| | | :data="treeList" |
| | | row-key="id" |
| | | :default-expand-all="isExpandAll" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | ref="demoTreeTableRef" |
| | | > |
| | | <el-table-column label="ç¶id" prop="parentId" v-if="columns[0].visible" /> |
| | | <el-table-column label="é¨é¨id" align="center" prop="deptId" v-if="columns[1].visible" /> |
| | | <el-table-column label="ç¨æ·id" align="center" prop="userId" v-if="columns[2].visible" /> |
| | | <el-table-column label="æ èç¹å" align="center" prop="treeName" v-if="columns[3].visible" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" v-if="columns[4].visible" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" fixed="right" align="center" width="150" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['demo:tree:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="æ°å¢" placement="top"> |
| | | <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['demo:tree:add']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['demo:tree:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | | <!-- æ·»å æä¿®æ¹æµè¯æ è¡¨å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="treeRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="ç¶id" prop="parentId"> |
| | | <el-tree-select |
| | | v-model="form.parentId" |
| | | :data="treeOptions" |
| | | :props="{ value: 'id', label: 'treeName', children: 'children' }" |
| | | value-key="id" |
| | | check-strictly |
| | | placeholder="è¯·éæ©ç¶id" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="é¨é¨id" prop="deptId"> |
| | | <el-input v-model="form.deptId" placeholder="请è¾å
¥é¨é¨id" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·id" prop="userId"> |
| | | <el-input v-model="form.userId" placeholder="请è¾å
¥ç¨æ·id" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ èç¹å" prop="treeName"> |
| | | <el-input v-model="form.treeName" placeholder="请è¾å
¥æ èç¹å" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button :loading="buttonLoading" type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="errPage-container"> |
| | | <el-button icon="arrow-left" class="pan-back-btn" @click="back"> è¿å </el-button> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <h1 class="text-jumbo text-ginormous">401é误!</h1> |
| | | <h2>æ¨æ²¡æè®¿é®æéï¼</h2> |
| | | <h6>对ä¸èµ·ï¼æ¨æ²¡æè®¿é®æéï¼è¯·ä¸è¦è¿è¡éæ³æä½ï¼æ¨å¯ä»¥è¿å主页é¢</h6> |
| | | <ul class="list-unstyled"> |
| | | <li class="link-type"> |
| | | <router-link to="/"> åé¦é¡µ </router-link> |
| | | </li> |
| | | </ul> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream." /> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <div class="errPage-container"> |
| | | <el-button icon="arrow-left" class="pan-back-btn" @click="back"> è¿å </el-button> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <h1 class="text-jumbo text-ginormous">401é误!</h1> |
| | | <h2>æ¨æ²¡æè®¿é®æéï¼</h2> |
| | | <h6>对ä¸èµ·ï¼æ¨æ²¡æè®¿é®æéï¼è¯·ä¸è¦è¿è¡éæ³æä½ï¼æ¨å¯ä»¥è¿å主页é¢</h6> |
| | | <ul class="list-unstyled"> |
| | | <li class="link-type"> |
| | | <router-link to="/"> åé¦é¡µ </router-link> |
| | | </li> |
| | | </ul> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream." /> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | |
| | | <template> |
| | | <div class="wscn-http404-container"> |
| | | <div class="wscn-http404"> |
| | | <div class="pic-404"> |
| | | <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404" /> |
| | | <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404" /> |
| | | <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404" /> |
| | | <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404" /> |
| | | </div> |
| | | <div class="bullshit"> |
| | | <div class="bullshit__oops">404é误!</div> |
| | | <div class="bullshit__headline"> |
| | | {{ message }} |
| | | </div> |
| | | <div class="bullshit__info"> |
| | | 对ä¸èµ·ï¼æ¨æ£å¨å¯»æ¾ç页é¢ä¸åå¨ãå°è¯æ£æ¥URLçé误ï¼ç¶åææµè§å¨ä¸çå·æ°æé®æå°è¯å¨æä»¬çåºç¨ç¨åºä¸æ¾å°å
¶ä»å
容ã |
| | | </div> |
| | | <router-link to="/index" class="bullshit__return-home"> è¿åé¦é¡µ </router-link> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="wscn-http404-container"> |
| | | <div class="wscn-http404"> |
| | | <div class="pic-404"> |
| | | <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404" /> |
| | | <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404" /> |
| | | <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404" /> |
| | | <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404" /> |
| | | </div> |
| | | <div class="bullshit"> |
| | | <div class="bullshit__oops">404é误!</div> |
| | | <div class="bullshit__headline"> |
| | | {{ message }} |
| | | </div> |
| | | <div class="bullshit__info"> |
| | | 对ä¸èµ·ï¼æ¨æ£å¨å¯»æ¾ç页é¢ä¸åå¨ãå°è¯æ£æ¥URLçé误ï¼ç¶åææµè§å¨ä¸çå·æ°æé®æå°è¯å¨æä»¬çåºç¨ç¨åºä¸æ¾å°å
¶ä»å
容ã |
| | | </div> |
| | | <router-link to="/index" class="bullshit__return-home"> è¿åé¦é¡µ </router-link> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | |
| | | <template> |
| | | <div class="app-container home"> |
| | | <el-row :gutter="20"> |
| | | <el-col :sm="24" :lg="12" style="padding-left: 20px"> |
| | | <h2>RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»</h2> |
| | | <p> |
| | | RuoYi-Vue-Plus æ¯åºäº RuoYi-Vue é对 åå¸å¼é群 åºæ¯å级(ä¸å
¼å®¹åæ¡æ¶) |
| | | <br /> |
| | | * å端å¼åæ¡æ¶ Vue3ãTSãElement Plus<br /> |
| | | * å端å¼åæ¡æ¶ Spring Boot<br /> |
| | | * 容卿¡æ¶ Undertow åºäº Netty ç髿§è½å®¹å¨<br /> |
| | | * æéè®¤è¯æ¡æ¶ Sa-Token æ¯æå¤ç»ç«¯è®¤è¯ç³»ç»<br /> |
| | | * å
³ç³»æ°æ®åº MySQL éé
8.X æä½ 5.7<br /> |
| | | * ç¼åæ°æ®åº Redis éé
6.X æä½ 4.X<br /> |
| | | * æ°æ®åºæ¡æ¶ Mybatis-Plus å¿«é CRUD å¢å å¼åæç<br /> |
| | | * æ°æ®åºæ¡æ¶ p6spy æ´å¼ºå²ç SQL åæ<br /> |
| | | * 夿°æ®æºæ¡æ¶ dynamic-datasource æ¯æä¸»ä»ä¸å¤ç§ç±»æ°æ®åºå¼æ<br /> |
| | | * åºååæ¡æ¶ Jackson ç»ä¸ä½¿ç¨ jackson 髿å¯é <br /> |
| | | * Redis客æ·ç«¯ Redisson æ§è½å¼ºå²ãAPI丰å¯<br /> |
| | | * åå¸å¼éæµ Redisson å
¨å±ã请æ±IPãé群ID å¤ç§éæµ<br /> |
| | | * åå¸å¼é Lock4j 注解éãå·¥å
·é å¤ç§å¤æ ·<br /> |
| | | * åå¸å¼å¹ç Lock4j åºäºåå¸å¼éå®ç°<br /> |
| | | * åå¸å¼é¾è·¯è¿½è¸ª SkyWalking æ¯æé¾è·¯è¿½è¸ªãç½æ ¼åæã度éèåãå¯è§å<br /> |
| | | * åå¸å¼ä»»å¡è°åº¦ Xxl-Job 髿§è½ é«å¯é ææ©å±<br /> |
| | | * æä»¶åå¨ Minio æ¬å°åå¨<br /> |
| | | * æä»¶åå¨ ä¸çãé¿éãè
¾è®¯ äºåå¨<br /> |
| | | * çæ§æ¡æ¶ SpringBoot-Admin å
¨æ¹ä½æå¡çæ§<br /> |
| | | * æ ¡éªæ¡æ¶ Validation å¢å¼ºæ¥å£å®å
¨æ§ 严谨æ§<br /> |
| | | * Excelæ¡æ¶ Alibaba EasyExcel æ§è½ä¼å¼ æ©å±æ§å¼º<br /> |
| | | * ææ¡£æ¡æ¶ SpringDocãjavadoc æ æ³¨è§£é¶å
¥ä¾µåºäºjava注é<br /> |
| | | * å·¥å
·ç±»æ¡æ¶ HutoolãLombok åå°ä»£ç åä½ å¢å å®å
¨æ§<br /> |
| | | * 代ç çæå¨ éé
MPãSpringDocè§èå代ç ä¸é®çæåå端代ç <br /> |
| | | * é¨ç½²æ¹å¼ Docker 容å¨ç¼æ ä¸é®é¨ç½²ä¸å¡é群<br /> |
| | | * å½é
å SpringMessage Springæ åå½é
åæ¹æ¡<br /> |
| | | </p> |
| | | <p><b>å½åçæ¬:</b> <span>v5.0.0</span></p> |
| | | <p> |
| | | <el-tag type="danger">¥å
è´¹å¼æº</el-tag> |
| | | </p> |
| | | <p> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/RuoYi-Vue-Plus')">访é®ç äº</el-button> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/RuoYi-Vue-Plus')">访é®GitHub</el-button> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/changlog')" |
| | | >æ´æ°æ¥å¿</el-button |
| | | > |
| | | </p> |
| | | </el-col> |
| | | <div class="app-container home"> |
| | | <el-row :gutter="20"> |
| | | <el-col :sm="24" :lg="12" style="padding-left: 20px"> |
| | | <h2>RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»</h2> |
| | | <p> |
| | | RuoYi-Vue-Plus æ¯åºäº RuoYi-Vue é对 åå¸å¼é群 åºæ¯å级(ä¸å
¼å®¹åæ¡æ¶) |
| | | <br /> |
| | | * å端å¼åæ¡æ¶ Vue3ãTSãElement Plus<br /> |
| | | * å端å¼åæ¡æ¶ Spring Boot<br /> |
| | | * 容卿¡æ¶ Undertow åºäº Netty ç髿§è½å®¹å¨<br /> |
| | | * æéè®¤è¯æ¡æ¶ Sa-Token æ¯æå¤ç»ç«¯è®¤è¯ç³»ç»<br /> |
| | | * å
³ç³»æ°æ®åº MySQL éé
8.X æä½ 5.7<br /> |
| | | * ç¼åæ°æ®åº Redis éé
6.X æä½ 4.X<br /> |
| | | * æ°æ®åºæ¡æ¶ Mybatis-Plus å¿«é CRUD å¢å å¼åæç<br /> |
| | | * æ°æ®åºæ¡æ¶ p6spy æ´å¼ºå²ç SQL åæ<br /> |
| | | * 夿°æ®æºæ¡æ¶ dynamic-datasource æ¯æä¸»ä»ä¸å¤ç§ç±»æ°æ®åºå¼æ<br /> |
| | | * åºååæ¡æ¶ Jackson ç»ä¸ä½¿ç¨ jackson 髿å¯é <br /> |
| | | * Redis客æ·ç«¯ Redisson æ§è½å¼ºå²ãAPI丰å¯<br /> |
| | | * åå¸å¼éæµ Redisson å
¨å±ã请æ±IPãé群ID å¤ç§éæµ<br /> |
| | | * åå¸å¼é Lock4j 注解éãå·¥å
·é å¤ç§å¤æ ·<br /> |
| | | * åå¸å¼å¹ç Lock4j åºäºåå¸å¼éå®ç°<br /> |
| | | * åå¸å¼é¾è·¯è¿½è¸ª SkyWalking æ¯æé¾è·¯è¿½è¸ªãç½æ ¼åæã度éèåãå¯è§å<br /> |
| | | * åå¸å¼ä»»å¡è°åº¦ Xxl-Job 髿§è½ é«å¯é ææ©å±<br /> |
| | | * æä»¶åå¨ Minio æ¬å°åå¨<br /> |
| | | * æä»¶åå¨ ä¸çãé¿éãè
¾è®¯ äºåå¨<br /> |
| | | * çæ§æ¡æ¶ SpringBoot-Admin å
¨æ¹ä½æå¡çæ§<br /> |
| | | * æ ¡éªæ¡æ¶ Validation å¢å¼ºæ¥å£å®å
¨æ§ 严谨æ§<br /> |
| | | * Excelæ¡æ¶ Alibaba EasyExcel æ§è½ä¼å¼ æ©å±æ§å¼º<br /> |
| | | * ææ¡£æ¡æ¶ SpringDocãjavadoc æ æ³¨è§£é¶å
¥ä¾µåºäºjava注é<br /> |
| | | * å·¥å
·ç±»æ¡æ¶ HutoolãLombok åå°ä»£ç åä½ å¢å å®å
¨æ§<br /> |
| | | * 代ç çæå¨ éé
MPãSpringDocè§èå代ç ä¸é®çæåå端代ç <br /> |
| | | * é¨ç½²æ¹å¼ Docker 容å¨ç¼æ ä¸é®é¨ç½²ä¸å¡é群<br /> |
| | | * å½é
å SpringMessage Springæ åå½é
åæ¹æ¡<br /> |
| | | </p> |
| | | <p><b>å½åçæ¬:</b> <span>v5.0.0</span></p> |
| | | <p> |
| | | <el-tag type="danger">¥å
è´¹å¼æº</el-tag> |
| | | </p> |
| | | <p> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/RuoYi-Vue-Plus')">访é®ç äº</el-button> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/RuoYi-Vue-Plus')">访é®GitHub</el-button> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://javalionli.gitee.io/plus-doc/#/ruoyi-vue-plus/changlog')" |
| | | >æ´æ°æ¥å¿</el-button |
| | | > |
| | | </p> |
| | | </el-col> |
| | | |
| | | <el-col :sm="24" :lg="12" style="padding-left: 20px"> |
| | | <h2>RuoYi-Cloud-Pluså¤ç§æ·å¾®æå¡ç®¡çç³»ç»</h2> |
| | | <p> |
| | | RuoYi-Cloud-Plus å¾®æå¡éç¨æé管çç³»ç» éå RuoYi-Cloud å
¨æ¹ä½å级(ä¸å
¼å®¹åæ¡æ¶) |
| | | <br /> |
| | | * å端å¼åæ¡æ¶ Vue3ãTSãElement UI<br /> |
| | | * å端å¼åæ¡æ¶ Spring Boot<br /> |
| | | * å¾®æå¡å¼åæ¡æ¶ Spring CloudãSpring Cloud Alibaba<br /> |
| | | * 容卿¡æ¶ Undertow åºäº XNIO ç髿§è½å®¹å¨<br /> |
| | | * æéè®¤è¯æ¡æ¶ Sa-TokenãJwt æ¯æå¤ç»ç«¯è®¤è¯ç³»ç»<br /> |
| | | * å
³ç³»æ°æ®åº MySQL éé
8.X æä½ 5.7<br /> |
| | | * å
³ç³»æ°æ®åº Oracle éé
11g 12c<br /> |
| | | * å
³ç³»æ°æ®åº PostgreSQL éé
13 14<br /> |
| | | * å
³ç³»æ°æ®åº SQLServer éé
2017 2019<br /> |
| | | * ç¼åæ°æ®åº Redis éé
6.X æä½ 5.X<br /> |
| | | * åå¸å¼æ³¨åä¸å¿ Alibaba Nacos éç¨2.X åºäºGRPCéä¿¡é«æ§è½<br /> |
| | | * åå¸å¼é
ç½®ä¸å¿ Alibaba Nacos éç¨2.X åºäºGRPCéä¿¡é«æ§è½<br /> |
| | | * æå¡ç½å
³ Spring Cloud Gateway ååºå¼é«æ§è½ç½å
³<br /> |
| | | * è´è½½åè¡¡ Spring Cloud Loadbalancer è´è½½åè¡¡å¤ç<br /> |
| | | * RPCè¿ç¨è°ç¨ Apache Dubbo åçæä½¿ç¨ä½éªã髿§è½<br /> |
| | | * åå¸å¼éæµçæ Alibaba Sentinel æ ä¾µå
¥ã髿©å±<br /> |
| | | * åå¸å¼äºå¡ Alibaba Seata æ ä¾µå
¥ã髿©å± æ¯æ åç§æ¨¡å¼<br /> |
| | | * åå¸å¼æ¶æ¯éå Spring Cloud Stream é¨é¢æ¡æ¶å
¼å®¹åç§MQéæ<br /> |
| | | * åå¸å¼æ¶æ¯éå Apache Kafka 髿§è½é«é度<br /> |
| | | * åå¸å¼æ¶æ¯éå Apache RocketMQ é«å¯ç¨åè½å¤æ ·<br /> |
| | | * åå¸å¼æ¶æ¯éå RabbitMQ æ¯æåç§æ©å±æä»¶åè½å¤æ ·æ§<br /> |
| | | * åå¸å¼æç´¢å¼æ ElasticSearch ä¸çç¥å<br /> |
| | | * åå¸å¼é¾è·¯è¿½è¸ª Apache SkyWalking é¾è·¯è¿½è¸ªãç½æ ¼åæã度éèåãå¯è§å<br /> |
| | | * åå¸å¼æ¥å¿ä¸å¿ ELK ä¸çæçè§£å³æ¹æ¡<br /> |
| | | * åå¸å¼çæ§ PrometheusãGrafana å
¨æ¹ä½æ§è½çæ§<br /> |
| | | * å
¶ä½ä¸ Vue çæ¬ä¸è´<br /> |
| | | </p> |
| | | <p><b>å½åçæ¬:</b> <span>v2.0.0</span></p> |
| | | <p> |
| | | <el-tag type="danger">¥å
è´¹å¼æº</el-tag> |
| | | </p> |
| | | <p> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/RuoYi-Cloud-Plus')">访é®ç äº</el-button> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/RuoYi-Cloud-Plus')">访é®GitHub</el-button> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://javalionli.gitee.io/plus-doc/#/ruoyi-cloud-plus/changlog')" |
| | | >æ´æ°æ¥å¿</el-button |
| | | > |
| | | </p> |
| | | </el-col> |
| | | </el-row> |
| | | <el-divider /> |
| | | </div> |
| | | <el-col :sm="24" :lg="12" style="padding-left: 20px"> |
| | | <h2>RuoYi-Cloud-Pluså¤ç§æ·å¾®æå¡ç®¡çç³»ç»</h2> |
| | | <p> |
| | | RuoYi-Cloud-Plus å¾®æå¡éç¨æé管çç³»ç» éå RuoYi-Cloud å
¨æ¹ä½å级(ä¸å
¼å®¹åæ¡æ¶) |
| | | <br /> |
| | | * å端å¼åæ¡æ¶ Vue3ãTSãElement UI<br /> |
| | | * å端å¼åæ¡æ¶ Spring Boot<br /> |
| | | * å¾®æå¡å¼åæ¡æ¶ Spring CloudãSpring Cloud Alibaba<br /> |
| | | * 容卿¡æ¶ Undertow åºäº XNIO ç髿§è½å®¹å¨<br /> |
| | | * æéè®¤è¯æ¡æ¶ Sa-TokenãJwt æ¯æå¤ç»ç«¯è®¤è¯ç³»ç»<br /> |
| | | * å
³ç³»æ°æ®åº MySQL éé
8.X æä½ 5.7<br /> |
| | | * å
³ç³»æ°æ®åº Oracle éé
11g 12c<br /> |
| | | * å
³ç³»æ°æ®åº PostgreSQL éé
13 14<br /> |
| | | * å
³ç³»æ°æ®åº SQLServer éé
2017 2019<br /> |
| | | * ç¼åæ°æ®åº Redis éé
6.X æä½ 5.X<br /> |
| | | * åå¸å¼æ³¨åä¸å¿ Alibaba Nacos éç¨2.X åºäºGRPCéä¿¡é«æ§è½<br /> |
| | | * åå¸å¼é
ç½®ä¸å¿ Alibaba Nacos éç¨2.X åºäºGRPCéä¿¡é«æ§è½<br /> |
| | | * æå¡ç½å
³ Spring Cloud Gateway ååºå¼é«æ§è½ç½å
³<br /> |
| | | * è´è½½åè¡¡ Spring Cloud Loadbalancer è´è½½åè¡¡å¤ç<br /> |
| | | * RPCè¿ç¨è°ç¨ Apache Dubbo åçæä½¿ç¨ä½éªã髿§è½<br /> |
| | | * åå¸å¼éæµçæ Alibaba Sentinel æ ä¾µå
¥ã髿©å±<br /> |
| | | * åå¸å¼äºå¡ Alibaba Seata æ ä¾µå
¥ã髿©å± æ¯æ åç§æ¨¡å¼<br /> |
| | | * åå¸å¼æ¶æ¯éå Spring Cloud Stream é¨é¢æ¡æ¶å
¼å®¹åç§MQéæ<br /> |
| | | * åå¸å¼æ¶æ¯éå Apache Kafka 髿§è½é«é度<br /> |
| | | * åå¸å¼æ¶æ¯éå Apache RocketMQ é«å¯ç¨åè½å¤æ ·<br /> |
| | | * åå¸å¼æ¶æ¯éå RabbitMQ æ¯æåç§æ©å±æä»¶åè½å¤æ ·æ§<br /> |
| | | * åå¸å¼æç´¢å¼æ ElasticSearch ä¸çç¥å<br /> |
| | | * åå¸å¼é¾è·¯è¿½è¸ª Apache SkyWalking é¾è·¯è¿½è¸ªãç½æ ¼åæã度éèåãå¯è§å<br /> |
| | | * åå¸å¼æ¥å¿ä¸å¿ ELK ä¸çæçè§£å³æ¹æ¡<br /> |
| | | * åå¸å¼çæ§ PrometheusãGrafana å
¨æ¹ä½æ§è½çæ§<br /> |
| | | * å
¶ä½ä¸ Vue çæ¬ä¸è´<br /> |
| | | </p> |
| | | <p><b>å½åçæ¬:</b> <span>v2.0.0</span></p> |
| | | <p> |
| | | <el-tag type="danger">¥å
è´¹å¼æº</el-tag> |
| | | </p> |
| | | <p> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/RuoYi-Cloud-Plus')">访é®ç äº</el-button> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/RuoYi-Cloud-Plus')">访é®GitHub</el-button> |
| | | <el-button type="primary" icon="Cloudy" plain @click="goTarget('https://javalionli.gitee.io/plus-doc/#/ruoyi-cloud-plus/changlog')" |
| | | >æ´æ°æ¥å¿</el-button |
| | | > |
| | | </p> |
| | | </el-col> |
| | | </el-row> |
| | | <el-divider /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Index" lang="ts"> |
| | |
| | | <template> |
| | | <div class="login"> |
| | | <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form"> |
| | | <h3 class="title">RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»</h3> |
| | | <el-form-item prop="tenantId" v-if="tenantEnabled"> |
| | | <el-select v-model="loginForm.tenantId" filterable placeholder="è¯·éæ©/è¾å
¥å
¬å¸åç§°" style="width: 100%"> |
| | | <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option> |
| | | <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item prop="username"> |
| | | <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="è´¦å·"> |
| | | <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input v-model="loginForm.password" type="password" size="large" auto-complete="off" placeholder="å¯ç " @keyup.enter="handleLogin"> |
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="code" v-if="captchaEnabled"> |
| | | <el-input v-model="loginForm.code" size="large" auto-complete="off" placeholder="éªè¯ç " style="width: 63%" @keyup.enter="handleLogin"> |
| | | <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | <div class="login-code"> |
| | | <img :src="codeUrl" @click="getCode" class="login-code-img" /> |
| | | </div> |
| | | </el-form-item> |
| | | <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">è®°ä½å¯ç </el-checkbox> |
| | | <el-form-item style="width:100%;"> |
| | | <el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleLogin"> |
| | | <span v-if="!loading">ç» å½</span> |
| | | <span v-else>ç» å½ ä¸...</span> |
| | | </el-button> |
| | | <div style="float: right;" v-if="register"> |
| | | <router-link class="link-type" :to="'/register'">ç«å³æ³¨å</router-link> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- åºé¨ --> |
| | | <div class="el-login-footer"> |
| | | <span>Copyright © 2018-2023 ç¯ççç®åLi All Rights Reserved.</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { getCodeImg, getTenantList } from '@/api/login'; |
| | | import Cookies from 'js-cookie'; |
| | |
| | | const router = useRouter(); |
| | | |
| | | const loginForm = ref<LoginData>({ |
| | | tenantId: "000000", |
| | | username: 'admin', |
| | | password: 'admin123', |
| | | rememberMe: false, |
| | | code: '', |
| | | uuid: '' |
| | | tenantId: "000000", |
| | | username: 'admin', |
| | | password: 'admin123', |
| | | rememberMe: false, |
| | | code: '', |
| | | uuid: '' |
| | | }); |
| | | |
| | | const loginRules: FormRules = { |
| | | tenantId: [{ required: true, trigger: "blur", message: "请è¾å
¥æ¨çç§æ·ç¼å·" }], |
| | | username: [{ required: true, trigger: 'blur', message: '请è¾å
¥æ¨çè´¦å·' }], |
| | | password: [{ required: true, trigger: 'blur', message: '请è¾å
¥æ¨çå¯ç ' }], |
| | | code: [{ required: true, trigger: 'change', message: '请è¾å
¥éªè¯ç ' }] |
| | | tenantId: [{ required: true, trigger: "blur", message: "请è¾å
¥æ¨çç§æ·ç¼å·" }], |
| | | username: [{ required: true, trigger: 'blur', message: '请è¾å
¥æ¨çè´¦å·' }], |
| | | password: [{ required: true, trigger: 'blur', message: '请è¾å
¥æ¨çå¯ç ' }], |
| | | code: [{ required: true, trigger: 'change', message: '请è¾å
¥éªè¯ç ' }] |
| | | }; |
| | | |
| | | const codeUrl = ref(''); |
| | |
| | | const tenantList = ref<TenantVO[]>([]); |
| | | |
| | | const handleLogin = () => { |
| | | loginRef.value.validate(async (valid:boolean, fields: any) => { |
| | | if (valid) { |
| | | loading.value = true; |
| | | // å¾éäºéè¦è®°ä½å¯ç è®¾ç½®å¨ cookie ä¸è®¾ç½®è®°ä½ç¨æ·ååå¯ç |
| | | if (loginForm.value.rememberMe) { |
| | | Cookies.set("tenantId", loginForm.value.tenantId, { expires: 30 }); |
| | | Cookies.set('username', loginForm.value.username, { expires: 30 }); |
| | | Cookies.set('password', String(encrypt(loginForm.value.password)), { expires: 30 }); |
| | | Cookies.set('rememberMe', String(loginForm.value.rememberMe), { expires: 30 }); |
| | | } else { |
| | | // å¦åç§»é¤ |
| | | Cookies.remove("tenantId"); |
| | | Cookies.remove('username'); |
| | | Cookies.remove('password'); |
| | | Cookies.remove('rememberMe'); |
| | | } |
| | | // è°ç¨actionçç»å½æ¹æ³ |
| | | // prittier-ignore |
| | | const [err] = await to(userStore.login(loginForm.value)); |
| | | if (!err) { |
| | | await router.push({ path: redirect.value || '/' }); |
| | | } else { |
| | | loading.value = false; |
| | | // éæ°è·åéªè¯ç |
| | | if (captchaEnabled.value) { |
| | | await getCode(); |
| | | loginRef.value.validate(async (valid:boolean, fields: any) => { |
| | | if (valid) { |
| | | loading.value = true; |
| | | // å¾éäºéè¦è®°ä½å¯ç è®¾ç½®å¨ cookie ä¸è®¾ç½®è®°ä½ç¨æ·ååå¯ç |
| | | if (loginForm.value.rememberMe) { |
| | | Cookies.set("tenantId", loginForm.value.tenantId, { expires: 30 }); |
| | | Cookies.set('username', loginForm.value.username, { expires: 30 }); |
| | | Cookies.set('password', String(encrypt(loginForm.value.password)), { expires: 30 }); |
| | | Cookies.set('rememberMe', String(loginForm.value.rememberMe), { expires: 30 }); |
| | | } else { |
| | | // å¦åç§»é¤ |
| | | Cookies.remove("tenantId"); |
| | | Cookies.remove('username'); |
| | | Cookies.remove('password'); |
| | | Cookies.remove('rememberMe'); |
| | | } |
| | | // è°ç¨actionçç»å½æ¹æ³ |
| | | // prittier-ignore |
| | | const [err] = await to(userStore.login(loginForm.value)); |
| | | if (!err) { |
| | | await router.push({ path: redirect.value || '/' }); |
| | | } else { |
| | | loading.value = false; |
| | | // éæ°è·åéªè¯ç |
| | | if (captchaEnabled.value) { |
| | | await getCode(); |
| | | } |
| | | } |
| | | } else { |
| | | console.log('error submit!', fields); |
| | | } |
| | | } |
| | | } else { |
| | | console.log('error submit!', fields); |
| | | } |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * è·åéªè¯ç |
| | | */ |
| | | const getCode = async () => { |
| | | const res = await getCodeImg(); |
| | | const { data } = res; |
| | | captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled; |
| | | if (captchaEnabled.value) { |
| | | codeUrl.value = 'data:image/gif;base64,' + data.img; |
| | | loginForm.value.uuid = data.uuid; |
| | | } |
| | | const res = await getCodeImg(); |
| | | const { data } = res; |
| | | captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled; |
| | | if (captchaEnabled.value) { |
| | | codeUrl.value = 'data:image/gif;base64,' + data.img; |
| | | loginForm.value.uuid = data.uuid; |
| | | } |
| | | }; |
| | | |
| | | const getCookie = () => { |
| | | const tenantId = Cookies.get("tenantId"); |
| | | const username = Cookies.get('username'); |
| | | const password = Cookies.get('password'); |
| | | const rememberMe = Cookies.get('rememberMe'); |
| | | loginForm.value = { |
| | | tenantId: tenantId === undefined ? loginForm.value.tenantId : tenantId, |
| | | username: username === undefined ? loginForm.value.username : username, |
| | | password: password === undefined ? loginForm.value.password : (decrypt(password) as string), |
| | | rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) |
| | | }; |
| | | const tenantId = Cookies.get("tenantId"); |
| | | const username = Cookies.get('username'); |
| | | const password = Cookies.get('password'); |
| | | const rememberMe = Cookies.get('rememberMe'); |
| | | loginForm.value = { |
| | | tenantId: tenantId === undefined ? loginForm.value.tenantId : tenantId, |
| | | username: username === undefined ? loginForm.value.username : username, |
| | | password: password === undefined ? loginForm.value.password : (decrypt(password) as string), |
| | | rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) |
| | | }; |
| | | } |
| | | |
| | | |
| | |
| | | * è·åç§æ·å表 |
| | | */ |
| | | const initTenantList = async () => { |
| | | const { data } = await getTenantList(); |
| | | tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled; |
| | | if (tenantEnabled.value) { |
| | | tenantList.value = data.voList; |
| | | if (tenantList.value != null && tenantList.value.length !== 0) { |
| | | loginForm.value.tenantId = tenantList.value[0].tenantId; |
| | | const { data } = await getTenantList(); |
| | | tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled; |
| | | if (tenantEnabled.value) { |
| | | tenantList.value = data.voList; |
| | | if (tenantList.value != null && tenantList.value.length !== 0) { |
| | | loginForm.value.tenantId = tenantList.value[0].tenantId; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getCode(); |
| | | initTenantList(); |
| | | getCookie(); |
| | | getCode(); |
| | | initTenantList(); |
| | | getCookie(); |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="login"> |
| | | <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form"> |
| | | <h3 class="title">RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»</h3> |
| | | <el-form-item prop="tenantId" v-if="tenantEnabled"> |
| | | <el-select v-model="loginForm.tenantId" filterable placeholder="è¯·éæ©/è¾å
¥å
¬å¸åç§°" style="width: 100%"> |
| | | <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option> |
| | | <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item prop="username"> |
| | | <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="è´¦å·"> |
| | | <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input v-model="loginForm.password" type="password" size="large" auto-complete="off" placeholder="å¯ç " @keyup.enter="handleLogin"> |
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="code" v-if="captchaEnabled"> |
| | | <el-input v-model="loginForm.code" size="large" auto-complete="off" placeholder="éªè¯ç " style="width: 63%" @keyup.enter="handleLogin"> |
| | | <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | <div class="login-code"> |
| | | <img :src="codeUrl" @click="getCode" class="login-code-img" /> |
| | | </div> |
| | | </el-form-item> |
| | | <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">è®°ä½å¯ç </el-checkbox> |
| | | <el-form-item style="width:100%;"> |
| | | <el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleLogin"> |
| | | <span v-if="!loading">ç» å½</span> |
| | | <span v-else>ç» å½ ä¸...</span> |
| | | </el-button> |
| | | <div style="float: right;" v-if="register"> |
| | | <router-link class="link-type" :to="'/register'">ç«å³æ³¨å</router-link> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- åºé¨ --> |
| | | <div class="el-login-footer"> |
| | | <span>Copyright © 2018-2023 ç¯ççç®åLi All Rights Reserved.</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | .login { |
| | |
| | | <template> |
| | | <div> |
| | | <i-frame v-model:src="url"></i-frame> |
| | | </div> |
| | | <div> |
| | | <i-frame v-model:src="url"></i-frame> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | | const getList = async () => { |
| | | proxy?.$modal.loading("æ£å¨å è½½ç¼åçæ§æ°æ®ï¼è¯·ç¨åï¼"); |
| | | const res = await getCache(); |
| | | proxy?.$modal.closeLoading(); |
| | | cache.value = res.data; |
| | | const commandstatsIntance = echarts.init(commandstats.value, "macarons"); |
| | | commandstatsIntance.setOption({ |
| | | tooltip: { |
| | | trigger: "item", |
| | | formatter: "{a} <br/>{b} : {c} ({d}%)" |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "å½ä»¤", |
| | | type: "pie", |
| | | roseType: "radius", |
| | | radius: [15, 95], |
| | | center: ["50%", "38%"], |
| | | data: res.data.commandStats, |
| | | animationEasing: "cubicInOut", |
| | | animationDuration: 1000 |
| | | } |
| | | ] |
| | | }); |
| | | proxy?.$modal.loading("æ£å¨å è½½ç¼åçæ§æ°æ®ï¼è¯·ç¨åï¼"); |
| | | const res = await getCache(); |
| | | proxy?.$modal.closeLoading(); |
| | | cache.value = res.data; |
| | | const commandstatsIntance = echarts.init(commandstats.value, "macarons"); |
| | | commandstatsIntance.setOption({ |
| | | tooltip: { |
| | | trigger: "item", |
| | | formatter: "{a} <br/>{b} : {c} ({d}%)" |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "å½ä»¤", |
| | | type: "pie", |
| | | roseType: "radius", |
| | | radius: [15, 95], |
| | | center: ["50%", "38%"], |
| | | data: res.data.commandStats, |
| | | animationEasing: "cubicInOut", |
| | | animationDuration: 1000 |
| | | } |
| | | ] |
| | | }); |
| | | |
| | | const usedmemoryInstance = echarts.init(usedmemory.value, "macarons"); |
| | | usedmemoryInstance.setOption({ |
| | | tooltip: { |
| | | formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "å³°å¼", |
| | | type: "gauge", |
| | | min: 0, |
| | | max: 1000, |
| | | detail: { |
| | | formatter: cache.value.info.used_memory_human |
| | | }, |
| | | data: [ |
| | | { |
| | | value: parseFloat(cache.value.info.used_memory_human), |
| | | name: "å
åæ¶è" |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | }) |
| | | const usedmemoryInstance = echarts.init(usedmemory.value, "macarons"); |
| | | usedmemoryInstance.setOption({ |
| | | tooltip: { |
| | | formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "å³°å¼", |
| | | type: "gauge", |
| | | min: 0, |
| | | max: 1000, |
| | | detail: { |
| | | formatter: cache.value.info.used_memory_human |
| | | }, |
| | | data: [ |
| | | { |
| | | value: parseFloat(cache.value.info.used_memory_human), |
| | | name: "å
åæ¶è" |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | getList(); |
| | | }) |
| | | </script> |
| | | <template> |
| | | <div class="p-2"> |
| | | <el-row> |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <template #header> |
| | | <Monitor style="width: 1em; height: 1em; vertical-align: middle;" /> |
| | | <span style="vertical-align: middle;">åºæ¬ä¿¡æ¯</span> |
| | | </template> |
| | | <div class="p-2"> |
| | | <el-row> |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <template #header> |
| | | <Monitor style="width: 1em; height: 1em; vertical-align: middle;" /> |
| | | <span style="vertical-align: middle;">åºæ¬ä¿¡æ¯</span> |
| | | </template> |
| | | |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table style="width: 100%"> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">Redisçæ¬</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">è¿è¡æ¨¡å¼</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.redis_mode === "standalone" ? "åæº" : "é群" }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">端å£</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">客æ·ç«¯æ°</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div> |
| | | </td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">è¿è¡æ¶é´(天)</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">使ç¨å
å</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">使ç¨CPU</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">å
åé
ç½®</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div> |
| | | </td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">AOFæ¯å¦å¼å¯</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.aof_enabled === "0" ? "å¦" : "æ¯" }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">RDBæ¯å¦æå</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">Keyæ°é</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.dbSize">{{ cache.dbSize }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">ç½ç»å
¥å£/åºå£</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info"> |
| | | {{ cache.info.instantaneous_input_kbps }}kps/{{ cache.info.instantaneous_output_kbps }}kps |
| | | </div> |
| | | </td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table style="width: 100%"> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">Redisçæ¬</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">è¿è¡æ¨¡å¼</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.redis_mode === "standalone" ? "åæº" : "é群" }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">端å£</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">客æ·ç«¯æ°</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div> |
| | | </td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">è¿è¡æ¶é´(天)</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">使ç¨å
å</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">使ç¨CPU</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">å
åé
ç½®</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div> |
| | | </td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">AOFæ¯å¦å¼å¯</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.aof_enabled === "0" ? "å¦" : "æ¯" }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">RDBæ¯å¦æå</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">Keyæ°é</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.dbSize">{{ cache.dbSize }}</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell">ç½ç»å
¥å£/åºå£</div> |
| | | </td> |
| | | <td class="el-table__cell is-leaf"> |
| | | <div class="cell" v-if="cache.info"> |
| | | {{ cache.info.instantaneous_input_kbps }}kps/{{ cache.info.instantaneous_output_kbps }}kps |
| | | </div> |
| | | </td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <template #header> |
| | | <PieChart style="width: 1em; height: 1em; vertical-align: middle;" /> |
| | | <span style="vertical-align: middle;">å½ä»¤ç»è®¡</span> |
| | | </template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <div ref="commandstats" style="height: 420px" /> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <template #header> |
| | | <PieChart style="width: 1em; height: 1em; vertical-align: middle;" /> |
| | | <span style="vertical-align: middle;">å½ä»¤ç»è®¡</span> |
| | | </template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <div ref="commandstats" style="height: 420px" /> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <template #header> |
| | | <Odometer style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">å
åä¿¡æ¯</span> |
| | | </template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <div ref="usedmemory" style="height: 420px" /> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <template #header> |
| | | <Odometer style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">å
åä¿¡æ¯</span> |
| | | </template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <div ref="usedmemory" style="height: 420px" /> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="ç»å½å°å" prop="ipaddr"> |
| | | <el-input v-model="queryParams.ipaddr" placeholder="请è¾å
¥ç»å½å°å" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input v-model="queryParams.userName" placeholder="请è¾å
¥ç¨æ·åç§°" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="ç»å½ç¶æ" clearable style="width: 240px"> |
| | | <el-option v-for="dict in sys_common_status" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç»å½æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['monitor:logininfor:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" @click="handleClean" v-hasPermi="['monitor:logininfor:remove']">æ¸
空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Unlock" :disabled="single" @click="handleUnlock" v-hasPermi="['monitor:logininfor:unlock']"> |
| | | è§£é |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['monitor:logininfor:export']">导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table |
| | | ref="loginInfoTableRef" |
| | | v-loading="loading" |
| | | :data="loginInfoList" |
| | | @selection-change="handleSelectionChange" |
| | | :default-sort="defaultSort" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="访é®ç¼å·" align="center" prop="infoId" /> |
| | | <el-table-column |
| | | label="ç¨æ·åç§°" |
| | | align="center" |
| | | prop="userName" |
| | | :show-overflow-tooltip="true" |
| | | sortable="custom" |
| | | :sort-orders="['descending', 'ascending']" |
| | | /> |
| | | <el-table-column label="å°å" align="center" prop="ipaddr" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½å°ç¹" align="center" prop="loginLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç³»ç»" align="center" prop="os" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æµè§å¨" align="center" prop="browser" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_common_status" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æè¿°" align="center" prop="msg" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="è®¿é®æ¶é´" align="center" prop="loginTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.loginTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Logininfor" lang="ts"> |
| | | import { list, delLoginInfo, cleanLoginInfo, unlockLoginInfo } from "@/api/monitor/loginInfo"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | |
| | | const loginInfoTableRef = ref(ElTable); |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = ref<LoginInfoQuery>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | ipaddr: '', |
| | | userName: '', |
| | | status: '', |
| | | orderByColumn: defaultSort.value.prop, |
| | | isAsc: defaultSort.value.order |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | ipaddr: '', |
| | | userName: '', |
| | | status: '', |
| | | orderByColumn: defaultSort.value.prop, |
| | | isAsc: defaultSort.value.order |
| | | }); |
| | | |
| | | /** æ¥è¯¢ç»å½æ¥å¿å表 */ |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const res = await list(proxy?.addDateRange(queryParams.value, dateRange.value)); |
| | | loginInfoList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | loading.value = true; |
| | | const res = await list(proxy?.addDateRange(queryParams.value, dateRange.value)); |
| | | loginInfoList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | loginInfoTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order); |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | loginInfoTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order); |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | const handleSelectionChange = (selection: LoginInfoVO[]) => { |
| | | ids.value = selection.map(item => item.infoId); |
| | | multiple.value = !selection.length; |
| | | single.value = selection.length != 1; |
| | | selectName.value = selection.map(item => item.userName); |
| | | ids.value = selection.map(item => item.infoId); |
| | | multiple.value = !selection.length; |
| | | single.value = selection.length != 1; |
| | | selectName.value = selection.map(item => item.userName); |
| | | } |
| | | /** æåºè§¦åäºä»¶ */ |
| | | const handleSortChange = (column: any) => { |
| | | queryParams.value.orderByColumn = column.prop; |
| | | queryParams.value.isAsc = column.order; |
| | | getList(); |
| | | queryParams.value.orderByColumn = column.prop; |
| | | queryParams.value.isAsc = column.order; |
| | | getList(); |
| | | } |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row?: LoginInfoVO) => { |
| | | const infoIds = row?.infoId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤è®¿é®ç¼å·ä¸º"' + infoIds + '"çæ°æ®é¡¹?'); |
| | | await delLoginInfo(infoIds); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | const infoIds = row?.infoId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤è®¿é®ç¼å·ä¸º"' + infoIds + '"çæ°æ®é¡¹?'); |
| | | await delLoginInfo(infoIds); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | /** æ¸
空æé®æä½ */ |
| | | const handleClean = async () => { |
| | | await proxy?.$modal.confirm("æ¯å¦ç¡®è®¤æ¸
空ææç»å½æ¥å¿æ°æ®é¡¹?"); |
| | | await cleanLoginInfo(); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("æ¸
空æå"); |
| | | await proxy?.$modal.confirm("æ¯å¦ç¡®è®¤æ¸
空ææç»å½æ¥å¿æ°æ®é¡¹?"); |
| | | await cleanLoginInfo(); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("æ¸
空æå"); |
| | | } |
| | | /** è§£éæé®æä½ */ |
| | | const handleUnlock = async () => { |
| | | const username = selectName.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤è§£éç¨æ·"' + username + '"æ°æ®é¡¹?'); |
| | | await unlockLoginInfo(username); |
| | | proxy?.$modal.msgSuccess("ç¨æ·" + username + "è§£éæå"); |
| | | const username = selectName.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤è§£éç¨æ·"' + username + '"æ°æ®é¡¹?'); |
| | | await unlockLoginInfo(username); |
| | | proxy?.$modal.msgSuccess("ç¨æ·" + username + "è§£éæå"); |
| | | } |
| | | /** å¯¼åºæé®æä½ */ |
| | | const handleExport = () => { |
| | | proxy?.download("monitor/logininfor/export", { |
| | | ...queryParams.value, |
| | | }, `config_${new Date().getTime()}.xlsx`); |
| | | proxy?.download("monitor/logininfor/export", { |
| | | ...queryParams.value, |
| | | }, `config_${new Date().getTime()}.xlsx`); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | getList(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="ç»å½å°å" prop="ipaddr"> |
| | | <el-input v-model="queryParams.ipaddr" placeholder="请è¾å
¥ç»å½å°å" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input v-model="queryParams.userName" placeholder="请è¾å
¥ç¨æ·åç§°" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="ç»å½ç¶æ" clearable style="width: 240px"> |
| | | <el-option v-for="dict in sys_common_status" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç»å½æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['monitor:logininfor:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" @click="handleClean" v-hasPermi="['monitor:logininfor:remove']">æ¸
空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Unlock" :disabled="single" @click="handleUnlock" v-hasPermi="['monitor:logininfor:unlock']"> |
| | | è§£é |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['monitor:logininfor:export']">导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table |
| | | ref="loginInfoTableRef" |
| | | v-loading="loading" |
| | | :data="loginInfoList" |
| | | @selection-change="handleSelectionChange" |
| | | :default-sort="defaultSort" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="访é®ç¼å·" align="center" prop="infoId" /> |
| | | <el-table-column |
| | | label="ç¨æ·åç§°" |
| | | align="center" |
| | | prop="userName" |
| | | :show-overflow-tooltip="true" |
| | | sortable="custom" |
| | | :sort-orders="['descending', 'ascending']" |
| | | /> |
| | | <el-table-column label="å°å" align="center" prop="ipaddr" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½å°ç¹" align="center" prop="loginLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç³»ç»" align="center" prop="os" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æµè§å¨" align="center" prop="browser" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_common_status" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æè¿°" align="center" prop="msg" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="è®¿é®æ¶é´" align="center" prop="loginTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.loginTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <div class="search"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true"> |
| | | <el-form-item label="ç»å½å°å" prop="ipaddr"> |
| | | <el-input v-model="queryParams.ipaddr" placeholder="请è¾å
¥ç»å½å°å" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input v-model="queryParams.userName" placeholder="请è¾å
¥ç¨æ·åç§°" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <div class="panel"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="onlineList.slice((queryParams.pageNum - 1) * queryParams.pageSize, queryParams.pageNum * queryParams.pageSize)" |
| | | style="width: 100%;" |
| | | > |
| | | <el-table-column label="åºå·" width="50" type="index" align="center"> |
| | | <template #default="scope"> |
| | | <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ä¼è¯ç¼å·" align="center" prop="tokenId" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½åç§°" align="center" prop="userName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æå±é¨é¨" align="center" prop="deptName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="主æº" align="center" prop="ipaddr" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½å°ç¹" align="center" prop="loginLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç³»ç»" align="center" prop="os" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æµè§å¨" align="center" prop="browser" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½æ¶é´" align="center" prop="loginTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.loginTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="强é" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleForceLogout(scope.row)" v-hasPermi="['monitor:online:forceLogout']"> |
| | | </el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Online" lang="ts"> |
| | | import { forceLogout, list as initData } from "@/api/monitor/online"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | |
| | | const queryFormRef = ref(ElForm); |
| | | |
| | | const queryParams = ref<OnlineQuery>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | ipaddr: '', |
| | | userName: '' |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | ipaddr: '', |
| | | userName: '' |
| | | }); |
| | | |
| | | /** æ¥è¯¢ç»å½æ¥å¿å表 */ |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const res = await initData(queryParams.value); |
| | | onlineList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | loading.value = true; |
| | | const res = await initData(queryParams.value); |
| | | onlineList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | handleQuery(); |
| | | queryFormRef.value.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** 强éæé®æä½ */ |
| | | const handleForceLogout = async (row: OnlineVO) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å¼ºéå称为"' + row.userName + '"çç¨æ·?'); |
| | | await forceLogout(row.tokenId); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å¼ºéå称为"' + row.userName + '"çç¨æ·?'); |
| | | await forceLogout(row.tokenId); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | getList(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="p-2"> |
| | | <div class="search"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true"> |
| | | <el-form-item label="ç»å½å°å" prop="ipaddr"> |
| | | <el-input v-model="queryParams.ipaddr" placeholder="请è¾å
¥ç»å½å°å" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input v-model="queryParams.userName" placeholder="请è¾å
¥ç¨æ·åç§°" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | <div class="panel"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="onlineList.slice((queryParams.pageNum - 1) * queryParams.pageSize, queryParams.pageNum * queryParams.pageSize)" |
| | | style="width: 100%;" |
| | | > |
| | | <el-table-column label="åºå·" width="50" type="index" align="center"> |
| | | <template #default="scope"> |
| | | <span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ä¼è¯ç¼å·" align="center" prop="tokenId" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½åç§°" align="center" prop="userName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æå±é¨é¨" align="center" prop="deptName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="主æº" align="center" prop="ipaddr" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½å°ç¹" align="center" prop="loginLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç³»ç»" align="center" prop="os" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æµè§å¨" align="center" prop="browser" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½æ¶é´" align="center" prop="loginTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.loginTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="强é" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleForceLogout(scope.row)" v-hasPermi="['monitor:online:forceLogout']"> |
| | | </el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="ç³»ç»æ¨¡å" prop="title"> |
| | | <el-input v-model="queryParams.title" placeholder="请è¾å
¥ç³»ç»æ¨¡å" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æä½äººå" prop="operName"> |
| | | <el-input v-model="queryParams.operName" placeholder="请è¾å
¥æä½äººå" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç±»å" prop="businessType"> |
| | | <el-select v-model="queryParams.businessType" placeholder="æä½ç±»å" clearable style="width: 240px"> |
| | | <el-option v-for="dict in sys_oper_type" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="æä½ç¶æ" clearable style="width: 240px"> |
| | | <el-option v-for="dict in sys_common_status" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æä½æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['monitor:operlog:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="WarnTriangleFilled" @click="handleClean" v-hasPermi="['monitor:operlog:remove']">æ¸
空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['monitor:operlog:export']">导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table |
| | | ref="operLogTableRef" |
| | | v-loading="loading" |
| | | :data="operlogList" |
| | | @selection-change="handleSelectionChange" |
| | | :default-sort="defaultSort" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="æ¥å¿ç¼å·" align="center" prop="operId" /> |
| | | <el-table-column label="ç³»ç»æ¨¡å" align="center" prop="title" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç±»å" align="center" prop="businessType"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_oper_type" :value="scope.row.businessType" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æä½äººå" |
| | | align="center" |
| | | width="110" |
| | | prop="operName" |
| | | :show-overflow-tooltip="true" |
| | | sortable="custom" |
| | | :sort-orders="['descending', 'ascending']" |
| | | /> |
| | | <el-table-column label="主æº" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_common_status" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½æ¥æ" align="center" prop="operTime" width="180" sortable="custom" :sort-orders="['descending', 'ascending']"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.operTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æ¶èæ¶é´" |
| | | align="center" |
| | | prop="costTime" |
| | | width="110" |
| | | :show-overflow-tooltip="true" |
| | | sortable="custom" |
| | | :sort-orders="['descending', 'ascending']" |
| | | > |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.costTime }}毫ç§</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" fixed="right" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="详ç»" placement="top"> |
| | | <el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['monitor:operlog:query']"> </el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | <!-- æä½æ¥å¿è¯¦ç» --> |
| | | <el-dialog title="æä½æ¥å¿è¯¦ç»" v-model="dialog.visible" width="700px" append-to-body> |
| | | <el-form :model="form" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æä½æ¨¡åï¼">{{ form.title }} / {{ typeFormat(form) }}</el-form-item> |
| | | <el-form-item label="ç»å½ä¿¡æ¯ï¼">{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="请æ±å°åï¼">{{ form.operUrl }}</el-form-item> |
| | | <el-form-item label="è¯·æ±æ¹å¼ï¼">{{ form.requestMethod }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æä½æ¹æ³ï¼">{{ form.method }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="请æ±åæ°ï¼">{{form.operParam}}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è¿ååæ°ï¼">{{ form.jsonResult }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="æä½ç¶æï¼"> |
| | | <div v-if="form.status === 0">æ£å¸¸</div> |
| | | <div v-else-if="form.status === 1">失败</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æ¶èæ¶é´ï¼">{{ form.costTime }}毫ç§</el-form-item> |
| | | </el-col> |
| | | <el-col :span="10"> |
| | | <el-form-item label="æä½æ¶é´ï¼">{{ parseTime(form.operTime) }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å¼å¸¸ä¿¡æ¯ï¼" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="dialog.visible = false">å
³ é</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Operlog" lang="ts"> |
| | | import { list, delOperlog, cleanOperlog } from '@/api/monitor/operlog'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | |
| | | const queryFormRef = ref(ElForm); |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: '' |
| | | visible: false, |
| | | title: '' |
| | | }); |
| | | |
| | | |
| | | const data = reactive<PageData<OperLogForm, OperLogQuery>>({ |
| | | form: { |
| | | operId: undefined, |
| | | tenantId: undefined, |
| | | title: '', |
| | | businessType: 0, |
| | | businessTypes: undefined, |
| | | method: '', |
| | | requestMethod: '', |
| | | operatorType: 0, |
| | | operName: '', |
| | | deptName: '', |
| | | operUrl: '', |
| | | operIp: '', |
| | | operLocation: '', |
| | | operParam: '', |
| | | jsonResult: '', |
| | | status: 0, |
| | | errorMsg: '', |
| | | operTime: '', |
| | | costTime: 0 |
| | | }, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | title: '', |
| | | operName: '', |
| | | businessType: '', |
| | | status: '', |
| | | orderByColumn: defaultSort.value.prop, |
| | | isAsc: defaultSort.value.order |
| | | }, |
| | | rules: {} |
| | | form: { |
| | | operId: undefined, |
| | | tenantId: undefined, |
| | | title: '', |
| | | businessType: 0, |
| | | businessTypes: undefined, |
| | | method: '', |
| | | requestMethod: '', |
| | | operatorType: 0, |
| | | operName: '', |
| | | deptName: '', |
| | | operUrl: '', |
| | | operIp: '', |
| | | operLocation: '', |
| | | operParam: '', |
| | | jsonResult: '', |
| | | status: 0, |
| | | errorMsg: '', |
| | | operTime: '', |
| | | costTime: 0 |
| | | }, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | title: '', |
| | | operName: '', |
| | | businessType: '', |
| | | status: '', |
| | | orderByColumn: defaultSort.value.prop, |
| | | isAsc: defaultSort.value.order |
| | | }, |
| | | rules: {} |
| | | }); |
| | | |
| | | const { queryParams, form } = toRefs(data); |
| | | |
| | | /** æ¥è¯¢ç»å½æ¥å¿ */ |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const res = await list(proxy?.addDateRange(queryParams.value, dateRange.value)); |
| | | operlogList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | loading.value = true; |
| | | const res = await list(proxy?.addDateRange(queryParams.value, dateRange.value)); |
| | | operlogList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | } |
| | | /** æä½æ¥å¿ç±»ååå
¸ç¿»è¯ */ |
| | | const typeFormat = (row: OperLogForm) => { |
| | | return proxy?.selectDictLabel(sys_oper_type.value, row.businessType); |
| | | return proxy?.selectDictLabel(sys_oper_type.value, row.businessType); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | operLogTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order); |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | operLogTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order); |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | const handleSelectionChange = (selection: OperLogVO[]) => { |
| | | ids.value = selection.map(item => item.operId); |
| | | multiple.value = !selection.length; |
| | | ids.value = selection.map(item => item.operId); |
| | | multiple.value = !selection.length; |
| | | } |
| | | /** æåºè§¦åäºä»¶ */ |
| | | const handleSortChange = (column: any) => { |
| | | queryParams.value.orderByColumn = column.prop; |
| | | queryParams.value.isAsc = column.order; |
| | | getList(); |
| | | queryParams.value.orderByColumn = column.prop; |
| | | queryParams.value.isAsc = column.order; |
| | | getList(); |
| | | } |
| | | /** è¯¦ç»æé®æä½ */ |
| | | const handleView = (row: OperLogVO) => { |
| | | dialog.visible = true; |
| | | form.value = row; |
| | | dialog.visible = true; |
| | | form.value = row; |
| | | } |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row?: OperLogVO) => { |
| | | const operIds = row?.operId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿¥å¿ç¼å·ä¸º"' + operIds + '"çæ°æ®é¡¹?'); |
| | | await delOperlog(operIds); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | const operIds = row?.operId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿¥å¿ç¼å·ä¸º"' + operIds + '"çæ°æ®é¡¹?'); |
| | | await delOperlog(operIds); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | |
| | | /** æ¸
空æé®æä½ */ |
| | | const handleClean = async () => { |
| | | await proxy?.$modal.confirm("æ¯å¦ç¡®è®¤æ¸
ç©ºæææä½æ¥å¿æ°æ®é¡¹?"); |
| | | await cleanOperlog(); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("æ¸
空æå"); |
| | | await proxy?.$modal.confirm("æ¯å¦ç¡®è®¤æ¸
ç©ºæææä½æ¥å¿æ°æ®é¡¹?"); |
| | | await cleanOperlog(); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("æ¸
空æå"); |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | const handleExport = () => { |
| | | proxy?.download("monitor/operlog/export", { |
| | | ...queryParams.value, |
| | | }, `config_${new Date().getTime()}.xlsx`); |
| | | proxy?.download("monitor/operlog/export", { |
| | | ...queryParams.value, |
| | | }, `config_${new Date().getTime()}.xlsx`); |
| | | } |
| | | onMounted(() => { |
| | | getList(); |
| | | getList(); |
| | | }) |
| | | </script> |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="ç³»ç»æ¨¡å" prop="title"> |
| | | <el-input v-model="queryParams.title" placeholder="请è¾å
¥ç³»ç»æ¨¡å" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æä½äººå" prop="operName"> |
| | | <el-input v-model="queryParams.operName" placeholder="请è¾å
¥æä½äººå" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç±»å" prop="businessType"> |
| | | <el-select v-model="queryParams.businessType" placeholder="æä½ç±»å" clearable style="width: 240px"> |
| | | <el-option v-for="dict in sys_oper_type" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="æä½ç¶æ" clearable style="width: 240px"> |
| | | <el-option v-for="dict in sys_common_status" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æä½æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['monitor:operlog:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="WarnTriangleFilled" @click="handleClean" v-hasPermi="['monitor:operlog:remove']">æ¸
空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['monitor:operlog:export']">导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table |
| | | ref="operLogTableRef" |
| | | v-loading="loading" |
| | | :data="operlogList" |
| | | @selection-change="handleSelectionChange" |
| | | :default-sort="defaultSort" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="æ¥å¿ç¼å·" align="center" prop="operId" /> |
| | | <el-table-column label="ç³»ç»æ¨¡å" align="center" prop="title" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç±»å" align="center" prop="businessType"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_oper_type" :value="scope.row.businessType" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æä½äººå" |
| | | align="center" |
| | | width="110" |
| | | prop="operName" |
| | | :show-overflow-tooltip="true" |
| | | sortable="custom" |
| | | :sort-orders="['descending', 'ascending']" |
| | | /> |
| | | <el-table-column label="主æº" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_common_status" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½æ¥æ" align="center" prop="operTime" width="180" sortable="custom" :sort-orders="['descending', 'ascending']"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.operTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æ¶èæ¶é´" |
| | | align="center" |
| | | prop="costTime" |
| | | width="110" |
| | | :show-overflow-tooltip="true" |
| | | sortable="custom" |
| | | :sort-orders="['descending', 'ascending']" |
| | | > |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.costTime }}毫ç§</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" fixed="right" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="详ç»" placement="top"> |
| | | <el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['monitor:operlog:query']"> </el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | <!-- æä½æ¥å¿è¯¦ç» --> |
| | | <el-dialog title="æä½æ¥å¿è¯¦ç»" v-model="dialog.visible" width="700px" append-to-body> |
| | | <el-form :model="form" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æä½æ¨¡åï¼">{{ form.title }} / {{ typeFormat(form) }}</el-form-item> |
| | | <el-form-item label="ç»å½ä¿¡æ¯ï¼">{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="请æ±å°åï¼">{{ form.operUrl }}</el-form-item> |
| | | <el-form-item label="è¯·æ±æ¹å¼ï¼">{{ form.requestMethod }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æä½æ¹æ³ï¼">{{ form.method }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="请æ±åæ°ï¼">{{form.operParam}}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è¿ååæ°ï¼">{{ form.jsonResult }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="æä½ç¶æï¼"> |
| | | <div v-if="form.status === 0">æ£å¸¸</div> |
| | | <div v-else-if="form.status === 1">失败</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æ¶èæ¶é´ï¼">{{ form.costTime }}毫ç§</el-form-item> |
| | | </el-col> |
| | | <el-col :span="10"> |
| | | <el-form-item label="æä½æ¶é´ï¼">{{ parseTime(form.operTime) }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å¼å¸¸ä¿¡æ¯ï¼" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="dialog.visible = false">å
³ é</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div> |
| | | <i-frame v-model:src="url"></i-frame> |
| | | </div> |
| | | <div> |
| | | <i-frame v-model:src="url"></i-frame> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | |
| | | <template> |
| | | <div></div> |
| | | <div></div> |
| | | </template> |
| | | |
| | | <script setup> |
| | |
| | | <template> |
| | | <div class="register"> |
| | | <el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form"> |
| | | <h3 class="title">RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»</h3> |
| | | <el-form-item prop="tenantId" v-if="tenantEnabled"> |
| | | <el-select v-model="registerForm.tenantId" filterable placeholder="è¯·éæ©/è¾å
¥å
¬å¸åç§°" style="width: 100%"> |
| | | <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option> |
| | | <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item prop="username"> |
| | | <el-input v-model="registerForm.username" type="text" size="large" auto-complete="off" placeholder="è´¦å·"> |
| | | <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input v-model="registerForm.password" type="password" size="large" auto-complete="off" placeholder="å¯ç " @keyup.enter="handleRegister"> |
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="confirmPassword"> |
| | | <el-input |
| | | v-model="registerForm.confirmPassword" |
| | | type="password" |
| | | size="large" |
| | | auto-complete="off" |
| | | placeholder="确认å¯ç " |
| | | @keyup.enter="handleRegister" |
| | | > |
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="code" v-if="captchaEnabled"> |
| | | <el-input size="large" v-model="registerForm.code" auto-complete="off" placeholder="éªè¯ç " style="width: 63%" @keyup.enter="handleRegister"> |
| | | <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | <div class="register-code"> |
| | | <img :src="codeUrl" @click="getCode" class="register-code-img" /> |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item style="width:100%;"> |
| | | <el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleRegister"> |
| | | <span v-if="!loading">注 å</span> |
| | | <span v-else>注 å ä¸...</span> |
| | | </el-button> |
| | | <div style="float: right;"> |
| | | <router-link class="link-type" :to="'/login'">使ç¨å·²æè´¦æ·ç»å½</router-link> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- åºé¨ --> |
| | | <div class="el-register-footer"> |
| | | <span>Copyright © 2018-2023 ç¯ççç®åLi All Rights Reserved.</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { getCodeImg, register, getTenantList } from '@/api/login'; |
| | | import { RegisterForm, TenantVO } from '@/api/types'; |
| | |
| | | const router = useRouter(); |
| | | |
| | | const registerForm = ref<RegisterForm>({ |
| | | tenantId: "", |
| | | username: "", |
| | | password: "", |
| | | confirmPassword: "", |
| | | code: "", |
| | | uuid: "", |
| | | userType: "sys_user" |
| | | tenantId: "", |
| | | username: "", |
| | | password: "", |
| | | confirmPassword: "", |
| | | code: "", |
| | | uuid: "", |
| | | userType: "sys_user" |
| | | }); |
| | | |
| | | // ç§æ·å¼å
³ |
| | |
| | | |
| | | |
| | | const equalToPassword = (rule: any, value: string, callback: any) => { |
| | | if (registerForm.value.password !== value) { |
| | | callback(new Error("两次è¾å
¥çå¯ç ä¸ä¸è´")); |
| | | } else { |
| | | callback(); |
| | | } |
| | | if (registerForm.value.password !== value) { |
| | | callback(new Error("两次è¾å
¥çå¯ç ä¸ä¸è´")); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }; |
| | | |
| | | const registerRules: FormRules = { |
| | | tenantId: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥æ¨çç§æ·ç¼å·" } |
| | | ], |
| | | username: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥æ¨çè´¦å·" }, |
| | | { min: 2, max: 20, message: "ç¨æ·è´¦å·é¿åº¦å¿
é¡»ä»äº 2 å 20 ä¹é´", trigger: "blur" } |
| | | ], |
| | | password: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥æ¨çå¯ç " }, |
| | | { min: 5, max: 20, message: "ç¨æ·å¯ç é¿åº¦å¿
é¡»ä»äº 5 å 20 ä¹é´", trigger: "blur" } |
| | | ], |
| | | confirmPassword: [ |
| | | { required: true, trigger: "blur", message: "è¯·åæ¬¡è¾å
¥æ¨çå¯ç " }, |
| | | { required: true, validator: equalToPassword, trigger: "blur" } |
| | | ], |
| | | code: [{ required: true, trigger: "change", message: "请è¾å
¥éªè¯ç " }] |
| | | tenantId: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥æ¨çç§æ·ç¼å·" } |
| | | ], |
| | | username: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥æ¨çè´¦å·" }, |
| | | { min: 2, max: 20, message: "ç¨æ·è´¦å·é¿åº¦å¿
é¡»ä»äº 2 å 20 ä¹é´", trigger: "blur" } |
| | | ], |
| | | password: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥æ¨çå¯ç " }, |
| | | { min: 5, max: 20, message: "ç¨æ·å¯ç é¿åº¦å¿
é¡»ä»äº 5 å 20 ä¹é´", trigger: "blur" } |
| | | ], |
| | | confirmPassword: [ |
| | | { required: true, trigger: "blur", message: "è¯·åæ¬¡è¾å
¥æ¨çå¯ç " }, |
| | | { required: true, validator: equalToPassword, trigger: "blur" } |
| | | ], |
| | | code: [{ required: true, trigger: "change", message: "请è¾å
¥éªè¯ç " }] |
| | | }; |
| | | const codeUrl = ref(""); |
| | | const loading = ref(false); |
| | |
| | | const tenantList = ref<TenantVO[]>([]); |
| | | |
| | | const handleRegister = () => { |
| | | registerRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | loading.value = true; |
| | | const [err] = await to(register(registerForm.value)); |
| | | if (!err) { |
| | | const username = registerForm.value.username; |
| | | await ElMessageBox.alert("<font color='red'>æåä½ ï¼æ¨çè´¦å· " + username + " 注åæåï¼</font>", "ç³»ç»æç¤º", { |
| | | dangerouslyUseHTMLString: true, |
| | | type: "success", |
| | | }); |
| | | await router.push("/login"); |
| | | } else { |
| | | loading.value = false; |
| | | if (captchaEnabled) { |
| | | getCode(); |
| | | registerRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | loading.value = true; |
| | | const [err] = await to(register(registerForm.value)); |
| | | if (!err) { |
| | | const username = registerForm.value.username; |
| | | await ElMessageBox.alert("<font color='red'>æåä½ ï¼æ¨çè´¦å· " + username + " 注åæåï¼</font>", "ç³»ç»æç¤º", { |
| | | dangerouslyUseHTMLString: true, |
| | | type: "success", |
| | | }); |
| | | await router.push("/login"); |
| | | } else { |
| | | loading.value = false; |
| | | if (captchaEnabled) { |
| | | getCode(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | const getCode = async () => { |
| | | const { data } = await getCodeImg(); |
| | | captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled; |
| | | const { data } = await getCodeImg(); |
| | | captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled; |
| | | if (captchaEnabled.value) { |
| | | codeUrl.value = "data:image/gif;base64," + data.img; |
| | | registerForm.value.uuid = data.uuid; |
| | | codeUrl.value = "data:image/gif;base64," + data.img; |
| | | registerForm.value.uuid = data.uuid; |
| | | } |
| | | } |
| | | |
| | | const initTenantList = async () => { |
| | | const { data } = await getTenantList(); |
| | | const { data } = await getTenantList(); |
| | | tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled; |
| | | if (tenantEnabled.value) { |
| | | tenantList.value = data.voList; |
| | | if (tenantList.value != null && tenantList.value.length !== 0) { |
| | | registerForm.value.tenantId = tenantList.value[0].tenantId; |
| | | } |
| | | tenantList.value = data.voList; |
| | | if (tenantList.value != null && tenantList.value.length !== 0) { |
| | | registerForm.value.tenantId = tenantList.value[0].tenantId; |
| | | } |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getCode(); |
| | | initTenantList(); |
| | | getCode(); |
| | | initTenantList(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="register"> |
| | | <el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form"> |
| | | <h3 class="title">RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»</h3> |
| | | <el-form-item prop="tenantId" v-if="tenantEnabled"> |
| | | <el-select v-model="registerForm.tenantId" filterable placeholder="è¯·éæ©/è¾å
¥å
¬å¸åç§°" style="width: 100%"> |
| | | <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option> |
| | | <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item prop="username"> |
| | | <el-input v-model="registerForm.username" type="text" size="large" auto-complete="off" placeholder="è´¦å·"> |
| | | <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input v-model="registerForm.password" type="password" size="large" auto-complete="off" placeholder="å¯ç " @keyup.enter="handleRegister"> |
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="confirmPassword"> |
| | | <el-input |
| | | v-model="registerForm.confirmPassword" |
| | | type="password" |
| | | size="large" |
| | | auto-complete="off" |
| | | placeholder="确认å¯ç " |
| | | @keyup.enter="handleRegister" |
| | | > |
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="code" v-if="captchaEnabled"> |
| | | <el-input size="large" v-model="registerForm.code" auto-complete="off" placeholder="éªè¯ç " style="width: 63%" @keyup.enter="handleRegister"> |
| | | <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | <div class="register-code"> |
| | | <img :src="codeUrl" @click="getCode" class="register-code-img" /> |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item style="width:100%;"> |
| | | <el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleRegister"> |
| | | <span v-if="!loading">注 å</span> |
| | | <span v-else>注 å ä¸...</span> |
| | | </el-button> |
| | | <div style="float: right;"> |
| | | <router-link class="link-type" :to="'/login'">使ç¨å·²æè´¦æ·ç»å½</router-link> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- åºé¨ --> |
| | | <div class="el-register-footer"> |
| | | <span>Copyright © 2018-2023 ç¯ççç®åLi All Rights Reserved.</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss" scoped> |
| | | .register { |
| | |
| | | /** æ¥è¯¢åæ°å表 */ |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const res = await listConfig(proxy?.addDateRange(queryParams.value, dateRange.value)); |
| | | configList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | const res = await listConfig(proxy?.addDateRange(queryParams.value, dateRange.value)); |
| | | configList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | } |
| | | /** åæ¶æé® */ |
| | | const cancel = () => { |
| | |
| | | } |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = {...initFormData}; |
| | | form.value = {...initFormData}; |
| | | configFormRef.value.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | } |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | const handleUpdate = (row?: ConfigVO) => { |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹åæ°"; |
| | | const configId = row?.configId || ids.value[0]; |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹åæ°"; |
| | | const configId = row?.configId || ids.value[0]; |
| | | nextTick(async () => { |
| | | reset(); |
| | | const res = await getConfig(configId); |
| | | form.value = res.data; |
| | | }) |
| | | reset(); |
| | | const res = await getConfig(configId); |
| | | form.value = res.data; |
| | | }) |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | configFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.configId ? await updateConfig(form.value) : await addConfig(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | if (valid) { |
| | | form.value.configId ? await updateConfig(form.value) : await addConfig(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | } |
| | | }); |
| | | } |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row?: ConfigVO) => { |
| | | const configIds = row?.configId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åæ°ç¼å·ä¸º"' + configIds + '"çæ°æ®é¡¹ï¼'); |
| | | await delConfig(configIds); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åæ°ç¼å·ä¸º"' + configIds + '"çæ°æ®é¡¹ï¼'); |
| | | await delConfig(configIds); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | /** å¯¼åºæé®æä½ */ |
| | | const handleExport = () => { |
| | |
| | | } |
| | | /** å·æ°ç¼åæé®æä½ */ |
| | | const handleRefreshCache = async () => { |
| | | await refreshCache(); |
| | | proxy?.$modal.msgSuccess("å·æ°ç¼åæå"); |
| | | await refreshCache(); |
| | | proxy?.$modal.msgSuccess("å·æ°ç¼åæå"); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | getList(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="åæ°åç§°" prop="configName"> |
| | | <el-input v-model="queryParams.configName" placeholder="请è¾å
¥åæ°åç§°" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°é®å" prop="configKey"> |
| | | <el-input v-model="queryParams.configKey" placeholder="请è¾å
¥åæ°é®å" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç³»ç»å
ç½®" prop="configType"> |
| | | <el-select v-model="queryParams.configType" placeholder="ç³»ç»å
ç½®" clearable> |
| | | <el-option v-for="dict in sys_yes_no" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" style="width: 308px;"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:config:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:config:edit']"> |
| | | ä¿®æ¹ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:config:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:config:export']">导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Refresh" @click="handleRefreshCache" v-hasPermi="['system:config:remove']">å·æ°ç¼å</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="åæ°åç§°" prop="configName"> |
| | | <el-input v-model="queryParams.configName" placeholder="请è¾å
¥åæ°åç§°" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°é®å" prop="configKey"> |
| | | <el-input v-model="queryParams.configKey" placeholder="请è¾å
¥åæ°é®å" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç³»ç»å
ç½®" prop="configType"> |
| | | <el-select v-model="queryParams.configType" placeholder="ç³»ç»å
ç½®" clearable> |
| | | <el-option v-for="dict in sys_yes_no" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" style="width: 308px;"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:config:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:config:edit']"> |
| | | ä¿®æ¹ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:config:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:config:export']">导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Refresh" @click="handleRefreshCache" v-hasPermi="['system:config:remove']">å·æ°ç¼å</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="忰䏻é®" align="center" prop="configId" v-if="false" /> |
| | | <el-table-column label="åæ°åç§°" align="center" prop="configName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="åæ°é®å" align="center" prop="configKey" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="åæ°é®å¼" align="center" prop="configValue" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç³»ç»å
ç½®" align="center" prop="configType"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_yes_no" :value="scope.row.configType" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="150" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:config:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:config:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="忰䏻é®" align="center" prop="configId" v-if="false" /> |
| | | <el-table-column label="åæ°åç§°" align="center" prop="configName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="åæ°é®å" align="center" prop="configKey" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="åæ°é®å¼" align="center" prop="configValue" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç³»ç»å
ç½®" align="center" prop="configType"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_yes_no" :value="scope.row.configType" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="150" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:config:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:config:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | |
| | | <!-- æ·»å æä¿®æ¹åæ°é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="configFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="åæ°åç§°" prop="configName"> |
| | | <el-input v-model="form.configName" placeholder="请è¾å
¥åæ°åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°é®å" prop="configKey"> |
| | | <el-input v-model="form.configKey" placeholder="请è¾å
¥åæ°é®å" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°é®å¼" prop="configValue"> |
| | | <el-input v-model="form.configValue" placeholder="请è¾å
¥åæ°é®å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç³»ç»å
ç½®" prop="configType"> |
| | | <el-radio-group v-model="form.configType"> |
| | | <el-radio v-for="dict in sys_yes_no" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | <!-- æ·»å æä¿®æ¹åæ°é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="configFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="åæ°åç§°" prop="configName"> |
| | | <el-input v-model="form.configName" placeholder="请è¾å
¥åæ°åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°é®å" prop="configKey"> |
| | | <el-input v-model="form.configKey" placeholder="请è¾å
¥åæ°é®å" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°é®å¼" prop="configValue"> |
| | | <el-input v-model="form.configValue" placeholder="请è¾å
¥åæ°é®å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç³»ç»å
ç½®" prop="configType"> |
| | | <el-radio-group v-model="form.configType"> |
| | | <el-radio v-for="dict in sys_yes_no" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px"> |
| | | <el-form-item label="èååç§°" prop="menuName"> |
| | | <el-input v-model="queryParams.deptName" placeholder="请è¾å
¥é¨é¨åç§°" clearable @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="é¨é¨ç¶æ" clearable> |
| | | <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['system:dept:add']">æ°å¢ </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">å±å¼/æå </el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="deptList" |
| | | row-key="deptId" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | ref="deptTableRef" |
| | | :default-expand-all="isExpandAll" |
| | | > |
| | | <el-table-column prop="deptName" label="é¨é¨åç§°" width="260"></el-table-column> |
| | | <el-table-column prop="orderNum" align="center" label="æåº" width="200"></el-table-column> |
| | | <el-table-column prop="status" align="center" label="ç¶æ" width="100"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="200"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" align="center" label="æä½"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']" /> |
| | | </el-tooltip> |
| | | <el-tooltip content="æ°å¢" placement="top"> |
| | | <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']" /> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dept:remove']" /> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" destroy-on-close append-to-bod width="600px"> |
| | | <el-form ref="deptFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-row> |
| | | <el-col :span="24" v-if="form.parentId !== 0"> |
| | | <el-form-item label="ä¸çº§é¨é¨" prop="parentId"> |
| | | <el-tree-select |
| | | v-model="form.parentId" |
| | | :data="deptOptions" |
| | | :props="{ value: 'deptId', label: 'deptName', children: 'children' }" |
| | | value-key="deptId" |
| | | placeholder="éæ©ä¸çº§é¨é¨" |
| | | check-strictly |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¨é¨åç§°" prop="deptName"> |
| | | <el-input v-model="form.deptName" placeholder="请è¾å
¥é¨é¨åç§°" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¾ç¤ºæåº" prop="orderNum"> |
| | | <el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è´è´£äºº" prop="leader"> |
| | | <el-input v-model="form.leader" placeholder="请è¾å
¥è´è´£äºº" maxlength="20" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯" prop="phone"> |
| | | <el-input v-model="form.phone" placeholder="请è¾å
¥èç³»çµè¯" maxlength="11" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é®ç®±" prop="email"> |
| | | <el-input v-model="form.email" placeholder="请è¾å
¥é®ç®±" maxlength="50" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¨é¨ç¶æ"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label |
| | | }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Dept" lang="ts"> |
| | | import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept" |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { DeptForm, DeptQuery, DeptVO } from "@/api/system/dept/types"; |
| | | |
| | | interface DeptOptionsType { |
| | | deptId: number | string; |
| | | deptName: string; |
| | | children: DeptOptionsType[]; |
| | | deptId: number | string; |
| | | deptName: string; |
| | | children: DeptOptionsType[]; |
| | | |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: '' |
| | | visible: false, |
| | | title: '' |
| | | }); |
| | | |
| | | const deptTableRef = ref(ElTable); |
| | |
| | | const deptFormRef = ref(ElForm); |
| | | |
| | | const initFormData: DeptForm = { |
| | | deptId: undefined, |
| | | parentId: undefined, |
| | | deptName: undefined, |
| | | orderNum: 0, |
| | | leader: undefined, |
| | | phone: undefined, |
| | | email: undefined, |
| | | status: "0" |
| | | deptId: undefined, |
| | | parentId: undefined, |
| | | deptName: undefined, |
| | | orderNum: 0, |
| | | leader: undefined, |
| | | phone: undefined, |
| | | email: undefined, |
| | | status: "0" |
| | | } |
| | | const data = reactive<PageData<DeptForm, DeptQuery>>({ |
| | | form: {...initFormData}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | deptName: undefined, |
| | | status: undefined |
| | | }, |
| | | rules: { |
| | | parentId: [{ required: true, message: "ä¸çº§é¨é¨ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | deptName: [{ required: true, message: "é¨é¨åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | orderNum: [{ required: true, message: "æ¾ç¤ºæåºä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | email: [{ type: "email", message: "请è¾å
¥æ£ç¡®çé®ç®±å°å", trigger: ["blur", "change"] }], |
| | | phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请è¾å
¥æ£ç¡®çææºå·ç ", trigger: "blur" }] |
| | | }, |
| | | form: {...initFormData}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | deptName: undefined, |
| | | status: undefined |
| | | }, |
| | | rules: { |
| | | parentId: [{ required: true, message: "ä¸çº§é¨é¨ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | deptName: [{ required: true, message: "é¨é¨åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | orderNum: [{ required: true, message: "æ¾ç¤ºæåºä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | email: [{ type: "email", message: "请è¾å
¥æ£ç¡®çé®ç®±å°å", trigger: ["blur", "change"] }], |
| | | phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请è¾å
¥æ£ç¡®çææºå·ç ", trigger: "blur" }] |
| | | }, |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs<PageData<DeptForm, DeptQuery>>(data) |
| | | |
| | | /** æ¥è¯¢èåå表 */ |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const res = await listDept(queryParams.value); |
| | | const data = proxy?.handleTree<DeptVO>(res.data, "deptId") |
| | | if (data) { |
| | | deptList.value = data |
| | | } |
| | | loading.value = false |
| | | loading.value = true; |
| | | const res = await listDept(queryParams.value); |
| | | const data = proxy?.handleTree<DeptVO>(res.data, "deptId") |
| | | if (data) { |
| | | deptList.value = data |
| | | } |
| | | loading.value = false |
| | | } |
| | | /** åæ¶æé® */ |
| | | const cancel = () => { |
| | | reset() |
| | | dialog.visible = false |
| | | reset() |
| | | dialog.visible = false |
| | | } |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = {...initFormData}; |
| | | deptFormRef.value.resetFields(); |
| | | form.value = {...initFormData}; |
| | | deptFormRef.value.resetFields(); |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | getList(); |
| | | getList(); |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | handleQuery() |
| | | queryFormRef.value.resetFields(); |
| | | handleQuery() |
| | | } |
| | | /** æ°å¢æé®æä½ */ |
| | | const handleAdd = (row?: DeptVO) => { |
| | | listDept().then(res => { |
| | | const data = proxy?.handleTree<DeptOptionsType>(res.data, "deptId"); |
| | | if (data) { |
| | | deptOptions.value = data |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å é¨é¨"; |
| | | nextTick(() => { |
| | | reset(); |
| | | if (row && row.deptId) { |
| | | form.value.parentId = row?.parentId; |
| | | listDept().then(res => { |
| | | const data = proxy?.handleTree<DeptOptionsType>(res.data, "deptId"); |
| | | if (data) { |
| | | deptOptions.value = data |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å é¨é¨"; |
| | | nextTick(() => { |
| | | reset(); |
| | | if (row && row.deptId) { |
| | | form.value.parentId = row?.parentId; |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | /** å±å¼/æå æä½ */ |
| | | const handleToggleExpandAll = () => { |
| | | isExpandAll.value = !isExpandAll.value; |
| | | toggleExpandAll(deptList.value, isExpandAll.value) |
| | | isExpandAll.value = !isExpandAll.value; |
| | | toggleExpandAll(deptList.value, isExpandAll.value) |
| | | } |
| | | /** å±å¼/æå ææ */ |
| | | const toggleExpandAll = (data: DeptVO[], status: boolean) => { |
| | | data.forEach((item) => { |
| | | deptTableRef.value.toggleRowExpansion(item, status) |
| | | if(item.children && item.children.length > 0) toggleExpandAll(item.children, status) |
| | | }) |
| | | data.forEach((item) => { |
| | | deptTableRef.value.toggleRowExpansion(item, status) |
| | | if(item.children && item.children.length > 0) toggleExpandAll(item.children, status) |
| | | }) |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | const handleUpdate = async (row: DeptVO) => { |
| | | const res = await getDept(row.deptId); |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹é¨é¨"; |
| | | nextTick(async () => { |
| | | reset(); |
| | | form.value = res.data |
| | | const response = await listDeptExcludeChild(row.deptId); |
| | | const data = proxy?.handleTree<DeptOptionsType>(response.data, "deptId") |
| | | if (data) { |
| | | deptOptions.value = data; |
| | | if (data.length === 0) { |
| | | const noResultsOptions: DeptOptionsType = { deptId: res.data.parentId, deptName: res.data.parentName, children: [] }; |
| | | deptOptions.value.push(noResultsOptions); |
| | | } |
| | | } |
| | | }) |
| | | const res = await getDept(row.deptId); |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹é¨é¨"; |
| | | nextTick(async () => { |
| | | reset(); |
| | | form.value = res.data |
| | | const response = await listDeptExcludeChild(row.deptId); |
| | | const data = proxy?.handleTree<DeptOptionsType>(response.data, "deptId") |
| | | if (data) { |
| | | deptOptions.value = data; |
| | | if (data.length === 0) { |
| | | const noResultsOptions: DeptOptionsType = { deptId: res.data.parentId, deptName: res.data.parentName, children: [] }; |
| | | deptOptions.value.push(noResultsOptions); |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | deptFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.deptId ? await updateDept(form.value) : await addDept(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | } |
| | | }) |
| | | deptFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.deptId ? await updateDept(form.value) : await addDept(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | } |
| | | }) |
| | | } |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row: DeptVO) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å称为"' + row.deptName + '"çæ°æ®é¡¹?'); |
| | | await delDept(row.deptId); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å称为"' + row.deptName + '"çæ°æ®é¡¹?'); |
| | | await delDept(row.deptId); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | getList(); |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px"> |
| | | <el-form-item label="èååç§°" prop="menuName"> |
| | | <el-input v-model="queryParams.deptName" placeholder="请è¾å
¥é¨é¨åç§°" clearable @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="é¨é¨ç¶æ" clearable> |
| | | <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['system:dept:add']">æ°å¢ </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">å±å¼/æå </el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="deptList" |
| | | row-key="deptId" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | ref="deptTableRef" |
| | | :default-expand-all="isExpandAll" |
| | | > |
| | | <el-table-column prop="deptName" label="é¨é¨åç§°" width="260"></el-table-column> |
| | | <el-table-column prop="orderNum" align="center" label="æåº" width="200"></el-table-column> |
| | | <el-table-column prop="status" align="center" label="ç¶æ" width="100"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="200"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" align="center" label="æä½"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']" /> |
| | | </el-tooltip> |
| | | <el-tooltip content="æ°å¢" placement="top"> |
| | | <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']" /> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dept:remove']" /> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" destroy-on-close append-to-bod width="600px"> |
| | | <el-form ref="deptFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-row> |
| | | <el-col :span="24" v-if="form.parentId !== 0"> |
| | | <el-form-item label="ä¸çº§é¨é¨" prop="parentId"> |
| | | <el-tree-select |
| | | v-model="form.parentId" |
| | | :data="deptOptions" |
| | | :props="{ value: 'deptId', label: 'deptName', children: 'children' }" |
| | | value-key="deptId" |
| | | placeholder="éæ©ä¸çº§é¨é¨" |
| | | check-strictly |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¨é¨åç§°" prop="deptName"> |
| | | <el-input v-model="form.deptName" placeholder="请è¾å
¥é¨é¨åç§°" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¾ç¤ºæåº" prop="orderNum"> |
| | | <el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è´è´£äºº" prop="leader"> |
| | | <el-input v-model="form.leader" placeholder="请è¾å
¥è´è´£äºº" maxlength="20" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯" prop="phone"> |
| | | <el-input v-model="form.phone" placeholder="请è¾å
¥èç³»çµè¯" maxlength="11" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é®ç®±" prop="email"> |
| | | <el-input v-model="form.email" placeholder="请è¾å
¥é®ç®±" maxlength="50" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¨é¨ç¶æ"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label |
| | | }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictType"> |
| | | <el-select v-model="queryParams.dictType" style="width: 200px"> |
| | | <el-option v-for="item in typeOptions" :key="item.dictId" :label="item.dictName" :value="item.dictType" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸æ ç¾" prop="dictLabel"> |
| | | <el-input v-model="queryParams.dictLabel" placeholder="请è¾å
¥åå
¸æ ç¾" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="æ°æ®ç¶æ" clearable style="width: 200px"> |
| | | <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:dict:edit']">ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:dict:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Close" @click="handleClose">å
³é</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="åå
¸ç¼ç " align="center" prop="dictCode" v-if="false" /> |
| | | <el-table-column label="åå
¸æ ç¾" align="center" prop="dictLabel"> |
| | | <template #default="scope"> |
| | | <span v-if="scope.row.listClass === '' || scope.row.listClass === 'default'">{{ scope.row.dictLabel }}</span> |
| | | <el-tag v-else :type="scope.row.listClass === 'primary' ? '' : scope.row.listClass">{{ scope.row.dictLabel |
| | | }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åå
¸é®å¼" align="center" prop="dictValue" /> |
| | | <el-table-column label="åå
¸æåº" align="center" prop="dictSort" /> |
| | | <el-table-column label="ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="160" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | <!-- æ·»å æä¿®æ¹åæ°é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="dataFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="åå
¸ç±»å"> |
| | | <el-input v-model="form.dictType" :disabled="true" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ°æ®æ ç¾" prop="dictLabel"> |
| | | <el-input v-model="form.dictLabel" placeholder="请è¾å
¥æ°æ®æ ç¾" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ°æ®é®å¼" prop="dictValue"> |
| | | <el-input v-model="form.dictValue" placeholder="请è¾å
¥æ°æ®é®å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ ·å¼å±æ§" prop="cssClass"> |
| | | <el-input v-model="form.cssClass" placeholder="请è¾å
¥æ ·å¼å±æ§" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¾ç¤ºæåº" prop="dictSort"> |
| | | <el-input-number v-model="form.dictSort" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ¾æ ·å¼" prop="listClass"> |
| | | <el-select v-model="form.listClass"> |
| | | <el-option |
| | | v-for="item in listClassOptions" |
| | | :key="item.value" |
| | | :label="item.label + '(' + item.value + ')'" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Data" lang="ts"> |
| | | import useDictStore from '@/store/modules/dict' |
| | | import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type"; |
| | |
| | | |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: '' |
| | | visible: false, |
| | | title: '' |
| | | }); |
| | | |
| | | // æ°æ®æ ç¾åæ¾æ ·å¼ |
| | | const listClassOptions = ref<Array<{ value: string, label: string }>>([ |
| | | { value: "default", label: "é»è®¤" }, |
| | | { value: "primary", label: "主è¦" }, |
| | | { value: "success", label: "æå" }, |
| | | { value: "info", label: "ä¿¡æ¯" }, |
| | | { value: "warning", label: "è¦å" }, |
| | | { value: "danger", label: "å±é©" } |
| | | { value: "default", label: "é»è®¤" }, |
| | | { value: "primary", label: "主è¦" }, |
| | | { value: "success", label: "æå" }, |
| | | { value: "info", label: "ä¿¡æ¯" }, |
| | | { value: "warning", label: "è¦å" }, |
| | | { value: "danger", label: "å±é©" } |
| | | ]); |
| | | |
| | | const initFormData: DictDataForm = { |
| | | dictCode: undefined, |
| | | dictLabel: '', |
| | | dictValue: '', |
| | | cssClass: '', |
| | | listClass: "default", |
| | | dictSort: 0, |
| | | status: "0", |
| | | remark: '' |
| | | dictCode: undefined, |
| | | dictLabel: '', |
| | | dictValue: '', |
| | | cssClass: '', |
| | | listClass: "default", |
| | | dictSort: 0, |
| | | status: "0", |
| | | remark: '' |
| | | } |
| | | const data = reactive<PageData<DictDataForm, DictDataQuery>>({ |
| | | form: { ...initFormData }, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | dictName: '', |
| | | dictType: '', |
| | | status: '', |
| | | dictLabel: '' |
| | | }, |
| | | rules: { |
| | | dictLabel: [{ required: true, message: "æ°æ®æ ç¾ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | dictValue: [{ required: true, message: "æ°æ®é®å¼ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | dictSort: [{ required: true, message: "æ°æ®é¡ºåºä¸è½ä¸ºç©º", trigger: "blur" }] |
| | | } |
| | | form: { ...initFormData }, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | dictName: '', |
| | | dictType: '', |
| | | status: '', |
| | | dictLabel: '' |
| | | }, |
| | | rules: { |
| | | dictLabel: [{ required: true, message: "æ°æ®æ ç¾ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | dictValue: [{ required: true, message: "æ°æ®é®å¼ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | dictSort: [{ required: true, message: "æ°æ®é¡ºåºä¸è½ä¸ºç©º", trigger: "blur" }] |
| | | } |
| | | }); |
| | | |
| | | const { queryParams, form, rules } = toRefs(data); |
| | | |
| | | /** æ¥è¯¢åå
¸ç±»åè¯¦ç» */ |
| | | const getTypes = async (dictId: string | number) => { |
| | | const { data } = await getType(dictId); |
| | | queryParams.value.dictType = data.dictType; |
| | | defaultDictType.value = data.dictType; |
| | | getList(); |
| | | const { data } = await getType(dictId); |
| | | queryParams.value.dictType = data.dictType; |
| | | defaultDictType.value = data.dictType; |
| | | getList(); |
| | | } |
| | | |
| | | /** æ¥è¯¢åå
¸ç±»åå表 */ |
| | | const getTypeList = async () => { |
| | | const res = await getDictOptionselect() |
| | | typeOptions.value = res.data; |
| | | const res = await getDictOptionselect() |
| | | typeOptions.value = res.data; |
| | | } |
| | | /** æ¥è¯¢åå
¸æ°æ®å表 */ |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const res = await listData(queryParams.value); |
| | | dataList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | loading.value = true; |
| | | const res = await listData(queryParams.value); |
| | | dataList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | } |
| | | /** åæ¶æé® */ |
| | | const cancel = () => { |
| | | dialog.visible = false; |
| | | reset(); |
| | | dialog.visible = false; |
| | | reset(); |
| | | } |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = { ...initFormData }; |
| | | dataFormRef.value.resetFields(); |
| | | form.value = { ...initFormData }; |
| | | dataFormRef.value.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | } |
| | | /** è¿åæé®æä½ */ |
| | | const handleClose = () => { |
| | | const obj = { path: "/system/dict" }; |
| | | proxy?.$tab.closeOpenPage(obj); |
| | | const obj = { path: "/system/dict" }; |
| | | proxy?.$tab.closeOpenPage(obj); |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryParams.value.dictType = defaultDictType.value; |
| | | handleQuery(); |
| | | queryFormRef.value.resetFields(); |
| | | queryParams.value.dictType = defaultDictType.value; |
| | | handleQuery(); |
| | | } |
| | | /** æ°å¢æé®æä½ */ |
| | | const handleAdd = () => { |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å åå
¸æ°æ®"; |
| | | nextTick(() => { |
| | | reset(); |
| | | form.value.dictType = queryParams.value.dictType; |
| | | }) |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å åå
¸æ°æ®"; |
| | | nextTick(() => { |
| | | reset(); |
| | | form.value.dictType = queryParams.value.dictType; |
| | | }) |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | const handleSelectionChange = (selection: DictDataVO[]) => { |
| | | ids.value = selection.map(item => item.dictCode); |
| | | single.value = selection.length != 1; |
| | | multiple.value = !selection.length; |
| | | ids.value = selection.map(item => item.dictCode); |
| | | single.value = selection.length != 1; |
| | | multiple.value = !selection.length; |
| | | } |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | const handleUpdate = (row?: DictDataVO) => { |
| | | const dictCode = row?.dictCode || ids.value[0]; |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹åå
¸æ°æ®"; |
| | | nextTick(async () => { |
| | | const res = await getData(dictCode); |
| | | reset(); |
| | | form.value = res.data; |
| | | }) |
| | | const dictCode = row?.dictCode || ids.value[0]; |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹åå
¸æ°æ®"; |
| | | nextTick(async () => { |
| | | const res = await getData(dictCode); |
| | | reset(); |
| | | form.value = res.data; |
| | | }) |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | dataFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.dictCode ? await updateData(form.value) : await addData(form.value); |
| | | useDictStore().removeDict(queryParams.value.dictType); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | dataFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.dictCode ? await updateData(form.value) : await addData(form.value); |
| | | useDictStore().removeDict(queryParams.value.dictType); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row?: DictDataVO) => { |
| | | const dictCodes = row?.dictCode || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åå
¸ç¼ç 为"' + dictCodes + '"çæ°æ®é¡¹ï¼'); |
| | | await delData(dictCodes); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | useDictStore().removeDict(queryParams.value.dictType); |
| | | const dictCodes = row?.dictCode || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åå
¸ç¼ç 为"' + dictCodes + '"çæ°æ®é¡¹ï¼'); |
| | | await delData(dictCodes); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | useDictStore().removeDict(queryParams.value.dictType); |
| | | |
| | | } |
| | | /** å¯¼åºæé®æä½ */ |
| | | const handleExport = () => { |
| | | proxy?.download("system/dict/data/export", { |
| | | ...queryParams.value |
| | | }, `dict_data_${new Date().getTime()}.xlsx`); |
| | | proxy?.download("system/dict/data/export", { |
| | | ...queryParams.value |
| | | }, `dict_data_${new Date().getTime()}.xlsx`); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getTypes(route.params && route.params.dictId as string); |
| | | getTypeList(); |
| | | getTypes(route.params && route.params.dictId as string); |
| | | getTypeList(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictType"> |
| | | <el-select v-model="queryParams.dictType" style="width: 200px"> |
| | | <el-option v-for="item in typeOptions" :key="item.dictId" :label="item.dictName" :value="item.dictType" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸æ ç¾" prop="dictLabel"> |
| | | <el-input v-model="queryParams.dictLabel" placeholder="请è¾å
¥åå
¸æ ç¾" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="æ°æ®ç¶æ" clearable style="width: 200px"> |
| | | <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:dict:edit']">ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:dict:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Close" @click="handleClose">å
³é</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="åå
¸ç¼ç " align="center" prop="dictCode" v-if="false" /> |
| | | <el-table-column label="åå
¸æ ç¾" align="center" prop="dictLabel"> |
| | | <template #default="scope"> |
| | | <span v-if="scope.row.listClass === '' || scope.row.listClass === 'default'">{{ scope.row.dictLabel }}</span> |
| | | <el-tag v-else :type="scope.row.listClass === 'primary' ? '' : scope.row.listClass">{{ scope.row.dictLabel |
| | | }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åå
¸é®å¼" align="center" prop="dictValue" /> |
| | | <el-table-column label="åå
¸æåº" align="center" prop="dictSort" /> |
| | | <el-table-column label="ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="160" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | <!-- æ·»å æä¿®æ¹åæ°é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="dataFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="åå
¸ç±»å"> |
| | | <el-input v-model="form.dictType" :disabled="true" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ°æ®æ ç¾" prop="dictLabel"> |
| | | <el-input v-model="form.dictLabel" placeholder="请è¾å
¥æ°æ®æ ç¾" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ°æ®é®å¼" prop="dictValue"> |
| | | <el-input v-model="form.dictValue" placeholder="请è¾å
¥æ°æ®é®å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ ·å¼å±æ§" prop="cssClass"> |
| | | <el-input v-model="form.cssClass" placeholder="请è¾å
¥æ ·å¼å±æ§" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¾ç¤ºæåº" prop="dictSort"> |
| | | <el-input-number v-model="form.dictSort" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ¾æ ·å¼" prop="listClass"> |
| | | <el-select v-model="form.listClass"> |
| | | <el-option |
| | | v-for="item in listClassOptions" |
| | | :key="item.value" |
| | | :label="item.label + '(' + item.value + ')'" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictName"> |
| | | <el-input v-model="queryParams.dictName" placeholder="请è¾å
¥åå
¸åç§°" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸ç±»å" prop="dictType"> |
| | | <el-input v-model="queryParams.dictType" placeholder="请è¾å
¥åå
¸ç±»å" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="åå
¸ç¶æ" clearable style="width: 240px"> |
| | | <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:dict:edit']">ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:dict:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Refresh" @click="handleRefreshCache" v-hasPermi="['system:dict:remove']">å·æ°ç¼å</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="åå
¸ç¼å·" align="center" prop="dictId" v-if="false" /> |
| | | <el-table-column label="åå
¸åç§°" align="center" prop="dictName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="åå
¸ç±»å" align="center" :show-overflow-tooltip="true"> |
| | | <template #default="scope"> |
| | | <router-link :to="'/system/dict-data/index/' + scope.row.dictId" class="link-type"> |
| | | <span>{{ scope.row.dictType }}</span> |
| | | </router-link> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="160" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | <!-- æ·»å æä¿®æ¹åæ°é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="dictFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictName"> |
| | | <el-input v-model="form.dictName" placeholder="请è¾å
¥åå
¸åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸ç±»å" prop="dictType"> |
| | | <el-input v-model="form.dictType" placeholder="请è¾å
¥åå
¸ç±»å" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Dict" lang="ts"> |
| | | import useDictStore from '@/store/modules/dict' |
| | | import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type"; |
| | |
| | | |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: '' |
| | | visible: false, |
| | | title: '' |
| | | }); |
| | | |
| | | const initFormData: DictTypeForm = { |
| | | dictId: undefined, |
| | | dictName: '', |
| | | dictType: '', |
| | | status: "0", |
| | | remark: '' |
| | | } |
| | | const data = reactive<PageData<DictTypeForm, DictTypeQuery>>({ |
| | | form: {...initFormData}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | dictId: undefined, |
| | | dictName: '', |
| | | dictType: '', |
| | | status: '' |
| | | }, |
| | | rules: { |
| | | dictName: [{ required: true, message: "åå
¸åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | dictType: [{ required: true, message: "åå
¸ç±»åä¸è½ä¸ºç©º", trigger: "blur" }] |
| | | }, |
| | | status: "0", |
| | | remark: '' |
| | | } |
| | | const data = reactive<PageData<DictTypeForm, DictTypeQuery>>({ |
| | | form: {...initFormData}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | dictName: '', |
| | | dictType: '', |
| | | status: '' |
| | | }, |
| | | rules: { |
| | | dictName: [{ required: true, message: "åå
¸åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | dictType: [{ required: true, message: "åå
¸ç±»åä¸è½ä¸ºç©º", trigger: "blur" }] |
| | | }, |
| | | }); |
| | | |
| | | const { queryParams, form, rules } = toRefs(data); |
| | | |
| | | /** æ¥è¯¢åå
¸ç±»åå表 */ |
| | | const getList = () => { |
| | | loading.value = true; |
| | | listType(proxy?.addDateRange(queryParams.value, dateRange.value)).then(res => { |
| | | typeList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | }); |
| | | loading.value = true; |
| | | listType(proxy?.addDateRange(queryParams.value, dateRange.value)).then(res => { |
| | | typeList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | }); |
| | | } |
| | | /** åæ¶æé® */ |
| | | const cancel = () => { |
| | | reset(); |
| | | dialog.visible = false; |
| | | reset(); |
| | | dialog.visible = false; |
| | | } |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = {...initFormData}; |
| | | dictFormRef.value.resetFields(); |
| | | form.value = {...initFormData}; |
| | | dictFormRef.value.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | handleQuery(); |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** æ°å¢æé®æä½ */ |
| | | const handleAdd = () => { |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å åå
¸ç±»å"; |
| | | nextTick(() => { |
| | | reset(); |
| | | }) |
| | | dialog.visible = true; |
| | | dialog.title = "æ·»å åå
¸ç±»å"; |
| | | nextTick(() => { |
| | | reset(); |
| | | }) |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | const handleSelectionChange = (selection: DictTypeVO[]) => { |
| | | ids.value = selection.map(item => item.dictId); |
| | | single.value = selection.length != 1; |
| | | multiple.value = !selection.length; |
| | | ids.value = selection.map(item => item.dictId); |
| | | single.value = selection.length != 1; |
| | | multiple.value = !selection.length; |
| | | } |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | const handleUpdate = (row?: DictTypeVO) => { |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹åå
¸ç±»å"; |
| | | const dictId = row?.dictId || ids.value[0]; |
| | | nextTick(async () => { |
| | | reset(); |
| | | const res = await getType(dictId); |
| | | form.value = res.data; |
| | | }) |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹åå
¸ç±»å"; |
| | | const dictId = row?.dictId || ids.value[0]; |
| | | nextTick(async () => { |
| | | reset(); |
| | | const res = await getType(dictId); |
| | | form.value = res.data; |
| | | }) |
| | | |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | dictFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.dictId ? await updateType(form.value) : await addType(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | } |
| | | }); |
| | | dictFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.dictId ? await updateType(form.value) : await addType(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | } |
| | | }); |
| | | } |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row?: DictTypeVO) => { |
| | | const dictIds = row?.dictId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åå
¸ç¼å·ä¸º"' + dictIds + '"çæ°æ®é¡¹ï¼'); |
| | | await delType(dictIds); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | const dictIds = row?.dictId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åå
¸ç¼å·ä¸º"' + dictIds + '"çæ°æ®é¡¹ï¼'); |
| | | await delType(dictIds); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | /** å¯¼åºæé®æä½ */ |
| | | const handleExport = () => { |
| | | proxy?.download("system/dict/type/export", { |
| | | ...queryParams.value |
| | | }, `dict_${new Date().getTime()}.xlsx`); |
| | | proxy?.download("system/dict/type/export", { |
| | | ...queryParams.value |
| | | }, `dict_${new Date().getTime()}.xlsx`); |
| | | } |
| | | /** å·æ°ç¼åæé®æä½ */ |
| | | const handleRefreshCache = async () => { |
| | | await refreshCache(); |
| | | proxy?.$modal.msgSuccess("å·æ°æå"); |
| | | useDictStore().cleanDict(); |
| | | await refreshCache(); |
| | | proxy?.$modal.msgSuccess("å·æ°æå"); |
| | | useDictStore().cleanDict(); |
| | | } |
| | | |
| | | onMounted(()=>{ |
| | | getList(); |
| | | getList(); |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictName"> |
| | | <el-input v-model="queryParams.dictName" placeholder="请è¾å
¥åå
¸åç§°" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸ç±»å" prop="dictType"> |
| | | <el-input v-model="queryParams.dictType" placeholder="请è¾å
¥åå
¸ç±»å" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="åå
¸ç¶æ" clearable style="width: 240px"> |
| | | <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:dict:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:dict:edit']">ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:dict:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:dict:export']">导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Refresh" @click="handleRefreshCache" v-hasPermi="['system:dict:remove']">å·æ°ç¼å</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="åå
¸ç¼å·" align="center" prop="dictId" v-if="false" /> |
| | | <el-table-column label="åå
¸åç§°" align="center" prop="dictName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="åå
¸ç±»å" align="center" :show-overflow-tooltip="true"> |
| | | <template #default="scope"> |
| | | <router-link :to="'/system/dict-data/index/' + scope.row.dictId" class="link-type"> |
| | | <span>{{ scope.row.dictType }}</span> |
| | | </router-link> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="160" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | <!-- æ·»å æä¿®æ¹åæ°é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="dictFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictName"> |
| | | <el-input v-model="form.dictName" placeholder="请è¾å
¥åå
¸åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸ç±»å" prop="dictType"> |
| | | <el-input v-model="form.dictType" placeholder="请è¾å
¥åå
¸ç±»å" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
src/views/system/menu/index.vue
src/views/system/notice/index.vue
src/views/system/oss/config.vue
src/views/system/oss/index.vue
src/views/system/post/index.vue
src/views/system/role/authUser.vue
src/views/system/role/index.vue
src/views/system/role/selectUser.vue
src/views/system/tenant/index.vue
src/views/system/tenantPackage/index.vue
src/views/system/user/authRole.vue
src/views/system/user/index.vue
src/views/system/user/profile/index.vue
src/views/system/user/profile/resetPwd.vue
src/views/system/user/profile/userAvatar.vue
src/views/system/user/profile/userInfo.vue
src/views/tool/build/index.vue
src/views/tool/gen/basicInfoForm.vue
src/views/tool/gen/editTable.vue
src/views/tool/gen/genInfoForm.vue
src/views/tool/gen/importTable.vue
src/views/tool/gen/index.vue
tsconfig.json
vite.config.ts
vite/plugins/auto-import.ts
vite/plugins/components.ts
vite/plugins/compression.ts
vite/plugins/icons.ts
vite/plugins/index.ts
vite/plugins/svg-icon.ts
vite/plugins/unocss.ts |