Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43750b306c | ||
|
|
28aa8b5f62 | ||
|
|
e71181f0a3 |
@@ -1,31 +0,0 @@
|
|||||||
# EditorConfig is awesome: https://EditorConfig.org
|
|
||||||
|
|
||||||
# top-most EditorConfig file
|
|
||||||
root = true
|
|
||||||
|
|
||||||
# Unix-style newlines with a newline ending every file
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
# Matches multiple files with brace expansion notation
|
|
||||||
[*.{js,jsx,ts,tsx,vue}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
# Matches multiple files with brace expansion notation
|
|
||||||
[*.{json,md,yml,yaml}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
# Matches multiple files with brace expansion notation
|
|
||||||
[*.scss]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
# The above files are for code, but for config files we want no indentation
|
|
||||||
[{package.json,.eslintrc.cjs,.prettierrc}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# 开发环境配置
|
|
||||||
VITE_API_BASE_URL=http://localhost:8000/api/v1
|
|
||||||
VITE_APP_TITLE=资产管理系统
|
|
||||||
+35
-3
@@ -1,3 +1,35 @@
|
|||||||
# 生产环境配置
|
APP_NAME=资产管理系统
|
||||||
VITE_API_BASE_URL=https://zc.workyai.cn/api/v1
|
APP_VERSION=1.0.0
|
||||||
VITE_APP_TITLE=资产管理系统
|
APP_ENVIRONMENT=production
|
||||||
|
DEBUG=False
|
||||||
|
HOST=0.0.0.0
|
||||||
|
PORT=8001
|
||||||
|
API_V1_PREFIX=/api/v1
|
||||||
|
|
||||||
|
# 数据库配置(从服务器获取)
|
||||||
|
DATABASE_URL=postgresql+asyncpg://asset_user:PASSWORD@118.145.218.2:5433/asset_management
|
||||||
|
DATABASE_ECHO=False
|
||||||
|
|
||||||
|
# Redis配置
|
||||||
|
REDIS_URL=redis://:PASSWORD@118.145.218.2:6380/0
|
||||||
|
REDIS_MAX_CONNECTIONS=50
|
||||||
|
|
||||||
|
# JWT配置
|
||||||
|
SECRET_KEY=请生成强密钥
|
||||||
|
ALGORITHM=HS256
|
||||||
|
ACCESS_TOKEN_EXPIRE_MINUTES=15
|
||||||
|
REFRESH_TOKEN_EXPIRE_DAYS=7
|
||||||
|
|
||||||
|
# CORS配置
|
||||||
|
CORS_ORIGINS=["https://zc.workyai.cn"]
|
||||||
|
CORS_ALLOW_CREDENTIALS=True
|
||||||
|
CORS_ALLOW_METHODS=["GET","POST","PUT","DELETE","PATCH"]
|
||||||
|
CORS_ALLOW_HEADERS=["*"]
|
||||||
|
|
||||||
|
# 文件上传配置
|
||||||
|
UPLOAD_DIR=uploads
|
||||||
|
MAX_UPLOAD_SIZE=104857600
|
||||||
|
|
||||||
|
# 日志配置
|
||||||
|
LOG_LEVEL=INFO
|
||||||
|
LOG_FILE=logs/app.log
|
||||||
|
|||||||
@@ -1,312 +0,0 @@
|
|||||||
{
|
|
||||||
"globals": {
|
|
||||||
"Component": true,
|
|
||||||
"ComponentPublicInstance": true,
|
|
||||||
"ComputedRef": true,
|
|
||||||
"DirectiveBinding": true,
|
|
||||||
"EffectScope": true,
|
|
||||||
"ExtractDefaultPropTypes": true,
|
|
||||||
"ExtractPropTypes": true,
|
|
||||||
"ExtractPublicPropTypes": true,
|
|
||||||
"InjectionKey": true,
|
|
||||||
"MaybeRef": true,
|
|
||||||
"MaybeRefOrGetter": true,
|
|
||||||
"PropType": true,
|
|
||||||
"Ref": true,
|
|
||||||
"VNode": true,
|
|
||||||
"WritableComputedRef": true,
|
|
||||||
"acceptHMRUpdate": true,
|
|
||||||
"asyncComputed": true,
|
|
||||||
"autoResetRef": true,
|
|
||||||
"computed": true,
|
|
||||||
"computedAsync": true,
|
|
||||||
"computedEager": true,
|
|
||||||
"computedInject": true,
|
|
||||||
"computedWithControl": true,
|
|
||||||
"controlledComputed": true,
|
|
||||||
"controlledRef": true,
|
|
||||||
"createApp": true,
|
|
||||||
"createEventHook": true,
|
|
||||||
"createGlobalState": true,
|
|
||||||
"createInjectionState": true,
|
|
||||||
"createPinia": true,
|
|
||||||
"createReactiveFn": true,
|
|
||||||
"createReusableTemplate": true,
|
|
||||||
"createSharedComposable": true,
|
|
||||||
"createTemplatePromise": true,
|
|
||||||
"createUnrefFn": true,
|
|
||||||
"customRef": true,
|
|
||||||
"debouncedRef": true,
|
|
||||||
"debouncedWatch": true,
|
|
||||||
"defineAsyncComponent": true,
|
|
||||||
"defineComponent": true,
|
|
||||||
"defineStore": true,
|
|
||||||
"eagerComputed": true,
|
|
||||||
"effectScope": true,
|
|
||||||
"extendRef": true,
|
|
||||||
"getActivePinia": true,
|
|
||||||
"getCurrentInstance": true,
|
|
||||||
"getCurrentScope": true,
|
|
||||||
"h": true,
|
|
||||||
"ignorableWatch": true,
|
|
||||||
"inject": true,
|
|
||||||
"injectLocal": true,
|
|
||||||
"isDefined": true,
|
|
||||||
"isProxy": true,
|
|
||||||
"isReactive": true,
|
|
||||||
"isReadonly": true,
|
|
||||||
"isRef": true,
|
|
||||||
"makeDestructurable": true,
|
|
||||||
"mapActions": true,
|
|
||||||
"mapGetters": true,
|
|
||||||
"mapState": true,
|
|
||||||
"mapStores": true,
|
|
||||||
"mapWritableState": true,
|
|
||||||
"markRaw": true,
|
|
||||||
"nextTick": true,
|
|
||||||
"onActivated": true,
|
|
||||||
"onBeforeMount": true,
|
|
||||||
"onBeforeRouteLeave": true,
|
|
||||||
"onBeforeRouteUpdate": true,
|
|
||||||
"onBeforeUnmount": true,
|
|
||||||
"onBeforeUpdate": true,
|
|
||||||
"onClickOutside": true,
|
|
||||||
"onDeactivated": true,
|
|
||||||
"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,
|
|
||||||
"useCounter": true,
|
|
||||||
"useCssModule": true,
|
|
||||||
"useCssVar": true,
|
|
||||||
"useCssVars": true,
|
|
||||||
"useCurrentElement": true,
|
|
||||||
"useCycleList": true,
|
|
||||||
"useDark": true,
|
|
||||||
"useDateFormat": true,
|
|
||||||
"useDebounce": true,
|
|
||||||
"useDebounceFn": true,
|
|
||||||
"useDebouncedRefHistory": true,
|
|
||||||
"useDeviceMotion": true,
|
|
||||||
"useDeviceOrientation": true,
|
|
||||||
"useDevicePixelRatio": true,
|
|
||||||
"useDevicesList": true,
|
|
||||||
"useDisplayMedia": true,
|
|
||||||
"useDocumentVisibility": true,
|
|
||||||
"useDraggable": true,
|
|
||||||
"useDropZone": true,
|
|
||||||
"useElementBounding": true,
|
|
||||||
"useElementByPoint": true,
|
|
||||||
"useElementHover": true,
|
|
||||||
"useElementSize": true,
|
|
||||||
"useElementVisibility": true,
|
|
||||||
"useEventBus": true,
|
|
||||||
"useEventListener": true,
|
|
||||||
"useEventSource": true,
|
|
||||||
"useEyeDropper": true,
|
|
||||||
"useFavicon": true,
|
|
||||||
"useFetch": true,
|
|
||||||
"useFileDialog": true,
|
|
||||||
"useFileSystemAccess": true,
|
|
||||||
"useFocus": true,
|
|
||||||
"useFocusWithin": true,
|
|
||||||
"useFps": true,
|
|
||||||
"useFullscreen": true,
|
|
||||||
"useGamepad": true,
|
|
||||||
"useGeolocation": true,
|
|
||||||
"useId": true,
|
|
||||||
"useIdle": true,
|
|
||||||
"useImage": true,
|
|
||||||
"useInfiniteScroll": true,
|
|
||||||
"useIntersectionObserver": true,
|
|
||||||
"useInterval": true,
|
|
||||||
"useIntervalFn": true,
|
|
||||||
"useKeyModifier": true,
|
|
||||||
"useLastChanged": true,
|
|
||||||
"useLink": true,
|
|
||||||
"useLocalStorage": true,
|
|
||||||
"useMagicKeys": true,
|
|
||||||
"useManualRefHistory": true,
|
|
||||||
"useMediaControls": true,
|
|
||||||
"useMediaQuery": true,
|
|
||||||
"useMemoize": true,
|
|
||||||
"useMemory": true,
|
|
||||||
"useModel": true,
|
|
||||||
"useMounted": true,
|
|
||||||
"useMouse": true,
|
|
||||||
"useMouseInElement": true,
|
|
||||||
"useMousePressed": true,
|
|
||||||
"useMutationObserver": true,
|
|
||||||
"useNavigatorLanguage": true,
|
|
||||||
"useNetwork": true,
|
|
||||||
"useNow": true,
|
|
||||||
"useObjectUrl": true,
|
|
||||||
"useOffsetPagination": true,
|
|
||||||
"useOnline": true,
|
|
||||||
"usePageLeave": true,
|
|
||||||
"useParallax": true,
|
|
||||||
"useParentElement": true,
|
|
||||||
"usePerformanceObserver": true,
|
|
||||||
"usePermission": true,
|
|
||||||
"usePointer": true,
|
|
||||||
"usePointerLock": true,
|
|
||||||
"usePointerSwipe": true,
|
|
||||||
"usePreferredColorScheme": true,
|
|
||||||
"usePreferredContrast": true,
|
|
||||||
"usePreferredDark": true,
|
|
||||||
"usePreferredLanguages": true,
|
|
||||||
"usePreferredReducedMotion": true,
|
|
||||||
"usePrevious": true,
|
|
||||||
"useRafFn": true,
|
|
||||||
"useRefHistory": true,
|
|
||||||
"useResizeObserver": true,
|
|
||||||
"useRoute": true,
|
|
||||||
"useRouter": true,
|
|
||||||
"useScreenOrientation": true,
|
|
||||||
"useScreenSafeArea": true,
|
|
||||||
"useScriptTag": true,
|
|
||||||
"useScroll": true,
|
|
||||||
"useScrollLock": true,
|
|
||||||
"useSessionStorage": true,
|
|
||||||
"useShare": true,
|
|
||||||
"useSlots": true,
|
|
||||||
"useSorted": true,
|
|
||||||
"useSpeechRecognition": true,
|
|
||||||
"useSpeechSynthesis": true,
|
|
||||||
"useStepper": true,
|
|
||||||
"useStorage": true,
|
|
||||||
"useStorageAsync": true,
|
|
||||||
"useStyleTag": true,
|
|
||||||
"useSupported": true,
|
|
||||||
"useSwipe": true,
|
|
||||||
"useTemplateRef": true,
|
|
||||||
"useTemplateRefsList": true,
|
|
||||||
"useTextDirection": true,
|
|
||||||
"useTextSelection": true,
|
|
||||||
"useTextareaAutosize": true,
|
|
||||||
"useThrottle": true,
|
|
||||||
"useThrottleFn": true,
|
|
||||||
"useThrottledRefHistory": true,
|
|
||||||
"useTimeAgo": true,
|
|
||||||
"useTimeout": true,
|
|
||||||
"useTimeoutFn": true,
|
|
||||||
"useTimeoutPoll": true,
|
|
||||||
"useTimestamp": true,
|
|
||||||
"useTitle": true,
|
|
||||||
"useToNumber": true,
|
|
||||||
"useToString": true,
|
|
||||||
"useToggle": true,
|
|
||||||
"useTransition": true,
|
|
||||||
"useUrlSearchParams": true,
|
|
||||||
"useUserMedia": true,
|
|
||||||
"useVModel": true,
|
|
||||||
"useVModels": true,
|
|
||||||
"useVibrate": true,
|
|
||||||
"useVirtualList": true,
|
|
||||||
"useWakeLock": true,
|
|
||||||
"useWebNotification": true,
|
|
||||||
"useWebSocket": true,
|
|
||||||
"useWebWorker": true,
|
|
||||||
"useWebWorkerFn": true,
|
|
||||||
"useWindowFocus": true,
|
|
||||||
"useWindowScroll": true,
|
|
||||||
"useWindowSize": true,
|
|
||||||
"watch": true,
|
|
||||||
"watchArray": true,
|
|
||||||
"watchAtMost": true,
|
|
||||||
"watchDebounced": true,
|
|
||||||
"watchDeep": true,
|
|
||||||
"watchEffect": true,
|
|
||||||
"watchIgnorable": true,
|
|
||||||
"watchImmediate": true,
|
|
||||||
"watchOnce": true,
|
|
||||||
"watchPausable": true,
|
|
||||||
"watchPostEffect": true,
|
|
||||||
"watchSyncEffect": true,
|
|
||||||
"watchThrottled": true,
|
|
||||||
"watchTriggerable": true,
|
|
||||||
"watchWithFilter": true,
|
|
||||||
"whenever": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
es2021: true,
|
|
||||||
node: true
|
|
||||||
},
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:vue/vue3-recommended'
|
|
||||||
],
|
|
||||||
parser: 'vue-eslint-parser',
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 'latest',
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
sourceType: 'module'
|
|
||||||
},
|
|
||||||
plugins: ['@typescript-eslint', 'vue'],
|
|
||||||
rules: {
|
|
||||||
// Vue 规则
|
|
||||||
'vue/multi-word-component-names': 'off',
|
|
||||||
'vue/no-v-html': 'off',
|
|
||||||
|
|
||||||
// TypeScript 规则
|
|
||||||
'@typescript-eslint/no-explicit-any': 'warn',
|
|
||||||
'@typescript-eslint/no-unused-vars': ['error', {
|
|
||||||
argsIgnorePattern: '^_',
|
|
||||||
varsIgnorePattern: '^_'
|
|
||||||
}],
|
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
||||||
|
|
||||||
// 通用规则
|
|
||||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
|
||||||
'prefer-const': 'error',
|
|
||||||
'no-var': 'error'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+102
-33
@@ -1,38 +1,107 @@
|
|||||||
# Logs
|
# Byte-compiled / optimized / DLL files
|
||||||
logs
|
__pycache__/
|
||||||
*.log
|
*.py[cod]
|
||||||
npm-debug.log*
|
*$py.class
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
node_modules
|
# C extensions
|
||||||
dist
|
*.so
|
||||||
dist-ssr
|
|
||||||
*.local
|
|
||||||
|
|
||||||
# Editor directories and files
|
# Distribution / packaging
|
||||||
.vscode/*
|
.Python
|
||||||
!.vscode/extensions.json
|
build/
|
||||||
.idea
|
develop-eggs/
|
||||||
.DS_Store
|
dist/
|
||||||
*.suo
|
downloads/
|
||||||
*.ntvs*
|
eggs/
|
||||||
*.njsproj
|
.eggs/
|
||||||
*.sln
|
lib/
|
||||||
*.sw?
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
# Environment variables
|
# PyInstaller
|
||||||
|
*.manifest
|
||||||
|
.spec
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
tests/.pytest_cache/
|
||||||
|
tests/*.png
|
||||||
|
|
||||||
|
# Environments
|
||||||
.env
|
.env
|
||||||
.env.local
|
.env.local
|
||||||
.env.development.local
|
.env.production
|
||||||
.env.test.local
|
.venv
|
||||||
.env.production.local
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Database
|
||||||
|
*.db
|
||||||
|
*.sqlite
|
||||||
|
*.sqlite3
|
||||||
|
|
||||||
|
# Uploads
|
||||||
|
uploads/*
|
||||||
|
!uploads/.gitkeep
|
||||||
|
|
||||||
|
# Alembic
|
||||||
|
alembic/versions/*.py
|
||||||
|
!alembic/versions/__init__.py
|
||||||
|
|
||||||
|
# MyPy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# Jupyter
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# VSCode
|
||||||
|
.vscode/
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
coverage
|
test_*.py
|
||||||
.nyc_output/
|
*_test.py
|
||||||
|
tests/
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
*.md
|
*.md
|
||||||
@@ -41,7 +110,6 @@ PHASE*.md
|
|||||||
DELIVERY*.md
|
DELIVERY*.md
|
||||||
SUMMARY*.md
|
SUMMARY*.md
|
||||||
!README.md
|
!README.md
|
||||||
!src/components/charts/README.md
|
|
||||||
|
|
||||||
# Temporary files
|
# Temporary files
|
||||||
*.tmp
|
*.tmp
|
||||||
@@ -49,7 +117,8 @@ SUMMARY*.md
|
|||||||
*.bak
|
*.bak
|
||||||
*.backup
|
*.backup
|
||||||
|
|
||||||
# Lock files
|
# Docker
|
||||||
package-lock.json
|
.dockerignore
|
||||||
yarn.lock
|
|
||||||
pnpm-lock.yaml
|
# Test reports
|
||||||
|
test_reports/
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"semi": false,
|
|
||||||
"singleQuote": true,
|
|
||||||
"printWidth": 100,
|
|
||||||
"tabWidth": 2,
|
|
||||||
"trailingComma": "none",
|
|
||||||
"arrowParens": "avoid",
|
|
||||||
"endOfLine": "auto"
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
图表组件库文件清单
|
|
||||||
===================
|
|
||||||
|
|
||||||
核心组件
|
|
||||||
--------
|
|
||||||
src/components/charts/BaseChart.vue
|
|
||||||
src/components/charts/PieChart.vue
|
|
||||||
src/components/charts/BarChart.vue
|
|
||||||
src/components/charts/LineChart.vue
|
|
||||||
src/components/charts/GaugeChart.vue
|
|
||||||
src/components/charts/FunnelChart.vue
|
|
||||||
|
|
||||||
业务图表组件
|
|
||||||
------------
|
|
||||||
src/components/charts/business/AssetStatusChart.vue
|
|
||||||
src/components/charts/business/AssetDistributionChart.vue
|
|
||||||
src/components/charts/business/AssetValueTrendChart.vue
|
|
||||||
src/components/charts/business/AssetUtilizationChart.vue
|
|
||||||
|
|
||||||
统计卡片组件
|
|
||||||
------------
|
|
||||||
src/components/statistics/StatCard.vue
|
|
||||||
src/components/statistics/StatCardGroup.vue
|
|
||||||
|
|
||||||
Composables
|
|
||||||
-----------
|
|
||||||
src/composables/useECharts.ts
|
|
||||||
src/composables/useChartData.ts
|
|
||||||
|
|
||||||
工具函数
|
|
||||||
--------
|
|
||||||
src/utils/echarts.ts
|
|
||||||
src/utils/echarts/performance.ts
|
|
||||||
|
|
||||||
类型定义
|
|
||||||
--------
|
|
||||||
src/types/charts.ts
|
|
||||||
src/components/charts/charts.d.ts
|
|
||||||
|
|
||||||
组件导出
|
|
||||||
--------
|
|
||||||
src/components/charts/index.ts
|
|
||||||
src/components/charts/README.md
|
|
||||||
src/components/statistics/index.ts
|
|
||||||
|
|
||||||
文档
|
|
||||||
----
|
|
||||||
CHARTS_README.md - 完整使用文档
|
|
||||||
CHARTS_DELIVERY.md - 交付文档
|
|
||||||
CHARTS_QUICKSTART.md - 快速开始指南
|
|
||||||
CHARTS_SUMMARY.md - 项目总结
|
|
||||||
CHARTS_FILES.txt - 本文件
|
|
||||||
|
|
||||||
示例和测试
|
|
||||||
----------
|
|
||||||
src/views/examples/ChartsExample.vue
|
|
||||||
tests/unit/components/PieChart.test.ts
|
|
||||||
tests/unit/composables/useECharts.test.ts
|
|
||||||
|
|
||||||
路由配置
|
|
||||||
--------
|
|
||||||
src/router/index.ts (已添加示例页面路由)
|
|
||||||
|
|
||||||
总计:25 个文件
|
|
||||||
+21
-7
@@ -1,12 +1,26 @@
|
|||||||
FROM nginx:alpine
|
FROM python:3.10-slim
|
||||||
|
|
||||||
# 复制构建产物
|
WORKDIR /app
|
||||||
COPY dist /usr/share/nginx/html
|
|
||||||
|
|
||||||
# 复制Nginx配置
|
# 安装系统依赖
|
||||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
RUN apt-get update && apt-get install -y \
|
||||||
|
gcc \
|
||||||
|
postgresql-client \
|
||||||
|
curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# 复制依赖文件
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# 复制应用代码
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 创建必要的目录
|
||||||
|
RUN mkdir -p logs uploads uploads/qrcodes
|
||||||
|
|
||||||
# 暴露端口
|
# 暴露端口
|
||||||
EXPOSE 3000
|
EXPOSE 8001
|
||||||
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
# 启动命令
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8001"]
|
||||||
|
|||||||
@@ -1,217 +1,284 @@
|
|||||||
# 资产管理系统前端
|
# 资产管理系统 - 后端API
|
||||||
|
|
||||||
> 基于 Vue 3 + TypeScript + Element Plus 构建的现代化资产管理系统前端应用
|
基于 FastAPI + SQLAlchemy + PostgreSQL 的企业级资产管理系统后端API
|
||||||
|
|
||||||
## 技术栈
|
## 技术栈
|
||||||
|
|
||||||
- **框架**: Vue 3.4+ (Composition API + `<script setup>`)
|
- **框架**: FastAPI 0.104+
|
||||||
- **语言**: TypeScript 5.0+
|
- **ORM**: SQLAlchemy 2.0+ (异步模式)
|
||||||
- **构建工具**: Vite 5
|
- **数据库**: PostgreSQL 14+
|
||||||
- **UI组件库**: Element Plus
|
- **缓存**: Redis
|
||||||
- **状态管理**: Pinia
|
- **认证**: JWT (python-jose)
|
||||||
- **路由**: Vue Router 4
|
- **密码加密**: bcrypt
|
||||||
- **HTTP客户端**: Axios
|
- **数据验证**: Pydantic v2
|
||||||
- **表单验证**: VeeValidate + Yup
|
- **数据库迁移**: Alembic
|
||||||
- **图表**: ECharts
|
- **测试**: pytest
|
||||||
- **工具库**: dayjs, lodash-es, qrcode
|
- **ASGI服务器**: Uvicorn
|
||||||
- **组合式函数**: @vueuse/core
|
|
||||||
- **代码规范**: ESLint + Prettier
|
|
||||||
- **测试**: Vitest
|
|
||||||
|
|
||||||
## 功能特性
|
## 项目结构
|
||||||
|
|
||||||
### Phase 1: 项目基础搭建 ✅
|
|
||||||
- [x] Vite + Vue 3项目初始化
|
|
||||||
- [x] TypeScript配置
|
|
||||||
- [x] ESLint + Prettier配置
|
|
||||||
- [x] 路由配置(Vue Router 4)
|
|
||||||
- [x] 状态管理(Pinia)
|
|
||||||
- [x] Axios请求封装
|
|
||||||
- [x] UI主题配置(青灰配色 #475569)
|
|
||||||
|
|
||||||
### Phase 2: 认证与布局 ✅
|
|
||||||
- [x] 登录页面(Login.vue)
|
|
||||||
- [x] 主应用布局(MainLayout.vue)
|
|
||||||
- [x] 侧边菜单组件
|
|
||||||
- [x] 顶部导航栏
|
|
||||||
- [x] 认证状态管理
|
|
||||||
- [x] 路由守卫
|
|
||||||
|
|
||||||
### Phase 3: 后台管理模块(开发中)
|
|
||||||
- [ ] 用户管理页面
|
|
||||||
- [ ] 角色权限页面
|
|
||||||
- [ ] 设备类型管理页面
|
|
||||||
- [ ] 动态表单设计器
|
|
||||||
- [ ] 机构网点管理页面
|
|
||||||
|
|
||||||
### Phase 4: 资产管理模块(部分完成)
|
|
||||||
- [x] 资产列表页面
|
|
||||||
- [x] 资产详情对话框
|
|
||||||
- [x] 资产入库页面
|
|
||||||
- [x] 资产编辑对话框
|
|
||||||
- [ ] 批量导入组件
|
|
||||||
- [ ] 批量导出组件
|
|
||||||
- [ ] 扫码查询页面
|
|
||||||
- [ ] 二维码对话框
|
|
||||||
- [ ] 资产状态追踪组件
|
|
||||||
|
|
||||||
### Phase 5: 资产分配模块(待开发)
|
|
||||||
- [ ] 分配单列表页面
|
|
||||||
- [ ] 创建分配单对话框
|
|
||||||
- [ ] 审批对话框
|
|
||||||
- [ ] 资产选择器
|
|
||||||
|
|
||||||
### Phase 6: 维修与统计(待开发)
|
|
||||||
- [ ] 维修管理页面
|
|
||||||
- [ ] 统计报表页面
|
|
||||||
- [ ] ECharts图表集成
|
|
||||||
|
|
||||||
### Phase 7: 系统管理(待开发)
|
|
||||||
- [ ] 系统配置页面
|
|
||||||
- [ ] 操作日志页面
|
|
||||||
- [ ] 消息通知组件
|
|
||||||
- [ ] 个人中心页面
|
|
||||||
|
|
||||||
## 目录结构
|
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
asset_management_backend/
|
||||||
├── api/ # API接口
|
├── app/
|
||||||
│ ├── request.ts # Axios封装
|
│ ├── api/ # API路由
|
||||||
│ ├── auth.ts # 认证接口
|
│ │ └── v1/
|
||||||
│ ├── assets.ts # 资产接口
|
│ │ ├── auth.py # 认证相关API
|
||||||
│ ├── users.ts # 用户接口
|
│ │ └── __init__.py
|
||||||
│ └── index.ts # 统一导出
|
│ ├── core/ # 核心模块
|
||||||
├── assets/ # 静态资源
|
│ │ ├── config.py # 配置管理
|
||||||
│ └── styles/ # 全局样式
|
│ │ ├── security.py # 安全相关
|
||||||
│ ├── variables.scss # 主题变量
|
│ │ ├── deps.py # 依赖注入
|
||||||
│ └── index.scss # 全局样式
|
│ │ ├── exceptions.py # 自定义异常
|
||||||
├── components/ # 通用组件
|
│ │ └── response.py # 统一响应
|
||||||
├── composables/ # 组合式函数
|
│ ├── crud/ # 数据库CRUD操作
|
||||||
│ ├── usePagination.ts # 分页
|
│ │ ├── user.py # 用户CRUD
|
||||||
│ └── useTable.ts # 表格
|
│ │ └── ...
|
||||||
├── layouts/ # 布局组件
|
│ ├── db/ # 数据库相关
|
||||||
│ └── MainLayout.vue # 主布局
|
│ │ ├── base.py # 模型基类
|
||||||
├── router/ # 路由配置
|
│ │ └── session.py # 会话管理
|
||||||
│ └── index.ts
|
│ ├── models/ # SQLAlchemy模型
|
||||||
├── stores/ # Pinia状态管理
|
│ │ ├── user.py # 用户模型
|
||||||
│ ├── modules/
|
│ │ └── ...
|
||||||
│ │ ├── user.ts # 用户状态
|
│ ├── schemas/ # Pydantic Schema
|
||||||
│ │ └── app.ts # 应用状态
|
│ │ ├── user.py # 用户Schema
|
||||||
│ └── index.ts
|
│ │ └── ...
|
||||||
├── types/ # TypeScript类型定义
|
│ ├── services/ # 业务逻辑层
|
||||||
│ └── index.ts
|
│ │ ├── auth_service.py # 认证服务
|
||||||
├── utils/ # 工具函数
|
│ │ └── ...
|
||||||
│ ├── auth.ts # 认证工具
|
│ └── utils/ # 工具函数
|
||||||
│ ├── format.ts # 格式化工具
|
│ └── ...
|
||||||
│ ├── validate.ts # 验证工具
|
├── alembic/ # 数据库迁移
|
||||||
│ └── constants.ts # 常量定义
|
│ └── versions/
|
||||||
├── views/ # 页面组件
|
├── tests/ # 测试
|
||||||
│ ├── auth/ # 认证相关
|
├── logs/ # 日志文件
|
||||||
│ │ └── Login.vue
|
├── uploads/ # 上传文件
|
||||||
│ ├── admin/ # 后台管理
|
├── .env.example # 环境变量示例
|
||||||
│ │ ├── UserManagement.vue
|
├── requirements.txt # 依赖包
|
||||||
│ │ ├── RoleManagement.vue
|
├── run.py # 开发服务器启动脚本
|
||||||
│ │ ├── DeviceTypeManagement.vue
|
└── README.md # 项目说明
|
||||||
│ │ └── OrganizationManagement.vue
|
|
||||||
│ ├── assets/ # 资产管理
|
|
||||||
│ │ ├── AssetList.vue
|
|
||||||
│ │ ├── AssetCreate.vue
|
|
||||||
│ │ ├── AssetAllocation.vue
|
|
||||||
│ │ ├── AssetScan.vue
|
|
||||||
│ │ ├── MaintenanceManagement.vue
|
|
||||||
│ │ ├── StatisticsDashboard.vue
|
|
||||||
│ │ └── components/ # 资产相关组件
|
|
||||||
│ │ ├── AssetDetailDialog.vue
|
|
||||||
│ │ ├── AssetEditDialog.vue
|
|
||||||
│ │ └── QrcodeDialog.vue
|
|
||||||
│ └── error/ # 错误页面
|
|
||||||
│ └── 404.vue
|
|
||||||
├── App.vue # 根组件
|
|
||||||
└── main.ts # 应用入口
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 开发指南
|
## 快速开始
|
||||||
|
|
||||||
### 安装依赖
|
### 1. 环境准备
|
||||||
|
|
||||||
|
确保已安装:
|
||||||
|
- Python 3.10+
|
||||||
|
- PostgreSQL 14+
|
||||||
|
- Redis
|
||||||
|
|
||||||
|
### 2. 安装依赖
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
# 创建虚拟环境
|
||||||
|
python -m venv venv
|
||||||
|
|
||||||
|
# 激活虚拟环境
|
||||||
|
# Windows:
|
||||||
|
venv\Scripts\activate
|
||||||
|
# Linux/Mac:
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
# 安装依赖包
|
||||||
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
### 启动开发服务器
|
### 3. 配置环境变量
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
# 复制环境变量示例文件
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
# 编辑 .env 文件,配置数据库等信息
|
||||||
```
|
```
|
||||||
|
|
||||||
访问 `http://localhost:3000`
|
### 4. 初始化数据库
|
||||||
|
|
||||||
### 构建生产版本
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run build
|
# 创建数据库
|
||||||
|
createdb asset_management
|
||||||
|
|
||||||
|
# 运行数据库迁移
|
||||||
|
alembic upgrade head
|
||||||
|
|
||||||
|
# 或在开发环境直接初始化(会自动创建表)
|
||||||
|
# 修改 app/main.py 中的 lifespan 函数,取消注释 init_db()
|
||||||
```
|
```
|
||||||
|
|
||||||
### 代码检查
|
### 5. 启动服务
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run lint
|
# 开发模式(支持热重载)
|
||||||
|
python run.py
|
||||||
|
|
||||||
|
# 或使用 uvicorn
|
||||||
|
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||||
```
|
```
|
||||||
|
|
||||||
### 代码格式化
|
### 6. 访问API文档
|
||||||
|
|
||||||
```bash
|
启动成功后,访问以下地址:
|
||||||
npm run format
|
|
||||||
```
|
|
||||||
|
|
||||||
### 运行测试
|
- Swagger UI: http://localhost:8000/docs
|
||||||
|
- ReDoc: http://localhost:8000/redoc
|
||||||
|
- OpenAPI JSON: http://localhost:8000/openapi.json
|
||||||
|
|
||||||
```bash
|
## API端点
|
||||||
npm run test
|
|
||||||
```
|
|
||||||
|
|
||||||
## 环境配置
|
### 认证模块
|
||||||
|
|
||||||
### 开发环境 (.env.development)
|
- `POST /api/v1/auth/login` - 用户登录
|
||||||
```
|
- `POST /api/v1/auth/refresh` - 刷新令牌
|
||||||
VITE_API_BASE_URL=http://localhost:8000/api/v1
|
- `POST /api/v1/auth/logout` - 用户登出
|
||||||
VITE_APP_TITLE=资产管理系统
|
- `PUT /api/v1/auth/change-password` - 修改密码
|
||||||
```
|
- `GET /api/v1/auth/captcha` - 获取验证码
|
||||||
|
|
||||||
### 生产环境 (.env.production)
|
### 用户管理
|
||||||
```
|
|
||||||
VITE_API_BASE_URL=https://api.yourcompany.com/api/v1
|
|
||||||
VITE_APP_TITLE=资产管理系统
|
|
||||||
```
|
|
||||||
|
|
||||||
## 主题定制
|
- `GET /api/v1/users` - 用户列表
|
||||||
|
- `POST /api/v1/users` - 创建用户
|
||||||
|
- `GET /api/v1/users/{user_id}` - 获取用户详情
|
||||||
|
- `PUT /api/v1/users/{user_id}` - 更新用户
|
||||||
|
- `DELETE /api/v1/users/{user_id}` - 删除用户
|
||||||
|
- `POST /api/v1/users/{user_id}/reset-password` - 重置密码
|
||||||
|
- `GET /api/v1/users/me` - 获取当前用户信息
|
||||||
|
|
||||||
主题色采用青灰配色方案 (#475569),在 `src/assets/styles/variables.scss` 中可以自定义主题变量。
|
### 角色权限
|
||||||
|
|
||||||
## API接口规范
|
- `GET /api/v1/roles` - 角色列表
|
||||||
|
- `POST /api/v1/roles` - 创建角色
|
||||||
|
- `GET /api/v1/roles/{role_id}` - 获取角色详情
|
||||||
|
- `PUT /api/v1/roles/{role_id}` - 更新角色
|
||||||
|
- `DELETE /api/v1/roles/{role_id}` - 删除角色
|
||||||
|
- `GET /api/v1/permissions/tree` - 权限树列表
|
||||||
|
|
||||||
详见 `complete_api_reference.md` 文档。
|
更多API请查看Swagger文档。
|
||||||
|
|
||||||
## 开发规范
|
## 开发规范
|
||||||
|
|
||||||
详见 `development_standards_guide.md` 文档。
|
请参考 `development_standards_guide.md` 文件。
|
||||||
|
|
||||||
## 页面原型
|
### 代码风格
|
||||||
|
|
||||||
详见 `frontend_page_prototypes.md` 文档。
|
- 遵循 PEP 8 规范
|
||||||
|
- 使用 Black 进行代码格式化
|
||||||
|
- 使用 isort 管理导入
|
||||||
|
- 使用 flake8 进行代码检查
|
||||||
|
- 使用 mypy 进行类型检查
|
||||||
|
|
||||||
## 浏览器支持
|
### 提交规范
|
||||||
|
|
||||||
- Chrome >= 90
|
遵循 Conventional Commits 规范:
|
||||||
- Firefox >= 88
|
|
||||||
- Safari >= 14
|
|
||||||
- Edge >= 90
|
|
||||||
|
|
||||||
## 作者
|
```
|
||||||
|
feat: 新功能
|
||||||
|
fix: Bug修复
|
||||||
|
docs: 文档更新
|
||||||
|
style: 代码格式
|
||||||
|
refactor: 重构
|
||||||
|
perf: 性能优化
|
||||||
|
test: 测试
|
||||||
|
chore: 构建/工具
|
||||||
|
```
|
||||||
|
|
||||||
老王
|
示例:
|
||||||
|
```bash
|
||||||
|
git commit -m "feat(auth): 实现用户登录功能"
|
||||||
|
git commit -m "fix(asset): 修复资产状态转换问题"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 运行所有测试
|
||||||
|
pytest
|
||||||
|
|
||||||
|
# 运行特定测试文件
|
||||||
|
pytest tests/api/test_auth.py
|
||||||
|
|
||||||
|
# 生成覆盖率报告
|
||||||
|
pytest --cov=app --cov-report=html
|
||||||
|
|
||||||
|
# 查看覆盖率报告
|
||||||
|
open htmlcov/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
## 数据库迁移
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建新的迁移
|
||||||
|
alembic revision --autogenerate -m "描述信息"
|
||||||
|
|
||||||
|
# 执行迁移
|
||||||
|
alembic upgrade head
|
||||||
|
|
||||||
|
# 回滚迁移
|
||||||
|
alembic downgrade -1
|
||||||
|
|
||||||
|
# 查看迁移历史
|
||||||
|
alembic history
|
||||||
|
|
||||||
|
# 查看当前版本
|
||||||
|
alembic current
|
||||||
|
```
|
||||||
|
|
||||||
|
## 生产部署
|
||||||
|
|
||||||
|
### 使用 Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 构建镜像
|
||||||
|
docker build -t asset-management-backend .
|
||||||
|
|
||||||
|
# 运行容器
|
||||||
|
docker run -d \
|
||||||
|
--name asset-backend \
|
||||||
|
-p 8000:8000 \
|
||||||
|
--env-file .env \
|
||||||
|
asset-management-backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用 Gunicorn + Uvicorn
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install gunicorn
|
||||||
|
|
||||||
|
gunicorn app.main:app \
|
||||||
|
--workers 4 \
|
||||||
|
--worker-class uvicorn.workers.UvicornWorker \
|
||||||
|
--bind 0.0.0.0:8000 \
|
||||||
|
--access-logfile - \
|
||||||
|
--error-logfile -
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### 数据库连接失败
|
||||||
|
|
||||||
|
检查 `DATABASE_URL` 是否正确配置,确保PostgreSQL服务正在运行。
|
||||||
|
|
||||||
|
### Redis连接失败
|
||||||
|
|
||||||
|
检查 `REDIS_URL` 是否正确配置,确保Redis服务正在运行。
|
||||||
|
|
||||||
|
### Token验证失败
|
||||||
|
|
||||||
|
确保 `SECRET_KEY` 配置正确,并检查Token是否过期。
|
||||||
|
|
||||||
|
## 贡献指南
|
||||||
|
|
||||||
|
1. Fork 本仓库
|
||||||
|
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
|
||||||
|
3. 提交更改 (`git commit -m 'feat: Add some AmazingFeature'`)
|
||||||
|
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||||||
|
5. 创建 Pull Request
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|
||||||
MIT
|
本项目采用 MIT 许可证。
|
||||||
|
|
||||||
|
## 联系方式
|
||||||
|
|
||||||
|
- 项目负责人: 老王
|
||||||
|
- 创建时间: 2025-01-24
|
||||||
|
- 版本: v1.0.0
|
||||||
|
|||||||
@@ -207,6 +207,9 @@ class AuthService:
|
|||||||
Returns:
|
Returns:
|
||||||
包含captcha_key和captcha_base64的字典
|
包含captcha_key和captcha_base64的字典
|
||||||
"""
|
"""
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
from app.utils.redis_client import redis_client
|
from app.utils.redis_client import redis_client
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
@@ -214,15 +217,17 @@ class AuthService:
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
# 生成4位随机验证码,使用更清晰的字符组合(排除易混淆的字符)
|
try:
|
||||||
captcha_text = ''.join(random.choices('23456789', k=4)) # 排除0、1
|
# 生成4位随机验证码,使用更清晰的字符组合(排除易混淆的字符)
|
||||||
|
captcha_text = ''.join(random.choices('23456789', k=4)) # 排除0、1
|
||||||
|
logger.info(f"生成验证码: {captcha_text}")
|
||||||
|
|
||||||
# 生成验证码图片
|
# 生成验证码图片
|
||||||
width, height = 200, 80 # 增大图片尺寸
|
width, height = 200, 80 # 增大图片尺寸
|
||||||
# 使用浅色背景而不是纯白
|
# 使用浅色背景而不是纯白
|
||||||
background_color = (245, 245, 250) # 浅蓝灰色
|
background_color = (245, 245, 250) # 浅蓝灰色
|
||||||
image = Image.new('RGB', (width, height), color=background_color)
|
image = Image.new('RGB', (width, height), color=background_color)
|
||||||
draw = ImageDraw.Draw(image)
|
draw = ImageDraw.Draw(image)
|
||||||
|
|
||||||
# 尝试使用更大的字体
|
# 尝试使用更大的字体
|
||||||
try:
|
try:
|
||||||
@@ -260,6 +265,7 @@ class AuthService:
|
|||||||
|
|
||||||
# 生成captcha_key
|
# 生成captcha_key
|
||||||
captcha_key = ''.join(random.choices(string.ascii_letters + string.digits, k=32))
|
captcha_key = ''.join(random.choices(string.ascii_letters + string.digits, k=32))
|
||||||
|
logger.info(f"生成验证码Key: {captcha_key}")
|
||||||
|
|
||||||
# 存储到Redis,5分钟过期
|
# 存储到Redis,5分钟过期
|
||||||
await redis_client.setex(
|
await redis_client.setex(
|
||||||
@@ -267,11 +273,15 @@ class AuthService:
|
|||||||
300,
|
300,
|
||||||
captcha_text
|
captcha_text
|
||||||
)
|
)
|
||||||
|
logger.info(f"验证码已存储到Redis: captcha:{captcha_key}, 值: {captcha_text}")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"captcha_key": captcha_key,
|
"captcha_key": captcha_key,
|
||||||
"captcha_base64": f"data:image/png;base64,{image_base64}"
|
"captcha_base64": f"data:image/png;base64,{image_base64}"
|
||||||
}
|
}
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"生成验证码失败: {str(e)}", exc_info=True)
|
||||||
|
raise
|
||||||
|
|
||||||
async def _verify_captcha(self, captcha_key: str, captcha: str) -> bool:
|
async def _verify_captcha(self, captcha_key: str, captcha: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user