diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e461761 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +frp/frpc +frp/frps +frp/frpc +frp/frps +frontend/node_modules/ diff --git a/frontend/frontend_beautiful.log b/frontend/frontend_beautiful.log new file mode 100644 index 0000000..dacfac6 --- /dev/null +++ b/frontend/frontend_beautiful.log @@ -0,0 +1,6 @@ + + VITE v5.4.21 ready in 2321 ms + + ➜ Local: http://localhost:5173/ + ➜ Network: http://10.255.255.254:5173/ + ➜ Network: http://172.27.77.221:5173/ diff --git a/frontend/frontend_final.log b/frontend/frontend_final.log new file mode 100644 index 0000000..1121f57 --- /dev/null +++ b/frontend/frontend_final.log @@ -0,0 +1,6 @@ + + VITE v5.4.21 ready in 2041 ms + + ➜ Local: http://localhost:5173/ + ➜ Network: http://10.255.255.254:5173/ + ➜ Network: http://172.27.77.221:5173/ diff --git a/frontend/frontend_improved.log b/frontend/frontend_improved.log new file mode 100644 index 0000000..1d5b643 --- /dev/null +++ b/frontend/frontend_improved.log @@ -0,0 +1,6 @@ + + VITE v5.4.21 ready in 2178 ms + + ➜ Local: http://localhost:5173/ + ➜ Network: http://10.255.255.254:5173/ + ➜ Network: http://172.27.77.221:5173/ diff --git a/frontend/frontend_output.log b/frontend/frontend_output.log new file mode 100644 index 0000000..2e89be6 --- /dev/null +++ b/frontend/frontend_output.log @@ -0,0 +1,9 @@ + +> gpf-pet-hospital-frontend@0.1.0 dev +> vite + + + VITE v5.4.21 ready in 2375 ms + + ➜ Local: http://localhost:5173/ + ➜ Network: use --host to expose diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..c55d873 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,12 @@ + + + + + + 爱维宠物医院管理平台 + + +
+ + + diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..91e43fa --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,1577 @@ +{ + "name": "gpf-pet-hospital-frontend", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "gpf-pet-hospital-frontend", + "version": "0.1.0", + "dependencies": { + "axios": "^1.6.7", + "pinia": "^2.1.7", + "tdesign-vue-next": "^1.8.8", + "vue": "^3.4.15", + "vue-router": "^4.2.5" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "typescript": "^5.3.3", + "vite": "^5.0.12" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.6", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "license": "MIT" + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.57.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.23", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/sortablejs": { + "version": "1.15.9", + "license": "MIT" + }, + "node_modules/@types/tinycolor2": { + "version": "1.4.6", + "license": "MIT" + }, + "node_modules/@types/validator": { + "version": "13.15.10", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.27", + "entities": "^7.0.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.27", + "@vue/shared": "3.5.27" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.27", + "@vue/compiler-dom": "3.5.27", + "@vue/compiler-ssr": "3.5.27", + "@vue/shared": "3.5.27", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.27", + "@vue/shared": "3.5.27" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "license": "MIT" + }, + "node_modules/@vue/reactivity": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.27" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.27", + "@vue/shared": "3.5.27" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.27", + "@vue/runtime-core": "3.5.27", + "@vue/shared": "3.5.27", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.27", + "@vue/shared": "3.5.27" + }, + "peerDependencies": { + "vue": "3.5.27" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.27", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.4", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "license": "MIT" + }, + "node_modules/dayjs": { + "version": "1.11.19", + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/entities": { + "version": "7.0.1", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/lodash-es": { + "version": "4.17.23", + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/pinia": { + "version": "2.3.1", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.57.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.57.0", + "@rollup/rollup-android-arm64": "4.57.0", + "@rollup/rollup-darwin-arm64": "4.57.0", + "@rollup/rollup-darwin-x64": "4.57.0", + "@rollup/rollup-freebsd-arm64": "4.57.0", + "@rollup/rollup-freebsd-x64": "4.57.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.57.0", + "@rollup/rollup-linux-arm-musleabihf": "4.57.0", + "@rollup/rollup-linux-arm64-gnu": "4.57.0", + "@rollup/rollup-linux-arm64-musl": "4.57.0", + "@rollup/rollup-linux-loong64-gnu": "4.57.0", + "@rollup/rollup-linux-loong64-musl": "4.57.0", + "@rollup/rollup-linux-ppc64-gnu": "4.57.0", + "@rollup/rollup-linux-ppc64-musl": "4.57.0", + "@rollup/rollup-linux-riscv64-gnu": "4.57.0", + "@rollup/rollup-linux-riscv64-musl": "4.57.0", + "@rollup/rollup-linux-s390x-gnu": "4.57.0", + "@rollup/rollup-linux-x64-gnu": "4.57.0", + "@rollup/rollup-linux-x64-musl": "4.57.0", + "@rollup/rollup-openbsd-x64": "4.57.0", + "@rollup/rollup-openharmony-arm64": "4.57.0", + "@rollup/rollup-win32-arm64-msvc": "4.57.0", + "@rollup/rollup-win32-ia32-msvc": "4.57.0", + "@rollup/rollup-win32-x64-gnu": "4.57.0", + "@rollup/rollup-win32-x64-msvc": "4.57.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.0.tgz", + "integrity": "sha512-tPgXB6cDTndIe1ah7u6amCI1T0SsnlOuKgg10Xh3uizJk4e5M1JGaUMk7J4ciuAUcFpbOiNhm2XIjP9ON0dUqA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-android-arm64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.0.tgz", + "integrity": "sha512-sa4LyseLLXr1onr97StkU1Nb7fWcg6niokTwEVNOO7awaKaoRObQ54+V/hrF/BP1noMEaaAW6Fg2d/CfLiq3Mg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.0.tgz", + "integrity": "sha512-/NNIj9A7yLjKdmkx5dC2XQ9DmjIECpGpwHoGmA5E1AhU0fuICSqSWScPhN1yLCkEdkCwJIDu2xIeLPs60MNIVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.0.tgz", + "integrity": "sha512-xoh8abqgPrPYPr7pTYipqnUi1V3em56JzE/HgDgitTqZBZ3yKCWI+7KUkceM6tNweyUKYru1UMi7FC060RyKwA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.0.tgz", + "integrity": "sha512-PCkMh7fNahWSbA0OTUQ2OpYHpjZZr0hPr8lId8twD7a7SeWrvT3xJVyza+dQwXSSq4yEQTMoXgNOfMCsn8584g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.0.tgz", + "integrity": "sha512-1j3stGx+qbhXql4OCDZhnK7b01s6rBKNybfsX+TNrEe9JNq4DLi1yGiR1xW+nL+FNVvI4D02PUnl6gJ/2y6WJA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.0.tgz", + "integrity": "sha512-eyrr5W08Ms9uM0mLcKfM/Uzx7hjhz2bcjv8P2uynfj0yU8GGPdz8iYrBPhiLOZqahoAMB8ZiolRZPbbU2MAi6Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.0.tgz", + "integrity": "sha512-Xds90ITXJCNyX9pDhqf85MKWUI4lqjiPAipJ8OLp8xqI2Ehk+TCVhF9rvOoN8xTbcafow3QOThkNnrM33uCFQA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.0.tgz", + "integrity": "sha512-Xws2KA4CLvZmXjy46SQaXSejuKPhwVdaNinldoYfqruZBaJHqVo6hnRa8SDo9z7PBW5x84SH64+izmldCgbezw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.0.tgz", + "integrity": "sha512-hrKXKbX5FdaRJj7lTMusmvKbhMJSGWJ+w++4KmjiDhpTgNlhYobMvKfDoIWecy4O60K6yA4SnztGuNTQF+Lplw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.0.tgz", + "integrity": "sha512-6A+nccfSDGKsPm00d3xKcrsBcbqzCTAukjwWK6rbuAnB2bHaL3r9720HBVZ/no7+FhZLz/U3GwwZZEh6tOSI8Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.0.tgz", + "integrity": "sha512-4P1VyYUe6XAJtQH1Hh99THxr0GKMMwIXsRNOceLrJnaHTDgk1FTcTimDgneRJPvB3LqDQxUmroBclQ1S0cIJwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.0.tgz", + "integrity": "sha512-8Vv6pLuIZCMcgXre6c3nOPhE0gjz1+nZP6T+hwWjr7sVH8k0jRkH+XnfjjOTglyMBdSKBPPz54/y1gToSKwrSQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.0.tgz", + "integrity": "sha512-r1te1M0Sm2TBVD/RxBPC6RZVwNqUTwJTA7w+C/IW5v9Ssu6xmxWEi+iJQlpBhtUiT1raJ5b48pI8tBvEjEFnFA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.0.tgz", + "integrity": "sha512-say0uMU/RaPm3CDQLxUUTF2oNWL8ysvHkAjcCzV2znxBr23kFfaxocS9qJm+NdkRhF8wtdEEAJuYcLPhSPbjuQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.0.tgz", + "integrity": "sha512-/MU7/HizQGsnBREtRpcSbSV1zfkoxSTR7wLsRmBPQ8FwUj5sykrP1MyJTvsxP5KBq9SyE6kH8UQQQwa0ASeoQQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.0.tgz", + "integrity": "sha512-Q9eh+gUGILIHEaJf66aF6a414jQbDnn29zeu0eX3dHMuysnhTvsUvZTCAyZ6tJhUjnvzBKE4FtuaYxutxRZpOg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.0.tgz", + "integrity": "sha512-XeatKzo4lHDsVEbm1XDHZlhYZZSQYym6dg2X/Ko0kSFgio+KXLsxwJQprnR48GvdIKDOpqWqssC3iBCjoMcMpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.0.tgz", + "integrity": "sha512-Lu71y78F5qOfYmubYLHPcJm74GZLU6UJ4THkf/a1K7Tz2ycwC2VUbsqbJAXaR6Bx70SRdlVrt2+n5l7F0agTUw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.0.tgz", + "integrity": "sha512-v5xwKDWcu7qhAEcsUubiav7r+48Uk/ENWdr82MBZZRIm7zThSxCIVDfb3ZeRRq9yqk+oIzMdDo6fCcA5DHfMyA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.0.tgz", + "integrity": "sha512-XnaaaSMGSI6Wk8F4KK3QP7GfuuhjGchElsVerCplUuxRIzdvZ7hRBpLR0omCmw+kI2RFJB80nenhOoGXlJ5TfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.0.tgz", + "integrity": "sha512-3K1lP+3BXY4t4VihLw5MEg6IZD3ojSYzqzBG571W3kNQe4G4CcFpSUQVgurYgib5d+YaCjeFow8QivWp8vuSvA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.0.tgz", + "integrity": "sha512-MDk610P/vJGc5L5ImE4k5s+GZT3en0KoK1MKPXCRgzmksAMk79j4h3k1IerxTNqwDLxsGxStEZVBqG0gIqZqoA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.0.tgz", + "integrity": "sha512-Zv7v6q6aV+VslnpwzqKAmrk5JdVkLUzok2208ZXGipjb+msxBr/fJPZyeEXiFgH7k62Ak0SLIfxQRZQvTuf7rQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/sortablejs": { + "version": "1.15.6", + "license": "MIT" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tdesign-icons-vue-next": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/tdesign-icons-vue-next/-/tdesign-icons-vue-next-0.4.2.tgz", + "integrity": "sha512-mTPk1ApcCA9oxDiSs9ttMdd09H8ICBooZIr2bwDEELnYr60sYSUbvWojQ2tp84MUAMuw21HgyVyGkT49db0GFg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.16.5" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/tdesign-vue-next": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tdesign-vue-next/-/tdesign-vue-next-1.18.0.tgz", + "integrity": "sha512-JSLb82fXAsO0FXFuMBCiLDSIvUlqG2bZ1CkWOLYfE4IFyPQ2hwjTxTsJRugVoLRYBuhiIKprhmoucZ4tlgWrGg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@popperjs/core": "^2.11.8", + "@types/lodash-es": "^4.17.12", + "@types/sortablejs": "^1.15.1", + "@types/tinycolor2": "^1.4.3", + "@types/validator": "^13.7.17", + "dayjs": "^1.11.10", + "lodash-es": "^4.17.21", + "mitt": "^3.0.1", + "sortablejs": "^1.15.0", + "tdesign-icons-vue-next": "~0.4.1", + "tinycolor2": "^1.6.0", + "validator": "^13.15.23" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "vue": ">=3.1.0" + } + }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.3", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/validator": { + "version": "13.15.26", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/vue": { + "version": "3.5.27", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.27", + "@vue/compiler-sfc": "3.5.27", + "@vue/runtime-dom": "3.5.27", + "@vue/server-renderer": "3.5.27", + "@vue/shared": "3.5.27" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "4.6.4", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..6895525 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,23 @@ +{ + "name": "gpf-pet-hospital-frontend", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "axios": "^1.6.7", + "pinia": "^2.1.7", + "tdesign-vue-next": "^1.8.8", + "vue": "^3.4.15", + "vue-router": "^4.2.5" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "typescript": "^5.3.3", + "vite": "^5.0.12" + } +} diff --git a/frontend/src/App.vue b/frontend/src/App.vue new file mode 100644 index 0000000..7c2aa3f --- /dev/null +++ b/frontend/src/App.vue @@ -0,0 +1,3 @@ + diff --git a/frontend/src/api/http.ts b/frontend/src/api/http.ts new file mode 100644 index 0000000..2121965 --- /dev/null +++ b/frontend/src/api/http.ts @@ -0,0 +1,23 @@ +import axios from 'axios'; +import { useAuthStore } from '../store/auth'; + +const http = axios.create({ + baseURL: '/api', + timeout: 15000, +}); + +http.interceptors.request.use((config) => { + const auth = useAuthStore(); + if (auth.token) { + config.headers = config.headers || {}; + config.headers.Authorization = `Bearer ${auth.token}`; + } + return config; +}); + +http.interceptors.response.use( + (resp) => resp.data, + (error) => Promise.reject(error), +); + +export default http; diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts new file mode 100644 index 0000000..662dd7e --- /dev/null +++ b/frontend/src/api/index.ts @@ -0,0 +1,69 @@ +import http from './http'; + +export const api = { + login: (payload: { account: string; password: string }) => http.post('/auth/login', payload), + register: (payload: { username: string; phone?: string; email?: string; password: string }) => + http.post('/auth/register', payload), + me: () => http.get('/users/me'), + + notices: (params?: any) => http.get('/public/notices', { params }), + noticesAdmin: (params?: any) => http.get('/notices', { params }), + createNotice: (payload: any) => http.post('/notices', payload), + updateNotice: (id: number, payload: any) => http.put(`/notices/${id}`, payload), + deleteNotice: (id: number) => http.delete(`/notices/${id}`), + + pets: (params?: any) => http.get('/pets', { params }), + createPet: (payload: any) => http.post('/pets', payload), + updatePet: (id: number, payload: any) => http.put(`/pets/${id}`, payload), + deletePet: (id: number) => http.delete(`/pets/${id}`), + + appointments: (params?: any) => http.get('/appointments', { params }), + createAppointment: (payload: any) => http.post('/appointments', payload), + adminAppointments: (params?: any) => http.get('/appointments/admin', { params }), + updateAppointmentStatus: (id: number, status: string) => http.put(`/appointments/${id}/status`, null, { params: { status } }), + + visits: (params?: any) => http.get('/visits', { params }), + createVisit: (payload: any) => http.post('/visits', payload), + updateVisit: (id: number, payload: any) => http.put(`/visits/${id}`, payload), + + medicalRecords: (params?: any) => http.get('/medical-records', { params }), + createMedicalRecord: (payload: any) => http.post('/medical-records', payload), + updateMedicalRecord: (id: number, payload: any) => http.put(`/medical-records/${id}`, payload), + deleteMedicalRecord: (id: number) => http.delete(`/medical-records/${id}`), + + prescriptions: (params?: any) => http.get('/prescriptions', { params }), + createPrescription: (payload: any) => http.post('/prescriptions', payload), + updatePrescription: (id: number, payload: any) => http.put(`/prescriptions/${id}`, payload), + + prescriptionItems: (params?: any) => http.get('/prescription-items', { params }), + + reports: (params?: any) => http.get('/reports', { params }), + createReport: (payload: any) => http.post('/reports', payload), + updateReport: (id: number, payload: any) => http.put(`/reports/${id}`, payload), + deleteReport: (id: number) => http.delete(`/reports/${id}`), + + orders: (params?: any) => http.get('/orders', { params }), + createOrder: (payload: any) => http.post('/orders', payload), + updateOrder: (id: number, payload: any) => http.put(`/orders/${id}`, payload), + + drugs: (params?: any) => http.get('/drugs', { params }), + createDrug: (payload: any) => http.post('/drugs', payload), + updateDrug: (id: number, payload: any) => http.put(`/drugs/${id}`, payload), + deleteDrug: (id: number) => http.delete(`/drugs/${id}`), + + stockIn: (params?: any) => http.get('/stock-in', { params }), + createStockIn: (payload: any) => http.post('/stock-in', payload), + stockOut: (params?: any) => http.get('/stock-out', { params }), + createStockOut: (payload: any) => http.post('/stock-out', payload), + + messages: (params?: any) => http.get('/messages/admin', { params }), + createMessage: (payload: any) => http.post('/messages', payload), + replyMessage: (id: number, payload: any) => http.put(`/messages/admin/${id}/reply`, payload), + + users: (params?: any) => http.get('/users', { params }), + createUser: (payload: any) => http.post('/users', payload), + updateUserStatus: (id: number, status: number) => http.put(`/users/${id}/status`, null, { params: { status } }), + resetUserPassword: (id: number, newPassword: string) => http.put(`/users/${id}/reset-password`, null, { params: { newPassword } }), + + stats: () => http.get('/admin/stats'), +}; diff --git a/frontend/src/config/menu.ts b/frontend/src/config/menu.ts new file mode 100644 index 0000000..dd2b9a8 --- /dev/null +++ b/frontend/src/config/menu.ts @@ -0,0 +1,23 @@ +export interface MenuItem { + label: string; + path: string; + roles: string[]; +} + +export const menuItems: MenuItem[] = [ + { label: '仪表盘', path: '/dashboard', roles: ['ADMIN', 'DOCTOR', 'CUSTOMER'] }, + { label: '公告管理', path: '/notices', roles: ['ADMIN'] }, + { label: '宠物档案', path: '/pets', roles: ['ADMIN', 'DOCTOR', 'CUSTOMER'] }, + { label: '门诊预约', path: '/appointments', roles: ['ADMIN', 'DOCTOR', 'CUSTOMER'] }, + { label: '就诊记录', path: '/visits', roles: ['ADMIN', 'DOCTOR'] }, + { label: '病历管理', path: '/records', roles: ['ADMIN', 'DOCTOR'] }, + { label: '处方管理', path: '/prescriptions', roles: ['ADMIN', 'DOCTOR'] }, + { label: '报告查询', path: '/reports', roles: ['ADMIN', 'DOCTOR', 'CUSTOMER'] }, + { label: '订单管理', path: '/orders', roles: ['ADMIN', 'CUSTOMER'] }, + { label: '药品管理', path: '/drugs', roles: ['ADMIN'] }, + { label: '入库流水', path: '/stock-in', roles: ['ADMIN'] }, + { label: '出库流水', path: '/stock-out', roles: ['ADMIN'] }, + { label: '留言板', path: '/messages', roles: ['ADMIN'] }, + { label: '账号管理', path: '/users', roles: ['ADMIN'] }, + { label: '统计报表', path: '/stats', roles: ['ADMIN'] }, +]; diff --git a/frontend/src/layouts/MainLayout.vue b/frontend/src/layouts/MainLayout.vue new file mode 100644 index 0000000..6c24814 --- /dev/null +++ b/frontend/src/layouts/MainLayout.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/frontend/src/main.ts b/frontend/src/main.ts new file mode 100644 index 0000000..69f1e2d --- /dev/null +++ b/frontend/src/main.ts @@ -0,0 +1,13 @@ +import { createApp } from 'vue'; +import { createPinia } from 'pinia'; +import TDesign from 'tdesign-vue-next'; +import 'tdesign-vue-next/es/style/index.css'; +import './styles/global.css'; +import App from './App.vue'; +import router from './router'; + +const app = createApp(App); +app.use(createPinia()); +app.use(router); +app.use(TDesign); +app.mount('#app'); diff --git a/frontend/src/pages/AppointmentPage.vue b/frontend/src/pages/AppointmentPage.vue new file mode 100644 index 0000000..b094646 --- /dev/null +++ b/frontend/src/pages/AppointmentPage.vue @@ -0,0 +1,170 @@ + + + diff --git a/frontend/src/pages/Dashboard.vue b/frontend/src/pages/Dashboard.vue new file mode 100644 index 0000000..b1345fb --- /dev/null +++ b/frontend/src/pages/Dashboard.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/frontend/src/pages/DrugPage.vue b/frontend/src/pages/DrugPage.vue new file mode 100644 index 0000000..d344626 --- /dev/null +++ b/frontend/src/pages/DrugPage.vue @@ -0,0 +1,112 @@ + + + diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue new file mode 100644 index 0000000..6560fbd --- /dev/null +++ b/frontend/src/pages/Login.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/frontend/src/pages/MedicalRecordPage.vue b/frontend/src/pages/MedicalRecordPage.vue new file mode 100644 index 0000000..9f4915f --- /dev/null +++ b/frontend/src/pages/MedicalRecordPage.vue @@ -0,0 +1,108 @@ + + + diff --git a/frontend/src/pages/MessagePage.vue b/frontend/src/pages/MessagePage.vue new file mode 100644 index 0000000..fe347b2 --- /dev/null +++ b/frontend/src/pages/MessagePage.vue @@ -0,0 +1,77 @@ + + + diff --git a/frontend/src/pages/NoticePage.vue b/frontend/src/pages/NoticePage.vue new file mode 100644 index 0000000..c8990e2 --- /dev/null +++ b/frontend/src/pages/NoticePage.vue @@ -0,0 +1,117 @@ + + + diff --git a/frontend/src/pages/OrderPage.vue b/frontend/src/pages/OrderPage.vue new file mode 100644 index 0000000..c93133a --- /dev/null +++ b/frontend/src/pages/OrderPage.vue @@ -0,0 +1,194 @@ + + + diff --git a/frontend/src/pages/PetPage.vue b/frontend/src/pages/PetPage.vue new file mode 100644 index 0000000..4bd5b6b --- /dev/null +++ b/frontend/src/pages/PetPage.vue @@ -0,0 +1,111 @@ + + + diff --git a/frontend/src/pages/PrescriptionPage.vue b/frontend/src/pages/PrescriptionPage.vue new file mode 100644 index 0000000..89ab1f6 --- /dev/null +++ b/frontend/src/pages/PrescriptionPage.vue @@ -0,0 +1,190 @@ + + + diff --git a/frontend/src/pages/ReportPage.vue b/frontend/src/pages/ReportPage.vue new file mode 100644 index 0000000..17bed2c --- /dev/null +++ b/frontend/src/pages/ReportPage.vue @@ -0,0 +1,108 @@ + + + diff --git a/frontend/src/pages/StatsPage.vue b/frontend/src/pages/StatsPage.vue new file mode 100644 index 0000000..029243d --- /dev/null +++ b/frontend/src/pages/StatsPage.vue @@ -0,0 +1,31 @@ + + + diff --git a/frontend/src/pages/StockInPage.vue b/frontend/src/pages/StockInPage.vue new file mode 100644 index 0000000..5f37504 --- /dev/null +++ b/frontend/src/pages/StockInPage.vue @@ -0,0 +1,60 @@ + + + diff --git a/frontend/src/pages/StockOutPage.vue b/frontend/src/pages/StockOutPage.vue new file mode 100644 index 0000000..281899b --- /dev/null +++ b/frontend/src/pages/StockOutPage.vue @@ -0,0 +1,60 @@ + + + diff --git a/frontend/src/pages/UserPage.vue b/frontend/src/pages/UserPage.vue new file mode 100644 index 0000000..25639ec --- /dev/null +++ b/frontend/src/pages/UserPage.vue @@ -0,0 +1,119 @@ + + + diff --git a/frontend/src/pages/VisitPage.vue b/frontend/src/pages/VisitPage.vue new file mode 100644 index 0000000..752fcf3 --- /dev/null +++ b/frontend/src/pages/VisitPage.vue @@ -0,0 +1,291 @@ + + + diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts new file mode 100644 index 0000000..689d87f --- /dev/null +++ b/frontend/src/router/index.ts @@ -0,0 +1,50 @@ +import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; +import { useAuthStore } from '../store/auth'; + +const routes: RouteRecordRaw[] = [ + { path: '/login', name: 'login', component: () => import('../pages/Login.vue') }, + { + path: '/', + component: () => import('../layouts/MainLayout.vue'), + children: [ + { path: '', redirect: '/dashboard' }, + { path: 'dashboard', name: 'dashboard', component: () => import('../pages/Dashboard.vue') }, + { path: 'notices', name: 'notices', component: () => import('../pages/NoticePage.vue'), meta: { roles: ['ADMIN'] } }, + { path: 'pets', name: 'pets', component: () => import('../pages/PetPage.vue'), meta: { roles: ['ADMIN', 'DOCTOR', 'CUSTOMER'] } }, + { path: 'appointments', name: 'appointments', component: () => import('../pages/AppointmentPage.vue'), meta: { roles: ['ADMIN', 'DOCTOR', 'CUSTOMER'] } }, + { path: 'visits', name: 'visits', component: () => import('../pages/VisitPage.vue'), meta: { roles: ['ADMIN', 'DOCTOR'] } }, + { path: 'records', name: 'records', component: () => import('../pages/MedicalRecordPage.vue'), meta: { roles: ['ADMIN', 'DOCTOR'] } }, + { path: 'prescriptions', name: 'prescriptions', component: () => import('../pages/PrescriptionPage.vue'), meta: { roles: ['ADMIN', 'DOCTOR'] } }, + { path: 'reports', name: 'reports', component: () => import('../pages/ReportPage.vue'), meta: { roles: ['ADMIN', 'DOCTOR', 'CUSTOMER'] } }, + { path: 'orders', name: 'orders', component: () => import('../pages/OrderPage.vue'), meta: { roles: ['ADMIN', 'CUSTOMER'] } }, + { path: 'drugs', name: 'drugs', component: () => import('../pages/DrugPage.vue'), meta: { roles: ['ADMIN'] } }, + { path: 'stock-in', name: 'stock-in', component: () => import('../pages/StockInPage.vue'), meta: { roles: ['ADMIN'] } }, + { path: 'stock-out', name: 'stock-out', component: () => import('../pages/StockOutPage.vue'), meta: { roles: ['ADMIN'] } }, + { path: 'messages', name: 'messages', component: () => import('../pages/MessagePage.vue'), meta: { roles: ['ADMIN'] } }, + { path: 'users', name: 'users', component: () => import('../pages/UserPage.vue'), meta: { roles: ['ADMIN'] } }, + { path: 'stats', name: 'stats', component: () => import('../pages/StatsPage.vue'), meta: { roles: ['ADMIN'] } } + ], + }, +]; + +const router = createRouter({ + history: createWebHistory(), + routes, +}); + +router.beforeEach((to) => { + const auth = useAuthStore(); + if (to.path !== '/login' && !auth.token) { + return '/login'; + } + if (to.path === '/login' && auth.token) { + return '/dashboard'; + } + const roles = to.meta?.roles as string[] | undefined; + if (roles && auth.user?.role && !roles.includes(auth.user.role)) { + return '/dashboard'; + } + return true; +}); + +export default router; diff --git a/frontend/src/store/auth.ts b/frontend/src/store/auth.ts new file mode 100644 index 0000000..8530953 --- /dev/null +++ b/frontend/src/store/auth.ts @@ -0,0 +1,28 @@ +import { defineStore } from 'pinia'; + +interface UserInfo { + userId?: number; + username?: string; + role?: string; +} + +export const useAuthStore = defineStore('auth', { + state: () => ({ + token: localStorage.getItem('token') || '', + user: JSON.parse(localStorage.getItem('user') || '{}') as UserInfo, + }), + actions: { + setAuth(token: string, user: UserInfo) { + this.token = token; + this.user = user; + localStorage.setItem('token', token); + localStorage.setItem('user', JSON.stringify(user)); + }, + clear() { + this.token = ''; + this.user = {}; + localStorage.removeItem('token'); + localStorage.removeItem('user'); + }, + }, +}); diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css new file mode 100644 index 0000000..c01c4d0 --- /dev/null +++ b/frontend/src/styles/global.css @@ -0,0 +1,174 @@ +:root { + --app-bg: #f8fafc; + --panel-bg: #ffffff; + --primary: #3b82f6; + --primary-hover: #2563eb; + --secondary: #64748b; + --success: #10b981; + --warning: #f59e0b; + --danger: #ef4444; + --text: #1e293b; + --text-secondary: #64748b; + --border: #e2e8f0; + --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + --radius: 8px; + --transition: all 0.2s ease; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + font-family: "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif; + background: var(--app-bg); + color: var(--text); + line-height: 1.5; +} + +.page { + padding: 24px; + max-width: 1400px; + margin: 0 auto; +} + +.panel { + background: var(--panel-bg); + border-radius: var(--radius); + padding: 24px; + box-shadow: var(--shadow); + margin-bottom: 24px; + transition: var(--transition); +} + +.panel:hover { + box-shadow: var(--shadow-lg); +} + +.page-title { + font-size: 24px; + font-weight: 600; + margin: 0 0 24px; + color: var(--text); + position: relative; + padding-bottom: 12px; +} + +.page-title::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 50px; + height: 3px; + background: var(--primary); + border-radius: 3px; +} + +.inline-form { + display: flex; + flex-wrap: wrap; + gap: 16px; + align-items: center; + margin-bottom: 20px; + padding-bottom: 20px; + border-bottom: 1px solid var(--border); +} + +.table-actions { + display: flex; + gap: 8px; +} + +.t-table { + border-radius: var(--radius); + overflow: hidden; +} + +.t-btn { + border-radius: var(--radius) !important; + transition: var(--transition) !important; +} + +.t-btn--variant-outline { + border-color: var(--primary) !important; + color: var(--primary) !important; +} + +.t-btn--variant-outline:hover { + background: var(--primary) !important; + color: white !important; +} + +.t-btn--theme-primary { + background: var(--primary) !important; + border-color: var(--primary) !important; +} + +.t-btn--theme-primary:hover { + background: var(--primary-hover) !important; + border-color: var(--primary-hover) !important; +} + +.t-tag { + border-radius: 20px !important; + padding: 4px 12px !important; + font-size: 12px !important; + font-weight: 500 !important; +} + +.t-card { + border-radius: var(--radius) !important; + box-shadow: var(--shadow) !important; +} + +.t-form__controls { + margin-top: 10px !important; +} + +.t-dialog__body { + padding: 24px !important; +} + +.t-dialog__footer { + padding: 16px 24px 24px !important; +} + +.form-section-title { + font-size: 16px; + font-weight: 600; + color: var(--text); + margin: 24px 0 16px; + padding-left: 12px; + border-left: 4px solid var(--primary); +} + +.status-badge { + display: inline-block; + padding: 4px 12px; + border-radius: 20px; + font-size: 12px; + font-weight: 500; +} + +.status-pending { + background: #fef3c7; + color: #d97706; +} + +.status-active { + background: #d1fae5; + color: #059669; +} + +.status-completed { + background: #dbeafe; + color: #2563eb; +} + +.status-cancelled { + background: #fee2e2; + color: #dc2626; +} diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..7975e51 --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "jsx": "preserve", + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "types": ["vite/client"] + }, + "include": ["src"] +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts new file mode 100644 index 0000000..bfb8e86 --- /dev/null +++ b/frontend/vite.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; + +export default defineConfig({ + plugins: [vue()], + server: { + port: 5173, + proxy: { + '/api': { + target: 'http://localhost:8081', + changeOrigin: true, + }, + }, + }, +}); diff --git a/frp/LICENSE b/frp/LICENSE new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/frp/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/frp/README.md b/frp/README.md new file mode 100644 index 0000000..5f4e95c --- /dev/null +++ b/frp/README.md @@ -0,0 +1,52 @@ +# FRP 内网穿透工具 + +## 文件说明 + +- `frpc`: FRP 客户端可执行文件 (Linux AMD64) +- `frps`: FRP 服务器端可执行文件 (Linux AMD64) +- `frpc.ini`: 客户端配置文件模板 +- `frpc.toml`: 客户端配置文件示例 (TOML格式) +- `frps.toml`: 服务器端配置文件示例 (TOML格式) +- `LICENSE`: 许可证文件 + +## 版本信息 +- FRP Version: 0.66.0 +- 架构: Linux AMD64 + +## 配置说明 + +### 客户端配置 (frpc.ini) +这是一个用于宠物医院管理系统的典型配置: + +```ini +[common] +server_addr = your_server_ip_or_domain +server_port = 7000 +token = your_token_here + +[web_frontend] +type = http +local_port = 5173 +custom_domains = hospital.yourdomain.com + +[web_backend] +type = tcp +local_port = 8081 +remote_port = 8081 +``` + +## 启动服务 + +### 启动客户端 +```bash +./frpc -c frpc.ini +``` + +### 启动服务器端 (在公网服务器) +```bash +./frps -c frps.ini +``` + +## 用于宠物医院管理系统的典型配置 + +请参考项目根目录下的 `frpc.ini` 配置文件,该文件已为宠物医院管理系统配置了适当的端口转发规则。 \ No newline at end of file diff --git a/frp/frpc.ini b/frp/frpc.ini new file mode 100644 index 0000000..1e9dfe7 --- /dev/null +++ b/frp/frpc.ini @@ -0,0 +1,35 @@ +# FRP 客户端配置文件 - 宠物医院管理系统 +# 请根据实际情况修改服务器地址和端口 + +[common] +# FRP 服务器地址 (公网服务器IP或域名) +server_addr = your_server_ip_or_domain +# FRP 服务器端口 +server_port = 7000 +# 通信密钥 (需与服务器端保持一致) +token = your_token_here + +# 前端服务穿透 - Vue开发服务器 +[web_frontend] +type = http +local_port = 5173 +custom_domains = hospital.yourdomain.com +# 替换为实际的域名 + +# 后端服务穿透 - Spring Boot应用 +[web_backend] +type = tcp +local_port = 8081 +remote_port = 8081 + +# 如果需要HTTPS支持 +[web_frontend_https] +type = https +local_port = 5173 +custom_domains = hospital.yourdomain.com + +# 管理面板 (如果需要远程管理) +[dashboard] +type = tcp +local_port = 7500 +remote_port = 7500 \ No newline at end of file diff --git a/frp/frpc.toml b/frp/frpc.toml new file mode 100644 index 0000000..6438f04 --- /dev/null +++ b/frp/frpc.toml @@ -0,0 +1,9 @@ +serverAddr = "127.0.0.1" +serverPort = 7000 + +[[proxies]] +name = "test-tcp" +type = "tcp" +localIP = "127.0.0.1" +localPort = 22 +remotePort = 6000 diff --git a/frp/frps.toml b/frp/frps.toml new file mode 100644 index 0000000..28e6d96 --- /dev/null +++ b/frp/frps.toml @@ -0,0 +1 @@ +bindPort = 7000 diff --git a/frp/run_frpc.sh b/frp/run_frpc.sh new file mode 100644 index 0000000..0b8d8cc --- /dev/null +++ b/frp/run_frpc.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# 启动FRP客户端 - 宠物医院管理系统 + +echo "启动FRP客户端..." + +# 检查配置文件是否存在 +if [ ! -f "frpc.ini" ]; then + echo "错误: 未找到配置文件 frpc.ini" + echo "请先创建配置文件或复制示例文件" + exit 1 +fi + +# 启动frpc +echo "正在启动FRP客户端..." +./frpc -c frpc.ini + +echo "FRP客户端已退出" \ No newline at end of file