diff --git a/vocata-admin/.env.development b/vocata-admin/.env.development index 32f09f7..4bc4d7e 100644 --- a/vocata-admin/.env.development +++ b/vocata-admin/.env.development @@ -1,5 +1,9 @@ + # 开发环境配置 - 默认使用本地环境 -VITE_APP_URL=http://127.0.0.1:9009 +VITE_APP_URL=http://101.200.141.46:9009 + VUE_APP_BASE_API=/api VUE_APP_TITLE=VocaTa 管理后台 - 开发环境 -VITE_APP_ENV=development \ No newline at end of file +VITE_APP_ENV=development + + diff --git a/vocata-admin/.env.production b/vocata-admin/.env.production index 20fb219..0765ec6 100644 --- a/vocata-admin/.env.production +++ b/vocata-admin/.env.production @@ -1,6 +1,8 @@ + # 生产环境配置 # 注意:VITE_APP_URL 将在CI/CD构建时动态替换 VITE_APP_URL=http://{{PRODUCTION_HOST}}:9009 VUE_APP_BASE_API=/api VUE_APP_TITLE=VocaTa 管理后台 -VITE_APP_ENV=production \ No newline at end of file +VITE_APP_ENV=production + diff --git a/vocata-admin/Dockerfile b/vocata-admin/Dockerfile index 77b1648..a99b11d 100644 --- a/vocata-admin/Dockerfile +++ b/vocata-admin/Dockerfile @@ -1,4 +1,4 @@ -# VocaTa管理后台 - 多阶段构建Dockerfile +# VocaTa前端客户端 - 多阶段构建Dockerfile # 基于Node.js官方镜像 # 构建阶段 @@ -91,23 +91,18 @@ http { application/xml+rss application/json; - # 管理后台服务器配置 + # 服务器配置 server { listen 8080; server_name localhost; root /usr/share/nginx/html; index index.html index.htm; - # 安全头 - 管理后台加强安全 - add_header X-Frame-Options "DENY" always; + # 安全头 + add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.vocata.com https://test-api.vocata.com;" always; - - # 管理后台访问控制(可选) - # allow 192.168.1.0/24; - # deny all; + add_header Referrer-Policy "no-referrer-when-downgrade" always; # SPA路由支持 location / { @@ -120,42 +115,21 @@ http { add_header Cache-Control "public, immutable"; } - # 管理API代理 + # API代理(如果需要) location /api { proxy_pass http://vocata-server:9009; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - - # 管理后台专用头部 - proxy_set_header X-Admin-Request "true"; } # 健康检查端点 location /health { access_log off; - return 200 "admin-healthy\n"; + return 200 "healthy\n"; add_header Content-Type text/plain; } - - # 管理后台特殊路径保护 - location /admin { - try_files $uri $uri/ /index.html; - } - - # 禁止访问敏感文件 - location ~ /\. { - deny all; - access_log off; - log_not_found off; - } - - location ~ \.(env|config)$ { - deny all; - access_log off; - log_not_found off; - } } } EOF @@ -179,9 +153,9 @@ ARG VERSION="1.0.0" LABEL maintainer="VocaTa Team " \ version="${VERSION}" \ build-date="${BUILD_DATE}" \ - description="VocaTa AI角色扮演平台管理后台" \ - org.opencontainers.image.title="vocata-admin" \ - org.opencontainers.image.description="VocaTa AI Role Playing Platform Admin Dashboard" \ + description="VocaTa AI角色扮演平台前端客户端" \ + org.opencontainers.image.title="vocata-web" \ + org.opencontainers.image.description="VocaTa AI Role Playing Platform Frontend Client" \ org.opencontainers.image.url="https://github.com/leivik/vocata" \ org.opencontainers.image.vendor="VocaTa Team" \ org.opencontainers.image.version="${VERSION}" \ diff --git a/vocata-admin/index.html b/vocata-admin/index.html index 9e5fc8f..fcd9708 100644 --- a/vocata-admin/index.html +++ b/vocata-admin/index.html @@ -1,13 +1,16 @@ - - - - - Vite App - - -
- - - + + + + + + 语Ta + + + +
+ + + + \ No newline at end of file diff --git a/vocata-admin/package-lock.json b/vocata-admin/package-lock.json index 4d7ac42..c2dd905 100644 --- a/vocata-admin/package-lock.json +++ b/vocata-admin/package-lock.json @@ -9,15 +9,20 @@ "version": "0.0.0", "dependencies": { "@element-plus/icons-vue": "^2.3.2", + "@tailwindcss/vite": "^4.1.13", + "@types/js-cookie": "^3.0.6", "axios": "^1.12.2", "element-plus": "^2.11.3", + "js-cookie": "^3.0.5", "pinia": "^3.0.3", + "tailwindcss": "^4.1.13", "vue": "^3.5.18", "vue-router": "^4.5.1" }, "devDependencies": { "@tsconfig/node22": "^22.0.2", "@types/node": "^22.16.5", + "@types/postcss-pxtorem": "^6.1.0", "@vitejs/plugin-vue": "^6.0.1", "@vue/eslint-config-prettier": "^10.2.0", "@vue/eslint-config-typescript": "^14.6.0", @@ -26,6 +31,7 @@ "eslint-plugin-vue": "~10.3.0", "jiti": "^2.4.2", "npm-run-all2": "^8.0.4", + "postcss-pxtorem": "^6.1.0", "prettier": "3.6.2", "sass": "^1.93.0", "typescript": "~5.8.0", @@ -547,7 +553,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -564,7 +569,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -581,7 +585,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -598,7 +601,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -615,7 +617,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -632,7 +633,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -649,7 +649,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -666,7 +665,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -683,7 +681,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -700,7 +697,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -717,7 +713,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -734,7 +729,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -751,7 +745,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -768,7 +761,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -785,7 +777,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -802,7 +793,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -819,7 +809,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -836,7 +825,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -853,7 +841,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -870,7 +857,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -887,7 +873,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -904,7 +889,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -921,7 +905,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -938,7 +921,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -955,7 +937,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -972,7 +953,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1235,11 +1215,22 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1250,7 +1241,6 @@ "version": "2.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -1261,7 +1251,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1277,7 +1266,6 @@ "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1326,7 +1314,6 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -1366,7 +1353,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1387,7 +1373,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1408,7 +1393,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1429,7 +1413,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1450,7 +1433,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1471,7 +1453,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1492,7 +1473,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1513,7 +1493,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1534,7 +1513,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1555,7 +1533,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1576,7 +1553,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1597,7 +1573,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1618,7 +1593,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1677,7 +1651,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1691,7 +1664,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1705,7 +1677,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1719,7 +1690,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1733,7 +1703,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1747,7 +1716,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1761,7 +1729,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1775,7 +1742,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1789,7 +1755,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1803,7 +1768,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1817,7 +1781,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1831,7 +1794,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1845,7 +1807,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1859,7 +1820,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1873,7 +1833,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1887,7 +1846,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1901,7 +1859,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1915,7 +1872,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1929,7 +1885,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1943,7 +1898,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1957,7 +1911,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1971,7 +1924,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1998,6 +1950,277 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@tailwindcss/node": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.13.tgz", + "integrity": "sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.5.1", + "lightningcss": "1.30.1", + "magic-string": "^0.30.18", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.13" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.13.tgz", + "integrity": "sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.13", + "@tailwindcss/oxide-darwin-arm64": "4.1.13", + "@tailwindcss/oxide-darwin-x64": "4.1.13", + "@tailwindcss/oxide-freebsd-x64": "4.1.13", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.13", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.13", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.13", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.13", + "@tailwindcss/oxide-linux-x64-musl": "4.1.13", + "@tailwindcss/oxide-wasm32-wasi": "4.1.13", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.13", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.13" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.13.tgz", + "integrity": "sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.13.tgz", + "integrity": "sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.13.tgz", + "integrity": "sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.13.tgz", + "integrity": "sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.13.tgz", + "integrity": "sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.13.tgz", + "integrity": "sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.13.tgz", + "integrity": "sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.13.tgz", + "integrity": "sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.13.tgz", + "integrity": "sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.13.tgz", + "integrity": "sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.5", + "@emnapi/runtime": "^1.4.5", + "@emnapi/wasi-threads": "^1.0.4", + "@napi-rs/wasm-runtime": "^0.2.12", + "@tybys/wasm-util": "^0.10.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.13.tgz", + "integrity": "sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.13.tgz", + "integrity": "sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide/node_modules/detect-libc": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.1.tgz", + "integrity": "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.13.tgz", + "integrity": "sha512-0PmqLQ010N58SbMTJ7BVJ4I2xopiQn/5i6nlb4JmxzQf8zcS5+m2Cv6tqh+sfDwtIdjoEnOvwsGQ1hkUi8QEHQ==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.13", + "@tailwindcss/oxide": "4.1.13", + "tailwindcss": "4.1.13" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, "node_modules/@tsconfig/node22": { "version": "22.0.2", "resolved": "https://registry.npmjs.org/@tsconfig/node22/-/node22-22.0.2.tgz", @@ -2009,7 +2232,12 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, + "license": "MIT" + }, + "node_modules/@types/js-cookie": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz", + "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==", "license": "MIT" }, "node_modules/@types/json-schema": { @@ -2038,12 +2266,22 @@ "version": "22.18.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.6.tgz", "integrity": "sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" } }, + "node_modules/@types/postcss-pxtorem": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/postcss-pxtorem/-/postcss-pxtorem-6.1.0.tgz", + "integrity": "sha512-kHsYTjQgllOfhi3J+xunjMKUZ3APARV/JYeOOcIVLhvPVS162S8Ir8LsZwioFFyYCSnQp+aisupiSaRWVwKyDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss": "^8.2.6" + } + }, "node_modules/@types/web-bluetooth": { "version": "0.0.16", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", @@ -2944,7 +3182,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -3068,7 +3306,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -3080,6 +3318,15 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3269,7 +3516,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, "license": "Apache-2.0", "optional": true, "bin": { @@ -3326,6 +3572,19 @@ "vue": "^3.2.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -3397,7 +3656,6 @@ "version": "0.25.10", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", - "dev": true, "hasInstallScript": true, "license": "MIT", "bin": { @@ -3878,7 +4136,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -3965,7 +4223,6 @@ "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, @@ -4087,6 +4344,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -4183,7 +4446,7 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/import-fresh": { @@ -4233,7 +4496,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4243,7 +4506,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -4275,7 +4538,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -4359,12 +4622,20 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.0.tgz", "integrity": "sha512-VXe6RjJkBPj0ohtqaO8vSWP3ZhAKo66fKrFNCll4BTcwljPLz03pCbaNKfzGP5MbrCYcbJ7v0nOYYwUzTEIdXQ==", - "dev": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4473,6 +4744,243 @@ "node": ">= 0.8.0" } }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.1.tgz", + "integrity": "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4576,7 +5084,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -4623,6 +5131,27 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", @@ -4682,7 +5211,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, "license": "MIT", "optional": true }, @@ -4983,7 +5511,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -5054,6 +5582,16 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-pxtorem": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-pxtorem/-/postcss-pxtorem-6.1.0.tgz", + "integrity": "sha512-ROODSNci9ADal3zUcPHOF/K83TiCgNSPXQFSbwyPHNV8ioHIE4SaC+FPOufd8jsr5jV2uIz29v1Uqy1c4ov42g==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "postcss": "^8.0.0" + } + }, "node_modules/postcss-selector-parser": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", @@ -5178,7 +5716,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 14.18.0" @@ -5219,7 +5757,6 @@ "version": "4.52.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.0.tgz", "integrity": "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g==", - "dev": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.8" @@ -5298,7 +5835,7 @@ "version": "1.93.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.93.0.tgz", "integrity": "sha512-CQi5/AzCwiubU3dSqRDJ93RfOfg/hhpW1l6wCIvolmehfwgCI35R/0QDs1+R+Ygrl8jFawwwIojE2w47/mf94A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "chokidar": "^4.0.0", @@ -5477,11 +6014,54 @@ "url": "https://opencollective.com/synckit" } }, + "node_modules/tailwindcss": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.13.tgz", + "integrity": "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz", + "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tar": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", + "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -5498,7 +6078,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -5516,7 +6095,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -5529,7 +6107,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -5616,7 +6194,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/unicorn-magic": { @@ -5714,7 +6292,6 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.7.tgz", "integrity": "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==", - "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", @@ -5934,7 +6511,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -5952,7 +6528,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" diff --git a/vocata-admin/package.json b/vocata-admin/package.json index 26297e4..80ac8af 100644 --- a/vocata-admin/package.json +++ b/vocata-admin/package.json @@ -1,5 +1,5 @@ { - "name": "vocata-admin", + "name": "vocata-web", "version": "0.0.0", "private": true, "type": "module", @@ -23,15 +23,20 @@ }, "dependencies": { "@element-plus/icons-vue": "^2.3.2", + "@tailwindcss/vite": "^4.1.13", + "@types/js-cookie": "^3.0.6", "axios": "^1.12.2", "element-plus": "^2.11.3", + "js-cookie": "^3.0.5", "pinia": "^3.0.3", + "tailwindcss": "^4.1.13", "vue": "^3.5.18", "vue-router": "^4.5.1" }, "devDependencies": { "@tsconfig/node22": "^22.0.2", "@types/node": "^22.16.5", + "@types/postcss-pxtorem": "^6.1.0", "@vitejs/plugin-vue": "^6.0.1", "@vue/eslint-config-prettier": "^10.2.0", "@vue/eslint-config-typescript": "^14.6.0", @@ -40,6 +45,7 @@ "eslint-plugin-vue": "~10.3.0", "jiti": "^2.4.2", "npm-run-all2": "^8.0.4", + "postcss-pxtorem": "^6.1.0", "prettier": "3.6.2", "sass": "^1.93.0", "typescript": "~5.8.0", diff --git a/vocata-admin/public/favicon.ico b/vocata-admin/public/favicon.ico index df36fcf..b9a89b0 100644 Binary files a/vocata-admin/public/favicon.ico and b/vocata-admin/public/favicon.ico differ diff --git a/vocata-admin/src/App.vue b/vocata-admin/src/App.vue index 307df29..f4eba70 100644 --- a/vocata-admin/src/App.vue +++ b/vocata-admin/src/App.vue @@ -1,22 +1,8 @@ - - - - diff --git a/vocata-admin/src/api/modules/role.ts b/vocata-admin/src/api/modules/role.ts new file mode 100644 index 0000000..a424b3d --- /dev/null +++ b/vocata-admin/src/api/modules/role.ts @@ -0,0 +1,25 @@ + +import request from '../request' + +export const roleApi = { + //增 + + // 删 + deleteRole(id: number) { + return request({ + url: `/api/admin/character/${id}`, + method: 'delete' + }) + }, + + //改 + + //查 + getRoleList(params: any) { + return request({ + url: '/api/admin/character', + method: 'get', + params + }) + } +} \ No newline at end of file diff --git a/vocata-admin/src/api/modules/user.ts b/vocata-admin/src/api/modules/user.ts new file mode 100644 index 0000000..8893f7a --- /dev/null +++ b/vocata-admin/src/api/modules/user.ts @@ -0,0 +1,36 @@ +import type { LoginParams, RegisterParams, Response, LoginResponse } from '@/types/api' +import request from '../request' + +export const userApi = { + // 登录 + login(params: LoginParams): Promise> { + return request.post('/api/client/auth/login', params) + }, + // 注册 + register(params: RegisterParams): Promise> { + return request.post('/api/client/auth/register', params) + }, + // 发送验证码 + sendCode(email: string): Promise> { + return request.post('/api/client/auth/sendCode', { email }) + }, + + // 退出登录 + logout(): Promise> { + return request.post('/api/client/auth/logout') + }, + // 获取用户信息 + getUserInfo(params): Promise> { + return request.get('/api/admin/user/list', params) + }, + + // 修改用户状态 + updateUserStatus(id, params): Promise> { + return request.put(`/api/admin/user/${id}/status`, params) + }, + + // 获取管理员信息 + getAdminInfo(): Promise> { + return request.get('/api/admin/auth/current') + }, +} \ No newline at end of file diff --git a/vocata-admin/src/api/request.ts b/vocata-admin/src/api/request.ts index e95db44..d8a7eb2 100644 --- a/vocata-admin/src/api/request.ts +++ b/vocata-admin/src/api/request.ts @@ -1,16 +1,22 @@ // src/utils/request.js import axios from 'axios' import { ElMessage } from 'element-plus' +import { getToken, removeToken } from '@/utils/token' +import router from '@/router' // 创建axios实例 -const service = axios.create({ - baseURL: import.meta.env.VUE_APP_BASE_API, // 从环境变量读取 +const request = axios.create({ + baseURL: import.meta.env.VITE_APP_URL, // 从环境变量读取 + // baseURL: 'http://127.0.0.1:4523/m1/7166225-6890394-default/', // 从环境变量读取 timeout: 10000 // 请求超时时间 }) // 请求拦截器 -service.interceptors.request.use( +request.interceptors.request.use( (config) => { + if (getToken()) { + config.headers['Authorization'] = 'Bearer ' + getToken() + } return config }, (error) => { @@ -20,17 +26,17 @@ service.interceptors.request.use( ) // 响应拦截器 -service.interceptors.response.use( +request.interceptors.response.use( (response) => { const res = response.data - // 根据你的后端接口约定修改判断逻辑 - if (res.code === 200) { - return res - } else { - ElMessage.error(res.message || '请求失败') - return Promise.reject(new Error(res.message || 'Error')) - } + // // 根据你的后端接口约定修改判断逻辑 + // if (res.code === 200) { + return res + // } else { + // ElMessage.error(res.message || '请求失败') + // return Promise.reject(new Error(res.message || 'Error')) + // } }, (error) => { // 处理HTTP错误状态码 @@ -39,7 +45,9 @@ service.interceptors.response.use( switch (error.response.status) { case 401: message = '未授权,请重新登录' + removeToken() // 跳转到登录页 + router.push('/login') break case 403: message = '拒绝访问' @@ -54,7 +62,7 @@ service.interceptors.response.use( message = '网络错误' } } else { - message = '网络连接失败' + message = '未知错误' } ElMessage.error(message) @@ -62,4 +70,4 @@ service.interceptors.response.use( } ) -export default service \ No newline at end of file +export default request \ No newline at end of file diff --git a/vocata-admin/src/assets/images/loginPic.png b/vocata-admin/src/assets/images/loginPic.png new file mode 100644 index 0000000..f6eabe2 Binary files /dev/null and b/vocata-admin/src/assets/images/loginPic.png differ diff --git a/vocata-admin/src/assets/images/logo-text.png b/vocata-admin/src/assets/images/logo-text.png new file mode 100644 index 0000000..847cd4c Binary files /dev/null and b/vocata-admin/src/assets/images/logo-text.png differ diff --git a/vocata-admin/src/assets/images/logo.png b/vocata-admin/src/assets/images/logo.png new file mode 100644 index 0000000..b9a89b0 Binary files /dev/null and b/vocata-admin/src/assets/images/logo.png differ diff --git a/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Bold.woff b/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Bold.woff new file mode 100644 index 0000000..98a673a Binary files /dev/null and b/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Bold.woff differ diff --git a/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Bold.woff2 b/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Bold.woff2 new file mode 100644 index 0000000..4f87f38 Binary files /dev/null and b/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Bold.woff2 differ diff --git a/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Regular.woff b/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Regular.woff new file mode 100644 index 0000000..8fe55bc Binary files /dev/null and b/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Regular.woff differ diff --git a/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Regular.woff2 b/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Regular.woff2 new file mode 100644 index 0000000..add9d78 Binary files /dev/null and b/vocata-admin/src/assets/styles/SweiB2SansCJKsc-Regular.woff2 differ diff --git a/vocata-admin/src/assets/styles/fonts.css b/vocata-admin/src/assets/styles/fonts.css new file mode 100644 index 0000000..588e68a --- /dev/null +++ b/vocata-admin/src/assets/styles/fonts.css @@ -0,0 +1,17 @@ +@import "tailwindcss"; + +@font-face { + font-family: 'CustomFont'; + src: url('./SweiB2SansCJKsc-Bold.woff') format('woff'); + src: url('./SweiB2SansCJKsc-Bold.woff2') format('woff2'); + font-weight: bold; + font-style: normal; +} + +@font-face { + font-family: 'CustomFont'; + src: url('./SweiB2SansCJKsc-Regular.woff') format('woff'); + src: url('./SweiB2SansCJKsc-Regular.woff2') format('woff2'); + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/vocata-admin/src/layouts/BasicLayout.vue b/vocata-admin/src/layouts/BasicLayout.vue index ba277ed..f6f77fa 100644 --- a/vocata-admin/src/layouts/BasicLayout.vue +++ b/vocata-admin/src/layouts/BasicLayout.vue @@ -1,17 +1,103 @@ - diff --git a/vocata-admin/src/layouts/BreadCrum.vue b/vocata-admin/src/layouts/BreadCrum.vue new file mode 100644 index 0000000..a2e2192 --- /dev/null +++ b/vocata-admin/src/layouts/BreadCrum.vue @@ -0,0 +1,32 @@ + + + + + + + diff --git a/vocata-admin/src/layouts/MenuCom.vue b/vocata-admin/src/layouts/MenuCom.vue new file mode 100644 index 0000000..fafbb20 --- /dev/null +++ b/vocata-admin/src/layouts/MenuCom.vue @@ -0,0 +1,64 @@ + + + + + + + diff --git a/vocata-admin/src/layouts/TabBar.vue b/vocata-admin/src/layouts/TabBar.vue new file mode 100644 index 0000000..26e39e3 --- /dev/null +++ b/vocata-admin/src/layouts/TabBar.vue @@ -0,0 +1,100 @@ + + + + diff --git a/vocata-admin/src/main.ts b/vocata-admin/src/main.ts index 8896bf7..6738661 100644 --- a/vocata-admin/src/main.ts +++ b/vocata-admin/src/main.ts @@ -5,7 +5,9 @@ import 'element-plus/dist/index.css' import App from './App.vue' import router from './router' import * as ElementPlusIconsVue from '@element-plus/icons-vue' -import '@/utils/rem.js' +// import '@/utils/rem.js' +import '@/assets/styles/fonts.css' + const app = createApp(App) app.use(createPinia()) diff --git a/vocata-admin/src/router/guards.ts b/vocata-admin/src/router/guards.ts index e69de29..50bc0fa 100644 --- a/vocata-admin/src/router/guards.ts +++ b/vocata-admin/src/router/guards.ts @@ -0,0 +1,29 @@ +import { getToken } from '@/utils/token' +import { ElMessage } from 'element-plus' +import type { Router } from 'vue-router' + +const whiteList = ['/passport/login', '/404'] +export default function setupRouterGuard(router: Router) { + router.beforeEach(async (to, from, next) => { + const token = getToken() + + // 白名单检查 + if (whiteList.includes(to.path)) { + // 如果已经登录,访问登录页时重定向到首页 + if (token && to.path === '/passport/login') { + next('/') + return + } + next() + return + } + + // 非白名单路径检查token + if (!token) { + ElMessage.warning('登录过期,请重新登录') + next(`/passport/login?redirect=${encodeURIComponent(to.fullPath)}`) + return + } + next() + }) +} \ No newline at end of file diff --git a/vocata-admin/src/router/index.ts b/vocata-admin/src/router/index.ts index 7f222f3..e632cc0 100644 --- a/vocata-admin/src/router/index.ts +++ b/vocata-admin/src/router/index.ts @@ -1,9 +1,10 @@ -import { createRouter, createWebHistory } from 'vue-router' +import { createRouter, createWebHashHistory } from 'vue-router' import routes from './routes.ts' +import guard from './guards' const router = createRouter({ - history: createWebHistory(import.meta.env.BASE_URL), + history: createWebHashHistory(import.meta.env.BASE_URL), routes }) - +guard(router) export default router diff --git a/vocata-admin/src/router/routes.ts b/vocata-admin/src/router/routes.ts index b70240a..ef57814 100644 --- a/vocata-admin/src/router/routes.ts +++ b/vocata-admin/src/router/routes.ts @@ -1,10 +1,67 @@ import type { RouteRecordRaw } from "vue-router" import BasicLayout from '@/layouts/BasicLayout.vue' const routes: RouteRecordRaw[] = [ + // 登录模块 { - path: '/', + path: '/passport', + name: 'Passport', + component: () => import('@/views/passport/PassPort.vue'), + meta: { title: '通行证', hidden: true }, + children: [ + { + path: '/passport/login', + name: 'Login', + component: () => import('@/views/passport/LoginPage.vue'), + meta: { title: '登录', hidden: true } + } + ] + }, + // 角色管理模块 + { + path: '/role', + name: 'Role', + component: BasicLayout, + + meta: { title: '角色管理', icon: 'User' }, + children: [ + { + path: '/role/roles', + name: 'Roles', + component: () => import('@/views/RolePage.vue'), + meta: { title: '角色管理', icon: 'User' } + } + ] + }, + // 角色管理模块 + { + path: '/user', + name: 'User', component: BasicLayout, - // redirect: '/dashboard', - } + + meta: { title: '用户管理', icon: 'User' }, + children: [ + { + path: '/user/users', + name: 'Users', + component: () => import('@/views/UserPage.vue'), + meta: { title: '用户管理', icon: 'User' } + } + ] + }, + // 根路由 + { + path: '/', + name: 'Root', + component: () => import('@/layouts/BasicLayout.vue'), + meta: { title: '首页', hidden: true }, + redirect: '/role/roles' + }, + // 404页面 + { + path: '/:pathMatch(.*)*', + name: 'NotFound', + component: () => import('@/views/ErrorPage.vue'), + meta: { title: '页面不存在', hidden: true } + }, ] export default routes \ No newline at end of file diff --git a/vocata-admin/src/store/index.ts b/vocata-admin/src/store/index.ts index e69de29..f996a05 100644 --- a/vocata-admin/src/store/index.ts +++ b/vocata-admin/src/store/index.ts @@ -0,0 +1,10 @@ + +import routes from '@/router/routes' +import { defineStore } from 'pinia' +export const user = defineStore('user', { + state: () => { + return { + menuRoutes: routes, + } + } +}) \ No newline at end of file diff --git a/vocata-admin/src/types/api.ts b/vocata-admin/src/types/api.ts new file mode 100644 index 0000000..dc327f0 --- /dev/null +++ b/vocata-admin/src/types/api.ts @@ -0,0 +1,51 @@ +// 公开角色查询参数 +export interface PublicRoleQuery { + keywords?: string, + status?: number, + isFeatured?: number, + isTrending?: number, + tags?: string[], + language?: string, + creatorId?: number, + pageNum: number, + pageSize: number, + orderBy?: string, + orderDirection?: string +} + +// 登录参数 +export interface LoginParams { + loginName: string, + password: string, + rememberMe: boolean +} + +// 注册参数 +export interface RegisterParams { + nickname: string, + password: string, + email: string, + confirmPassword: string, + verificationCode: string, + gender: number, + hasRead?: boolean +} + +// 登录响应数据 +export interface LoginResponse { + token: string, + expiresIn: number +} + +// 修改密码参数 +export interface ChangePasswordParams { + oldPassword: string, + newPassword: string +} + +// 返回参数 +export interface Response { + code: number, + message: string, + data: T +} \ No newline at end of file diff --git a/vocata-admin/src/types/common.ts b/vocata-admin/src/types/common.ts new file mode 100644 index 0000000..42b78c3 --- /dev/null +++ b/vocata-admin/src/types/common.ts @@ -0,0 +1,22 @@ +export interface roleInfo { + "id"?: number, + "characterCode"?: string, + "name"?: string, + "description"?: string, + "greeting"?: string, + "avatarUrl"?: string, + "tags"?: string, + "language"?: string, + "status"?: number, + "statusName"?: string, + "isOfficial"?: number, + "isFeatured"?: number, + "isTrending"?: number, + "trendingScore"?: number, + "chatCount"?: number, + "userCount"?: number, + "isPrivate"?: boolean, + "creatorId"?: number, + "createdAt"?: string, + "updatedAt"?: string +} \ No newline at end of file diff --git a/vocata-admin/src/utils/debounce.ts b/vocata-admin/src/utils/debounce.ts new file mode 100644 index 0000000..cd8c5bb --- /dev/null +++ b/vocata-admin/src/utils/debounce.ts @@ -0,0 +1,32 @@ +// 防抖函数 +function debounce void>( + func: T, + wait: number, + immediate: boolean = false +): (...args: Parameters) => void { + + let timeout: ReturnType | null = null; + + return function (this: unknown, ...args: Parameters): void { + const later = (): void => { + timeout = null; + if (!immediate) { + func.apply(this, args); + } + }; + + const shouldCallNow = immediate && timeout === null; + + if (timeout !== null) { + clearTimeout(timeout); + } + + timeout = setTimeout(later, wait); + + if (shouldCallNow) { + func.apply(this, args); + } + }; + +} +export default debounce; \ No newline at end of file diff --git a/vocata-admin/src/utils/rem.ts b/vocata-admin/src/utils/rem.ts index 300e0f6..10fa4b9 100644 --- a/vocata-admin/src/utils/rem.ts +++ b/vocata-admin/src/utils/rem.ts @@ -1,27 +1,18 @@ - -(function() { - // 设计稿宽度(根据你的设计稿修改,通常是1920或1440) - const designWidth = 1920 - - // 设置根元素字体大小(1rem = 100px) +(function () { function setRem() { - const clientWidth = document.documentElement.clientWidth || document.body.clientWidth - // 计算比例:当前宽度 / 设计稿宽度 - const scale = clientWidth / designWidth - // 设置根元素字体大小:比例 × 100(实现1rem = 100px) - document.documentElement.style.fontSize = scale * 100 + 'px' + const width = document.documentElement.clientWidth + + if (width <= 768) { + // 移动端:基于375px设计稿,1rem = 100px + document.documentElement.style.fontSize = (width / 375 * 100) + 'px' + } else { + // PC端:基于1920px设计稿,1rem = 100px + const fontSize = Math.min(width / 1920 * 100, 100) // 限制最大字体大小 + document.documentElement.style.fontSize = fontSize + 'px' + } } - - // 初始化 + setRem() - - // 监听窗口变化 window.addEventListener('resize', setRem) - - // 监听页面显示(解决浏览器后退问题) - window.addEventListener('pageshow', function(e) { - if (e.persisted) { - setRem() - } - }) + window.addEventListener('pageshow', (e) => e.persisted && setRem()) })() \ No newline at end of file diff --git a/vocata-admin/src/utils/token.ts b/vocata-admin/src/utils/token.ts new file mode 100644 index 0000000..8307893 --- /dev/null +++ b/vocata-admin/src/utils/token.ts @@ -0,0 +1,15 @@ +import Cookies from "js-cookie"; + +export function getToken() { + return Cookies.get("token"); +} + +export function setToken(token: string, time: number) { + Cookies.set("token", token, { + expires: time, + }); +} + +export function removeToken() { + Cookies.remove("token"); +} \ No newline at end of file diff --git a/vocata-admin/src/views/ErrorPage.vue b/vocata-admin/src/views/ErrorPage.vue new file mode 100644 index 0000000..7097370 --- /dev/null +++ b/vocata-admin/src/views/ErrorPage.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/vocata-admin/src/views/RolePage.vue b/vocata-admin/src/views/RolePage.vue new file mode 100644 index 0000000..239ddeb --- /dev/null +++ b/vocata-admin/src/views/RolePage.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/vocata-admin/src/views/UserPage.vue b/vocata-admin/src/views/UserPage.vue new file mode 100644 index 0000000..a74ebc0 --- /dev/null +++ b/vocata-admin/src/views/UserPage.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/vocata-admin/src/views/passport/LoginPage.vue b/vocata-admin/src/views/passport/LoginPage.vue new file mode 100644 index 0000000..a6d8351 --- /dev/null +++ b/vocata-admin/src/views/passport/LoginPage.vue @@ -0,0 +1,98 @@ + + + diff --git a/vocata-admin/src/views/passport/PassPort.vue b/vocata-admin/src/views/passport/PassPort.vue new file mode 100644 index 0000000..dca77dd --- /dev/null +++ b/vocata-admin/src/views/passport/PassPort.vue @@ -0,0 +1,14 @@ + diff --git a/vocata-admin/vite.config.ts b/vocata-admin/vite.config.ts index cacbfe4..e77a98e 100644 --- a/vocata-admin/vite.config.ts +++ b/vocata-admin/vite.config.ts @@ -3,7 +3,7 @@ import { fileURLToPath, URL } from 'node:url' import { defineConfig, loadEnv } from 'vite' import vue from '@vitejs/plugin-vue' import vueDevTools from 'vite-plugin-vue-devtools' - +import tailwindcss from '@tailwindcss/vite' // https://vite.dev/config/ export default defineConfig(({ mode }) => { // 根据当前模式加载对应的环境变量 @@ -13,6 +13,7 @@ export default defineConfig(({ mode }) => { plugins: [ vue(), vueDevTools(), + tailwindcss() ], resolve: { alias: { @@ -32,4 +33,5 @@ export default defineConfig(({ mode }) => { } }, } + }) diff --git a/vocata-web/.env.development b/vocata-web/.env.development index e2b885d..4bc4d7e 100644 --- a/vocata-web/.env.development +++ b/vocata-web/.env.development @@ -1,4 +1,9 @@ -# 测试环境配置 -VITE_APP_URL=http://127.0.0.1:9009 -VUE_APP_TITLE=VocaTa - 测试环境 -VITE_APP_ENV=test \ No newline at end of file + +# 开发环境配置 - 默认使用本地环境 +VITE_APP_URL=http://101.200.141.46:9009 + +VUE_APP_BASE_API=/api +VUE_APP_TITLE=VocaTa 管理后台 - 开发环境 +VITE_APP_ENV=development + + diff --git a/vocata-web/.env.production b/vocata-web/.env.production index f64a14f..0765ec6 100644 --- a/vocata-web/.env.production +++ b/vocata-web/.env.production @@ -1,5 +1,8 @@ + # 生产环境配置 # 注意:VITE_APP_URL 将在CI/CD构建时动态替换 VITE_APP_URL=http://{{PRODUCTION_HOST}}:9009 -VUE_APP_TITLE=VocaTa -VITE_APP_ENV=production \ No newline at end of file +VUE_APP_BASE_API=/api +VUE_APP_TITLE=VocaTa 管理后台 +VITE_APP_ENV=production + diff --git a/vocata-web/.env.test b/vocata-web/.env.test index ce93b83..74842ea 100644 --- a/vocata-web/.env.test +++ b/vocata-web/.env.test @@ -1,5 +1,6 @@ # 测试环境配置 # 注意:VITE_APP_URL 将在CI/CD构建时动态替换 VITE_APP_URL=http://{{STAGING_HOST}}:9009 -VUE_APP_TITLE=VocaTa - 测试环境 +VUE_APP_BASE_API=/api +VUE_APP_TITLE=VocaTa 管理后台 - 测试环境 VITE_APP_ENV=test \ No newline at end of file diff --git a/vocata-web/src/api/modules/role.ts b/vocata-web/src/api/modules/role.ts index 58d58b7..94842b2 100644 --- a/vocata-web/src/api/modules/role.ts +++ b/vocata-web/src/api/modules/role.ts @@ -18,6 +18,14 @@ export const roleApi = { params }) }, + // 获取我的角色列表 + getMyRoleList() { + return request({ + url: '/api/client/character/my', + method: 'get', + // params + }) + }, // 搜索角色 searchRole(params: { keyword: string }) { return request({ diff --git a/vocata-web/src/api/modules/user.ts b/vocata-web/src/api/modules/user.ts index 627636f..4c73ba7 100644 --- a/vocata-web/src/api/modules/user.ts +++ b/vocata-web/src/api/modules/user.ts @@ -22,5 +22,9 @@ export const userApi = { // 获取用户信息 getUserInfo(): Promise> { return request.get('/api/client/user/profile') + }, + // 更新用户信息 + updateUserInfo(params: UserInfo): Promise> { + return request.post('/api/client/user/profile', params) } } \ No newline at end of file diff --git a/vocata-web/src/layouts/SliderBar.vue b/vocata-web/src/layouts/SliderBar.vue index cc024e5..d5ab28b 100644 --- a/vocata-web/src/layouts/SliderBar.vue +++ b/vocata-web/src/layouts/SliderBar.vue @@ -204,15 +204,24 @@ const toggleSidebar = () => { } const showRoleGallery = () => { console.log('showRoleGallery') + if (isM.value) { + toggleSidebar() + } router.push('/searchRole') } const createNewRole = () => { console.log('createNewRole') + if (isM.value) { + toggleSidebar() + } router.push('/newRole') } const selectChat = (conversationUuid: string) => { console.log('selectChat', conversationUuid) activeChatId.value = conversationUuid + if (isM.value) { + toggleSidebar() + } router.push(`/chat/${conversationUuid}`) } const searchIconHandler = () => { diff --git a/vocata-web/src/layouts/UserInfo.vue b/vocata-web/src/layouts/UserInfo.vue index 05a9418..a751ca2 100644 --- a/vocata-web/src/layouts/UserInfo.vue +++ b/vocata-web/src/layouts/UserInfo.vue @@ -10,8 +10,8 @@
- - + 昵称 性别 - - + + 电话 生日 -
创建
+
修改
@@ -84,12 +85,26 @@ const getUserInfo = async () => { try { const res = await userApi.getUserInfo() if (res.code === 200) { - form.value = res.data + form.value.nickname = res.data.nickname + form.value.gender = res.data.gender + form.value.phone = res.data.phone + form.value.birthday = res.data.birthday } } catch (error) { console.log(error) } } +const update = async () => { + try { + const res = await userApi.updateUserInfo(form.value) + if (res.code === 200) { + ElMessage.success('修改成功') + } + } catch (error) { + ElMessage.error('修改失败') + console.log(error) + } +}