fix(web): 修复代码格式和文件清理问题
清理无用文件和资源,调整代码格式统一双引号,修复部分组件路径引用问题 删除大量无用图片资源和组件文件,统一代码风格使用双引号,修复国际化文件路径引用,调整部分组件逻辑,优化项目结构
@@ -1,326 +0,0 @@
|
||||
{
|
||||
"globals": {
|
||||
"Component": true,
|
||||
"ComponentPublicInstance": true,
|
||||
"ComputedRef": true,
|
||||
"DirectiveBinding": true,
|
||||
"EffectScope": true,
|
||||
"ElMessage": true,
|
||||
"ElNotification": true,
|
||||
"ExtractDefaultPropTypes": true,
|
||||
"ExtractPropTypes": true,
|
||||
"ExtractPublicPropTypes": true,
|
||||
"InjectionKey": true,
|
||||
"MaybeRef": true,
|
||||
"MaybeRefOrGetter": true,
|
||||
"PropType": true,
|
||||
"Ref": true,
|
||||
"ShallowRef": true,
|
||||
"Slot": true,
|
||||
"Slots": true,
|
||||
"VNode": true,
|
||||
"WritableComputedRef": true,
|
||||
"acceptHMRUpdate": true,
|
||||
"asyncComputed": true,
|
||||
"autoResetRef": true,
|
||||
"computed": true,
|
||||
"computedAsync": true,
|
||||
"computedEager": true,
|
||||
"computedInject": true,
|
||||
"computedWithControl": true,
|
||||
"controlledComputed": true,
|
||||
"controlledRef": true,
|
||||
"createApp": true,
|
||||
"createEventHook": true,
|
||||
"createGlobalState": true,
|
||||
"createInjectionState": true,
|
||||
"createPinia": true,
|
||||
"createReactiveFn": true,
|
||||
"createRef": true,
|
||||
"createReusableTemplate": true,
|
||||
"createSharedComposable": true,
|
||||
"createTemplatePromise": true,
|
||||
"createUnrefFn": true,
|
||||
"customRef": true,
|
||||
"debouncedRef": true,
|
||||
"debouncedWatch": true,
|
||||
"defineAsyncComponent": true,
|
||||
"defineComponent": true,
|
||||
"defineStore": true,
|
||||
"eagerComputed": true,
|
||||
"effectScope": true,
|
||||
"extendRef": true,
|
||||
"getActivePinia": true,
|
||||
"getCurrentInstance": true,
|
||||
"getCurrentScope": true,
|
||||
"getCurrentWatcher": true,
|
||||
"h": true,
|
||||
"ignorableWatch": true,
|
||||
"inject": true,
|
||||
"injectLocal": true,
|
||||
"isDefined": true,
|
||||
"isProxy": true,
|
||||
"isReactive": true,
|
||||
"isReadonly": true,
|
||||
"isRef": true,
|
||||
"isShallow": true,
|
||||
"makeDestructurable": true,
|
||||
"mapActions": true,
|
||||
"mapGetters": true,
|
||||
"mapState": true,
|
||||
"mapStores": true,
|
||||
"mapWritableState": true,
|
||||
"markRaw": true,
|
||||
"nextTick": true,
|
||||
"onActivated": true,
|
||||
"onBeforeMount": true,
|
||||
"onBeforeRouteLeave": true,
|
||||
"onBeforeRouteUpdate": true,
|
||||
"onBeforeUnmount": true,
|
||||
"onBeforeUpdate": true,
|
||||
"onClickOutside": true,
|
||||
"onDeactivated": true,
|
||||
"onElementRemoval": true,
|
||||
"onErrorCaptured": true,
|
||||
"onKeyStroke": true,
|
||||
"onLongPress": true,
|
||||
"onMounted": true,
|
||||
"onRenderTracked": true,
|
||||
"onRenderTriggered": true,
|
||||
"onScopeDispose": true,
|
||||
"onServerPrefetch": true,
|
||||
"onStartTyping": true,
|
||||
"onUnmounted": true,
|
||||
"onUpdated": true,
|
||||
"onWatcherCleanup": true,
|
||||
"pausableWatch": true,
|
||||
"provide": true,
|
||||
"provideLocal": true,
|
||||
"reactify": true,
|
||||
"reactifyObject": true,
|
||||
"reactive": true,
|
||||
"reactiveComputed": true,
|
||||
"reactiveOmit": true,
|
||||
"reactivePick": true,
|
||||
"readonly": true,
|
||||
"ref": true,
|
||||
"refAutoReset": true,
|
||||
"refDebounced": true,
|
||||
"refDefault": true,
|
||||
"refThrottled": true,
|
||||
"refWithControl": true,
|
||||
"resolveComponent": true,
|
||||
"resolveRef": true,
|
||||
"resolveUnref": true,
|
||||
"setActivePinia": true,
|
||||
"setMapStoreSuffix": true,
|
||||
"shallowReactive": true,
|
||||
"shallowReadonly": true,
|
||||
"shallowRef": true,
|
||||
"storeToRefs": true,
|
||||
"syncRef": true,
|
||||
"syncRefs": true,
|
||||
"templateRef": true,
|
||||
"throttledRef": true,
|
||||
"throttledWatch": true,
|
||||
"toRaw": true,
|
||||
"toReactive": true,
|
||||
"toRef": true,
|
||||
"toRefs": true,
|
||||
"toValue": true,
|
||||
"triggerRef": true,
|
||||
"tryOnBeforeMount": true,
|
||||
"tryOnBeforeUnmount": true,
|
||||
"tryOnMounted": true,
|
||||
"tryOnScopeDispose": true,
|
||||
"tryOnUnmounted": true,
|
||||
"unref": true,
|
||||
"unrefElement": true,
|
||||
"until": true,
|
||||
"useActiveElement": true,
|
||||
"useAnimate": true,
|
||||
"useArrayDifference": true,
|
||||
"useArrayEvery": true,
|
||||
"useArrayFilter": true,
|
||||
"useArrayFind": true,
|
||||
"useArrayFindIndex": true,
|
||||
"useArrayFindLast": true,
|
||||
"useArrayIncludes": true,
|
||||
"useArrayJoin": true,
|
||||
"useArrayMap": true,
|
||||
"useArrayReduce": true,
|
||||
"useArraySome": true,
|
||||
"useArrayUnique": true,
|
||||
"useAsyncQueue": true,
|
||||
"useAsyncState": true,
|
||||
"useAttrs": true,
|
||||
"useBase64": true,
|
||||
"useBattery": true,
|
||||
"useBluetooth": true,
|
||||
"useBreakpoints": true,
|
||||
"useBroadcastChannel": true,
|
||||
"useBrowserLocation": true,
|
||||
"useCached": true,
|
||||
"useClipboard": true,
|
||||
"useClipboardItems": true,
|
||||
"useCloned": true,
|
||||
"useColorMode": true,
|
||||
"useConfirmDialog": true,
|
||||
"useCountdown": true,
|
||||
"useCounter": true,
|
||||
"useCssModule": true,
|
||||
"useCssVar": true,
|
||||
"useCssVars": true,
|
||||
"useCurrentElement": true,
|
||||
"useCycleList": true,
|
||||
"useDark": true,
|
||||
"useDateFormat": true,
|
||||
"useDebounce": true,
|
||||
"useDebounceFn": true,
|
||||
"useDebouncedRefHistory": true,
|
||||
"useDeviceMotion": true,
|
||||
"useDeviceOrientation": true,
|
||||
"useDevicePixelRatio": true,
|
||||
"useDevicesList": true,
|
||||
"useDisplayMedia": true,
|
||||
"useDocumentVisibility": true,
|
||||
"useDraggable": true,
|
||||
"useDropZone": true,
|
||||
"useElementBounding": true,
|
||||
"useElementByPoint": true,
|
||||
"useElementHover": true,
|
||||
"useElementSize": true,
|
||||
"useElementVisibility": true,
|
||||
"useEventBus": true,
|
||||
"useEventListener": true,
|
||||
"useEventSource": true,
|
||||
"useEyeDropper": true,
|
||||
"useFavicon": true,
|
||||
"useFetch": true,
|
||||
"useFileDialog": true,
|
||||
"useFileSystemAccess": true,
|
||||
"useFocus": true,
|
||||
"useFocusWithin": true,
|
||||
"useFps": true,
|
||||
"useFullscreen": true,
|
||||
"useGamepad": true,
|
||||
"useGeolocation": true,
|
||||
"useI18n": true,
|
||||
"useId": true,
|
||||
"useIdle": true,
|
||||
"useImage": true,
|
||||
"useInfiniteScroll": true,
|
||||
"useIntersectionObserver": true,
|
||||
"useInterval": true,
|
||||
"useIntervalFn": true,
|
||||
"useKeyModifier": true,
|
||||
"useLastChanged": true,
|
||||
"useLink": true,
|
||||
"useLocalStorage": true,
|
||||
"useMagicKeys": true,
|
||||
"useManualRefHistory": true,
|
||||
"useMediaControls": true,
|
||||
"useMediaQuery": true,
|
||||
"useMemoize": true,
|
||||
"useMemory": true,
|
||||
"useModel": true,
|
||||
"useMounted": true,
|
||||
"useMouse": true,
|
||||
"useMouseInElement": true,
|
||||
"useMousePressed": true,
|
||||
"useMutationObserver": true,
|
||||
"useNavigatorLanguage": true,
|
||||
"useNetwork": true,
|
||||
"useNow": true,
|
||||
"useObjectUrl": true,
|
||||
"useOffsetPagination": true,
|
||||
"useOnline": true,
|
||||
"usePageLeave": true,
|
||||
"useParallax": true,
|
||||
"useParentElement": true,
|
||||
"usePerformanceObserver": true,
|
||||
"usePermission": true,
|
||||
"usePointer": true,
|
||||
"usePointerLock": true,
|
||||
"usePointerSwipe": true,
|
||||
"usePreferredColorScheme": true,
|
||||
"usePreferredContrast": true,
|
||||
"usePreferredDark": true,
|
||||
"usePreferredLanguages": true,
|
||||
"usePreferredReducedMotion": true,
|
||||
"usePreferredReducedTransparency": true,
|
||||
"usePrevious": true,
|
||||
"useRafFn": true,
|
||||
"useRefHistory": true,
|
||||
"useResizeObserver": true,
|
||||
"useRoute": true,
|
||||
"useRouter": true,
|
||||
"useSSRWidth": true,
|
||||
"useScreenOrientation": true,
|
||||
"useScreenSafeArea": true,
|
||||
"useScriptTag": true,
|
||||
"useScroll": true,
|
||||
"useScrollLock": true,
|
||||
"useSessionStorage": true,
|
||||
"useShare": true,
|
||||
"useSlots": true,
|
||||
"useSorted": true,
|
||||
"useSpeechRecognition": true,
|
||||
"useSpeechSynthesis": true,
|
||||
"useStepper": true,
|
||||
"useStorage": true,
|
||||
"useStorageAsync": true,
|
||||
"useStyleTag": true,
|
||||
"useSupported": true,
|
||||
"useSwipe": true,
|
||||
"useTemplateRef": true,
|
||||
"useTemplateRefsList": true,
|
||||
"useTextDirection": true,
|
||||
"useTextSelection": true,
|
||||
"useTextareaAutosize": true,
|
||||
"useThrottle": true,
|
||||
"useThrottleFn": true,
|
||||
"useThrottledRefHistory": true,
|
||||
"useTimeAgo": true,
|
||||
"useTimeAgoIntl": true,
|
||||
"useTimeout": true,
|
||||
"useTimeoutFn": true,
|
||||
"useTimeoutPoll": true,
|
||||
"useTimestamp": true,
|
||||
"useTitle": true,
|
||||
"useToNumber": true,
|
||||
"useToString": true,
|
||||
"useToggle": true,
|
||||
"useTransition": true,
|
||||
"useUrlSearchParams": true,
|
||||
"useUserMedia": true,
|
||||
"useVModel": true,
|
||||
"useVModels": true,
|
||||
"useVibrate": true,
|
||||
"useVirtualList": true,
|
||||
"useWakeLock": true,
|
||||
"useWebNotification": true,
|
||||
"useWebSocket": true,
|
||||
"useWebWorker": true,
|
||||
"useWebWorkerFn": true,
|
||||
"useWindowFocus": true,
|
||||
"useWindowScroll": true,
|
||||
"useWindowSize": true,
|
||||
"watch": true,
|
||||
"watchArray": true,
|
||||
"watchAtMost": true,
|
||||
"watchDebounced": true,
|
||||
"watchDeep": true,
|
||||
"watchEffect": true,
|
||||
"watchIgnorable": true,
|
||||
"watchImmediate": true,
|
||||
"watchOnce": true,
|
||||
"watchPausable": true,
|
||||
"watchPostEffect": true,
|
||||
"watchSyncEffect": true,
|
||||
"watchThrottled": true,
|
||||
"watchTriggerable": true,
|
||||
"watchWithFilter": true,
|
||||
"whenever": true
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@ VITE_APP_ENV=development
|
||||
VITE_APP_TITLE=fastapiadmin
|
||||
|
||||
# 网络请求公用地址,根据实际部署情况修改
|
||||
VITE_API_BASE_URL=https://service.fastapiadmin.com
|
||||
# VITE_API_BASE_URL=http://127.0.0.1:8001
|
||||
VITE_API_BASE_URL=https://server.fastapiadmin.com
|
||||
|
||||
# 代理前缀
|
||||
VITE_APP_BASE_API=/api/v1
|
||||
@@ -18,36 +18,5 @@ VITE_APP_PORT=5180
|
||||
VITE_TIMEOUT=10000
|
||||
|
||||
# WebSocket 端点(不配置则关闭),ai对话需要配置
|
||||
VITE_APP_WS_ENDPOINT=wss://service.fastapiadmin.com
|
||||
# VITE_APP_WS_ENDPOINT=ws://127.0.0.1:8001
|
||||
|
||||
|
||||
# 版本号
|
||||
VITE_VERSION = 3.0.2
|
||||
|
||||
# 权限模式【 frontend 前端模式 / backend 后端模式 】
|
||||
VITE_ACCESS_MODE = frontend
|
||||
|
||||
# 端口号
|
||||
VITE_PORT = 3006
|
||||
|
||||
# 应用部署基础路径(如部署在子目录 /admin,则设置为 /admin/)
|
||||
VITE_BASE_URL = /
|
||||
|
||||
# 跨域请求时是否携带 Cookie(开启前需确保后端支持)
|
||||
VITE_WITH_CREDENTIALS = false
|
||||
|
||||
# 是否打开路由信息
|
||||
VITE_OPEN_ROUTE_INFO = false
|
||||
|
||||
# 锁屏加密密钥
|
||||
VITE_LOCK_ENCRYPT_KEY = s3cur3k3y4adpro
|
||||
|
||||
# API 请求基础路径(开发环境设置为 / 使用代理,生产环境设置为完整后端地址)
|
||||
VITE_API_URL = /
|
||||
|
||||
# 代理目标地址(开发环境通过 Vite 代理转发请求到此地址,解决跨域问题)
|
||||
VITE_API_PROXY_URL = https://m1.apifoxmock.com/m1/6400575-6097373-default
|
||||
|
||||
# Delete console
|
||||
VITE_DROP_CONSOLE = false
|
||||
VITE_APP_WS_ENDPOINT=wss://server.fastapiadmin.com
|
||||
|
||||
@@ -5,7 +5,7 @@ VITE_APP_ENV=production
|
||||
VITE_APP_TITLE=fastapiadmin
|
||||
|
||||
# 网络请求公用地址,如果没有认证可以使用http
|
||||
VITE_API_BASE_URL=https://service.fastapiadmin.com
|
||||
VITE_API_BASE_URL=https://server.fastapiadmin.com
|
||||
|
||||
# 代理前缀
|
||||
VITE_APP_BASE_API=/api/v1
|
||||
@@ -17,35 +17,4 @@ VITE_APP_PORT=5180
|
||||
VITE_TIMEOUT=10000
|
||||
|
||||
# WebSocket 端点(不配置则关闭),ai对话需要配置,如果没有认证wss需要改为ws
|
||||
VITE_APP_WS_ENDPOINT=wss://service.fastapiadmin.com
|
||||
|
||||
|
||||
# 版本号
|
||||
VITE_VERSION = 3.0.2
|
||||
|
||||
# 权限模式【 frontend 前端模式 / backend 后端模式 】
|
||||
VITE_ACCESS_MODE = frontend
|
||||
|
||||
# 端口号
|
||||
VITE_PORT = 3006
|
||||
|
||||
# 应用部署基础路径(如部署在子目录 /admin,则设置为 /admin/)
|
||||
VITE_BASE_URL = /
|
||||
|
||||
# 跨域请求时是否携带 Cookie(开启前需确保后端支持)
|
||||
VITE_WITH_CREDENTIALS = false
|
||||
|
||||
# 是否打开路由信息
|
||||
VITE_OPEN_ROUTE_INFO = false
|
||||
|
||||
# 锁屏加密密钥
|
||||
VITE_LOCK_ENCRYPT_KEY = s3cur3k3y4adpro
|
||||
|
||||
# API 请求基础路径(开发环境设置为 / 使用代理,生产环境设置为完整后端地址)
|
||||
VITE_API_URL = /
|
||||
|
||||
# 代理目标地址(开发环境通过 Vite 代理转发请求到此地址,解决跨域问题)
|
||||
VITE_API_PROXY_URL = https://m1.apifoxmock.com/m1/6400575-6097373-default
|
||||
|
||||
# Delete console
|
||||
VITE_DROP_CONSOLE = false
|
||||
VITE_APP_WS_ENDPOINT=wss://server.fastapiadmin.com
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
*.html linguist-detectable=false
|
||||
*.vue linguist-detectable=true
|
||||
@@ -4,7 +4,6 @@ dist
|
||||
dist-ssr
|
||||
*.local
|
||||
.history
|
||||
.cursorrules
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
|
||||
@@ -23,7 +23,7 @@ requirePragma: false
|
||||
# 在语句末尾添加分号
|
||||
semi: true
|
||||
# 使用双引号而不是单引号
|
||||
singleQuote: true
|
||||
singleQuote: false
|
||||
# 缩进使用 2 个空格
|
||||
tabWidth: 2
|
||||
# 在多行元素的末尾添加逗号(ES5 支持的对象、数组等)
|
||||
@@ -31,7 +31,7 @@ trailingComma: "es5"
|
||||
# 使用空格而不是制表符缩进
|
||||
useTabs: false
|
||||
# Vue 文件中的 <script> 和 <style> 不增加额外的缩进
|
||||
vueIndentScriptAndStyle: true
|
||||
vueIndentScriptAndStyle: false
|
||||
# 根据系统自动检测换行符
|
||||
endOfLine: "auto"
|
||||
# 对 HTML 文件应用特定格式化规则
|
||||
@@ -39,5 +39,3 @@ overrides:
|
||||
- files: "*.html"
|
||||
options:
|
||||
parser: "html"
|
||||
# 从文件开头开始格式化
|
||||
rangeStart: 0
|
||||
|
||||
@@ -1,90 +1,38 @@
|
||||
module.exports = {
|
||||
// 继承推荐规范配置
|
||||
extends: [
|
||||
'stylelint-config-recommended',
|
||||
'stylelint-config-recommended-scss',
|
||||
'stylelint-config-recommended-vue/scss',
|
||||
'stylelint-config-html/vue',
|
||||
'stylelint-config-recess-order',
|
||||
"stylelint-config-recommended",
|
||||
"stylelint-config-recommended-scss",
|
||||
"stylelint-config-recommended-vue/scss",
|
||||
"stylelint-config-html/vue",
|
||||
"stylelint-config-recess-order",
|
||||
],
|
||||
// 插件配置
|
||||
|
||||
plugins: [
|
||||
'stylelint-prettier', // 统一代码风格,格式冲突时以 Prettier 规则为准
|
||||
"stylelint-prettier", // 统一代码风格,格式冲突时以 Prettier 规则为准
|
||||
],
|
||||
// 指定不同文件对应的解析器
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*.{vue,html}'],
|
||||
customSyntax: 'postcss-html',
|
||||
files: ["**/*.{vue,html}"],
|
||||
customSyntax: "postcss-html",
|
||||
},
|
||||
{
|
||||
files: ['**/*.{css,scss}'],
|
||||
customSyntax: 'postcss-scss',
|
||||
files: ["**/*.{css,scss}"],
|
||||
customSyntax: "postcss-scss",
|
||||
},
|
||||
],
|
||||
// 自定义规则
|
||||
rules: {
|
||||
'import-notation': 'string', // 指定导入CSS文件的方式("string"|"url")
|
||||
'selector-class-pattern': null, // 选择器类名命名规则
|
||||
'custom-property-pattern': null, // 自定义属性命名规则
|
||||
'keyframes-name-pattern': null, // 动画帧节点样式命名规则
|
||||
'no-descending-specificity': null, // 允许无降序特异性
|
||||
'no-empty-source': null, // 允许空样式
|
||||
'property-no-vendor-prefix': null, // 允许属性前缀
|
||||
'prettier/prettier': true, // 强制执行 Prettier 格式化规则(需配合 .prettierrc 配置文件)
|
||||
'declaration-property-value-no-unknown': null, // 允许非常规数值格式 ,如 height: calc(100% - 50)
|
||||
// 允许 global 、export 、deep伪类
|
||||
'selector-pseudo-class-no-unknown': [
|
||||
"prettier/prettier": true, // 强制执行 Prettier 格式化规则(需配合 .prettierrc 配置文件)
|
||||
"no-empty-source": null, // 允许空的样式文件
|
||||
"declaration-property-value-no-unknown": null, // 允许非常规数值格式 ,如 height: calc(100% - 50)
|
||||
// 允许使用未知伪类
|
||||
"selector-pseudo-class-no-unknown": [
|
||||
true,
|
||||
{
|
||||
ignorePseudoClasses: ['global', 'export', 'deep'],
|
||||
},
|
||||
],
|
||||
// 允许未知属性
|
||||
'property-no-unknown': [
|
||||
true,
|
||||
{
|
||||
ignoreProperties: [],
|
||||
ignorePseudoClasses: ["global", "export", "deep"],
|
||||
},
|
||||
],
|
||||
// 允许使用未知伪元素
|
||||
'at-rule-no-unknown': [
|
||||
true,
|
||||
{
|
||||
ignoreAtRules: [
|
||||
'apply',
|
||||
'use',
|
||||
'forward',
|
||||
'mixin',
|
||||
'include',
|
||||
'extend',
|
||||
'each',
|
||||
'if',
|
||||
'else',
|
||||
'for',
|
||||
'while',
|
||||
'reference',
|
||||
],
|
||||
},
|
||||
],
|
||||
'scss/at-rule-no-unknown': [
|
||||
true,
|
||||
{
|
||||
ignoreAtRules: [
|
||||
'apply',
|
||||
'use',
|
||||
'forward',
|
||||
'mixin',
|
||||
'include',
|
||||
'extend',
|
||||
'each',
|
||||
'if',
|
||||
'else',
|
||||
'for',
|
||||
'while',
|
||||
'reference',
|
||||
],
|
||||
},
|
||||
],
|
||||
"at-rule-no-unknown": null, // 禁用默认的未知 at-rule 检查
|
||||
"scss/at-rule-no-unknown": true, // 启用 SCSS 特定的 at-rule 检查
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,650 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Released]
|
||||
|
||||
### v3.0.1 - 2025-11-15
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed repeated API calls issue when accessing non-existent interfaces during route registration
|
||||
- Fixed one-click cleanup script build failure issue
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Enhanced route configuration validation mechanism, automatically detects and prompts path configuration errors for non-first-level menus
|
||||
- Optimized top progress bar ghosting issue
|
||||
- Optimized vite pre-build configuration
|
||||
- Unified border radius and border consistency
|
||||
- Redesigned lock screen page, improved visual experience
|
||||
- Optimized visual experience issue caused by logout menu disappearing prematurely
|
||||
|
||||
#### Added
|
||||
|
||||
- ArtForm and ArtSearchBar component labels support custom render functions, enabling complex labels with tooltips
|
||||
- Menu management form key fields added Tooltip hints, lowering user configuration threshold
|
||||
- Iconify added offline icon loading mode
|
||||
- Logout added redirect property for redirecting to corresponding page after re-login
|
||||
- Logout and re-entry preserves user tabs, identified by userId
|
||||
- Dual menu added collapse button
|
||||
- Enhanced menu icons
|
||||
- Multi-tab pages added icon display
|
||||
- Added WebSocket connection example
|
||||
- Lock screen password error triggers input box shake animation
|
||||
|
||||
#### ⚠️ Important Notice
|
||||
|
||||
> This version requires re-login
|
||||
|
||||
---
|
||||
|
||||
### v3.0.0 - 2025-11-09 🎉
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Style system refactored: Sass fully migrated to Tailwind CSS, improving development efficiency and style consistency
|
||||
- Icon solution upgraded: Iconfont replaced with Iconify, supporting richer icon libraries and on-demand loading
|
||||
- Route registration refactored: Comprehensive refactoring of route registration system with object-oriented design, improving code maintainability, testability and extensibility
|
||||
- Refactored ArtTextScroll component, improving performance and maintainability
|
||||
- Refactored color system, unified UI visual specifications, improving interface consistency
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Build optimization: Complete package size reduced by 1.3 MB, significantly improving loading performance
|
||||
- Architecture optimization: Optimized directory structure with clearer responsibility division, reducing user learning curve and onboarding difficulty
|
||||
- Comment optimization: Unified module comment standards, improved component descriptions, feature explanations and usage examples, reducing user understanding cost and onboarding difficulty
|
||||
- Performance improvement: Optimized core code logic, improving system runtime efficiency
|
||||
- Menu optimization: Refined menu styles, optimized interaction experience and visual presentation
|
||||
- Responsive optimization: Optimized ArtForm and ArtSearchBar grid layout, adapting to various screen sizes
|
||||
- Configuration management optimization: Added setting.ts configuration file, supporting one-click copy and reset of system default settings
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed ArtForm and ArtSearchBar custom component rendering issues
|
||||
|
||||
#### Added
|
||||
|
||||
- ArtForm and ArtSearchBar added render property, supporting custom component rendering
|
||||
- Festival feature enhancement: Fireworks configuration supports cross-date range settings and custom playback counts
|
||||
|
||||
#### Upgraded
|
||||
|
||||
- Dependency updates: Upgraded core dependencies to latest stable versions
|
||||
|
||||
#### ⚠️ Important Notice
|
||||
|
||||
> This upgrade involves fundamental refactoring of the style system (Sass → Tailwind CSS) and icon library (Iconfont → Iconify), which is a breaking change. It is recommended to use v3.0 for new projects. Upgrading existing projects is not recommended.
|
||||
|
||||
---
|
||||
|
||||
### v2.6.1 - 2025-10-19
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed repeated API calls issue when accessing invalid addresses for user info and menu endpoints
|
||||
- Fixed ElButton circle mode styles
|
||||
- Fixed ElSelect keyboard selection issue
|
||||
- Fixed static routes with parameters redirecting to login page issue
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Upgraded some dependencies to be compatible with tailwindcss
|
||||
- Optimized external link menu click selection state
|
||||
- Added theme color switching feature to authorization pages
|
||||
|
||||
---
|
||||
|
||||
### v2.6.0 - 2025-10-16
|
||||
|
||||
#### Added
|
||||
|
||||
- Extended registration and password reset page top component support
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Optimized streamlined version menu data structure, improved data consistency
|
||||
- Optimized local development environment network request proxy configuration
|
||||
- Optimized ElTree component default styles
|
||||
- Added VsCode recommended plugin related configuration
|
||||
- Optimized ElDropdown component click trigger mode interaction styles
|
||||
- Optimized menu filtering logic
|
||||
- Optimized page switching animation, improved loading speed
|
||||
- Optimized dark mode text color
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed static route custom home page path first visit redirecting to login page issue
|
||||
- Fixed logout briefly jumping to 500 page issue
|
||||
- Fixed v2.5.9 version home route redirect configuration failure issue
|
||||
- Fixed v2.5.9 auto-import mechanism causing build exception
|
||||
|
||||
#### ⚠️ Important Notice
|
||||
|
||||
> This version requires re-login
|
||||
|
||||
---
|
||||
|
||||
### v2.5.9 - 2025-10-12
|
||||
|
||||
#### Code Optimized
|
||||
|
||||
- Optimized views file directory, file names, and code
|
||||
- Added global configuration for useTable pagination request fields (tableConfig.ts)
|
||||
- Optimized routing configuration to modular structure
|
||||
- Menu API now uses apifox mock data (set VITE_ACCESS_MODE to backend mode in .env)
|
||||
|
||||
---
|
||||
|
||||
### v2.5.8 - 2025-09-29
|
||||
|
||||
#### Upgraded
|
||||
|
||||
- Upgraded core libraries including vue, vite, element-plus
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed rich text editor fullscreen top bar z-index issue
|
||||
- Fixed table column sorting component text overflow issue
|
||||
- Fixed statistics card condition judgment
|
||||
- Fixed infinite redirect when root path / and HOME_PAGE_PATH are both /
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Optimized el-tag styles
|
||||
- Optimized top progress bar color
|
||||
- Optimized custom theme configuration
|
||||
- Optimized ElementPlus custom theme issues
|
||||
|
||||
#### ⚠️ Important Notice
|
||||
|
||||
> Due to dependency upgrades, Node version needs to be upgraded to v20.19.0 or above
|
||||
|
||||
---
|
||||
|
||||
### v2.5.7 - 2025-09-14
|
||||
|
||||
#### Added
|
||||
|
||||
- Added ArtForm component
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed theme switching flicker issue in new Chrome versions
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Optimized form label height alignment issue
|
||||
- First screen startup performance optimization
|
||||
|
||||
---
|
||||
|
||||
### v2.5.6 - 2025-09-06
|
||||
|
||||
#### Added
|
||||
|
||||
- ArtTableHeader added search button to control top search bar visibility
|
||||
- Added permission demonstration examples
|
||||
- Added global error handling framework
|
||||
|
||||
#### Optimized
|
||||
|
||||
- useTable type inference optimization, no need to manually pass types for type hints
|
||||
- useTable removeColumn supports multiple data deletion
|
||||
- useTable auto-recognizes response body with custom configuration (src/utils/table/tableConfig.ts)
|
||||
- useTable empty data browser warning optimization
|
||||
- API request code optimization, api.d.ts type optimization
|
||||
- Optimized ArtTable top button wrapping adaptive issue
|
||||
- ArtTable pagination component selection style optimization
|
||||
- ArtTable empty state height fills by default
|
||||
- ArtButtonMore component added icon and color configuration
|
||||
- ArtSearchBar label doesn't occupy space when empty
|
||||
- Table operation column drag prohibits fixed column dragging
|
||||
- Role management page API integration and code optimization
|
||||
- Menu management page optimization
|
||||
- Optimized settings center scroll following issue
|
||||
- First-level route external link component validation logic optimization
|
||||
- Optimized map bottom-right drag issue
|
||||
- Optimized dark mode page refresh white background issue
|
||||
- Optimized left menu collapse button spacing issue
|
||||
- Mobile displays left menu logo
|
||||
- Network request added showSuccessMessage to configure success message display
|
||||
- Global components use async loading strategy to improve first screen loading performance
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed bug where batch deleting entire page data doesn't return to previous page
|
||||
- Fixed dynamic route parameter issues
|
||||
- Fixed dynamic route configuration first-level route iframe page fullscreen issue
|
||||
|
||||
---
|
||||
|
||||
### v2.5.5 - 2025-08-17
|
||||
|
||||
#### Added
|
||||
|
||||
- Added ArtSearchBar component examples
|
||||
- useTable added excludeParams to exclude certain parameters from requests
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Refactored ArtSearchBar component, supports more components and form validation
|
||||
|
||||
#### Optimized
|
||||
|
||||
- useTable column configuration: supports dynamic update capability
|
||||
- Optimized color picker border radius
|
||||
- Unified el-radio and el-checkbox sizes
|
||||
- art-stats-card added decimal places and separator configuration
|
||||
- Route configuration example optimization
|
||||
- Advanced table added custom data fetching example
|
||||
- Optimized path alias type issues
|
||||
- Local development CORS configuration optimization
|
||||
- useTable property and method naming optimization
|
||||
- Login page UI upgrade
|
||||
- 403, 404, 500 page UI upgrade
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed multiple rich text editor icon inconsistency issue
|
||||
- Fixed useTable deleting last entire page data not returning to previous page issue
|
||||
- Fixed echarts chart data initialization and update browser error
|
||||
- Network request supports logout on HTTP status code 401
|
||||
- Optimized network request logout multiple prompt issue
|
||||
|
||||
#### Removed
|
||||
|
||||
- Removed art-chart-empty component
|
||||
|
||||
---
|
||||
|
||||
### v2.5.4 - 2025-07-27
|
||||
|
||||
#### Added
|
||||
|
||||
- Network request headers support custom configuration
|
||||
- Expand row supports formatter rendering
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Route registration added component validation
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed user info API timing issue causing route registration menu rendering error
|
||||
- Fixed dynamic route validation issue causing iframe not to display
|
||||
- Fixed reset file syntax error
|
||||
- Fixed ArtTable data type error
|
||||
- Fixed map scroll wheel zoom issue
|
||||
|
||||
---
|
||||
|
||||
### v2.5.3 - 2025-07-20
|
||||
|
||||
#### Added
|
||||
|
||||
- Added table left-right layout example
|
||||
|
||||
#### Refactored
|
||||
|
||||
- ArtTable component refactored
|
||||
|
||||
#### Upgraded
|
||||
|
||||
- Element Plus upgraded to v2.10.2
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Optimized useTable pagination parameter issue
|
||||
- Optimized network request example: initialization parameters, pagination carrying parameters
|
||||
- Optimized search date range parameter handling
|
||||
- Optimized el-date-picker component border radius
|
||||
- Optimized el-select component hover style
|
||||
- Search component and pagination component height reduced
|
||||
- Optimized login page slider animation interval
|
||||
- Optimized menu without submenu display issue
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed ArtTable switching page size executing two requests bug
|
||||
|
||||
---
|
||||
|
||||
### v2.5.2 - 2025-07-13
|
||||
|
||||
#### Added
|
||||
|
||||
- Added one-click cleanup script for quick development environment preparation
|
||||
- useTable hooks support custom pagination field name mapping
|
||||
- Horizontal menu, mixed menu, double column menu support badge display
|
||||
- Quick entry supports configuration file mode
|
||||
- Top bar function supports configuration file mode
|
||||
- Support custom home page path
|
||||
- Route supports redirect and other attributes configuration
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Global event bus mittBus type safety optimization
|
||||
- Optimized mobile settings container width style
|
||||
- Optimized login page verification slider text centering effect
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed table no data header not displaying issue
|
||||
- Fixed v2.5.0 top progress bar not displaying issue
|
||||
- Fixed left menu mask abnormal display issue
|
||||
- Fixed hiding all submenus still showing parent menu issue
|
||||
- Fixed stylelint causing login page slider style abnormality
|
||||
- Fixed old mobile device loading positioning issue
|
||||
|
||||
---
|
||||
|
||||
### v2.5.1 - 2025-07-08
|
||||
|
||||
#### Optimized
|
||||
|
||||
- el-card and el-table background color consistent with system
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed first login system loading closing early bug
|
||||
- Fixed v2.5.0 version causing fullscreen page style z-index too low bug
|
||||
- Fixed v2.5.0 version causing table expand row collapse bug
|
||||
|
||||
---
|
||||
|
||||
### v2.5.0 - 2025-07-06 🎉
|
||||
|
||||
#### Added
|
||||
|
||||
- Added useTable hooks table encapsulation, supports data fetching, transformation, response adaptation, intelligent caching (based on LRU algorithm), error handling, column configuration and slots, pagination control, refresh strategies and other core functions, comprehensively improving development efficiency and user experience
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Refactored ArtTable, ArtTableHeader, ArtNotification components
|
||||
|
||||
#### Upgraded
|
||||
|
||||
- Echarts version upgraded to 5.6.0
|
||||
|
||||
#### Removed
|
||||
|
||||
- Removed CountTo plugin, replaced with ArtCountTo component
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed menu management search directly modifying pinia data issue
|
||||
- Fixed route guard loading flicker issue
|
||||
|
||||
#### ⚠️ Important Notice
|
||||
|
||||
> Recommended upgrade for more efficient and intelligent table development experience
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.9 - 2025-07-02
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Menu layout and top navigation code refactored
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Optimized mobile menu scroll user experience
|
||||
- Optimized top menu style issues
|
||||
- Top menu width adaptive, can display more content, mixed menu supports mouse scroll
|
||||
- asyncRoutes route configuration auth_mark field changed to authMark
|
||||
- Removed duplicate components.d.ts file, components.d.ts and auto-imports.d.ts ignored from commits
|
||||
- Optimized i18n language file loading method, changed from async to sync mode
|
||||
- Optimized el-pagination size inconsistency issue
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed mobile lock screen page some browsers unable to unlock bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.8 - 2025-06-26
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed v2.4.2.7 version accessing / path showing 404 issue
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.7 - 2025-06-25
|
||||
|
||||
#### Added
|
||||
|
||||
- Route supports fullscreen mode configuration
|
||||
- Route supports auto-jump to first valid route of menu
|
||||
- Dynamic route added removeAllDynamicRoutes method for completely clearing all dynamic routes
|
||||
- Permission custom directive optimization, added role permission directive v-roles for controlling element visibility
|
||||
- Added tab operation examples
|
||||
|
||||
#### Optimized
|
||||
|
||||
- CORS request carrying cookie configuration from environment variables, disabled by default
|
||||
- Some optimizations for SEO and accessibility
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed login page drag component ArtDragVerify width and color abnormal bug
|
||||
- Fixed iframe page mixed mode and double column mode abnormal bug
|
||||
- Optimized lock screen page being penetrated by el-loading bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.6 - 2025-06-23
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Refactored form-related components in components/core/forms folder, improved maintainability and consistency
|
||||
- Refactored ArtBreadcrumb breadcrumb navigation component, optimized logic structure and styles
|
||||
- Refactored ArtFireworksEffect fireworks effect component, significantly improved rendering performance and animation smoothness
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Optimized ArtChatWindow and ArtFastEnter component code, improved readability and performance
|
||||
|
||||
#### Added
|
||||
|
||||
- README documentation added official website link for easy access to project documentation
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.5 - 2025-06-22
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Refactored chart components, optimized code structure and maintainability
|
||||
- Fine-tuned chart animations and theme color schemes, improved visual consistency
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.4 - 2025-06-18
|
||||
|
||||
#### Refactored
|
||||
|
||||
- ArtMenuRight component refactored
|
||||
- Components under components/core/cards refactored, code optimized
|
||||
|
||||
#### Optimized
|
||||
|
||||
- ArtWatermark added type annotations
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.3 - 2025-06-18
|
||||
|
||||
#### Refactored
|
||||
|
||||
- ArtResultPage component refactored
|
||||
|
||||
#### Optimized
|
||||
|
||||
- ArtTextScroll component code optimization
|
||||
- ArtException component added type hints
|
||||
- ArtCutterImg component style optimization, added type definitions
|
||||
- ArtVideoPlayer component added type definitions
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.2 - 2025-06-16
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Back to top component refactored
|
||||
- Icon selector component refactored
|
||||
|
||||
#### Changed
|
||||
|
||||
- System Logo component property changes
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.1 - 2025-06-16
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Banner component refactored and optimized
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed mixed menu first menu nested menu jump bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2 - 2025-06-14
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Refactored network request module, enhanced error handling, type safety and multi-language support
|
||||
|
||||
#### Added
|
||||
|
||||
- Route configuration added activePath active menu path property
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Guide and column settings multi-language improvement
|
||||
- Removed invalid code from user list and menu management pages
|
||||
- Updated technical support link
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed mobile search bar unable to scroll, iPad page scroll abnormal issue
|
||||
- Fixed el-dialog enabling draggable property causing custom animation failure issue
|
||||
- Fixed v2.3.0 local storage refactoring causing login, registration page multi-language settings unable to persist issue
|
||||
- Fixed table fixed column not working bug
|
||||
- Fixed infinite redirect when root path / and HOME_PAGE_PATH are both /
|
||||
|
||||
#### ⚠️ Important Notice
|
||||
|
||||
> This version requires re-login
|
||||
|
||||
---
|
||||
|
||||
### v2.4.1.1 - 2025-06-07
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Optimized role management page code
|
||||
- el-dialog visual effect optimization, supports line configuration
|
||||
- System theme mode changed from Light to follow system mode
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed menu management collapse bug
|
||||
- Fixed table empty data height infinitely growing bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.1 - 2025-06-07
|
||||
|
||||
#### Added
|
||||
|
||||
- Prohibit using developer tools to crack lock screen when locked
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Improved menu operation responsiveness
|
||||
- Page entrance animation time reduced by 0.04s
|
||||
- Echarts chart performance optimization, added visible area initialization, memory leak protection, debounce handling
|
||||
|
||||
#### Fixed
|
||||
|
||||
- Fixed Echarts chart component not displaying in dialog bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.0 - 2025-06-06 🎉
|
||||
|
||||
#### Refactored
|
||||
|
||||
- Global TypeScript type system refactored, improved type accuracy and maintainability
|
||||
- Refactored utils toolkit, unified utility method structure, enhanced readability and reusability
|
||||
|
||||
#### Added
|
||||
|
||||
- utils added form validation and Cookie operation related utility functions
|
||||
- Page components added defineOptions for explicit component naming
|
||||
- HTTP request added token expiration auto-handling logic, improved security and user experience
|
||||
|
||||
#### Optimized
|
||||
|
||||
- Deleted unused utility modules and invalid resources, streamlined project size
|
||||
- Optimized views page structure, removed redundant page files
|
||||
- Exception page multi-language support, improved internationalization experience
|
||||
- Image resources uniformly converted to webp format, overall resource size reduced by about 50%
|
||||
- Build output reduced by about 1MB, improved loading efficiency
|
||||
|
||||
#### ⚠️ Important Notice
|
||||
|
||||
> This version requires re-login
|
||||
|
||||
---
|
||||
|
||||
## Version Guidelines
|
||||
|
||||
### Version Number Rules
|
||||
|
||||
This project follows [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html):
|
||||
|
||||
- **Major**: Incompatible API changes
|
||||
- **Minor**: Backwards-compatible functionality additions
|
||||
- **Patch**: Backwards-compatible bug fixes
|
||||
|
||||
### Change Types
|
||||
|
||||
- **Added**: New features
|
||||
- **Changed**: Changes to existing functionality
|
||||
- **Deprecated**: Soon-to-be removed features
|
||||
- **Removed**: Removed features
|
||||
- **Fixed**: Bug fixes
|
||||
- **Security**: Security-related fixes
|
||||
- **Optimized**: Performance or experience optimizations
|
||||
- **Refactored**: Code refactoring
|
||||
- **Upgraded**: Dependency upgrades
|
||||
|
||||
### Important Notice Markers
|
||||
|
||||
- 🎉 **Major Update**: Versions with important new features
|
||||
- ⚠️ **Breaking Changes**: Updates requiring special attention for incompatibility
|
||||
- 🔒 **Security Update**: Versions fixing security vulnerabilities
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
If you want to contribute to the project, please check [CONTRIBUTING.md](./CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
[MIT License](./LICENSE)
|
||||
|
||||
---
|
||||
|
||||
**Note**: This changelog starts recording from version v2.4.0. For earlier version history, please check Git commit records.
|
||||
|
||||
@@ -1,654 +0,0 @@
|
||||
# 更新日志
|
||||
|
||||
所有重要的项目变更都将记录在此文件中。
|
||||
|
||||
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
||||
|
||||
## [已发布]
|
||||
|
||||
### v3.0.1 - 2025-11-15
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复路由注册时不存在接口的重复请求问题
|
||||
- 修复一键精简脚本打包失败的问题
|
||||
|
||||
#### 优化
|
||||
|
||||
- 完善路由配置验证机制,自动检测并提示非一级菜单的路径配置错误
|
||||
- 优化顶部进度条残影问题
|
||||
- 优化 vite 预构建配置
|
||||
- 优化圆角、边框统一性
|
||||
- 重新设计锁屏页面,提升视觉体验
|
||||
- 优化退出登录菜单提前消失造成的视觉体验不好问题
|
||||
|
||||
#### 新增
|
||||
|
||||
- ArtForm 和 ArtSearchBar 组件的 label 支持自定义渲染函数,可实现带 tooltip 等复杂标签
|
||||
- 菜单管理表单关键字段新增 Tooltip 提示,降低用户配置门槛
|
||||
- iconify 新增离线图标加载模式
|
||||
- 退出登录新增 redirect 属性,用于重新登录后跳转到对应页面
|
||||
- 退出登录重新进入系统保留用户标签页,根据 userId 进行身份识别
|
||||
- 双列菜单新增折叠按钮
|
||||
- 完善菜单图标
|
||||
- 多标签页增加图标显示
|
||||
- 新增 WebSocket 连接示例
|
||||
- 锁屏密码错误时增加输入框抖动动效
|
||||
|
||||
#### ⚠️ 重要提示
|
||||
|
||||
> 此版本需要重新登录
|
||||
|
||||
---
|
||||
|
||||
### v3.0.0 - 2025-11-09 🎉
|
||||
|
||||
#### 重构
|
||||
|
||||
- 样式系统重构:Sass 全面迁移至 Tailwind CSS,提升开发效率与样式一致性
|
||||
- 图标方案升级:Iconfont 替换为 Iconify,支持更丰富的图标库与按需加载
|
||||
- 路由注册重构:全面重构路由注册系统,引入面向对象设计,提高代码的可维护性、可测试性和扩展能力
|
||||
- 重构 ArtTextScroll 组件,提升性能与可维护性
|
||||
- 重构颜色体系,统一 UI 视觉规范,提升界面一致性
|
||||
|
||||
#### 优化
|
||||
|
||||
- 构建优化:完整包体积减少 1.3 MB,显著提升加载性能
|
||||
- 架构优化:优化目录结构,职责划分更清晰,降低用户学习成本与上手难度
|
||||
- 注释优化:统一模块注释规范,完善每一个组件介绍、功能说明与使用示例,降低用户理解成本与上手难度
|
||||
- 性能提升:优化核心代码逻辑,提升系统运行效率
|
||||
- 菜单优化:细化菜单样式,优化交互体验与视觉呈现
|
||||
- 响应式优化:优化 ArtForm、ArtSearchBar 栅格布局,适配多种屏幕尺寸
|
||||
- 配置管理优化:新增 setting.ts 配置文件,支持一键复制与重置系统默认设置
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 ArtForm、ArtSearchBar 自定义组件渲染异常
|
||||
|
||||
#### 新增
|
||||
|
||||
- ArtForm、ArtSearchBar 新增 render 属性,支持自定义组件渲染
|
||||
- 节日功能增强:礼花配置支持跨日期范围设置与自定义播放次数
|
||||
|
||||
#### 升级
|
||||
|
||||
- 依赖更新:升级核心依赖至最新稳定版本
|
||||
|
||||
#### ⚠️ 重要提示
|
||||
|
||||
> 本次升级涉及样式系统(Sass → Tailwind CSS)与图标库(Iconfont → Iconify)的底层重构,属于破坏性更新。建议新项目直接使用 v3.0,旧版本项目不建议升级。
|
||||
|
||||
---
|
||||
|
||||
### v2.6.1 - 2025-10-19
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复获取用户信息、获取菜单接口访问无效地址重复调用问题
|
||||
- 修复 ElButton circle 模式样式
|
||||
- 修复 ElSelect 无法通过键盘选择问题
|
||||
- 修复带参数静态路由跳转登录页面问题
|
||||
|
||||
#### 优化
|
||||
|
||||
- 升级部分依赖兼容 tailwindcss
|
||||
- 优化外部链接菜单点击选中状态
|
||||
- 授权页增加主题色切换功能
|
||||
|
||||
---
|
||||
|
||||
### v2.6.0 - 2025-10-16
|
||||
|
||||
#### 新增
|
||||
|
||||
- 扩展注册、密码重置页面顶部组件支持
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化精简版本菜单数据结构,提升数据一致性
|
||||
- 优化本地开发环境网络请求代理配置
|
||||
- 优化 ElTree 组件默认样式
|
||||
- 新增 VsCode 推荐插件相关配置
|
||||
- 优化 ElDropdown 组件点击触发模式下的交互样式
|
||||
- 优化菜单过滤逻辑
|
||||
- 优化页面切换动画,提升加载速度
|
||||
- 优化暗黑模式文字颜色
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复静态路由自定义首页路径首次访问跳转登录页问题
|
||||
- 修复退出登录时短暂跳转至 500 页的问题
|
||||
- 修复 v2.5.9 版本首页路由跳转配置失效问题
|
||||
- 修复 v2.5.9 自动导包机制导致的构建异常
|
||||
|
||||
#### ⚠️ 重要提示
|
||||
|
||||
> 此版本需要重新登录
|
||||
|
||||
---
|
||||
|
||||
### v2.5.9 - 2025-10-12
|
||||
|
||||
#### 代码优化
|
||||
|
||||
- views 文件目录、文件名、代码优化
|
||||
- useTable 分页请求字段增加全局配置 tableConfig.ts
|
||||
- 优化路由配置为模块化结构
|
||||
- 获取菜单接口使用 apifox mock 数据(需在 .env 中将 VITE_ACCESS_MODE 设为 backend 模式)
|
||||
|
||||
---
|
||||
|
||||
### v2.5.8 - 2025-09-29
|
||||
|
||||
#### 升级
|
||||
|
||||
- vue、vite、element-plus 等核心库升级
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复富文本编辑器全屏顶栏层级问题
|
||||
- 修复表格列排序组件文字溢出问题
|
||||
- 修复统计卡片条件判断
|
||||
- 修复根路径 / 与 HOME_PAGE_PATH 同为 / 时出现的无限重定向
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化 el-tag 样式
|
||||
- 优化顶部进度条颜色
|
||||
- 优化自定义主题配置
|
||||
- 优化 ElementPlus 自定义主题问题
|
||||
|
||||
#### ⚠️ 重要提示
|
||||
|
||||
> 由于项目依赖升级,node 版本需要升级到 v20.19.0 或以上
|
||||
|
||||
---
|
||||
|
||||
### v2.5.7 - 2025-09-14
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增 ArtForm 组件
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复新版本谷歌浏览器切换主题闪烁问题
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化表单 label 高度没有对齐问题
|
||||
- 首屏启动性能优化
|
||||
|
||||
---
|
||||
|
||||
### v2.5.6 - 2025-09-06
|
||||
|
||||
#### 新增
|
||||
|
||||
- ArtTableHeader 新增搜索按钮,用于控制顶部搜索栏的显示与隐藏
|
||||
- 新增权限演示示例
|
||||
- 添加全局错误处理基础框架
|
||||
|
||||
#### 优化
|
||||
|
||||
- useTable 类型推导优化,不需要手动传递类型即可实现类型提示
|
||||
- useTable removeColumn 支持多数据删除
|
||||
- useTable 自动识别响应体支持自定义配置 (src/utils/table/tableConfig.ts)
|
||||
- useTable 空数据浏览器警告优化
|
||||
- api 接口请求代码优化、api.d.ts 类型优化
|
||||
- 优化 ArtTable 顶部按钮换行无法自适应问题(示例:功能示例 / 左右布局表格)
|
||||
- ArtTable 分页组件选中样式优化
|
||||
- ArtTable 空状态高度默认撑满
|
||||
- ArtButtonMore 组件新增图标、颜色配置
|
||||
- ArtSearchBar label 为空时不占空间
|
||||
- 表格操作栏拖拽禁止固定列拖拽
|
||||
- 角色管理页面接口对接、代码优化
|
||||
- 菜单管理页面优化
|
||||
- 优化设置中心滚动页面跟随滚动问题
|
||||
- 一级路由是外链时,component 校验逻辑优化
|
||||
- 优化地图右下角拖动问题
|
||||
- 优化暗黑模式刷新页面白色背景问题
|
||||
- 优化左侧菜单折叠按钮间距问题
|
||||
- 移动端显示左侧菜单 logo
|
||||
- 网络请求新增 showSuccessMessage,用于配置是否显示成功消息
|
||||
- 全局组件采用异步加载策略,提升首屏加载性能
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复批量删除整页数据没有返回上一页的bug
|
||||
- 修复动态路由参数导致的问题
|
||||
- 修复动态路由配置一级路由是 iframe 页面时,全屏问题
|
||||
|
||||
---
|
||||
|
||||
### v2.5.5 - 2025-08-17
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增 ArtSearchBar 组件示例
|
||||
- useTable 新增 excludeParams,用于排除某些参数不参与请求
|
||||
|
||||
#### 重构
|
||||
|
||||
- 重构 ArtSearchBar 组件,支持更多组件、表单校验等能力
|
||||
|
||||
#### 优化
|
||||
|
||||
- useTable 列配置:支持动态更新能力
|
||||
- 优化颜色选择器圆角
|
||||
- el-radio、el-checkbox 统一大小
|
||||
- art-stats-card 新增小数位、分隔符配置
|
||||
- 路由配置示例优化
|
||||
- 高级表格新增自定义获取数据示例(等待其他请求完成后执行 useTable 数据获取)
|
||||
- 优化路径别名类型问题
|
||||
- 本地开发跨域配置优化
|
||||
- useTable 属性、方法命名优化
|
||||
- 登录页UI升级
|
||||
- 403、404、500 页面UI升级
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复多个富文本编辑器图标不统一问题
|
||||
- 修复 useTable 删除最后一整页数据没有返回上一页的问题
|
||||
- 修复 echarts 图表数据初始化、更新数据浏览器报错
|
||||
- 网络请求支持 http 状态码为 401 时退出登录
|
||||
- 优化网络请求退出登录多次提示问题
|
||||
|
||||
#### 移除
|
||||
|
||||
- 删除 art-chart-empty 组件
|
||||
|
||||
---
|
||||
|
||||
### v2.5.4 - 2025-07-27
|
||||
|
||||
#### 新增
|
||||
|
||||
- 网络请求 headers 支持自定义配置
|
||||
- 展开行支持 formatter 渲染
|
||||
|
||||
#### 优化
|
||||
|
||||
- 路由注册新增 component 校验
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复获取用户信息接口时序问题导致路由注册菜单渲染错误bug
|
||||
- 修复动态路由校验问题导致的 iframe 不显示bug
|
||||
- 修复 reset 文件语法错误
|
||||
- 修复 ArtTable 数据类型错误
|
||||
- 修复地图滚轮滚动放大问题
|
||||
|
||||
---
|
||||
|
||||
### v2.5.3 - 2025-07-20
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增表格左右布局示例
|
||||
|
||||
#### 重构
|
||||
|
||||
- ArtTable 组件重构
|
||||
|
||||
#### 升级
|
||||
|
||||
- Element Plus 升级到 v2.10.2
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化 useTable 分页参数问题
|
||||
- 优化网络请求示例:初始化参数、分页携带参数问题
|
||||
- 优化搜索日期范围参数处理
|
||||
- 优化 el-date-picker 组件圆角问题
|
||||
- 优化 el-select 组件 hover 样式
|
||||
- 搜索组件、分页组件高度降低
|
||||
- 优化登录页面滑块动画间隔时长
|
||||
- 优化菜单没有子菜单显示的问题
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 ArtTable 切换分页大小时执行两次请求bug
|
||||
|
||||
---
|
||||
|
||||
### v2.5.2 - 2025-07-13
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增一键精简脚本,快速准备开发环境
|
||||
- useTable hooks 支持分页字段名自定义映射
|
||||
- 水平菜单、混合菜单、双列菜单支持徽章显示
|
||||
- 快速入口支持配置文件模式
|
||||
- 顶栏功能支持配置文件模式
|
||||
- 支持自定义首页路径
|
||||
- 路由支持配置 redirect 等属性
|
||||
|
||||
#### 优化
|
||||
|
||||
- 全局事件总线 mittBus 类型安全优化
|
||||
- 优化移动端设置中容器宽度样式
|
||||
- 优化登录页验证滑块文字居中效果
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复表格无数据时表头不显示问题
|
||||
- 修复 v2.5.0 顶部进度条不显示问题
|
||||
- 修复左侧菜单遮罩异常显示问题
|
||||
- 修复隐藏所有子菜单时仍显示父级菜单的问题
|
||||
- 修复 stylelint 导致的登录页滑块样式异常
|
||||
- 修复老旧移动端设备 loading 定位问题
|
||||
|
||||
---
|
||||
|
||||
### v2.5.1 - 2025-07-08
|
||||
|
||||
#### 优化
|
||||
|
||||
- el-card、el-table 背景色跟系统保持一致
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复首次登录系统时 loading 提前关闭bug
|
||||
- 修复 v2.5.0 版本引起的全屏页样式层级过低bug
|
||||
- 修复 v2.5.0 版本引起的表格展开行折叠bug
|
||||
|
||||
---
|
||||
|
||||
### v2.5.0 - 2025-07-06 🎉
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增 useTable hooks 表格封装,支持数据获取、转换、响应适配、智能缓存(基于 LRU 算法)、错误处理、列配置与插槽、分页控制、刷新策略等核心功能,全面提升开发效率与用户体验
|
||||
|
||||
#### 重构
|
||||
|
||||
- 重构 ArtTable、ArtTableHeader、ArtNotification 组件
|
||||
|
||||
#### 升级
|
||||
|
||||
- Echarts 版本升级到 5.6.0
|
||||
|
||||
#### 移除
|
||||
|
||||
- 移除 CountTo 插件,替换为 ArtCountTo 组件
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复菜单管理搜索直接修改 pinia 数据的问题
|
||||
- 修复路由守卫 loading 闪烁问题
|
||||
|
||||
#### ⚠️ 重要提示
|
||||
|
||||
> 建议升级,带来更高效、更智能的表格开发体验
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.9 - 2025-07-02
|
||||
|
||||
#### 重构
|
||||
|
||||
- 菜单布局、顶部导航代码重构
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化移动端菜单滚动用户体验
|
||||
- 优化顶部菜单样式问题
|
||||
- 顶部菜单宽度自适应,可显示更多内容,混合菜单支持鼠标滚动
|
||||
- asyncRoutes 路由配置 auth_mark 字段改为 authMark
|
||||
- 去除重复的 components.d.ts 文件,components.d.ts、auto-imports.d.ts 忽略提交
|
||||
- 优化国际化语言文件加载方式,异步改成同步模式
|
||||
- 优化 el-pagination 大小不一致问题
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复移动端锁屏页部分浏览器无法解锁bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.8 - 2025-06-26
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 v2.4.2.7 版本访问 / 路径时显示 404 的问题
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.7 - 2025-06-25
|
||||
|
||||
#### 新增
|
||||
|
||||
- 路由支持配置全屏模式
|
||||
- 路由支持自动跳转到菜单的第一个有效路由
|
||||
- 动态路由新增 removeAllDynamicRoutes 方法,可用于彻底清除所有动态路由
|
||||
- 权限自定义指令优化、新增角色权限指令 v-roles、可用于控制元素的显示与隐藏
|
||||
- 新增标签页操作示例
|
||||
|
||||
#### 优化
|
||||
|
||||
- 跨域请求携带 cookie 配置从环境变量中获取,默认关闭
|
||||
- 针对SEO、可访问性做一些优化
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复登录页面拖拽组件 ArtDragVerify 宽度、颜色异常bug
|
||||
- 修复 iframe 页面混合模式、双列模式异常bug
|
||||
- 优化锁屏页面被 el-loading 穿透bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.6 - 2025-06-23
|
||||
|
||||
#### 重构
|
||||
|
||||
- 重构 components/core/forms 文件夹下的表单相关组件,提升可维护性与一致性
|
||||
- 重构 ArtBreadcrumb 面包屑导航组件,优化逻辑结构与样式
|
||||
- 重构 ArtFireworksEffect 烟花效果组件,显著提升渲染性能与动画流畅度
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化 ArtChatWindow 与 ArtFastEnter 组件代码,提升可读性与性能
|
||||
|
||||
#### 新增
|
||||
|
||||
- README 文档新增官方网站链接,便于用户查看项目文档
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.5 - 2025-06-22
|
||||
|
||||
#### 重构
|
||||
|
||||
- 重构图表组件,优化代码结构与可维护性
|
||||
- 精细调整图表动画与主题配色方案,提升视觉一致性
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.4 - 2025-06-18
|
||||
|
||||
#### 重构
|
||||
|
||||
- ArtMenuRight 组件重构
|
||||
- components/core/cards 下面的组件重构,代码优化
|
||||
|
||||
#### 优化
|
||||
|
||||
- ArtWatermark 增加类型注释
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.3 - 2025-06-18
|
||||
|
||||
#### 重构
|
||||
|
||||
- ArtResultPage 组件重构
|
||||
|
||||
#### 优化
|
||||
|
||||
- ArtTextScroll 组件代码优化
|
||||
- ArtException 组件增加类型提示
|
||||
- ArtCutterImg 组件样式优化、增加类型定义
|
||||
- ArtVideoPlayer 组件增加类型定义
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.2 - 2025-06-16
|
||||
|
||||
#### 重构
|
||||
|
||||
- 返回顶部组件重构
|
||||
- 图标选择器组件重构
|
||||
|
||||
#### 修改
|
||||
|
||||
- 系统Logo组件属性变更
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2.1 - 2025-06-16
|
||||
|
||||
#### 重构
|
||||
|
||||
- 横幅组件重构以及优化
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复混合菜单下第一个菜单是嵌套菜单跳转bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.2 - 2025-06-14
|
||||
|
||||
#### 重构
|
||||
|
||||
- 重构网络请求模块,增强错误处理、类型安全与多语言支持
|
||||
|
||||
#### 新增
|
||||
|
||||
- 路由配置新增 activePath 激活菜单路径属性
|
||||
|
||||
#### 优化
|
||||
|
||||
- 引导、列设置多语言完善
|
||||
- 去除用户列表、菜单管理页面无效代码
|
||||
- 更新技术支持链接
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复移动端搜索栏无法滚动、iPad端页面滚动异常问题
|
||||
- 修复 el-dialog 启用 draggable 属性后,自定义动画失效的问题
|
||||
- 修复 2.3.0 版本本地存储重构后,导致登录、注册等页面多语言设置无法持久化的问题
|
||||
- 修复表格固定列不起作用bug
|
||||
- 修复根路径 / 与 HOME_PAGE_PATH 同为 / 时出现的无限重定向
|
||||
|
||||
#### ⚠️ 重要提示
|
||||
|
||||
> 此版本需要重新登录
|
||||
|
||||
---
|
||||
|
||||
### v2.4.1.1 - 2025-06-07
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化角色管理页面代码
|
||||
- el-dialog视觉效果优化,支持配置线条
|
||||
- 系统主题模式从Light改成跟随系统模式
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复菜单管理折叠 bug
|
||||
- 修复表格数据为空高度无限变大bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.1 - 2025-06-07
|
||||
|
||||
#### 新增
|
||||
|
||||
- 锁屏状态下禁止使用开发者工具破解锁屏
|
||||
|
||||
#### 优化
|
||||
|
||||
- 提升菜单操作跟手感
|
||||
- 页面入场动画时间减少0.04s
|
||||
- Echarts 图表性能优化,新增可视区域初始化、内存泄漏防护、防抖处理
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 Echarts 图表组件在弹窗中不显示的 bug
|
||||
|
||||
---
|
||||
|
||||
### v2.4.0 - 2025-06-06 🎉
|
||||
|
||||
#### 重构
|
||||
|
||||
- 全局 TypeScript 类型体系重构,提升类型准确性与可维护性
|
||||
- 重构 utils 工具包,统一工具方法结构,增强可读性与复用性
|
||||
|
||||
#### 新增
|
||||
|
||||
- utils 新增表单验证与 Cookie 操作相关工具函数
|
||||
- 页面组件增加 defineOptions,明确组件命名
|
||||
- HTTP 请求增加 token 过期自动处理逻辑,提升安全性与用户体验
|
||||
|
||||
#### 优化
|
||||
|
||||
- 删除未使用的工具模块与无效资源,精简项目体积
|
||||
- 优化 views 页面结构,移除冗余页面文件
|
||||
- 异常页面多语言支持, 提升国际化体验
|
||||
- 图片资源统一转换为 webp 格式,整体资源体积减少约 50%
|
||||
- 打包产物减少约 1MB,提高加载效率
|
||||
|
||||
#### ⚠️ 重要提示
|
||||
|
||||
> 此版本需要重新登录
|
||||
|
||||
---
|
||||
|
||||
## 版本说明
|
||||
|
||||
### 版本号规则
|
||||
|
||||
本项目遵循 [语义化版本 2.0.0](https://semver.org/lang/zh-CN/) 规范:
|
||||
|
||||
- **主版本号(Major)**:当你做了不兼容的 API 修改
|
||||
- **次版本号(Minor)**:当你做了向下兼容的功能性新增
|
||||
- **修订号(Patch)**:当你做了向下兼容的问题修正
|
||||
|
||||
### 变更类型
|
||||
|
||||
- **新增(Added)**:新功能
|
||||
- **修改(Changed)**:对现有功能的变更
|
||||
- **弃用(Deprecated)**:即将移除的功能
|
||||
- **移除(Removed)**:已移除的功能
|
||||
- **修复(Fixed)**:Bug 修复
|
||||
- **安全(Security)**:安全相关的修复
|
||||
- **优化(Optimized)**:性能优化或体验优化
|
||||
- **重构(Refactored)**:代码重构
|
||||
- **升级(Upgraded)**:依赖升级
|
||||
|
||||
### 重要提示标记
|
||||
|
||||
- 🎉 **重大更新**:包含重要新特性的版本
|
||||
- ⚠️ **破坏性变更**:需要特别注意的不兼容更新
|
||||
- 🔒 **安全更新**:修复安全漏洞的版本
|
||||
|
||||
---
|
||||
|
||||
## 贡献指南
|
||||
|
||||
如果你想为项目做出贡献,请查看 [CONTRIBUTING.md](./CONTRIBUTING.md)。
|
||||
|
||||
## 许可证
|
||||
|
||||
[MIT License](./LICENSE)
|
||||
|
||||
---
|
||||
|
||||
**注意**:本更新日志从 v2.4.0 版本开始记录。更早的版本历史请查看 Git 提交记录。
|
||||
|
||||
---
|
||||
|
||||
[English Version](./CHANGELOG.en.md)
|
||||
@@ -39,7 +39,7 @@ FastapiAdmin/frontend
|
||||
|
||||
```sh
|
||||
# 进入前端工程目录
|
||||
cd frontend/web
|
||||
cd frontend
|
||||
# 安装依赖
|
||||
pnpm install
|
||||
# 启动前端服务
|
||||
@@ -49,45 +49,3 @@ pnpm run build
|
||||
# 运行命令,查看未用到的依赖
|
||||
depcheck
|
||||
```
|
||||
|
||||
### 4. 开发模式启动
|
||||
|
||||
#### 方式:一键启动(推荐)
|
||||
|
||||
```bash
|
||||
# 直接启动Electron开发模式(自动启动后端)
|
||||
cd frontend/web
|
||||
npm run electron:dev
|
||||
```
|
||||
|
||||
## 📦 生产环境打包
|
||||
|
||||
### 完整打包流程
|
||||
|
||||
```bash
|
||||
# 1. 打包后端为独立可执行文件
|
||||
cd backend
|
||||
uv run pyinstaller --onefile --name fastapi-backend main.py
|
||||
|
||||
# 2. 复制后端可执行文件到前端资源目录
|
||||
# 注意:PyInstaller会根据平台自动添加后缀(.exe on Windows, no suffix on macOS/Linux)
|
||||
cp dist/fastapi-backend* ../frontend/web/resources/
|
||||
|
||||
# 3. 构建前端
|
||||
cd ../frontend/web
|
||||
npm run build
|
||||
|
||||
# 4. 打包Electron应用
|
||||
# electron-builder配置位于package.json的build字段中
|
||||
npm run electron:build
|
||||
```
|
||||
|
||||
### 输出文件
|
||||
- **Windows**:
|
||||
- 安装包:`frontend/release/MyElectronApp Setup 1.0.0.exe`
|
||||
- 便携版:`frontend/release/win-unpacked/MyElectronApp.exe`
|
||||
- **macOS**:
|
||||
- 安装包:`frontend/release/MyElectronApp-1.0.0-arm64-mac.zip`(或类似名称)
|
||||
- 应用程序:`frontend/release/mac-arm64/MyElectronApp.app`
|
||||
- **Linux**:
|
||||
- AppImage:`frontend/release/MyElectronApp-1.0.0-arm64.AppImage`(或类似名称)
|
||||
|
||||
@@ -1,53 +1,46 @@
|
||||
/**
|
||||
* commitlint 配置文件
|
||||
* 文档
|
||||
* https://commitlint.js.org/#/reference-rules
|
||||
* https://cz-git.qbb.sh/zh/guide/
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// 继承的规则
|
||||
extends: ['@commitlint/config-conventional'],
|
||||
extends: ["@commitlint/config-conventional"],
|
||||
// 自定义规则
|
||||
rules: {
|
||||
// @see https://commitlint.js.org/#/reference-rules
|
||||
|
||||
// 提交类型枚举,git提交type必须是以下类型
|
||||
'type-enum': [
|
||||
"type-enum": [
|
||||
2,
|
||||
'always',
|
||||
"always",
|
||||
[
|
||||
'feat', // 新增功能
|
||||
'fix', // 修复缺陷
|
||||
'docs', // 文档变更
|
||||
'style', // 代码格式(不影响功能,例如空格、分号等格式修正)
|
||||
'refactor', // 代码重构(不包括 bug 修复、功能新增)
|
||||
'perf', // 性能优化
|
||||
'test', // 添加疏漏测试或已有测试改动
|
||||
'build', // 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)
|
||||
'ci', // 修改 CI 配置、脚本
|
||||
'revert', // 回滚 commit
|
||||
'chore', // 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)
|
||||
'wip', // 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)
|
||||
"feat", // 新增功能
|
||||
"fix", // 修复缺陷
|
||||
"docs", // 文档变更
|
||||
"style", // 代码格式(不影响功能,例如空格、分号等格式修正)
|
||||
"refactor", // 代码重构(不包括 bug 修复、功能新增)
|
||||
"perf", // 性能优化
|
||||
"test", // 添加疏漏测试或已有测试改动
|
||||
"build", // 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)
|
||||
"ci", // 修改 CI 配置、脚本
|
||||
"revert", // 回滚 commit
|
||||
"chore", // 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)
|
||||
"wip", // 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)
|
||||
],
|
||||
],
|
||||
'subject-case': [0], // subject大小写不做校验
|
||||
"subject-case": [0], // subject大小写不做校验
|
||||
},
|
||||
|
||||
prompt: {
|
||||
messages: {
|
||||
type: '选择你要提交的类型 :',
|
||||
scope: '选择一个提交范围(可选):',
|
||||
customScope: '请输入自定义的提交范围 :',
|
||||
subject: '填写简短精炼的变更描述 :\n',
|
||||
type: "选择你要提交的类型 :",
|
||||
scope: "选择一个提交范围(可选):",
|
||||
customScope: "请输入自定义的提交范围 :",
|
||||
subject: "填写简短精炼的变更描述 :\n",
|
||||
body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
|
||||
breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
|
||||
footerPrefixesSelect: '选择关联issue前缀(可选):',
|
||||
customFooterPrefix: '输入自定义issue前缀 :',
|
||||
footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
|
||||
generatingByAI: '正在通过 AI 生成你的提交简短描述...',
|
||||
generatedSelectByAI: '选择一个 AI 生成的简短描述:',
|
||||
confirmCommit: '是否提交或修改commit ?',
|
||||
footerPrefixesSelect: "选择关联issue前缀(可选):",
|
||||
customFooterPrefix: "输入自定义issue前缀 :",
|
||||
footer: "列举关联issue (可选) 例如: #31, #I3244 :\n",
|
||||
generatingByAI: "正在通过 AI 生成你的提交简短描述...",
|
||||
generatedSelectByAI: "选择一个 AI 生成的简短描述:",
|
||||
confirmCommit: "是否提交或修改commit ?",
|
||||
},
|
||||
// prettier-ignore
|
||||
types: [
|
||||
@@ -65,26 +58,26 @@ module.exports = {
|
||||
{ value: "wip", name: "开发中: 🚧 开发阶段临时提交", emoji: ":construction:"},
|
||||
],
|
||||
useEmoji: true,
|
||||
emojiAlign: 'center',
|
||||
emojiAlign: "center",
|
||||
useAI: false,
|
||||
aiNumber: 1,
|
||||
themeColorCode: '',
|
||||
themeColorCode: "",
|
||||
scopes: [],
|
||||
allowCustomScopes: true,
|
||||
allowEmptyScopes: true,
|
||||
customScopesAlign: 'bottom',
|
||||
customScopesAlias: 'custom',
|
||||
emptyScopesAlias: 'empty',
|
||||
customScopesAlign: "bottom",
|
||||
customScopesAlias: "custom",
|
||||
emptyScopesAlias: "empty",
|
||||
upperCaseSubject: false,
|
||||
markBreakingChangeMode: false,
|
||||
allowBreakingChanges: ['feat', 'fix'],
|
||||
allowBreakingChanges: ["feat", "fix"],
|
||||
breaklineNumber: 100,
|
||||
breaklineChar: '|',
|
||||
skipQuestions: ['breaking', 'footerPrefix', 'footer'], // 跳过的步骤
|
||||
issuePrefixes: [{ value: 'closed', name: 'closed: ISSUES has been processed' }],
|
||||
customIssuePrefixAlign: 'top',
|
||||
emptyIssuePrefixAlias: 'skip',
|
||||
customIssuePrefixAlias: 'custom',
|
||||
breaklineChar: "|",
|
||||
skipQuestions: [],
|
||||
issuePrefixes: [{ value: "closed", name: "closed: ISSUES has been processed" }],
|
||||
customIssuePrefixAlign: "top",
|
||||
emptyIssuePrefixAlias: "skip",
|
||||
customIssuePrefixAlias: "custom",
|
||||
allowCustomIssuePrefix: true,
|
||||
allowEmptyIssuePrefix: true,
|
||||
confirmColorize: true,
|
||||
@@ -92,9 +85,9 @@ module.exports = {
|
||||
maxSubjectLength: Infinity,
|
||||
minSubjectLength: 0,
|
||||
scopeOverrides: undefined,
|
||||
defaultBody: '',
|
||||
defaultIssues: '',
|
||||
defaultScope: '',
|
||||
defaultSubject: '',
|
||||
defaultBody: "",
|
||||
defaultIssues: "",
|
||||
defaultScope: "",
|
||||
defaultSubject: "",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,231 +1,224 @@
|
||||
// https://eslint.org/docs/latest/use/configure/configuration-files-new
|
||||
|
||||
import fs from 'fs';
|
||||
import path, { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import pluginJs from '@eslint/js';
|
||||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
||||
import globals from 'globals';
|
||||
import eslint from "@eslint/js";
|
||||
import globals from "globals";
|
||||
// TypeScript支持
|
||||
import * as typescriptEslint from "typescript-eslint";
|
||||
// Vue支持
|
||||
import pluginVue from "eslint-plugin-vue";
|
||||
import vueParser from "vue-eslint-parser";
|
||||
// 代码风格与格式化
|
||||
import configPrettier from "eslint-config-prettier";
|
||||
import prettierPlugin from "eslint-plugin-prettier";
|
||||
|
||||
import typescriptEslint from 'typescript-eslint';
|
||||
import pluginVue from 'eslint-plugin-vue';
|
||||
import vueParser from 'vue-eslint-parser';
|
||||
import configPrettier from 'eslint-config-prettier';
|
||||
import prettierPlugin from 'eslint-plugin-prettier';
|
||||
|
||||
// 使用 import.meta.url 获取当前模块的路径
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
// 读取 .auto-import.json 文件的内容,并将其解析为 JSON 对象
|
||||
let autoImportConfig = { globals: {} };
|
||||
// 解析自动导入配置
|
||||
import fs from "node:fs";
|
||||
let autoImportGlobals = {};
|
||||
try {
|
||||
autoImportConfig = JSON.parse(
|
||||
fs.readFileSync(path.resolve(__dirname, '.auto-import.json'), 'utf-8')
|
||||
);
|
||||
autoImportGlobals =
|
||||
JSON.parse(fs.readFileSync("./.eslintrc-auto-import.json", "utf-8")).globals || {};
|
||||
} catch (error) {
|
||||
console.warn('Warning: .auto-import.json file not found, using default configuration');
|
||||
// 文件不存在或解析错误时使用空对象
|
||||
console.warn("Could not load auto-import globals", error);
|
||||
}
|
||||
|
||||
// Element Plus组件
|
||||
const elementPlusComponents = {
|
||||
// Element Plus 组件添加为全局变量,避免 no-undef 报错
|
||||
ElInput: 'readonly',
|
||||
ElSelect: 'readonly',
|
||||
ElSwitch: 'readonly',
|
||||
ElCascader: 'readonly',
|
||||
ElInputNumber: 'readonly',
|
||||
ElTimePicker: 'readonly',
|
||||
ElTimeSelect: 'readonly',
|
||||
ElDatePicker: 'readonly',
|
||||
ElTreeSelect: 'readonly',
|
||||
ElText: 'readonly',
|
||||
ElRadioGroup: 'readonly',
|
||||
ElCheckboxGroup: 'readonly',
|
||||
ElOption: 'readonly',
|
||||
ElRadio: 'readonly',
|
||||
ElCheckbox: 'readonly',
|
||||
ElInputTag: 'readonly',
|
||||
ElForm: 'readonly',
|
||||
ElFormItem: 'readonly',
|
||||
ElTable: 'readonly',
|
||||
ElTableColumn: 'readonly',
|
||||
ElButton: 'readonly',
|
||||
ElDialog: 'readonly',
|
||||
ElPagination: 'readonly',
|
||||
ElMessage: 'readonly',
|
||||
ElMessageBox: 'readonly',
|
||||
ElNotification: 'readonly',
|
||||
ElTree: 'readonly',
|
||||
ElInput: "readonly",
|
||||
ElSelect: "readonly",
|
||||
ElSwitch: "readonly",
|
||||
ElCascader: "readonly",
|
||||
ElInputNumber: "readonly",
|
||||
ElTimePicker: "readonly",
|
||||
ElTimeSelect: "readonly",
|
||||
ElDatePicker: "readonly",
|
||||
ElTreeSelect: "readonly",
|
||||
ElText: "readonly",
|
||||
ElRadioGroup: "readonly",
|
||||
ElCheckboxGroup: "readonly",
|
||||
ElOption: "readonly",
|
||||
ElRadio: "readonly",
|
||||
ElCheckbox: "readonly",
|
||||
ElInputTag: "readonly",
|
||||
ElForm: "readonly",
|
||||
ElFormItem: "readonly",
|
||||
ElTable: "readonly",
|
||||
ElTableColumn: "readonly",
|
||||
ElButton: "readonly",
|
||||
ElDialog: "readonly",
|
||||
ElPagination: "readonly",
|
||||
ElMessage: "readonly",
|
||||
ElMessageBox: "readonly",
|
||||
ElNotification: "readonly",
|
||||
ElTree: "readonly",
|
||||
};
|
||||
|
||||
export default [
|
||||
// 忽略文件配置
|
||||
{
|
||||
ignores: [
|
||||
'**/node_modules/**',
|
||||
'**/dist/**',
|
||||
'**/*.min.*',
|
||||
'**/auto-imports.d.ts',
|
||||
'**/components.d.ts',
|
||||
'**/types/**/*.d.ts',
|
||||
'**/public/**',
|
||||
'**/.vscode/**',
|
||||
'**/src/assets/**',
|
||||
'**/src/utils/console.ts',
|
||||
"**/node_modules/**",
|
||||
"**/dist/**",
|
||||
"**/*.min.*",
|
||||
"**/auto-imports.d.ts",
|
||||
"**/components.d.ts",
|
||||
"**/types/**/*.d.ts",
|
||||
],
|
||||
},
|
||||
|
||||
// 基础 JavaScript 配置
|
||||
pluginJs.configs.recommended,
|
||||
eslint.configs.recommended,
|
||||
|
||||
// Vue 推荐配置
|
||||
...pluginVue.configs["flat/recommended"],
|
||||
|
||||
// TypeScript 推荐配置
|
||||
...typescriptEslint.configs.recommended,
|
||||
// Vue 推荐配置
|
||||
...pluginVue.configs['flat/recommended'],
|
||||
|
||||
// 全局配置
|
||||
{
|
||||
// 指定要检查的文件
|
||||
files: ['**/*.{js,mjs,cjs,ts,tsx,mts,cts,vue}'],
|
||||
files: ["**/*.{js,mjs,cjs,ts,mts,cts,vue}"],
|
||||
languageOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
globals: {
|
||||
...globals.browser, // 浏览器环境全局变量
|
||||
...globals.node, // Node.js 环境全局变量
|
||||
...(autoImportConfig.globals || {}), // 自动导入的 API 函数
|
||||
...globals.es2022, // ES2022 全局对象
|
||||
...autoImportGlobals, // 自动导入的 API 函数
|
||||
...elementPlusComponents, // Element Plus 组件
|
||||
// 全局类型定义,解决 TypeScript 中定义但 ESLint 不识别的问题
|
||||
Api: 'readonly',
|
||||
PageQuery: 'readonly',
|
||||
PageResult: 'readonly',
|
||||
OptionType: 'readonly',
|
||||
ApiResponse: 'readonly',
|
||||
ExcelResult: 'readonly',
|
||||
CommonType: 'readonly',
|
||||
updatorType: 'readonly',
|
||||
creatorType: 'readonly',
|
||||
TagView: 'readonly',
|
||||
AppSettings: 'readonly',
|
||||
__APP_INFO__: 'readonly',
|
||||
PageQuery: "readonly",
|
||||
PageResult: "readonly",
|
||||
OptionType: "readonly",
|
||||
ApiResponse: "readonly",
|
||||
ExcelResult: "readonly",
|
||||
CommonType: "readonly",
|
||||
updatorType: "readonly",
|
||||
creatorType: "readonly",
|
||||
TagView: "readonly",
|
||||
AppSettings: "readonly",
|
||||
__APP_INFO__: "readonly",
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
vue: pluginVue,
|
||||
'@typescript-eslint': typescriptEslint.plugin,
|
||||
"@typescript-eslint": typescriptEslint.plugin,
|
||||
},
|
||||
rules: {
|
||||
// 基础规则
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
|
||||
// ES6+ 规则
|
||||
'prefer-const': 'error',
|
||||
'no-var': 'error',
|
||||
'object-shorthand': 'error',
|
||||
"prefer-const": "error",
|
||||
"no-var": "error",
|
||||
"object-shorthand": "error",
|
||||
|
||||
// 最佳实践
|
||||
eqeqeq: 'off',
|
||||
'no-multi-spaces': 'error',
|
||||
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }],
|
||||
eqeqeq: "off",
|
||||
"no-multi-spaces": "error",
|
||||
"no-multiple-empty-lines": ["error", { max: 1, maxBOF: 0, maxEOF: 0 }],
|
||||
|
||||
// 禁用与 TypeScript 冲突的规则
|
||||
'no-unused-vars': 'off',
|
||||
'no-undef': 'off',
|
||||
'no-redeclare': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
"no-unused-vars": "off",
|
||||
"no-undef": "off",
|
||||
"no-redeclare": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
},
|
||||
},
|
||||
|
||||
// Vue 文件特定配置
|
||||
{
|
||||
files: ['**/*.vue'],
|
||||
files: ["**/*.vue"],
|
||||
languageOptions: {
|
||||
parser: vueParser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
parser: typescriptEslint.parser,
|
||||
extraFileExtensions: ['.vue'],
|
||||
extraFileExtensions: [".vue"],
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// Vue 规则
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'vue/no-v-html': 'off',
|
||||
'vue/require-default-prop': 'off',
|
||||
'vue/require-explicit-emits': 'error',
|
||||
'vue/no-unused-vars': 'error',
|
||||
'vue/no-mutating-props': 'off',
|
||||
'vue/valid-v-for': 'warn',
|
||||
'vue/no-template-shadow': 'warn',
|
||||
'vue/return-in-computed-property': 'warn',
|
||||
'vue/block-order': [
|
||||
'error',
|
||||
"vue/multi-word-component-names": "off",
|
||||
"vue/no-v-html": "off",
|
||||
"vue/require-default-prop": "off",
|
||||
"vue/require-explicit-emits": "error",
|
||||
"vue/no-unused-vars": "error",
|
||||
"vue/no-mutating-props": "off",
|
||||
"vue/valid-v-for": "warn",
|
||||
"vue/no-template-shadow": "warn",
|
||||
"vue/return-in-computed-property": "warn",
|
||||
"vue/block-order": [
|
||||
"error",
|
||||
{
|
||||
order: ['template', 'script', 'style'],
|
||||
order: ["template", "script", "style"],
|
||||
},
|
||||
],
|
||||
'vue/html-self-closing': [
|
||||
'error',
|
||||
"vue/html-self-closing": [
|
||||
"error",
|
||||
{
|
||||
html: {
|
||||
void: 'always',
|
||||
normal: 'never',
|
||||
component: 'always',
|
||||
void: "always",
|
||||
normal: "never",
|
||||
component: "always",
|
||||
},
|
||||
svg: 'always',
|
||||
math: 'always',
|
||||
svg: "always",
|
||||
math: "always",
|
||||
},
|
||||
],
|
||||
'vue/component-name-in-template-casing': ['error', 'PascalCase'],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
"vue/component-name-in-template-casing": ["error", "PascalCase"],
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
},
|
||||
},
|
||||
|
||||
// TypeScript 文件特定配置
|
||||
{
|
||||
files: ['**/*.{ts,tsx,mts,cts}'],
|
||||
files: ["**/*.{ts,tsx,mts,cts}"],
|
||||
languageOptions: {
|
||||
parser: typescriptEslint.parser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
project: './tsconfig.json',
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
project: "./tsconfig.json",
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
// TypeScript 规则
|
||||
'@typescript-eslint/no-explicit-any': 'off', // 允许使用any类型,方便开发
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'warn', // 降级为警告
|
||||
'@typescript-eslint/no-unused-expressions': 'warn', // 降级为警告
|
||||
'@typescript-eslint/consistent-type-imports': 'off', // 关闭强制使用type import
|
||||
'@typescript-eslint/no-import-type-side-effects': 'error',
|
||||
"@typescript-eslint/no-explicit-any": "off", // 允许使用any类型,方便开发
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-empty-object-type": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/no-unused-vars": "warn", // 降级为警告
|
||||
"@typescript-eslint/no-unused-expressions": "warn", // 降级为警告
|
||||
"@typescript-eslint/consistent-type-imports": "off", // 关闭强制使用type import
|
||||
"@typescript-eslint/no-import-type-side-effects": "error",
|
||||
},
|
||||
},
|
||||
|
||||
// .d.ts 文件配置
|
||||
{
|
||||
files: ['**/*.d.ts'],
|
||||
files: ["**/*.d.ts"],
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
},
|
||||
},
|
||||
|
||||
// CURD 组件配置
|
||||
{
|
||||
files: ['**/components/CURD/**/*.{ts,vue}'],
|
||||
files: ["**/components/CURD/**/*.{ts,vue}"],
|
||||
rules: {
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -236,9 +229,9 @@ export default [
|
||||
},
|
||||
rules: {
|
||||
...configPrettier.rules,
|
||||
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
|
||||
'arrow-body-style': 'off',
|
||||
'prefer-arrow-callback': 'off',
|
||||
"prettier/prettier": ["error", {}, { usePrettierrc: true }],
|
||||
"arrow-body-style": "off",
|
||||
"prefer-arrow-callback": "off",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,45 +1,93 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>%VITE_APP_TITLE%</title>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/logo.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Vue3 + Vite + TypeScript + Element-Plus 的后台管理模板 " />
|
||||
<meta name="keywords" content="vue,element-plus,typescript" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="src/assets/images/favicon.png" />
|
||||
|
||||
<style>
|
||||
/* 防止页面刷新时白屏的初始样式 */
|
||||
html {
|
||||
background-color: #fafbfc;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
background-color: #070707;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// 初始化 html class 主题属性
|
||||
(function () {
|
||||
try {
|
||||
if (typeof Storage === 'undefined' || !window.localStorage) {
|
||||
return;
|
||||
}
|
||||
|
||||
const themeType = localStorage.getItem('sys-theme');
|
||||
if (themeType === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Failed to apply initial theme:', e);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="vue,element-plus,typescript,vue-element-admin,vue3-element-admin"
|
||||
/>
|
||||
<title>%VITE_APP_TITLE%</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
<div id="app">
|
||||
<div class="loading-container">
|
||||
<div class="loading-spinner">
|
||||
<div class="loading-bar"></div>
|
||||
<div class="loading-bar"></div>
|
||||
<div class="loading-bar"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.loading-bar {
|
||||
width: 4px;
|
||||
height: 24px;
|
||||
background-color: #498cff;
|
||||
border-radius: 2px;
|
||||
animation: loading-animation 1.2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.loading-bar:nth-child(1) {
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.loading-bar:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.loading-bar:nth-child(3) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
@keyframes loading-animation {
|
||||
0% {
|
||||
opacity: 0.3;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: scaleY(1.2);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.3;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</html>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "fastweb",
|
||||
"name": "fastapiadmin",
|
||||
"description": "Vue3 + Vite + TypeScript + Element-Plus 的后台管理模板",
|
||||
"version": "3.0.0",
|
||||
"version": "2.2.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"i": "pnpm install",
|
||||
"dev": "vite --open",
|
||||
"dev": "vite",
|
||||
"dev:force": "vite --force",
|
||||
"prod": "vite --mode prod",
|
||||
"build": "vue-tsc --noEmit & vite build",
|
||||
@@ -18,12 +18,10 @@
|
||||
"serve:dev": "pnpm vite preview --mode dev",
|
||||
"serve:test": "pnpm vite preview --mode test",
|
||||
"clean": "pnpx rimraf node_modules",
|
||||
"clean:dev": "tsx scripts/clean-dev.ts",
|
||||
"ts:check": "pnpm vue-tsc --noEmit --skipLibCheck",
|
||||
"npm:check": "pnpx npm-check-updates -u",
|
||||
"clean:cache": "pnpx rimraf node_modules/.cache node_modules/.vite",
|
||||
"prepare": "husky install",
|
||||
"p": "plop",
|
||||
"icon": "esno ./scripts/icon.ts",
|
||||
"preview": "vite preview",
|
||||
"type-check": "vue-tsc --noEmit",
|
||||
@@ -31,7 +29,7 @@
|
||||
"lint:style": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
|
||||
"lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.cjs",
|
||||
"lint:eslint": "eslint --cache \"src/**/*.{vue,ts,js}\" --fix",
|
||||
"lint:prettier": "prettier --write \"**/*.{js,cjs,ts,json,tsx,css,less,scss,vue,html,md}\"",
|
||||
"lint:prettier": "prettier --write \"**/*.{js,cjs,ts,json,css,scss,vue,html,md}\"",
|
||||
"lint:stylelint": "stylelint --cache \"**/*.{css,scss,vue}\" --fix",
|
||||
"lint": "pnpm run lint:eslint && pnpm run lint:prettier && pnpm run lint:stylelint",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
@@ -43,85 +41,67 @@
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,ts,mjs,mts,tsx}": [
|
||||
"*.{js,ts}": [
|
||||
"eslint --fix",
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{cjs,json,jsonc}": [
|
||||
"*.{cjs,json}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"*.vue": [
|
||||
"*.{vue,html}": [
|
||||
"eslint --fix",
|
||||
"stylelint --fix --allow-empty-input",
|
||||
"prettier --write",
|
||||
"stylelint --fix"
|
||||
],
|
||||
"*.{scss,css}": [
|
||||
"stylelint --fix",
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{html,htm}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{scss,css,less}": [
|
||||
"stylelint --fix --allow-empty-input",
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{md,mdx}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{yaml,yml}": [
|
||||
"*.md": [
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.2",
|
||||
"@iconify/vue": "^5.0.0",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@vue-flow/background": "^1.3.2",
|
||||
"@vue-flow/controls": "^1.1.3",
|
||||
"@vue-flow/core": "^1.48.1",
|
||||
"@vue-flow/minimap": "^1.5.4",
|
||||
"@vue/reactivity": "^3.5.21",
|
||||
"@vueuse/core": "^13.9.0",
|
||||
"@vueuse/core": "^13.5.0",
|
||||
"@wangeditor-next/editor": "^5.6.49",
|
||||
"@wangeditor-next/editor-for-vue": "^5.1.14",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.12.0",
|
||||
"axios": "^1.10.0",
|
||||
"clipboard": "^2.0.11",
|
||||
"codemirror": "^5.65.19",
|
||||
"codemirror-editor-vue3": "^2.8.0",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dagre": "^0.8.5",
|
||||
"dayjs": "^1.11.13",
|
||||
"dompurify": "^3.3.1",
|
||||
"echarts": "^6.0.0",
|
||||
"element-plus": "^2.11.2",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.11.0",
|
||||
"exceljs": "^4.4.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"highlight.js": "^11.11.1",
|
||||
"js-beautify": "^1.15.4",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-highlightjs": "^4.2.0",
|
||||
"mitt": "^3.0.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"ohash": "^2.0.11",
|
||||
"path-browserify": "^1.0.1",
|
||||
"path-to-regexp": "^8.2.0",
|
||||
"pinia": "^3.0.3",
|
||||
"pinia-plugin-persistedstate": "^4.4.1",
|
||||
"qrcode.vue": "^3.6.0",
|
||||
"qs": "^6.14.0",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"vue": "^3.5.21",
|
||||
"vue": "^3.5.17",
|
||||
"vue-draggable-plus": "^0.6.0",
|
||||
"vue-i18n": "^11.1.10",
|
||||
"vue-json-pretty": "^2.5.0",
|
||||
"vue-router": "^4.5.1",
|
||||
"vue-web-terminal": "^3.4.1",
|
||||
"vue3-cron-plus": "^0.1.9",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"xgplayer": "^3.0.20",
|
||||
"xlsx": "^0.18.5"
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.4.1",
|
||||
"@commitlint/config-conventional": "^19.4.1",
|
||||
"@eslint/js": "^9.32.0",
|
||||
"@iconify/utils": "^2.3.0",
|
||||
"@types/codemirror": "^5.60.16",
|
||||
@@ -129,14 +109,13 @@
|
||||
"@types/dompurify": "^3.2.0",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/markdown-it": "^14.1.2",
|
||||
"@types/node": "^24.0.5",
|
||||
"@types/node": "^22.16.5",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/path-browserify": "^1.0.3",
|
||||
"@types/qs": "^6.14.0",
|
||||
"@types/terser": "^3.12.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.38.0",
|
||||
"@typescript-eslint/parser": "^8.38.0",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"commitizen": "^4.3.1",
|
||||
"cz-git": "^1.12.0",
|
||||
@@ -148,7 +127,6 @@
|
||||
"globals": "^15.15.0",
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^15.5.2",
|
||||
"plop": "^4.0.1",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-html": "^1.8.0",
|
||||
"postcss-scss": "^4.0.9",
|
||||
@@ -160,27 +138,21 @@
|
||||
"stylelint-config-recommended": "^15.0.0",
|
||||
"stylelint-config-recommended-scss": "^14.1.0",
|
||||
"stylelint-config-recommended-vue": "^1.6.1",
|
||||
"stylelint-config-standard": "^36.0.1",
|
||||
"stylelint-prettier": "^5.0.3",
|
||||
"terser": "^5.43.1",
|
||||
"tsx": "^4.20.3",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.38.0",
|
||||
"unplugin-auto-import": "^20.2.0",
|
||||
"unplugin-element-plus": "^0.10.0",
|
||||
"unplugin-vue-components": "^29.1.0",
|
||||
"vite": "^7.1.5",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-electron": "^0.15.5",
|
||||
"vite-plugin-vue-devtools": "^8.1.1",
|
||||
"vue-demi": "^0.14.9",
|
||||
"unocss": "66.2.3",
|
||||
"unplugin-auto-import": "^19.3.0",
|
||||
"unplugin-vue-components": "^28.8.0",
|
||||
"vite": "^6.3.5",
|
||||
"vue-eslint-parser": "^10.2.0",
|
||||
"vue-img-cutter": "^3.0.5",
|
||||
"vue-tsc": "^2.2.12"
|
||||
},
|
||||
"packageManager": "pnpm@9.15.3",
|
||||
"engines": {
|
||||
"node": ">=20.0.0",
|
||||
"node": ">=18.0.0",
|
||||
"npm": ">=10.0.0",
|
||||
"pnpm": ">=8.1.0"
|
||||
},
|
||||
"repository": {
|
||||
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 3.3 MiB After Width: | Height: | Size: 3.3 MiB |
|
Before Width: | Height: | Size: 3.0 MiB After Width: | Height: | Size: 3.0 MiB |
@@ -1,838 +0,0 @@
|
||||
// scripts/clean-dev.ts
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
|
||||
// 现代化颜色主题
|
||||
const theme = {
|
||||
// 基础颜色
|
||||
reset: '\x1b[0m',
|
||||
bold: '\x1b[1m',
|
||||
dim: '\x1b[2m',
|
||||
|
||||
// 前景色
|
||||
primary: '\x1b[38;5;75m', // 亮蓝色
|
||||
success: '\x1b[38;5;82m', // 亮绿色
|
||||
warning: '\x1b[38;5;220m', // 亮黄色
|
||||
error: '\x1b[38;5;196m', // 亮红色
|
||||
info: '\x1b[38;5;159m', // 青色
|
||||
purple: '\x1b[38;5;141m', // 紫色
|
||||
orange: '\x1b[38;5;208m', // 橙色
|
||||
gray: '\x1b[38;5;245m', // 灰色
|
||||
white: '\x1b[38;5;255m', // 白色
|
||||
|
||||
// 背景色
|
||||
bgDark: '\x1b[48;5;235m', // 深灰背景
|
||||
bgBlue: '\x1b[48;5;24m', // 蓝色背景
|
||||
bgGreen: '\x1b[48;5;22m', // 绿色背景
|
||||
bgRed: '\x1b[48;5;52m', // 红色背景
|
||||
};
|
||||
|
||||
// 现代化图标集
|
||||
const icons = {
|
||||
rocket: '🚀',
|
||||
fire: '🔥',
|
||||
star: '⭐',
|
||||
gem: '💎',
|
||||
crown: '👑',
|
||||
magic: '✨',
|
||||
warning: '⚠️',
|
||||
success: '✅',
|
||||
error: '❌',
|
||||
info: 'ℹ️',
|
||||
folder: '📁',
|
||||
file: '📄',
|
||||
image: '🖼️',
|
||||
code: '💻',
|
||||
data: '📊',
|
||||
globe: '🌐',
|
||||
map: '🗺️',
|
||||
chat: '💬',
|
||||
bolt: '⚡',
|
||||
shield: '🛡️',
|
||||
key: '🔑',
|
||||
link: '🔗',
|
||||
clean: '🧹',
|
||||
trash: '🗑️',
|
||||
check: '✓',
|
||||
cross: '✗',
|
||||
arrow: '→',
|
||||
loading: '⏳',
|
||||
};
|
||||
|
||||
// 格式化工具
|
||||
const fmt = {
|
||||
title: (text: string) => `${theme.bold}${theme.primary}${text}${theme.reset}`,
|
||||
subtitle: (text: string) => `${theme.purple}${text}${theme.reset}`,
|
||||
success: (text: string) => `${theme.success}${text}${theme.reset}`,
|
||||
error: (text: string) => `${theme.error}${text}${theme.reset}`,
|
||||
warning: (text: string) => `${theme.warning}${text}${theme.reset}`,
|
||||
info: (text: string) => `${theme.info}${text}${theme.reset}`,
|
||||
highlight: (text: string) => `${theme.bold}${theme.white}${text}${theme.reset}`,
|
||||
dim: (text: string) => `${theme.dim}${theme.gray}${text}${theme.reset}`,
|
||||
orange: (text: string) => `${theme.orange}${text}${theme.reset}`,
|
||||
|
||||
// 带背景的文本
|
||||
badge: (text: string, bg: string = theme.bgBlue) =>
|
||||
`${bg}${theme.white}${theme.bold} ${text} ${theme.reset}`,
|
||||
|
||||
// 渐变效果模拟
|
||||
gradient: (text: string) => {
|
||||
const colors = ['\x1b[38;5;75m', '\x1b[38;5;81m', '\x1b[38;5;87m', '\x1b[38;5;159m'];
|
||||
const chars = text.split('');
|
||||
return chars.map((char, i) => `${colors[i % colors.length]}${char}`).join('') + theme.reset;
|
||||
},
|
||||
};
|
||||
|
||||
// 创建现代化标题横幅
|
||||
function createModernBanner() {
|
||||
console.log();
|
||||
console.log(
|
||||
fmt.gradient(' ╔══════════════════════════════════════════════════════════════════╗')
|
||||
);
|
||||
console.log(
|
||||
fmt.gradient(' ║ ║')
|
||||
);
|
||||
console.log(
|
||||
` ║ ${icons.rocket} ${fmt.title('ART DESIGN PRO')} ${fmt.subtitle('· 代码精简程序')} ${icons.magic} ║`
|
||||
);
|
||||
console.log(
|
||||
` ║ ${fmt.dim('为项目移除演示数据,快速切换至开发模式')} ║`
|
||||
);
|
||||
console.log(
|
||||
fmt.gradient(' ║ ║')
|
||||
);
|
||||
console.log(
|
||||
fmt.gradient(' ╚══════════════════════════════════════════════════════════════════╝')
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
// 创建分割线
|
||||
function createDivider(char = '─', color = theme.primary) {
|
||||
console.log(`${color}${' ' + char.repeat(66)}${theme.reset}`);
|
||||
}
|
||||
|
||||
// 创建卡片样式容器
|
||||
function createCard(title: string, content: string[]) {
|
||||
console.log(` ${fmt.badge('', theme.bgBlue)} ${fmt.title(title)}`);
|
||||
console.log();
|
||||
content.forEach((line) => {
|
||||
console.log(` ${line}`);
|
||||
});
|
||||
console.log();
|
||||
}
|
||||
|
||||
// 进度条动画
|
||||
function createProgressBar(current: number, total: number, text: string, width = 40) {
|
||||
const percentage = Math.round((current / total) * 100);
|
||||
const filled = Math.round((current / total) * width);
|
||||
const empty = width - filled;
|
||||
|
||||
const filledBar = '█'.repeat(filled);
|
||||
const emptyBar = '░'.repeat(empty);
|
||||
|
||||
process.stdout.write(
|
||||
`\r ${fmt.info('进度')} [${theme.success}${filledBar}${theme.gray}${emptyBar}${theme.reset}] ${fmt.highlight(percentage + '%')})}`
|
||||
);
|
||||
|
||||
if (current === total) {
|
||||
console.log();
|
||||
}
|
||||
}
|
||||
|
||||
// 统计信息
|
||||
const stats = {
|
||||
deletedFiles: 0,
|
||||
deletedPaths: 0,
|
||||
failedPaths: 0,
|
||||
startTime: Date.now(),
|
||||
totalFiles: 0,
|
||||
};
|
||||
|
||||
// 清理目标
|
||||
const targets = [
|
||||
'README.md',
|
||||
'README.zh-CN.md',
|
||||
'CHANGELOG.md',
|
||||
'CHANGELOG.zh-CN.md',
|
||||
'src/views/change',
|
||||
'src/views/safeguard',
|
||||
'src/views/article',
|
||||
'src/views/examples',
|
||||
'src/views/system/nested',
|
||||
'src/views/widgets',
|
||||
'src/views/template',
|
||||
'src/views/dashboard/analysis',
|
||||
'src/views/dashboard/ecommerce',
|
||||
'src/mock/json',
|
||||
'src/mock/temp/articleList.ts',
|
||||
'src/mock/temp/commentDetail.ts',
|
||||
'src/mock/temp/commentList.ts',
|
||||
'src/assets/images/cover',
|
||||
'src/assets/images/safeguard',
|
||||
'src/assets/images/3d',
|
||||
'src/components/core/charts/art-map-chart',
|
||||
'src/components/business/comment-widget',
|
||||
];
|
||||
|
||||
// 递归统计文件数量
|
||||
async function countFiles(targetPath: string): Promise<number> {
|
||||
const fullPath = path.resolve(process.cwd(), targetPath);
|
||||
|
||||
try {
|
||||
const stat = await fs.stat(fullPath);
|
||||
|
||||
if (stat.isFile()) {
|
||||
return 1;
|
||||
} else if (stat.isDirectory()) {
|
||||
const entries = await fs.readdir(fullPath);
|
||||
let count = 0;
|
||||
|
||||
for (const entry of entries) {
|
||||
const entryPath = path.join(targetPath, entry);
|
||||
count += await countFiles(entryPath);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
} catch {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 统计所有目标的文件数量
|
||||
async function countAllFiles(): Promise<number> {
|
||||
let totalCount = 0;
|
||||
|
||||
for (const target of targets) {
|
||||
const count = await countFiles(target);
|
||||
totalCount += count;
|
||||
}
|
||||
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
// 删除文件和目录
|
||||
async function remove(targetPath: string, index: number) {
|
||||
const fullPath = path.resolve(process.cwd(), targetPath);
|
||||
|
||||
createProgressBar(index + 1, targets.length, targetPath);
|
||||
|
||||
try {
|
||||
const fileCount = await countFiles(targetPath);
|
||||
await fs.rm(fullPath, { recursive: true, force: true });
|
||||
stats.deletedFiles += fileCount;
|
||||
stats.deletedPaths++;
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
} catch (err) {
|
||||
stats.failedPaths++;
|
||||
console.log();
|
||||
console.log(` ${icons.error} ${fmt.error('删除失败')}: ${fmt.highlight(targetPath)}`);
|
||||
console.log(` ${fmt.dim('错误详情: ' + err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 清理路由模块
|
||||
async function cleanRouteModules() {
|
||||
const modulesPath = path.resolve(process.cwd(), 'src/router/modules');
|
||||
|
||||
try {
|
||||
// 删除演示相关的路由模块
|
||||
const modulesToRemove = [
|
||||
'template.ts',
|
||||
'widgets.ts',
|
||||
'examples.ts',
|
||||
'article.ts',
|
||||
'safeguard.ts',
|
||||
'help.ts',
|
||||
];
|
||||
|
||||
for (const module of modulesToRemove) {
|
||||
const modulePath = path.join(modulesPath, module);
|
||||
try {
|
||||
await fs.rm(modulePath, { force: true });
|
||||
} catch {
|
||||
// 文件不存在时忽略错误
|
||||
}
|
||||
}
|
||||
|
||||
// 重写 dashboard.ts - 只保留 console
|
||||
const dashboardContent = `import { AppRouteRecord } from '@/types/router'
|
||||
|
||||
export const dashboardRoutes: AppRouteRecord = {
|
||||
name: 'Dashboard',
|
||||
path: '/dashboard',
|
||||
component: '/index/index',
|
||||
meta: {
|
||||
title: 'menus.dashboard.title',
|
||||
icon: 'ri:pie-chart-line',
|
||||
roles: ['R_SUPER', 'R_ADMIN']
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'console',
|
||||
name: 'Console',
|
||||
component: '/dashboard/console',
|
||||
meta: {
|
||||
title: 'menus.dashboard.console',
|
||||
keepAlive: false,
|
||||
fixedTab: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`;
|
||||
await fs.writeFile(path.join(modulesPath, 'dashboard.ts'), dashboardContent, 'utf-8');
|
||||
|
||||
// 重写 system.ts - 移除 nested 嵌套菜单
|
||||
const systemContent = `import { AppRouteRecord } from '@/types/router'
|
||||
|
||||
export const systemRoutes: AppRouteRecord = {
|
||||
path: '/system',
|
||||
name: 'System',
|
||||
component: '/index/index',
|
||||
meta: {
|
||||
title: 'menus.system.title',
|
||||
icon: 'ri:user-3-line',
|
||||
roles: ['R_SUPER', 'R_ADMIN']
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'user',
|
||||
name: 'User',
|
||||
component: '/system/user',
|
||||
meta: {
|
||||
title: 'menus.system.user',
|
||||
keepAlive: true,
|
||||
roles: ['R_SUPER', 'R_ADMIN']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
name: 'Role',
|
||||
component: '/system/role',
|
||||
meta: {
|
||||
title: 'menus.system.role',
|
||||
keepAlive: true,
|
||||
roles: ['R_SUPER']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'user-center',
|
||||
name: 'UserCenter',
|
||||
component: '/system/user-center',
|
||||
meta: {
|
||||
title: 'menus.system.userCenter',
|
||||
isHide: true,
|
||||
keepAlive: true,
|
||||
isHideTab: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'menu',
|
||||
name: 'Menus',
|
||||
component: '/system/menu',
|
||||
meta: {
|
||||
title: 'menus.system.menu',
|
||||
keepAlive: true,
|
||||
roles: ['R_SUPER'],
|
||||
authList: [
|
||||
{ title: '新增', authMark: 'add' },
|
||||
{ title: '编辑', authMark: 'edit' },
|
||||
{ title: '删除', authMark: 'delete' }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
`;
|
||||
await fs.writeFile(path.join(modulesPath, 'system.ts'), systemContent, 'utf-8');
|
||||
|
||||
// 重写 index.ts - 只导入保留的模块
|
||||
const indexContent = `import { AppRouteRecord } from '@/types/router'
|
||||
import { dashboardRoutes } from './dashboard'
|
||||
import { systemRoutes } from './system'
|
||||
import { resultRoutes } from './result'
|
||||
import { exceptionRoutes } from './exception'
|
||||
|
||||
/**
|
||||
* 导出所有模块化路由
|
||||
*/
|
||||
export const routeModules: AppRouteRecord[] = [
|
||||
dashboardRoutes,
|
||||
systemRoutes,
|
||||
resultRoutes,
|
||||
exceptionRoutes
|
||||
]
|
||||
`;
|
||||
await fs.writeFile(path.join(modulesPath, 'index.ts'), indexContent, 'utf-8');
|
||||
|
||||
console.log(` ${icons.success} ${fmt.success('清理路由模块完成')}`);
|
||||
} catch (err) {
|
||||
console.log(` ${icons.error} ${fmt.error('清理路由模块失败')}`);
|
||||
console.log(` ${fmt.dim('错误详情: ' + err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 清理路由别名
|
||||
async function cleanRoutesAlias() {
|
||||
const routesAliasPath = path.resolve(process.cwd(), 'src/router/routesAlias.ts');
|
||||
|
||||
try {
|
||||
const cleanedAlias = `/**
|
||||
* 公共路由别名
|
||||
# 存放系统级公共路由路径,如布局容器、登录页等
|
||||
*/
|
||||
export enum RoutesAlias {
|
||||
Layout = '/index/index', // 布局容器
|
||||
Login = '/auth/login' // 登录页
|
||||
}
|
||||
`;
|
||||
|
||||
await fs.writeFile(routesAliasPath, cleanedAlias, 'utf-8');
|
||||
console.log(` ${icons.success} ${fmt.success('重写路由别名配置完成')}`);
|
||||
} catch (err) {
|
||||
console.log(` ${icons.error} ${fmt.error('清理路由别名失败')}`);
|
||||
console.log(` ${fmt.dim('错误详情: ' + err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 清理变更日志
|
||||
async function cleanChangeLog() {
|
||||
const changeLogPath = path.resolve(process.cwd(), 'src/mock/upgrade/changeLog.ts');
|
||||
|
||||
try {
|
||||
const cleanedChangeLog = `import { ref } from 'vue'
|
||||
|
||||
interface UpgradeLog {
|
||||
version: string // 版本号
|
||||
title: string // 更新标题
|
||||
date: string // 更新日期
|
||||
detail?: string[] // 更新内容
|
||||
requireReLogin?: boolean // 是否需要重新登录
|
||||
remark?: string // 备注
|
||||
}
|
||||
|
||||
export const upgradeLogList = ref<UpgradeLog[]>([])
|
||||
`;
|
||||
|
||||
await fs.writeFile(changeLogPath, cleanedChangeLog, 'utf-8');
|
||||
console.log(` ${icons.success} ${fmt.success('清空变更日志数据完成')}`);
|
||||
} catch (err) {
|
||||
console.log(` ${icons.error} ${fmt.error('清理变更日志失败')}`);
|
||||
console.log(` ${fmt.dim('错误详情: ' + err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 清理语言文件
|
||||
async function cleanLanguageFiles() {
|
||||
const languageFiles = [
|
||||
{ path: 'src/locales/langs/zh.json', name: '中文语言文件' },
|
||||
{ path: 'src/locales/langs/en.json', name: '英文语言文件' },
|
||||
];
|
||||
|
||||
for (const { path: langPath, name } of languageFiles) {
|
||||
try {
|
||||
const fullPath = path.resolve(process.cwd(), langPath);
|
||||
const content = await fs.readFile(fullPath, 'utf-8');
|
||||
const langData = JSON.parse(content);
|
||||
|
||||
const menusToRemove = [
|
||||
'widgets',
|
||||
'template',
|
||||
'article',
|
||||
'examples',
|
||||
'safeguard',
|
||||
'plan',
|
||||
'help',
|
||||
];
|
||||
|
||||
if (langData.menus) {
|
||||
menusToRemove.forEach((menuKey) => {
|
||||
if (langData.menus[menuKey]) {
|
||||
delete langData.menus[menuKey];
|
||||
}
|
||||
});
|
||||
|
||||
if (langData.menus.dashboard) {
|
||||
if (langData.menus.dashboard.analysis) {
|
||||
delete langData.menus.dashboard.analysis;
|
||||
}
|
||||
if (langData.menus.dashboard.ecommerce) {
|
||||
delete langData.menus.dashboard.ecommerce;
|
||||
}
|
||||
}
|
||||
|
||||
if (langData.menus.system) {
|
||||
const systemKeysToRemove = [
|
||||
'nested',
|
||||
'menu1',
|
||||
'menu2',
|
||||
'menu21',
|
||||
'menu3',
|
||||
'menu31',
|
||||
'menu32',
|
||||
'menu321',
|
||||
];
|
||||
systemKeysToRemove.forEach((key) => {
|
||||
if (langData.menus.system[key]) {
|
||||
delete langData.menus.system[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await fs.writeFile(fullPath, JSON.stringify(langData, null, 2), 'utf-8');
|
||||
console.log(` ${icons.success} ${fmt.success(`清理${name}完成`)}`);
|
||||
} catch (err) {
|
||||
console.log(` ${icons.error} ${fmt.error(`清理${name}失败`)}`);
|
||||
console.log(` ${fmt.dim('错误详情: ' + err)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清理快速入口组件
|
||||
async function cleanFastEnterComponent() {
|
||||
const fastEnterPath = path.resolve(process.cwd(), 'src/config/fastEnter.ts');
|
||||
|
||||
try {
|
||||
const cleanedFastEnter = `/**
|
||||
* 快速入口配置
|
||||
* 包含:应用列表、快速链接等配置
|
||||
*/
|
||||
import { WEB_LINKS } from '@/utils/constants'
|
||||
import type { FastEnterConfig } from '@/types/config'
|
||||
|
||||
const fastEnterConfig: FastEnterConfig = {
|
||||
// 显示条件(屏幕宽度)
|
||||
minWidth: 1200,
|
||||
// 应用列表
|
||||
applications: [
|
||||
{
|
||||
name: '工作台',
|
||||
description: '系统概览与数据统计',
|
||||
icon: 'ri:pie-chart-line',
|
||||
iconColor: '#377dff',
|
||||
enabled: true,
|
||||
order: 1,
|
||||
routeName: 'Console'
|
||||
},
|
||||
{
|
||||
name: '官方文档',
|
||||
description: '使用指南与开发文档',
|
||||
icon: 'ri:bill-line',
|
||||
iconColor: '#ffb100',
|
||||
enabled: true,
|
||||
order: 2,
|
||||
link: WEB_LINKS.DOCS
|
||||
},
|
||||
{
|
||||
name: '技术支持',
|
||||
description: '技术支持与问题反馈',
|
||||
icon: 'ri:user-location-line',
|
||||
iconColor: '#ff6b6b',
|
||||
enabled: true,
|
||||
order: 3,
|
||||
link: WEB_LINKS.COMMUNITY
|
||||
},
|
||||
{
|
||||
name: '哔哩哔哩',
|
||||
description: '技术分享与交流',
|
||||
icon: 'ri:bilibili-line',
|
||||
iconColor: '#FB7299',
|
||||
enabled: true,
|
||||
order: 4,
|
||||
link: WEB_LINKS.BILIBILI
|
||||
}
|
||||
],
|
||||
// 快速链接
|
||||
quickLinks: [
|
||||
{
|
||||
name: '登录',
|
||||
enabled: true,
|
||||
order: 1,
|
||||
routeName: 'Login'
|
||||
},
|
||||
{
|
||||
name: '注册',
|
||||
enabled: true,
|
||||
order: 2,
|
||||
routeName: 'Register'
|
||||
},
|
||||
{
|
||||
name: '忘记密码',
|
||||
enabled: true,
|
||||
order: 3,
|
||||
routeName: 'ForgetPassword'
|
||||
},
|
||||
{
|
||||
name: '个人中心',
|
||||
enabled: true,
|
||||
order: 4,
|
||||
routeName: 'UserCenter'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default Object.freeze(fastEnterConfig)
|
||||
`;
|
||||
|
||||
await fs.writeFile(fastEnterPath, cleanedFastEnter, 'utf-8');
|
||||
console.log(` ${icons.success} ${fmt.success('清理快速入口配置完成')}`);
|
||||
} catch (err) {
|
||||
console.log(` ${icons.error} ${fmt.error('清理快速入口配置失败')}`);
|
||||
console.log(` ${fmt.dim('错误详情: ' + err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新菜单接口
|
||||
async function updateMenuApi() {
|
||||
const apiPath = path.resolve(process.cwd(), 'src/api/system-manage.ts');
|
||||
|
||||
try {
|
||||
const content = await fs.readFile(apiPath, 'utf-8');
|
||||
const updatedContent = content.replace(
|
||||
"url: '/api/v3/system/menus'",
|
||||
"url: '/api/v3/system/menus/simple'"
|
||||
);
|
||||
|
||||
await fs.writeFile(apiPath, updatedContent, 'utf-8');
|
||||
console.log(` ${icons.success} ${fmt.success('更新菜单接口完成')}`);
|
||||
} catch (err) {
|
||||
console.log(` ${icons.error} ${fmt.error('更新菜单接口失败')}`);
|
||||
console.log(` ${fmt.dim('错误详情: ' + err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 用户确认函数
|
||||
async function getUserConfirmation(): Promise<boolean> {
|
||||
const { createInterface } = await import('readline');
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const rl = createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
console.log(
|
||||
` ${fmt.highlight('请输入')} ${fmt.success('yes')} ${fmt.highlight('确认执行清理操作,或按 Enter 取消')}`
|
||||
);
|
||||
console.log();
|
||||
process.stdout.write(` ${icons.arrow} `);
|
||||
|
||||
rl.question('', (answer: string) => {
|
||||
rl.close();
|
||||
resolve(answer.toLowerCase().trim() === 'yes');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 显示清理警告
|
||||
async function showCleanupWarning() {
|
||||
createCard('安全警告', [
|
||||
`${fmt.warning('此操作将永久删除以下演示内容,且无法恢复!')}`,
|
||||
`${fmt.dim('请仔细阅读清理列表,确认后再继续操作')}`,
|
||||
]);
|
||||
|
||||
const cleanupItems = [
|
||||
{
|
||||
icon: icons.image,
|
||||
name: '图片资源',
|
||||
desc: '演示用的封面图片、3D图片、运维图片等',
|
||||
color: theme.orange,
|
||||
},
|
||||
{
|
||||
icon: icons.file,
|
||||
name: '演示页面',
|
||||
desc: 'widgets、template、article、examples、safeguard等页面',
|
||||
color: theme.purple,
|
||||
},
|
||||
{
|
||||
icon: icons.code,
|
||||
name: '路由模块文件',
|
||||
desc: '删除演示路由模块,只保留核心模块(dashboard、system、result、exception)',
|
||||
color: theme.primary,
|
||||
},
|
||||
{
|
||||
icon: icons.link,
|
||||
name: '路由别名',
|
||||
desc: '重写routesAlias.ts,移除演示路由别名',
|
||||
color: theme.info,
|
||||
},
|
||||
{
|
||||
icon: icons.data,
|
||||
name: 'Mock数据',
|
||||
desc: '演示用的JSON数据、文章列表、评论数据等',
|
||||
color: theme.success,
|
||||
},
|
||||
{
|
||||
icon: icons.globe,
|
||||
name: '多语言文件',
|
||||
desc: '清理中英文语言包中的演示菜单项',
|
||||
color: theme.warning,
|
||||
},
|
||||
{ icon: icons.map, name: '地图组件', desc: '移除art-map-chart地图组件', color: theme.error },
|
||||
{ icon: icons.chat, name: '评论组件', desc: '移除comment-widget评论组件', color: theme.orange },
|
||||
{
|
||||
icon: icons.bolt,
|
||||
name: '快速入口',
|
||||
desc: '移除分析页、礼花效果、聊天、更新日志、定价、留言管理等无效项目',
|
||||
color: theme.purple,
|
||||
},
|
||||
];
|
||||
|
||||
console.log(` ${fmt.badge('', theme.bgRed)} ${fmt.title('将要清理的内容')}`);
|
||||
console.log();
|
||||
|
||||
cleanupItems.forEach((item, index) => {
|
||||
console.log(` ${item.color}${theme.reset} ${fmt.highlight(`${index + 1}. ${item.name}`)}`);
|
||||
console.log(` ${fmt.dim(item.desc)}`);
|
||||
});
|
||||
|
||||
console.log();
|
||||
console.log(` ${fmt.badge('', theme.bgGreen)} ${fmt.title('保留的功能模块')}`);
|
||||
console.log();
|
||||
|
||||
const preservedModules = [
|
||||
{ name: 'Dashboard', desc: '工作台页面' },
|
||||
{ name: 'System', desc: '系统管理模块' },
|
||||
{ name: 'Result', desc: '结果页面' },
|
||||
{ name: 'Exception', desc: '异常页面' },
|
||||
{ name: 'Auth', desc: '登录注册功能' },
|
||||
{ name: 'Core Components', desc: '核心组件库' },
|
||||
];
|
||||
|
||||
preservedModules.forEach((module) => {
|
||||
console.log(` ${icons.check} ${fmt.success(module.name)} ${fmt.dim(`- ${module.desc}`)}`);
|
||||
});
|
||||
|
||||
console.log();
|
||||
createDivider();
|
||||
console.log();
|
||||
}
|
||||
|
||||
// 显示统计信息
|
||||
async function showStats() {
|
||||
const duration = Date.now() - stats.startTime;
|
||||
const seconds = (duration / 1000).toFixed(2);
|
||||
|
||||
console.log();
|
||||
createCard('清理统计', [
|
||||
`${fmt.success('成功删除')}: ${fmt.highlight(stats.deletedFiles.toString())} 个文件`,
|
||||
`${fmt.info('涉及路径')}: ${fmt.highlight(stats.deletedPaths.toString())} 个目录/文件`,
|
||||
...(stats.failedPaths > 0
|
||||
? [
|
||||
`${icons.error} ${fmt.error('删除失败')}: ${fmt.highlight(stats.failedPaths.toString())} 个路径`,
|
||||
]
|
||||
: []),
|
||||
`${fmt.info('耗时')}: ${fmt.highlight(seconds)} 秒`,
|
||||
]);
|
||||
}
|
||||
|
||||
// 创建成功横幅
|
||||
function createSuccessBanner() {
|
||||
console.log();
|
||||
console.log(
|
||||
fmt.gradient(' ╔══════════════════════════════════════════════════════════════════╗')
|
||||
);
|
||||
console.log(
|
||||
fmt.gradient(' ║ ║')
|
||||
);
|
||||
console.log(
|
||||
` ║ ${icons.star} ${fmt.success('清理完成!项目已准备就绪')} ${icons.rocket} ║`
|
||||
);
|
||||
console.log(
|
||||
` ║ ${fmt.dim('现在可以开始您的开发之旅了!')} ║`
|
||||
);
|
||||
console.log(
|
||||
fmt.gradient(' ║ ║')
|
||||
);
|
||||
console.log(
|
||||
fmt.gradient(' ╚══════════════════════════════════════════════════════════════════╝')
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
// 主函数
|
||||
async function main() {
|
||||
// 清屏并显示横幅
|
||||
console.clear();
|
||||
createModernBanner();
|
||||
|
||||
// 显示清理警告
|
||||
await showCleanupWarning();
|
||||
|
||||
// 统计文件数量
|
||||
console.log(` ${fmt.info('正在统计文件数量...')}`);
|
||||
stats.totalFiles = await countAllFiles();
|
||||
|
||||
console.log(` ${fmt.info('即将清理')}: ${fmt.highlight(stats.totalFiles.toString())} 个文件`);
|
||||
console.log(` ${fmt.dim(`涉及 ${targets.length} 个目录/文件路径`)}`);
|
||||
console.log();
|
||||
|
||||
// 用户确认
|
||||
const confirmed = await getUserConfirmation();
|
||||
|
||||
if (!confirmed) {
|
||||
console.log(` ${fmt.warning('操作已取消,清理中止')}`);
|
||||
console.log();
|
||||
return;
|
||||
}
|
||||
|
||||
console.log();
|
||||
console.log(` ${icons.check} ${fmt.success('确认成功,开始清理...')}`);
|
||||
console.log();
|
||||
|
||||
// 开始清理过程
|
||||
console.log(` ${fmt.badge('步骤 1/6', theme.bgBlue)} ${fmt.title('删除演示文件')}`);
|
||||
console.log();
|
||||
for (let i = 0; i < targets.length; i++) {
|
||||
await remove(targets[i], i);
|
||||
}
|
||||
console.log();
|
||||
|
||||
console.log(` ${fmt.badge('步骤 2/6', theme.bgBlue)} ${fmt.title('清理路由模块')}`);
|
||||
console.log();
|
||||
await cleanRouteModules();
|
||||
console.log();
|
||||
|
||||
console.log(` ${fmt.badge('步骤 3/6', theme.bgBlue)} ${fmt.title('重写路由别名')}`);
|
||||
console.log();
|
||||
await cleanRoutesAlias();
|
||||
console.log();
|
||||
|
||||
console.log(` ${fmt.badge('步骤 4/6', theme.bgBlue)} ${fmt.title('清空变更日志')}`);
|
||||
console.log();
|
||||
await cleanChangeLog();
|
||||
console.log();
|
||||
|
||||
console.log(` ${fmt.badge('步骤 5/6', theme.bgBlue)} ${fmt.title('清理语言文件')}`);
|
||||
console.log();
|
||||
await cleanLanguageFiles();
|
||||
console.log();
|
||||
|
||||
console.log(` ${fmt.badge('步骤 6/7', theme.bgBlue)} ${fmt.title('清理快速入口')}`);
|
||||
console.log();
|
||||
await cleanFastEnterComponent();
|
||||
console.log();
|
||||
|
||||
console.log(` ${fmt.badge('步骤 7/7', theme.bgBlue)} ${fmt.title('更新菜单接口')}`);
|
||||
console.log();
|
||||
await updateMenuApi();
|
||||
|
||||
// 显示统计信息
|
||||
await showStats();
|
||||
|
||||
// 显示成功横幅
|
||||
createSuccessBanner();
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.log();
|
||||
console.log(` ${icons.error} ${fmt.error('清理脚本执行出错')}`);
|
||||
console.log(` ${fmt.dim('错误详情: ' + err)}`);
|
||||
console.log();
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,93 +1,46 @@
|
||||
<template>
|
||||
<ElConfigProvider
|
||||
:locale="locales"
|
||||
:size="size"
|
||||
:z-index="3000"
|
||||
:card="{
|
||||
shadow: 'never',
|
||||
}"
|
||||
>
|
||||
<el-config-provider :locale="locale" :size="size">
|
||||
<!-- 开启水印 -->
|
||||
<ElWatermark
|
||||
<el-watermark
|
||||
:font="{ color: fontColor }"
|
||||
:content="showWatermark ? watermarkContent : ''"
|
||||
:z-index="9999"
|
||||
class="wh-full"
|
||||
>
|
||||
<RouterView />
|
||||
<router-view />
|
||||
|
||||
<!-- AI 助手 -->
|
||||
<AiAssistant v-if="enableAiAssistant" />
|
||||
</ElWatermark>
|
||||
</ElConfigProvider>
|
||||
|
||||
<!-- <ElConfigProvider
|
||||
size="default"
|
||||
:locale="locales[language]"
|
||||
:z-index="3000"
|
||||
:card="{
|
||||
shadow: 'never'
|
||||
}"
|
||||
>
|
||||
<RouterView></RouterView>
|
||||
</ElConfigProvider> -->
|
||||
</el-watermark>
|
||||
</el-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import { useUserStore } from './store/modules/user'
|
||||
// import zh from 'element-plus/es/locale/lang/zh-cn'
|
||||
// import en from 'element-plus/es/locale/lang/en'
|
||||
// import { systemUpgrade } from './utils/sys'
|
||||
// import { toggleTransition } from './utils/ui/animation'
|
||||
// import { checkStorageCompatibility } from './utils/storage'
|
||||
// import { initializeTheme } from './hooks/core/useTheme'
|
||||
import { useAppStore, useSettingsStore, useUserStore } from "@/store";
|
||||
import { defaultSettings } from "@/settings";
|
||||
import { ThemeMode } from "@/enums/settings/theme.enum";
|
||||
import { ComponentSize } from "@/enums/settings/layout.enum";
|
||||
import AiAssistant from "@/components/AiAssistant/index.vue";
|
||||
|
||||
// const userStore = useUserStore()
|
||||
// const { language } = storeToRefs(userStore)
|
||||
const appStore = useAppStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
// const locales = {
|
||||
// zh: zh,
|
||||
// en: en
|
||||
// }
|
||||
const locale = computed(() => appStore.locale);
|
||||
const size = computed(() => appStore.size as ComponentSize);
|
||||
const showWatermark = computed(() => settingsStore.showWatermark);
|
||||
const watermarkContent = defaultSettings.watermarkContent;
|
||||
|
||||
// onBeforeMount(() => {
|
||||
// toggleTransition(true)
|
||||
// initializeTheme()
|
||||
// })
|
||||
// 只有在启用 AI 助手且用户已登录时才显示
|
||||
// 使用 userInfo 作为响应式依赖,当用户退出登录时会自动更新
|
||||
const enableAiAssistant = computed(() => {
|
||||
const isEnabled = settingsStore.userEnableAi;
|
||||
const isLoggedIn = userStore.basicInfo && Object.keys(userStore.basicInfo).length > 0;
|
||||
return isEnabled && isLoggedIn;
|
||||
});
|
||||
|
||||
// onMounted(() => {
|
||||
// checkStorageCompatibility()
|
||||
// toggleTransition(false)
|
||||
// systemUpgrade()
|
||||
// })
|
||||
|
||||
import { useAppStore, useSettingsStore, useUserStore } from '@/store';
|
||||
import { defaultSettings } from '@/settings';
|
||||
import { ThemeMode } from '@/enums/settings/theme.enum';
|
||||
import { ComponentSize } from '@/enums/settings/layout.enum';
|
||||
import AiAssistant from '@/components/AiAssistant/index.vue';
|
||||
|
||||
const appStore = useAppStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const locales = computed(() => appStore.locale);
|
||||
const size = computed(() => appStore.size as ComponentSize);
|
||||
const showWatermark = computed(() => settingsStore.showWatermark);
|
||||
const watermarkContent = defaultSettings.watermarkContent;
|
||||
|
||||
// 只有在启用 AI 助手且用户已登录时才显示
|
||||
// 使用 userInfo 作为响应式依赖,当用户退出登录时会自动更新
|
||||
const enableAiAssistant = computed(() => {
|
||||
const isEnabled = settingsStore.userEnableAi;
|
||||
const isLoggedIn = userStore.basicInfo && Object.keys(userStore.basicInfo).length > 0;
|
||||
return isEnabled && isLoggedIn;
|
||||
});
|
||||
|
||||
// 明亮/暗黑主题水印字体颜色适配
|
||||
const fontColor = computed(() => {
|
||||
return settingsStore.theme === ThemeMode.DARK
|
||||
? 'rgba(255, 255, 255, .15)'
|
||||
: 'rgba(0, 0, 0, .15)';
|
||||
});
|
||||
// 明亮/暗黑主题水印字体颜色适配
|
||||
const fontColor = computed(() => {
|
||||
return settingsStore.theme === ThemeMode.DARK ? "rgba(255, 255, 255, .15)" : "rgba(0, 0, 0, .15)";
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import request from '@/utils/http';
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @param params 登录参数
|
||||
* @returns 登录响应
|
||||
*/
|
||||
export function fetchLogin(params: Api.Auth.LoginParams) {
|
||||
return request.post<Api.Auth.LoginResponse>({
|
||||
url: '/api/auth/login',
|
||||
params,
|
||||
// showSuccessMessage: true // 显示成功消息
|
||||
// showErrorMessage: false // 不显示错误消息
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @returns 用户信息
|
||||
*/
|
||||
export function fetchGetUserInfo() {
|
||||
return request.get<Api.Auth.UserInfo>({
|
||||
url: '/api/user/info',
|
||||
// 自定义请求头
|
||||
// headers: {
|
||||
// 'X-Custom-Header': 'your-custom-value'
|
||||
// }
|
||||
});
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/ai/chat';
|
||||
const API_PATH = "/ai/chat";
|
||||
|
||||
export const AiChatAPI = {
|
||||
/**
|
||||
* 查询会话列表
|
||||
* @param query 查询参数
|
||||
*/
|
||||
getSessionList(query: {
|
||||
page_no: number;
|
||||
page_size: number;
|
||||
@@ -14,70 +10,49 @@ export const AiChatAPI = {
|
||||
created_at?: string[];
|
||||
updated_at?: string[];
|
||||
}) {
|
||||
return request<PageResult<ChatSession[]>>({
|
||||
return request<ApiResponse<PageResult<ChatSession[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建会话
|
||||
* @param body 会话信息
|
||||
*/
|
||||
createSession(body: { title: string }) {
|
||||
return request<ApiResponse<ChatSession>>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新会话
|
||||
* @param id 会话ID
|
||||
* @param body 会话信息
|
||||
*/
|
||||
updateSession(id: string, body: { title: string }) {
|
||||
return request<ApiResponse<ChatSession>>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除会话
|
||||
* @param body 会话ID数组
|
||||
*/
|
||||
deleteSession(body: string[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 调用AI模型
|
||||
* @param body 调用参数
|
||||
*/
|
||||
chat(body: { message: string; session_id?: string | null }) {
|
||||
return request<ApiResponse<AiChatResponse>>({
|
||||
url: `${API_PATH}/ai-chat`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查询会话详情
|
||||
* @param sessionId 会话ID
|
||||
*/
|
||||
getSessionDetail(sessionId: string) {
|
||||
return request<ApiResponse<ChatSessionDetail>>({
|
||||
url: `${API_PATH}/detail/${sessionId}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/application/portal';
|
||||
const API_PATH = "/application/portal";
|
||||
|
||||
export const ApplicationAPI = {
|
||||
/**
|
||||
@@ -10,7 +10,7 @@ export const ApplicationAPI = {
|
||||
detailApp(id: number) {
|
||||
return request<ApiResponse<ApplicationInfo>>({
|
||||
url: `${API_PATH}/detail/${id}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
@@ -19,9 +19,9 @@ export const ApplicationAPI = {
|
||||
* @param query 查询参数
|
||||
*/
|
||||
listApp(query: ApplicationPageQuery) {
|
||||
return request<PageResult<ApplicationInfo[]>>({
|
||||
return request<ApiResponse<PageResult<ApplicationInfo[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
@@ -31,9 +31,9 @@ export const ApplicationAPI = {
|
||||
* @param body 应用信息
|
||||
*/
|
||||
createApp(body: ApplicationForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
@@ -44,9 +44,9 @@ export const ApplicationAPI = {
|
||||
* @param body 应用信息
|
||||
*/
|
||||
updateApp(id: number, body: ApplicationForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
@@ -56,9 +56,9 @@ export const ApplicationAPI = {
|
||||
* @param body 应用ID数组
|
||||
*/
|
||||
deleteApp(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
@@ -68,9 +68,9 @@ export const ApplicationAPI = {
|
||||
* @param body 批量操作参数
|
||||
*/
|
||||
batchApp(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,115 +1,79 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/example/demo';
|
||||
const API_PATH = "/example/demo";
|
||||
|
||||
const DemoAPI = {
|
||||
/**
|
||||
* 查询演示列表
|
||||
* @param query 查询参数
|
||||
*/
|
||||
getDemoList(query: DemoPageQuery) {
|
||||
return request<PageResult<DemoTable[]>>({
|
||||
return request<ApiResponse<PageResult<DemoTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查询演示详情
|
||||
* @param query 演示ID
|
||||
*/
|
||||
getDemoDetail(query: number) {
|
||||
return request<ApiResponse<DemoTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建演示
|
||||
* @param body 演示信息
|
||||
*/
|
||||
createDemo(body: DemoForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新演示
|
||||
* @param id 演示ID
|
||||
* @param body 演示信息
|
||||
*/
|
||||
updateDemo(id: number, body: DemoForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除演示
|
||||
* @param body 演示ID数组
|
||||
*/
|
||||
deleteDemo(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量操作演示
|
||||
* @param body 批量操作参数
|
||||
*/
|
||||
batchDemo(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出演示
|
||||
* @param body 导出参数
|
||||
*/
|
||||
exportDemo(body: DemoPageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载演示模板
|
||||
*/
|
||||
downloadTemplateDemo() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/download/template`,
|
||||
method: 'post',
|
||||
responseType: 'blob',
|
||||
method: "post",
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导入演示
|
||||
* @param body 导入参数
|
||||
*/
|
||||
importDemo(body: FormData) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/import`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,115 +1,79 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/example/demo01';
|
||||
const API_PATH = "/example/demo01";
|
||||
|
||||
const Demo01API = {
|
||||
/**
|
||||
* 查询演示列表
|
||||
* @param query 查询参数
|
||||
*/
|
||||
getDemo01List(query: Demo01PageQuery) {
|
||||
return request<PageResult<Demo01Table[]>>({
|
||||
return request<ApiResponse<PageResult<Demo01Table[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查询演示详情
|
||||
* @param id 演示ID
|
||||
*/
|
||||
getDemo01Detail(id: number) {
|
||||
return request<ApiResponse<Demo01Table>>({
|
||||
url: `${API_PATH}/detail/${id}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建演示
|
||||
* @param body 演示信息
|
||||
*/
|
||||
createDemo01(body: Demo01Form) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新演示
|
||||
* @param id 演示ID
|
||||
* @param body 演示信息
|
||||
*/
|
||||
updateDemo01(id: number, body: Demo01Form) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除演示
|
||||
* @param body 演示ID列表
|
||||
*/
|
||||
deleteDemo01(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置演示状态
|
||||
* @param body 批量设置参数
|
||||
*/
|
||||
batchDemo01(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出演示
|
||||
* @param body 漼示参数
|
||||
*/
|
||||
exportDemo01(body: Demo01PageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载演示模板
|
||||
*/
|
||||
downloadDemo01Template() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/download/template`,
|
||||
method: 'post',
|
||||
responseType: 'blob',
|
||||
method: "post",
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导入演示
|
||||
* @param body 演示数据
|
||||
*/
|
||||
importDemo01(body: FormData) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/import`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,148 +1,109 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/generator/gencode';
|
||||
const API_PATH = "/generator/gencode";
|
||||
|
||||
const GencodeAPI = {
|
||||
/**
|
||||
* 查询生成表列表
|
||||
* @param query 查询参数
|
||||
* @returns 生成表列表
|
||||
*/
|
||||
// 查询生成表数据
|
||||
listTable(query: GenTablePageQuery) {
|
||||
return request<PageResult<GenTableSchema[]>>({
|
||||
return request<ApiResponse<PageResult<GenTableSchema[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查询db数据库列表
|
||||
* @param query 查询参数
|
||||
* @returns db数据库列表
|
||||
*/
|
||||
// 查询db数据库列表
|
||||
listDbTable(query: DBTablePageQuery) {
|
||||
return request<PageResult<DBTableSchema[]>>({
|
||||
return request<ApiResponse<PageResult<DBTableSchema[]>>>({
|
||||
url: `${API_PATH}/db/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导入表
|
||||
* @param table_names 表名列表
|
||||
*/
|
||||
// 导入表
|
||||
importTable(table_names: string[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/import`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: table_names,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查询表详细信息
|
||||
* @param table_id 表ID
|
||||
*/
|
||||
// 查询表详细信息
|
||||
detailTable(table_id: number) {
|
||||
return request<ApiResponse<GenTableSchema>>({
|
||||
url: `${API_PATH}/detail/${table_id}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建表(与后端 GenCreateTableSqlBody 一致)
|
||||
* @param sql 表SQL语句
|
||||
*/
|
||||
// 创建表(与后端 GenCreateTableSqlBody 一致)
|
||||
createTable(sql: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: { sql },
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新表信息
|
||||
* @param data 表数据
|
||||
* @param table_id 表ID
|
||||
*/
|
||||
// 更新表信息
|
||||
updateTable(data: GenTableSchema, table_id: number) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${table_id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除表数据
|
||||
* @param table_ids 表ID列表
|
||||
*/
|
||||
// 删除表数据
|
||||
deleteTable(table_ids: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: table_ids,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量生成代码
|
||||
* @param table_names 表名列表
|
||||
*/
|
||||
// 批量生成代码
|
||||
batchGenCode(table_names: string[]) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/batch/output`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: table_names,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 生成代码到指定路径
|
||||
* @param table_name 表名
|
||||
*/
|
||||
// 生成代码到指定路径
|
||||
genCodeToPath(table_name: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/output/${table_name}`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 预览生成代码
|
||||
* @param id 表ID
|
||||
*/
|
||||
// 预览生成代码
|
||||
previewTable(id: number) {
|
||||
return request<Record<string, string>>({
|
||||
return request<ApiResponse<Record<string, string>>>({
|
||||
url: `${API_PATH}/preview/${id}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 同步数据库
|
||||
* @param table_name 表名
|
||||
*/
|
||||
// 同步数据库
|
||||
syncDb(table_name: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/sync_db/${table_name}`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 同步数据库差异预览(不落库)
|
||||
* @param table_name 表名
|
||||
*/
|
||||
// 同步数据库差异预览(不落库)
|
||||
syncDbPreview(table_name: string) {
|
||||
return request<ApiResponse<GenSyncPreviewSchema>>({
|
||||
url: `${API_PATH}/sync_db/preview/${table_name}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,85 +1,54 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/monitor/cache';
|
||||
const API_PATH = "/monitor/cache";
|
||||
|
||||
const CacheAPI = {
|
||||
/**
|
||||
* 获取缓存信息
|
||||
* @returns 缓存信息
|
||||
*/
|
||||
getCacheInfo() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/info`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取所有缓存名称
|
||||
* @returns 所有缓存名称
|
||||
*/
|
||||
getCacheNames() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/get/names`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取指定缓存名称下的所有键
|
||||
* @param cacheName 缓存名称
|
||||
* @returns 所有键
|
||||
*/
|
||||
getCacheKeys(cacheName: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/get/keys/${cacheName}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取指定缓存名称下的指定键的值
|
||||
* @param cacheName 缓存名称
|
||||
* @param cacheKey 键
|
||||
* @returns 值
|
||||
*/
|
||||
getCacheValue(cacheName: string, cacheKey: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/get/value/${cacheName}/${cacheKey}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除指定缓存名称
|
||||
* @param cacheName 缓存名称
|
||||
*/
|
||||
deleteCacheName(cacheName: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete/name/${cacheName}`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除指定缓存名称下的指定键
|
||||
* @param cacheName 缓存名称
|
||||
* @param cacheKey 键
|
||||
*/
|
||||
deleteCacheKey(cacheKey: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete/key/${cacheKey}`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除所有缓存
|
||||
*/
|
||||
deleteCacheAll() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete/all`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,39 +1,31 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/monitor/online';
|
||||
const API_PATH = "/monitor/online";
|
||||
|
||||
const OnlineAPI = {
|
||||
/**
|
||||
* 查询所有在线用户列表
|
||||
* @returns 所有在线用户列表
|
||||
*/
|
||||
// 查询在线用户列表
|
||||
listOnline(query: OnlineUserPageQuery) {
|
||||
return request<PageResult<OnlineUserTable[]>>({
|
||||
return request<ApiResponse<PageResult<OnlineUserTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 强退用户
|
||||
* @param body 用户会话ID列表
|
||||
*/
|
||||
// 强退用户
|
||||
deleteOnline(body: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 强退所有在线用户
|
||||
*/
|
||||
// 强退用户
|
||||
clearOnline() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/clear`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/monitor/resource';
|
||||
const API_PATH = "/monitor/resource";
|
||||
|
||||
export const ResourceAPI = {
|
||||
/**
|
||||
@@ -8,9 +8,9 @@ export const ResourceAPI = {
|
||||
* @param query 查询参数
|
||||
*/
|
||||
listResource(query: ResourcePageQuery) {
|
||||
return request<PageResult<ResourceItem[]>>({
|
||||
return request<ApiResponse<PageResult<ResourceItem[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
@@ -22,9 +22,9 @@ export const ResourceAPI = {
|
||||
uploadFile(formData: FormData) {
|
||||
return request<ApiResponse<ResourceUploadSchema>>({
|
||||
url: `${API_PATH}/upload`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: formData,
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
},
|
||||
|
||||
@@ -33,11 +33,11 @@ export const ResourceAPI = {
|
||||
* @param path 文件路径
|
||||
*/
|
||||
downloadFile(path: string) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/download`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: { path },
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
@@ -46,9 +46,9 @@ export const ResourceAPI = {
|
||||
* @param body 文件路径数组
|
||||
*/
|
||||
deleteResource(body: string[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
@@ -58,9 +58,9 @@ export const ResourceAPI = {
|
||||
* @param body 移动参数
|
||||
*/
|
||||
moveResource(body: ResourceMoveQuery) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/move`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
@@ -70,9 +70,9 @@ export const ResourceAPI = {
|
||||
* @param body 复制参数
|
||||
*/
|
||||
copyResource(body: ResourceCopyQuery) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/copy`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
@@ -82,9 +82,9 @@ export const ResourceAPI = {
|
||||
* @param body 重命名参数
|
||||
*/
|
||||
renameResource(body: ResourceRenameQuery) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/rename`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
@@ -94,9 +94,9 @@ export const ResourceAPI = {
|
||||
* @param body 创建目录参数
|
||||
*/
|
||||
createDirectory(body: ResourceCreateDirQuery) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create-dir`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
@@ -106,11 +106,11 @@ export const ResourceAPI = {
|
||||
* @param body 导出条件
|
||||
*/
|
||||
exportResource(body: ResourcePageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/monitor/server';
|
||||
const API_PATH = "/monitor/server";
|
||||
|
||||
const ServerAPI = {
|
||||
/**
|
||||
* 获取当前服务信息
|
||||
* @returns 服务信息
|
||||
*/
|
||||
// 获取服务信息
|
||||
getServer() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/info`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,93 +1,64 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/auth';
|
||||
const API_PATH = "/system/auth";
|
||||
|
||||
const AuthAPI = {
|
||||
/**
|
||||
* 登录
|
||||
* @param body 登录表单数据
|
||||
* @returns 登录响应
|
||||
*/
|
||||
login(body: LoginFormData) {
|
||||
return request<ApiResponse<LoginResult>>({
|
||||
url: `${API_PATH}/login`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 刷新令牌
|
||||
* @param body 刷新令牌请求体
|
||||
* @returns 刷新响应
|
||||
*/
|
||||
refreshToken(body: RefreshToekenBody) {
|
||||
return request<ApiResponse<LoginResult>>({
|
||||
url: `${API_PATH}/token/refresh`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
* @returns 验证码信息
|
||||
*/
|
||||
getCaptcha() {
|
||||
return request<ApiResponse<CaptchaInfo>>({
|
||||
url: `${API_PATH}/captcha/get`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
* @param body 退出登录操作
|
||||
*/
|
||||
logout(body: LogoutBody) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/logout`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取免登录用户列表
|
||||
* @returns 免登录用户列表
|
||||
*/
|
||||
/** 获取免登录用户列表 */
|
||||
getAutoLoginUsers() {
|
||||
return request<ApiResponse<AutoLoginUser[]>>({
|
||||
url: `${API_PATH}/auto-login/users`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取免登录Token
|
||||
* @param userId 用户ID
|
||||
* @returns 免登录Token响应
|
||||
*/
|
||||
/** 获取免登录Token */
|
||||
getAutoLoginToken(userId: number) {
|
||||
return request<ApiResponse<AutoLoginToken>>({
|
||||
url: `${API_PATH}/auto-login/token`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
params: { user_id: userId },
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 免登录
|
||||
* @param token 免登录Token
|
||||
* @returns 登录响应
|
||||
*/
|
||||
/** 免登录 */
|
||||
autoLogin(token: string) {
|
||||
return request<ApiResponse<LoginResult>>({
|
||||
url: `${API_PATH}/auto-login`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
params: { token },
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,78 +1,51 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/dept';
|
||||
const API_PATH = "/system/dept";
|
||||
|
||||
const DeptAPI = {
|
||||
/**
|
||||
* 获取部门树
|
||||
* @param query 查询参数
|
||||
* @returns 部门树
|
||||
*/
|
||||
listDept(query?: DeptPageQuery) {
|
||||
return request<ApiResponse<DeptTable[]>>({
|
||||
url: `${API_PATH}/tree`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取部门详情
|
||||
* @param query 部门ID
|
||||
* @returns 部门详情
|
||||
*/
|
||||
detailDept(query: number) {
|
||||
return request<ApiResponse<DeptTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建部门
|
||||
* @param body 部门信息
|
||||
*/
|
||||
createDept(body: DeptForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新部门
|
||||
* @param id 部门ID
|
||||
* @param body 部门信息
|
||||
*/
|
||||
updateDept(id: number, body: DeptForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除部门
|
||||
* @param body 部门ID列表
|
||||
*/
|
||||
deleteDept(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置部门状态
|
||||
* @param body 批量设置部门状态请求体
|
||||
*/
|
||||
batchDept(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,204 +1,131 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/dict';
|
||||
const API_PATH = "/system/dict";
|
||||
|
||||
const DictAPI = {
|
||||
/**
|
||||
* 获取字典类型列表
|
||||
* @param query 查询参数
|
||||
* @returns 字典类型列表
|
||||
*/
|
||||
listDictType(query: DictPageQuery) {
|
||||
return request<PageResult<DictTable[]>>({
|
||||
return request<ApiResponse<PageResult<DictTable[]>>>({
|
||||
url: `${API_PATH}/type/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典类型选项选择列表
|
||||
* @returns 字典类型选项选择列表
|
||||
*/
|
||||
optionDictType() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/type/optionselect`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典类型详情
|
||||
* @param query 字典类型ID
|
||||
* @returns 字典类型详情
|
||||
*/
|
||||
detailDictType(query: number) {
|
||||
return request<ApiResponse<DictTable>>({
|
||||
url: `${API_PATH}/type/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建字典类型
|
||||
* @param body 字典类型信息
|
||||
*/
|
||||
createDictType(body: DictForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/type/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新字典类型
|
||||
* @param id 字典类型ID
|
||||
* @param body 字典类型信息
|
||||
*/
|
||||
updateDictType(id: number, body: DictForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/type/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除字典类型
|
||||
* @param body 字典类型ID列表
|
||||
*/
|
||||
deleteDictType(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/type/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置字典类型状态
|
||||
* @param body 批量设置字典类型状态请求体
|
||||
*/
|
||||
batchDictType(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/type/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出字典类型
|
||||
* @param body 查询参数
|
||||
* @returns 字典类型导出文件
|
||||
*/
|
||||
exportDictType(body: DictPageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/type/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典数据列表
|
||||
* @param query 查询参数
|
||||
* @returns 字典数据列表
|
||||
*/
|
||||
listDictData(query: DictDataPageQuery) {
|
||||
return request<PageResult<DictDataTable[]>>({
|
||||
return request<ApiResponse<PageResult<DictDataTable[]>>>({
|
||||
url: `${API_PATH}/data/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典数据详情
|
||||
* @param query 字典数据ID
|
||||
* @returns 字典数据详情
|
||||
*/
|
||||
detailDictData(query: number) {
|
||||
return request<ApiResponse<DictDataTable>>({
|
||||
url: `${API_PATH}/data/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建字典数据
|
||||
* @param body 字典数据信息
|
||||
*/
|
||||
createDictData(body: DictDataForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/data/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新字典数据
|
||||
* @param id 字典数据ID
|
||||
* @param body 字典数据信息
|
||||
*/
|
||||
updateDictData(id: number, body: DictDataForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/data/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除字典数据
|
||||
* @param body 字典数据ID列表
|
||||
*/
|
||||
deleteDictData(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/data/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置字典数据状态
|
||||
* @param body 批量设置字典数据状态请求体
|
||||
*/
|
||||
batchDictData(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/data/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出字典数据
|
||||
* @param body 查询参数
|
||||
* @returns 字典数据导出文件
|
||||
*/
|
||||
exportDictData(body: DictDataPageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/data/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取初始化字典数据
|
||||
* @param dict_type 字典类型
|
||||
* @returns 初始化字典数据
|
||||
*/
|
||||
getInitDict(dict_type: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/data/info/${dict_type}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,56 +1,37 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/log';
|
||||
const API_PATH = "/system/log";
|
||||
|
||||
const LogAPI = {
|
||||
/**
|
||||
* 获取日志列表
|
||||
* @param query 查询参数
|
||||
* @returns 日志列表
|
||||
*/
|
||||
listLog(query: LogPageQuery) {
|
||||
return request<PageResult<LogTable[]>>({
|
||||
return request<ApiResponse<PageResult<LogTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取日志详情
|
||||
* @param query 日志ID
|
||||
* @returns 日志详情
|
||||
*/
|
||||
detailLog(query: number) {
|
||||
return request<ApiResponse<LogTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除日志
|
||||
* @param body 日志ID列表
|
||||
*/
|
||||
deleteLog(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出日志
|
||||
* @param body 查询参数
|
||||
* @returns 日志导出文件
|
||||
*/
|
||||
exportLog(body: LogPageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,78 +1,51 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/menu';
|
||||
const API_PATH = "/system/menu";
|
||||
|
||||
const MenuAPI = {
|
||||
/**
|
||||
* 获取菜单树
|
||||
* @param query 查询参数
|
||||
* @returns 菜单树
|
||||
*/
|
||||
listMenu(query?: MenuPageQuery) {
|
||||
return request<ApiResponse<MenuTable[]>>({
|
||||
url: `${API_PATH}/tree`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取菜单详情
|
||||
* @param query 菜单ID
|
||||
* @returns 菜单详情
|
||||
*/
|
||||
detailMenu(query: number) {
|
||||
return request<ApiResponse<MenuTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建菜单
|
||||
* @param body 菜单信息
|
||||
*/
|
||||
createMenu(body: MenuForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新菜单
|
||||
* @param id 菜单ID
|
||||
* @param body 菜单信息
|
||||
*/
|
||||
updateMenu(id: number, body: MenuForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除菜单
|
||||
* @param body 菜单ID列表
|
||||
*/
|
||||
deleteMenu(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置菜单状态
|
||||
* @param body 批量操作参数
|
||||
*/
|
||||
batchMenu(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,104 +1,68 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/notice';
|
||||
const API_PATH = "/system/notice";
|
||||
|
||||
const NoticeAPI = {
|
||||
/**
|
||||
* 获取通知列表
|
||||
* @param query 查询参数
|
||||
* @returns 通知列表
|
||||
*/
|
||||
listNotice(query: NoticePageQuery) {
|
||||
return request<PageResult<NoticeTable[]>>({
|
||||
return request<ApiResponse<PageResult<NoticeTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取可用通知列表
|
||||
* @returns 通知列表
|
||||
*/
|
||||
listNoticeAvailable() {
|
||||
return request<PageResult<NoticeTable[]>>({
|
||||
return request<ApiResponse<PageResult<NoticeTable[]>>>({
|
||||
url: `${API_PATH}/available`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取通知详情
|
||||
* @param query 通知ID
|
||||
* @returns 通知详情
|
||||
*/
|
||||
detailNotice(query: number) {
|
||||
return request<ApiResponse<NoticeTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建通知
|
||||
* @param body 通知信息
|
||||
*/
|
||||
createNotice(body: NoticeForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新通知
|
||||
* @param id 通知ID
|
||||
* @param body 通知信息
|
||||
*/
|
||||
updateNotice(id: number, body: NoticeForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除通知
|
||||
* @param body 通知ID列表
|
||||
*/
|
||||
deleteNotice(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置通知状态
|
||||
* @param body 批量操作参数
|
||||
*/
|
||||
batchNotice(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出通知
|
||||
* @param body 查询参数
|
||||
* @returns 通知导出文件
|
||||
*/
|
||||
exportNotice(body: NoticePageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,106 +1,69 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/param';
|
||||
const API_PATH = "/system/param";
|
||||
|
||||
const ParamsAPI = {
|
||||
/**
|
||||
* 上传文件
|
||||
* @param body 文件数据
|
||||
* @returns 上传后的文件路径
|
||||
*/
|
||||
uploadFile(body: any) {
|
||||
return request<ApiResponse<UploadFilePath>>({
|
||||
url: `${API_PATH}/upload`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取初始化配置
|
||||
* @returns 初始化配置列表
|
||||
*/
|
||||
getInitConfig() {
|
||||
return request<ApiResponse<ConfigTable[]>>({
|
||||
url: `${API_PATH}/info`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取参数列表
|
||||
* @param query 查询参数
|
||||
* @returns 参数列表
|
||||
*/
|
||||
listParams(query: ConfigPageQuery) {
|
||||
return request<PageResult<ConfigTable[]>>({
|
||||
return request<ApiResponse<PageResult<ConfigTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取参数详情
|
||||
* @param query 参数ID
|
||||
* @returns 参数详情
|
||||
*/
|
||||
detailParams(query: number) {
|
||||
return request<ApiResponse<ConfigTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建参数
|
||||
* @param body 参数信息
|
||||
*/
|
||||
createParams(body: ConfigForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新参数
|
||||
* @param id 参数ID
|
||||
* @param body 参数信息
|
||||
*/
|
||||
updateParams(id: number, body: ConfigForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除参数
|
||||
* @param body 参数ID列表
|
||||
*/
|
||||
deleteParams(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出参数
|
||||
* @param body 查询参数
|
||||
* @returns 导出的参数文件
|
||||
*/
|
||||
exportParams(body: ConfigPageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,93 +1,61 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/position';
|
||||
const API_PATH = "/system/position";
|
||||
|
||||
const PositionAPI = {
|
||||
/**
|
||||
* 获取岗位列表
|
||||
* @param query 查询参数
|
||||
* @returns 岗位列表
|
||||
*/
|
||||
listPosition(query?: PositionPageQuery) {
|
||||
return request<PageResult<PositionTable[]>>({
|
||||
return request<ApiResponse<PageResult<PositionTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取岗位详情
|
||||
* @param query 岗位ID
|
||||
* @returns 岗位详情
|
||||
*/
|
||||
detailPosition(query: number) {
|
||||
return request<ApiResponse<PositionTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建岗位
|
||||
* @param body 岗位信息
|
||||
*/
|
||||
createPosition(body: PositionForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新岗位
|
||||
* @param id 岗位ID
|
||||
* @param body 岗位信息
|
||||
*/
|
||||
updatePosition(id: number, body: PositionForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除岗位
|
||||
* @param body 岗位ID列表
|
||||
*/
|
||||
deletePosition(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置岗位状态
|
||||
* @param body 批量操作参数
|
||||
*/
|
||||
batchPosition(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出岗位
|
||||
* @param body 查询参数
|
||||
* @returns 导出的岗位文件
|
||||
*/
|
||||
exportPosition(body: PositionPageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,105 +1,69 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/role';
|
||||
const API_PATH = "/system/role";
|
||||
|
||||
const RoleAPI = {
|
||||
/**
|
||||
* 获取角色列表
|
||||
* @param query 查询参数
|
||||
* @returns 角色列表
|
||||
*/
|
||||
listRole(query?: TablePageQuery) {
|
||||
return request<PageResult<RoleTable[]>>({
|
||||
return request<ApiResponse<PageResult<RoleTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取角色详情
|
||||
* @param query 角色ID
|
||||
* @returns 角色详情
|
||||
*/
|
||||
detailRole(query: number) {
|
||||
return request<ApiResponse<RoleTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建角色
|
||||
* @param body 角色信息
|
||||
*/
|
||||
createRole(body: RoleForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新角色
|
||||
* @param id 角色ID
|
||||
* @param body 角色信息
|
||||
*/
|
||||
updateRole(id: number, body: RoleForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除角色
|
||||
* @param body 角色ID列表
|
||||
*/
|
||||
deleteRole(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置角色状态
|
||||
* @param body 批量操作参数
|
||||
*/
|
||||
batchRole(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置角色权限
|
||||
* @param body 批量操作参数
|
||||
*/
|
||||
setPermission(body: permissionDataType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/permission/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出角色列表
|
||||
* @param body 查询参数
|
||||
* @returns 导出的文件
|
||||
*/
|
||||
exportRole(body: TablePageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -131,9 +95,9 @@ export interface RoleForm extends BaseFormType {
|
||||
|
||||
export interface permissionDataType {
|
||||
data_scope: number;
|
||||
role_ids: RoleTable['id'][];
|
||||
menu_ids: permissionMenuType['id'][];
|
||||
dept_ids: permissionDeptType['id'][];
|
||||
role_ids: RoleTable["id"][];
|
||||
menu_ids: permissionMenuType["id"][];
|
||||
dept_ids: permissionDeptType["id"][];
|
||||
}
|
||||
|
||||
export interface permissionDeptType {
|
||||
|
||||
@@ -1,78 +1,51 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/system/tenant';
|
||||
const API_PATH = "/system/tenant";
|
||||
|
||||
const TenantAPI = {
|
||||
/**
|
||||
* 获取租户列表
|
||||
* @param query 查询参数
|
||||
* @returns 租户列表
|
||||
*/
|
||||
listTenant(query?: TenantPageQuery) {
|
||||
return request<PageResult<TenantTable[]>>({
|
||||
return request<ApiResponse<PageResult<TenantTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取租户详情
|
||||
* @param id 租户ID
|
||||
* @returns 租户详情
|
||||
*/
|
||||
detailTenant(id: number) {
|
||||
return request<ApiResponse<TenantTable>>({
|
||||
url: `${API_PATH}/detail/${id}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建租户
|
||||
* @param body 租户信息
|
||||
*/
|
||||
createTenant(body: TenantCreateForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新租户
|
||||
* @param id 租户ID
|
||||
* @param body 租户信息
|
||||
*/
|
||||
updateTenant(id: number, body: TenantUpdateForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除租户
|
||||
* @param body 租户ID列表
|
||||
*/
|
||||
deleteTenant(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置租户状态
|
||||
* @param body 批量操作参数
|
||||
*/
|
||||
batchTenant(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,214 +1,136 @@
|
||||
import request from '@/utils/http';
|
||||
import { MenuTable, MenuForm } from '@/api/module_system/menu';
|
||||
import request from "@/utils/request";
|
||||
import { MenuTable, MenuForm } from "@/api/module_system/menu";
|
||||
|
||||
const API_PATH = '/system/user';
|
||||
const API_PATH = "/system/user";
|
||||
|
||||
export const UserAPI = {
|
||||
/**
|
||||
* 获取当前用户信息
|
||||
* @returns 当前用户信息
|
||||
*/
|
||||
getCurrentUserInfo() {
|
||||
return request<ApiResponse<UserInfo>>({
|
||||
url: `${API_PATH}/current/info`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 上传当前用户头像
|
||||
* @param body 头像文件
|
||||
* @returns 上传后的文件路径
|
||||
*/
|
||||
uploadCurrentUserAvatar(body: any) {
|
||||
return request<ApiResponse<UploadFilePath>>({
|
||||
url: `${API_PATH}/current/avatar/upload`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新当前用户信息
|
||||
* @param body 用户信息
|
||||
* @returns 更新后的用户信息
|
||||
*/
|
||||
updateCurrentUserInfo(body: InfoFormState) {
|
||||
return request<ApiResponse<UserInfo>>({
|
||||
url: `${API_PATH}/current/info/update`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新当前用户密码
|
||||
* @param body 密码信息
|
||||
* @returns 更新后的用户信息
|
||||
*/
|
||||
changeCurrentUserPassword(body: PasswordFormState) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/current/password/change`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
* @param body 重置密码信息
|
||||
* @returns 重置密码后的用户信息
|
||||
*/
|
||||
resetUserPassword(body: ResetPasswordForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/reset/password`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 注册用户
|
||||
* @param body 注册信息
|
||||
* @returns 注册后的用户信息
|
||||
*/
|
||||
registerUser(body: RegisterForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/register`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 忘记密码
|
||||
* @param body 忘记密码信息
|
||||
* @returns 忘记密码后的用户信息
|
||||
*/
|
||||
forgetPassword(body: ForgetPasswordForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/forget/password`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @param query 查询参数
|
||||
* @returns 用户列表
|
||||
*/
|
||||
listUser(query: UserPageQuery) {
|
||||
return request<PageResult<UserInfo[]>>({
|
||||
return request<ApiResponse<PageResult<UserInfo[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取用户详情
|
||||
* @param id 用户ID
|
||||
* @returns 用户详情
|
||||
*/
|
||||
detailUser(query: number) {
|
||||
return request<ApiResponse<UserInfo>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
* @param body 用户信息
|
||||
* @returns 创建后的用户信息
|
||||
*/
|
||||
createUser(body: UserForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新用户
|
||||
* @param id 用户ID
|
||||
* @param body 用户信息
|
||||
* @returns 更新后的用户信息
|
||||
*/
|
||||
updateUser(id: number, body: UserForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @param body 用户ID列表
|
||||
*/
|
||||
deleteUser(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量设置用户状态
|
||||
* @param body 批量设置用户状态信息
|
||||
* @returns 批量设置用户状态后的用户列表
|
||||
*/
|
||||
batchUser(body: BatchType) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/available/setting`,
|
||||
method: 'patch',
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导出用户
|
||||
* @param body 查询参数
|
||||
* @returns 导出的用户文件
|
||||
*/
|
||||
exportUser(body: UserPageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
responseType: 'blob',
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载用户导入模板
|
||||
* @returns 导入模板文件
|
||||
*/
|
||||
downloadTemplateUser() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/import/template`,
|
||||
method: 'post',
|
||||
responseType: 'blob',
|
||||
method: "post",
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 导入用户数据
|
||||
* @param body 导入数据文件
|
||||
* @returns 导入后的用户列表
|
||||
*/
|
||||
importUser(body: any) {
|
||||
return request<ApiResponse<UserInfo[]>>({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/import/data`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
});
|
||||
},
|
||||
@@ -256,14 +178,14 @@ export interface UserInfo extends BaseType {
|
||||
password?: string;
|
||||
menus?: MenuTable[];
|
||||
dept?: deptTreeType;
|
||||
dept_id?: deptTreeType['id'];
|
||||
dept_name?: deptTreeType['name'];
|
||||
dept_id?: deptTreeType["id"];
|
||||
dept_name?: deptTreeType["name"];
|
||||
roles?: roleSelectorType[];
|
||||
role_names?: roleSelectorType['name'][];
|
||||
role_ids?: roleSelectorType['id'][];
|
||||
role_names?: roleSelectorType["name"][];
|
||||
role_ids?: roleSelectorType["id"][];
|
||||
positions?: positionSelectorType[];
|
||||
position_names?: positionSelectorType['name'][];
|
||||
position_ids?: positionSelectorType['id'][];
|
||||
position_names?: positionSelectorType["name"][];
|
||||
position_ids?: positionSelectorType["id"][];
|
||||
is_superuser?: boolean;
|
||||
last_login?: string;
|
||||
created_by?: CommonType;
|
||||
|
||||
@@ -1,179 +1,118 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/task/cronjob/job';
|
||||
const API_PATH = "/task/cronjob/job";
|
||||
|
||||
const JobAPI = {
|
||||
/**
|
||||
* 获取任务调度器状态
|
||||
* @returns 任务调度器状态
|
||||
*/
|
||||
getSchedulerStatus() {
|
||||
return request<ApiResponse<SchedulerStatus>>({
|
||||
url: `${API_PATH}/scheduler/status`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取任务调度器所有任务
|
||||
* @returns 任务调度器所有任务
|
||||
*/
|
||||
getSchedulerJobs() {
|
||||
return request<ApiResponse<SchedulerJob[]>>({
|
||||
url: `${API_PATH}/scheduler/jobs`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 启动任务调度器
|
||||
*/
|
||||
startScheduler() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/scheduler/start`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 暂停任务调度器
|
||||
*/
|
||||
pauseScheduler() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/scheduler/pause`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 恢复任务调度器
|
||||
*/
|
||||
resumeScheduler() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/scheduler/resume`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 关闭任务调度器
|
||||
*/
|
||||
shutdownScheduler() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/scheduler/shutdown`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 清除所有任务
|
||||
*/
|
||||
clearAllJobs() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/scheduler/jobs/clear`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取任务调度器控制台输出
|
||||
* @returns 任务调度器控制台输出
|
||||
*/
|
||||
getSchedulerConsole() {
|
||||
return request<ApiResponse<string>>({
|
||||
url: `${API_PATH}/scheduler/console`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 同步任务到数据库
|
||||
* @returns 同步任务到数据库的记录数
|
||||
*/
|
||||
syncJobsToDb() {
|
||||
return request<ApiResponse<number>>({
|
||||
url: `${API_PATH}/scheduler/sync`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
* @param jobId 任务ID
|
||||
*/
|
||||
pauseJob(jobId: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/task/pause/${jobId}`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 恢复任务
|
||||
* @param jobId 任务ID
|
||||
*/
|
||||
resumeJob(jobId: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/task/resume/${jobId}`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 立即运行任务
|
||||
* @param jobId 任务ID
|
||||
*/
|
||||
runJobNow(jobId: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/task/run/${jobId}`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
* @param jobId 任务ID
|
||||
*/
|
||||
removeJob(jobId: string) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/task/remove/${jobId}`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取任务日志列表
|
||||
* @param query 查询参数
|
||||
* @returns 任务日志列表
|
||||
*/
|
||||
getJobLogList(query: JobLogPageQuery) {
|
||||
return request<PageResult<JobLogTable[]>>({
|
||||
return request<ApiResponse<PageResult<JobLogTable[]>>>({
|
||||
url: `${API_PATH}/log/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取任务日志详情
|
||||
* @param id 任务日志ID
|
||||
* @returns 任务日志详情
|
||||
*/
|
||||
getJobLogDetail(id: number) {
|
||||
return request<ApiResponse<JobLogTable>>({
|
||||
url: `${API_PATH}/log/detail/${id}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除任务日志
|
||||
* @param ids 任务日志ID列表
|
||||
*/
|
||||
deleteJobLog(ids: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/log/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: ids,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,101 +1,65 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/task/cronjob/node';
|
||||
const API_PATH = "/task/cronjob/node";
|
||||
|
||||
const NodeAPI = {
|
||||
/**
|
||||
* 获取节点类型选项
|
||||
* @returns 节点类型选项
|
||||
*/
|
||||
getNodeTypeOptions() {
|
||||
return request<ApiResponse<NodeType[]>>({
|
||||
url: `${API_PATH}/options`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取节点列表
|
||||
* @param query 查询参数
|
||||
* @returns 节点列表
|
||||
*/
|
||||
listNode(query: NodePageQuery) {
|
||||
return request<PageResult<NodeTable[]>>({
|
||||
return request<ApiResponse<PageResult<NodeTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取节点详情
|
||||
* @param id 节点ID
|
||||
* @returns 节点详情
|
||||
*/
|
||||
detailNode(query: number) {
|
||||
return request<ApiResponse<NodeTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建节点
|
||||
* @param body 节点信息
|
||||
*/
|
||||
createNode(body: NodeForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新节点
|
||||
* @param id 节点ID
|
||||
* @param body 节点信息
|
||||
*/
|
||||
updateNode(id: number, body: NodeForm) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除节点
|
||||
* @param body 节点ID列表
|
||||
*/
|
||||
deleteNode(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 清空所有节点
|
||||
*/
|
||||
clearNode() {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/clear`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 执行节点
|
||||
* @param id 节点ID
|
||||
* @param params 执行参数
|
||||
* @returns 执行结果
|
||||
*/
|
||||
executeNode(id: number, params: ExecuteNodeParams = { trigger: 'now' }) {
|
||||
executeNode(id: number, params: ExecuteNodeParams = { trigger: "now" }) {
|
||||
return request<ApiResponse<ExecuteNodeResult>>({
|
||||
url: `${API_PATH}/execute/${id}`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: params,
|
||||
});
|
||||
},
|
||||
@@ -112,7 +76,7 @@ export interface NodePageQuery extends PageQuery {
|
||||
updated_time?: string[];
|
||||
}
|
||||
|
||||
export type TriggerType = 'now' | 'cron' | 'interval' | 'date';
|
||||
export type TriggerType = "now" | "cron" | "interval" | "date";
|
||||
|
||||
export interface ExecuteNodeParams {
|
||||
trigger: TriggerType;
|
||||
|
||||
@@ -1,95 +1,60 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
const API_PATH = '/task/workflow/definition';
|
||||
/** 对应后端 `plugin.module_task.workflow.definition` */
|
||||
const API_PATH = "/task/workflow/definition";
|
||||
|
||||
const WorkflowDefinitionAPI = {
|
||||
/**
|
||||
* 获取工作流列表
|
||||
* @param query 查询参数
|
||||
* @returns 工作流列表
|
||||
*/
|
||||
getWorkflowList(query: WorkflowPageQuery) {
|
||||
return request<PageResult<WorkflowTable[]>>({
|
||||
return request<ApiResponse<PageResult<WorkflowTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取工作流详情
|
||||
* @param query 工作流ID
|
||||
* @returns 工作流详情
|
||||
*/
|
||||
getWorkflowDetail(query: number) {
|
||||
return request<ApiResponse<WorkflowTable>>({
|
||||
url: `${API_PATH}/detail/${query}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建工作流
|
||||
* @param body 工作流信息
|
||||
* @returns 工作流详情
|
||||
*/
|
||||
createWorkflow(body: WorkflowForm) {
|
||||
return request<ApiResponse<WorkflowTable>>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新工作流
|
||||
* @param id 工作流ID
|
||||
* @param body 工作流信息
|
||||
* @returns 工作流详情
|
||||
*/
|
||||
updateWorkflow(id: number, body: WorkflowForm) {
|
||||
return request<ApiResponse<WorkflowTable>>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除工作流
|
||||
* @param body 工作流ID列表
|
||||
*/
|
||||
deleteWorkflow(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 发布工作流
|
||||
* @param id 工作流ID
|
||||
* @param body 发布参数
|
||||
* @returns 工作流详情
|
||||
*/
|
||||
publishWorkflow(id: number, body: WorkflowPublishForm) {
|
||||
return request<ApiResponse<WorkflowTable>>({
|
||||
url: `${API_PATH}/publish/${id}`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 执行工作流
|
||||
* @param body 执行参数
|
||||
* @returns 执行结果
|
||||
*/
|
||||
executeWorkflow(body: WorkflowExecuteForm) {
|
||||
return request<ApiResponse<WorkflowExecuteResult>>({
|
||||
url: `${API_PATH}/execute`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,82 +1,51 @@
|
||||
import request from '@/utils/http';
|
||||
import request from "@/utils/request";
|
||||
|
||||
/** 对应后端 `plugin.module_task.workflow.node_type` */
|
||||
const API_PATH = '/task/workflow/node-type';
|
||||
const API_PATH = "/task/workflow/node-type";
|
||||
|
||||
const WorkflowNodeTypeAPI = {
|
||||
/**
|
||||
* 获取编排节点类型选项
|
||||
* @returns 编排节点类型选项
|
||||
*/
|
||||
getWorkflowNodeTypeOptions() {
|
||||
return request<ApiResponse<WorkflowNodeTypeOption[]>>({
|
||||
url: `${API_PATH}/options`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取编排节点类型列表
|
||||
* @param query 查询参数
|
||||
* @returns 编排节点类型列表
|
||||
*/
|
||||
getWorkflowNodeTypeList(query: WorkflowNodeTypePageQuery) {
|
||||
return request<PageResult<WorkflowNodeTypeTable[]>>({
|
||||
return request<ApiResponse<PageResult<WorkflowNodeTypeTable[]>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取编排节点类型详情
|
||||
* @param id 编排节点类型ID
|
||||
* @returns 编排节点类型详情
|
||||
*/
|
||||
getWorkflowNodeTypeDetail(id: number) {
|
||||
return request<ApiResponse<WorkflowNodeTypeTable>>({
|
||||
url: `${API_PATH}/detail/${id}`,
|
||||
method: 'get',
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建编排节点类型
|
||||
* @param body 编排节点类型信息
|
||||
* @returns 编排节点类型详情
|
||||
*/
|
||||
createWorkflowNodeType(body: WorkflowNodeTypeForm) {
|
||||
return request<ApiResponse<WorkflowNodeTypeTable>>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: 'post',
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新编排节点类型
|
||||
* @param id 编排节点类型ID
|
||||
* @param body 编排节点类型信息
|
||||
* @returns 编排节点类型详情
|
||||
*/
|
||||
updateWorkflowNodeType(id: number, body: WorkflowNodeTypeForm) {
|
||||
return request<ApiResponse<WorkflowNodeTypeTable>>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: 'put',
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除编排节点类型
|
||||
* @param body 编排节点类型ID列表
|
||||
* @returns 删除结果
|
||||
* @returns 删除结果
|
||||
*/
|
||||
deleteWorkflowNodeType(body: number[]) {
|
||||
return request({
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: 'delete',
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import request from '@/utils/http';
|
||||
import { AppRouteRecord } from '@/types/router';
|
||||
|
||||
// 获取用户列表
|
||||
export function fetchGetUserList(params: Api.SystemManage.UserSearchParams) {
|
||||
return request.get<Api.SystemManage.UserList>({
|
||||
url: '/api/user/list',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取角色列表
|
||||
export function fetchGetRoleList(params: Api.SystemManage.RoleSearchParams) {
|
||||
return request.get<Api.SystemManage.RoleList>({
|
||||
url: '/api/role/list',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取菜单列表
|
||||
export function fetchGetMenuList() {
|
||||
return request.get<AppRouteRecord[]>({
|
||||
url: '/api/v3/system/menus',
|
||||
});
|
||||
}
|
||||
|
Before Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 954 B |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 726 B |
|
Before Width: | Height: | Size: 944 B |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 810 B |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 514 B |
|
Before Width: | Height: | Size: 409 B |
|
Before Width: | Height: | Size: 431 B |
|
Before Width: | Height: | Size: 439 B |
|
Before Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 286 B |
|
Before Width: | Height: | Size: 293 B |
|
Before Width: | Height: | Size: 448 B |
|
Before Width: | Height: | Size: 416 B |
|
Before Width: | Height: | Size: 509 B |
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 400 300" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="94" y="34" width="212" height="233"><path d="M306 34H94v233h212V34Z" fill="#fff"/></mask><g mask="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M234.427 155.64h38.36V69.6h-38.36v86.04ZM113.326 155.64h121.1V69.6h-121.1v86.04Z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M130.126 155.354h104.2v-72.95h-104.2v72.95ZM236.369 71.05s0 3.3 1.65 5.05c2.33 2.52 7.38-.2 7.38-.2s-1.75 5.15-1.55 10.19c.29 8.24 6.99 9.51 10 4.75 4.56 4.85 8.94-.29 9.52-2.62 4.27 4.76 9.32-.87 9.32-.87v-6.3l-23.99-12.13-12.33 2.13Z" fill="#C7DEFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M234.429 155.641h-121.1l-15.93 32.11h121.1l15.93-32.11Z" fill="#fff"/><path d="M234.427 69.6h38.46v86.04M113.326 146.52V69.6h121.1M234.429 155.641l-15.93 32.11h-121.1l15.93-32.11h111.39" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M226.37 159.715H116.82l-12.04 23.86H215l11.37-23.86Z" fill="#006EFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="m288.807 187.751-15.92-32.11h-38.46l16.02 32.11h38.36Z" fill="#fff"/><path d="m238.607 163.981 11.84 23.77h38.36l-15.92-32.11h-38.46" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M207.336 223.734c-3.69-13.77-15.44-23.86-29.33-23.86h-8.65s-27.09 14.94-27.09 33.27c0 18.34 25.44 33.18 25.44 33.18h10.4c13.79-.1 25.44-10.19 29.13-23.87 1.75-12.51 0-18.62.1-18.72Z" fill="#C7DEFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M243.459 240.421c3.98 0 7.28-3.3 7.28-7.27 0-3.98-3.3-7.28-7.28-7.28h-31.08c-3.98 0-7.28 3.3-7.28 7.28 0 3.97 3.3 7.27 7.28 7.27h31.08Z" fill="#C7DEFF"/><path d="M210.342 223.737c-4.08-13.87-16.9-23.96-32.05-23.96H168.972s-29.62 14.94-29.62 33.37 27.87 33.37 27.87 33.37h11.27c15.05-.1 27.77-10.19 31.75-23.96" stroke="#071F4D"/><path d="M212.379 240.421c-3.98 0-7.28-3.3-7.28-7.27m0 0c0-3.98 3.3-7.28 7.28-7.28" stroke="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M168.781 199.777c-18.45 0-33.41 14.94-33.41 33.37s14.96 33.37 33.41 33.37c18.45 0 33.4-14.94 33.4-33.37s-14.95-33.37-33.4-33.37Z" fill="#006EFF"/><path d="M168.781 199.777c-18.45 0-33.41 14.94-33.41 33.37s14.96 33.37 33.41 33.37c18.45 0 33.4-14.94 33.4-33.37s-14.95-33.37-33.4-33.37Z" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M168.775 209.38c-13.14 0-23.79 10.64-23.79 23.77 0 13.12 10.65 23.76 23.79 23.76 13.14 0 23.8-10.64 23.8-23.76 0-13.13-10.66-23.77-23.8-23.77Z" fill="#00E4E5"/><path d="M162.174 223.736a17.48 17.48 0 0 1 14.76-8.05M159.455 231.982c.1-1.36.29-2.62.68-3.88" stroke="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M173.535 209.87c-1.55-.3-3.11-.49-4.76-.49-13.11 0-23.79 10.67-23.79 23.77 0 13.09 10.68 23.76 23.79 23.76 1.65 0 3.21-.19 4.76-.48-10.88-2.23-19.03-11.84-19.03-23.28 0-11.45 8.15-21.05 19.03-23.28Z" fill="#071F4D"/><path d="M219.957 225.774h23.6c4.08 0 7.38 3.3 7.38 7.37m0 0c0 4.08-3.3 7.37-7.38 7.37h-20.1M212.091 225.774h3.3" stroke="#071F4D"/><path d="m248.894 34.485-.19 18.24c0 4.07-.39 5.23-2.14 6.79-8.15 6.88-10.97 9.02-9.22 12.9 1.45 3.2 6.79 2.23 9.61-1.55-.39 4.56-5.24 15.32-.58 18.04 4.37 2.52 6.89-3.49 6.89-3.49s.49 3.49 4.47 3.49c3.69 0 5.24-4.75 5.24-4.75s2.14 3.49 6.22 1.35c3.11-1.55 5.44-7.08 5.44-26.67v-24.35" fill="#fff"/><path d="m248.894 34.485-.19 18.24c0 4.07-.39 5.23-2.14 6.79-8.15 6.88-10.97 9.02-9.22 12.9 1.45 3.2 6.79 2.23 9.61-1.55-.39 4.56-5.24 15.32-.58 18.04 4.37 2.52 6.89-3.49 6.89-3.49s.49 3.49 4.47 3.49c3.69 0 5.24-4.75 5.24-4.75s2.14 3.49 6.22 1.35c3.11-1.55 5.44-7.08 5.44-26.67v-24.35" stroke="#071F4D"/><path d="M255.307 75.71s-.39 5.43-2.04 9.6l2.04-9.6Z" fill="#fff"/><path d="M255.307 75.71s-.39 5.43-2.04 9.6" stroke="#071F4D"/><path d="M264.921 75.323s-.68 5.24-2.04 8.63l2.04-8.63Z" fill="#fff"/><path d="M264.921 75.323s-.68 5.24-2.04 8.63M147.801 34.485v34.92M121.775 34.485v34.92M102.546 204.724v13.97M102.546 222.379v.87M102.546 197.934v3.49M115.268 206.955v26.29M115.268 239.451v5.34M244.43 197.643v11.93M244.43 213.939v3.49M270.359 201.232v33.76M115.369 47.774h-13.6M94.486 47.774h3.4M241.516 47.774h-84.1M280.168 47.774h25.35" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="m282.497 183.575-12.04-23.86h-27.29l11.36 23.86h27.97Z" fill="#00E4E5"/><path d="M234.427 134.88V69.6M234.427 140.412v7.66" stroke="#071F4D"/><path d="M220.831 228.684h16.99M240.934 228.684h2.43" stroke="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="m223.842 187.462 21.46-.2-10.97-20.66-10.49 20.86Z" fill="#071F4D"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
@@ -1,5 +0,0 @@
|
||||
<svg
|
||||
viewBox="0 0 400 300"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="47" y="38" width="307" height="224"><path d="M353.3 38H47.5v223.8h305.8V38Z" fill="#fff"/></mask><g mask="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M299.2 200.6H61.6v5.1h240.3l-2.7-5.1Z" fill="#C7DEFF"/><path d="m308.9 185.8-6.5 20H183.7M332.3 127.6h10.6l-5 16.7-14.8-.1-7.2 21.1M328.8 127.4l13.6-39.6M307.6 166 337 84.7H180.6l-9.8 26.9h-10.5M296.6 196l4.3-11.8M157.2 149.2l6.4-17.7" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M324.8 93.1H188.5l-34.8 95.8h136.4l34.7-95.8ZM169.9 166.2l5-13.6-5 13.6Z" fill="#fff"/><path d="m169.9 166.2 5-13.6" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M324.8 93.1H188.5l-4 11.7h135.8l4.5-11.7Z" fill="#006EFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M102.6 159.5h38.3l2.7 36.6h-38.4c-10.1 0-20.9-8.2-20.9-18.3 0-10.1 8.2-18.3 18.3-18.3Z" fill="#DEEBFC"/><path fill-rule="evenodd" clip-rule="evenodd" d="M84.3 174.102c2.5 3.4 10 5 17.9 2.8 16.6-6.5 23.8-3.9 23.8-3.9s.5-3.4 1.3-5c-5.8-3-15.4.3-26.1 3.1-10.7 2.8-15.8-2.5-15.8-2.5-.4 0-1.1 2.8-1.1 5.5Z" fill="#fff"/><path d="M96.5 194.2c-7.2-3.3-12.2-10.5-12.2-19m0 0c0-11.5 9.3-20.8 20.8-20.8h29.4" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M140.3 195.1c-8.4-2.7-14.5-10.6-14.5-19.8l14.5 19.8Zm-14.5-19.8c0-11.5 9.3-20.8 20.8-20.8l-20.8 20.8Zm20.8-20.8c11.5 0 20.8 9.3 20.8 20.8l-20.8-20.8Zm20.8 20.8c0 8.4-5 15.6-12.1 18.9l12.1-18.9Z" fill="#fff"/><path d="M140.3 195.1c-8.4-2.7-14.5-10.6-14.5-19.8m0 0c0-11.5 9.3-20.8 20.8-20.8m0 0c11.5 0 20.8 9.3 20.8 20.8m0 0c0 8.4-5 15.6-12.1 18.9" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M161.5 177.2c0-7.7-6.3-14-14-14s-14 6.3-14 14c0 5.8 3.5 10.8 8.6 12.9.1 0 5.8 1.6 10.7 0 5.3-1.7 8.7-7.1 8.7-12.9Z" fill="#00E4E5"/><path d="M140.5 190.1c-5.8-2.4-9.9-8.2-9.9-14.9 0-8.9 7.2-16.1 16.1-16.1 8.9 0 16.1 7.2 16.1 16.1 0 6.8-4.2 12.5-10.1 14.9M88.4 170.604c2.9 1.3 7.7 2.6 13.6.3 14.7-5.7 22.3-4.3 24.6-3.5M84.5 174.599s5.9 6.5 19 1.7c9.2-3.4 15.3-3.9 18.8-3.8" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M340.6 112.3h-55.2l-2.7 6.2H338l2.6-6.2Z" fill="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M236.8 117.9c-16.13 0-29.2 13.07-29.2 29.2s13.07 29.2 29.2 29.2 29.2-13.07 29.2-29.2-13.07-29.2-29.2-29.2Z" fill="#00E4E5"/><path d="M265 123.3c13.1 13.1 13.1 34.4 0 47.6M306 205.9h19.2M61.7 205.9h32.9M181.2 196.2h115.2M47.5 205.9h10v-9.7h73.8" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M146.7 179.2c-2.49 0-4.5 2.01-4.5 4.5s2.01 4.5 4.5 4.5 4.5-2.01 4.5-4.5-2.01-4.5-4.5-4.5Z" fill="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M169.5 196.2c3.9 0 7.1 3.2 7.1 7.1 0 3.9-3.2 7.1-7.1 7.1H144c-2.1 0-3.9 1.7-3.9 3.9v1c0 2.1 1.7 3.9 3.9 3.9h48c5.1 0 9.2 4.1 9.2 9.2s-4.1 9.3-9.2 9.2h-33.8c-2.3 0-4.1 1.8-4.1 4.1s1.8 4.1 4.1 4.1h4.2c4.4 0 8 3.6 8 8s-3.6 8-8 8H111c-3.7 0-6.8-3-6.8-6.8 0-3.7 3-6.8 6.8-6.8h.3c2.3 0 4.1-1.8 4.1-4.1s-1.8-4.1-4.1-4.1H79c-4.5 0-8.1-3.6-8.1-8.1s3.6-8.1 8.1-8.1h37.7c2.1 0 3.9-1.7 3.9-3.9 0-2.1-1.7-3.9-3.9-3.9h-7.9c-4.4 0-7.9-3.5-7.9-7.9s3.5-7.9 7.9-7.9h30.4c2.2 0 3.9-1.8 3.9-3.9V187c0-1.9 1.6-3.5 3.5-3.5s3.5 1.6 3.5 3.5v5.3c0 2.2 1.8 3.9 3.9 3.9h15.5Z" fill="#006EFF"/><path d="m227.8 138.5 18.7 18.7M227.8 157.2l18.7-18.7" stroke="#fff" stroke-width="6"/><path fill-rule="evenodd" clip-rule="evenodd" d="M194.8 96.9c-.99 0-1.8.81-1.8 1.8s.81 1.8 1.8 1.8 1.8-.81 1.8-1.8-.81-1.8-1.8-1.8ZM202.9 96.9c-.99 0-1.8.81-1.8 1.8s.81 1.8 1.8 1.8 1.8-.81 1.8-1.8-.81-1.8-1.8-1.8Z" fill="#fff"/><path d="m291.7 184.3-1.6 4.6h-121M298.1 166.7l22.5-61.9" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="m193 134.1 2.2-5.1h-19.4l-2.3 5.1H193ZM313.2 123.5l2.2-5.1h-24.5l-2.3 5.1h24.6Z" fill="#DEEBFC"/><path d="m164.5 159.2 19.8-54.6" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M199.6 119.8h-53.2l-4.4 9.3h53.2l4.4-9.3Z" fill="#00E4E5"/><path d="M151.3 129.1H142l4.4-9.3h16.9" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M353.3 169.4h-67.4l-4.8 12.2h67.3l4.9-12.2Z" fill="#006EFF"/><path d="M332.4 169.4h20.9l-4.9 12.2h-39.7M242.7 235.5v-4.8c0-3.8 3.1-7 7-7h20.2c3.8 0 7 3.1 7 7" stroke="#071F4D"/><path d="M261.1 235.5v-4.8c0-3.8 3.1-7 7-7h13.7c3.8 0 7 3.1 7 7v4.8M242.6 230.7h13.7M235.2 237.7h63.3M224 237.7h6.7" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M324.1 141.3H335l3.3-10.7h-10.2l-4 10.7Z" fill="#C7DEFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M288.3 230.4c0-3.6-2.9-6.5-6.5-6.5h-14.2c-3.6 0-6.5 2.9-6.5 6.5v5.3h27.2v-5.3Z" fill="#071F4D"/><path d="M80.4 228.5H83M87.7 228.5h19.2M146.3 195.8v2c0 3.6-2.9 6.6-6.6 6.6H138M133.4 204.3h1.5M154 249.9h9.4" stroke="#DEEBFC"/><path d="m299.4 141.9 5.1-13.9" stroke="#071F4D"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 4.8 KiB |
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 400 300" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="44" y="42" width="312" height="217"><path d="M355.3 42H44v216.9h311.3V42Z" fill="#fff"/></mask><g mask="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M288.2 248.4h25.1v-30h-25.1v30Z" fill="#C7DEFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M304.498 238.199c-1.5-3.9-5.9-15.4-4-21.6-2.9.8-3.3.1-5-.1-1.7-.1 0 10.7 2.2 16.4 1.7 4.5 2.1 11.1 2.1 13.6h5.4c.2-1.9.3-5.5-.7-8.3Z" fill="#fff"/><path d="M311.5 214.7v-1.6c0-.7-.6-1.3-1.3-1.3h-22.8c-.7 0-1.3.6-1.3 1.3v1.6" fill="#fff"/><path d="M311.5 214.7v-1.6c0-.7-.6-1.3-1.3-1.3h-22.8c-.7 0-1.3.6-1.3 1.3v1.6M290.2 214.7h21.4c1 0 1.8.8 1.8 1.8v29" stroke="#071F4D" stroke-width="1.096"/><path d="M284.3 245.6v-29c0-1 .8-1.8 1.8-1.8h1.6" fill="#fff"/><path d="M284.3 245.6v-29c0-1 .8-1.8 1.8-1.8h1.6" stroke="#071F4D" stroke-width="1.096"/><path d="M295.402 216.5c-.9 4.2-.4 9.7 2.8 17.5 2.4 5.9 1.9 10.2 1.8 12.3M300.502 216.5c-.9 4.2-.4 9.7 2.8 17.5 2.4 5.9 1.9 10.2 1.8 12.3" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="m331 258.4-.3-5.2H88.5l-1.2 5.2H331Z" fill="#C7DEFF"/><path d="M252.9 248.7H331M216.6 258.4H331M47.1 139.3l-2.6 1.5 42.7 117.6h129.2v-6.6" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="m247.2 248.6-40.4-111.3H50.5l40.3 111.3h156.4Z" fill="#fff"/><path d="m247.2 248.6-40.4-111.3H50.5l40.3 111.3h156.4Z" stroke="#071F4D"/><path d="m203.2 153.2 32.2 88.7H97.8l-32.3-88.7" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M72.2 146.9c-.77 0-1.4.63-1.4 1.4 0 .77.63 1.4 1.4 1.4.77 0 1.4-.63 1.4-1.4 0-.77-.63-1.4-1.4-1.4ZM79.3 146.9c-.77 0-1.4.63-1.4 1.4 0 .77.63 1.4 1.4 1.4.77 0 1.4-.63 1.4-1.4 0-.77-.63-1.4-1.4-1.4Z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M263.5 171.2h80.3v-63.7h-80.3v63.7Z" fill="#C7DEFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M290 143.9h-45.6l12.5 51.3H290v-51.3Z" fill="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M286 117.4h-29.3v77.8h92.9v-67.6l-55.9.6-7.7-10.8Z" fill="#00E4E5"/><path d="m332.6 127.6-38.9.6-7.7-10.8h-11.7M308.9 195.2h45.9M250.3 195.2h28.5M287.3 195.2h12.3" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M130.5 211.4H186v-44h-55.5v44Z" fill="#C7DEFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M148.7 192.5h-31.6l8.7 35.5h22.9v-35.5Z" fill="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M145.9 174.2h-20.2V228h64.1v-46.7l-38.6.4-5.3-7.5Z" fill="#006EFF"/><path d="m179 181.3-27.8.4-5.3-7.5h-7.7M176.2 201.7h19.2M163.2 210.7H195M172.1 228h-54.2M184.8 228h8.1M174.9 228h5.4" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="m293.2 155.7-6.4 6.3 15.3 15.3 22.7-22.6-6.4-6.4-16.3 16.3-8.9-8.9Z" fill="#fff"/><path d="M57.2 258.4h283.6M345.9 258.4h8.1M55.4 258.4h220.5M160.1 118.8l-1.2 2.7M156.7 127c-.3.8-.7 1.8-1.1 2.8M222 68.5c-1 .2-1.9.5-2.9.8M214.1 70.7c-5.8 1.9-11.3 4.4-16.5 7.4M195.4 79.5c-.9.5-1.7 1.1-2.5 1.6M314.2 98.5c-.6-.8-1.3-1.5-2-2.3M308.9 92.8c-4-4-8.3-7.6-13-10.8M293.9 80.7c-.8-.5-1.7-1.1-2.5-1.6" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M251.296 71.203c-3.6-1.5-18.5-2.9-21.8-1.9-1 5.8 4.9 13.5 4.9 13.5s6-9.9 16.9-11.6Z" fill="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M251.3 42.704c-6.5 6.7-7.8 13-8.8 19.3 24.4-1.1 36.3 13 42.8 20 3.2-9.1 7.8-23 7.2-29-7.1-6.4-20-11.7-41.2-10.3Z" fill="#C7DEFF"/><path d="M230 69.3c36.2-3.8 52 21.1 52 21.1s11.4-28.2 10.5-37.4c-7.3-6.5-23.3-12-45.6-10.1-9 6.3-15.6 18.7-16.9 26.4Z" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M161.604 70.7c-6 8.4-9.9 21.9-8.8 33.8 8.4 5.3 32.3 10.5 43.6 11.5 6.1-7.9 15.9-26 15.9-26s-32-4.8-50.7-19.3Z" fill="#C7DEFF"/><path d="M193.103 119.5c4.8-2.7 19.2-29.5 19.2-29.5s-35.8-5.4-53.7-21.8c-9.3 6.1-16.4 24.3-15 40.1 10.6 6.7 45.8 13.3 49.5 11.2Z" stroke="#071F4D"/><path fill-rule="evenodd" clip-rule="evenodd" d="M189.5 111.6c-3 5.2-5.7 7.2-9.8 6.6 12.2 2.6 13.5 1.2 15.6-1.1 2.2-2.4 4.2-6.6 4.2-6.6s-3.1 2.5-10 1.1Z" fill="#071F4D"/><path d="M331 251.8v6.6M77 165.4l-2.7-6.7h7.8M222.8 228.9l2.8 6.6h-7.9" stroke="#071F4D"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |