commit 5485c3b85a6f83e5f3b131fe8b0a3ec574c3a56e Author: dzc <2388224167@qq.com> Date: Fri Oct 17 13:01:55 2025 +0800 init diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..b2c559f --- /dev/null +++ b/.env.development @@ -0,0 +1,11 @@ +# 开发环境配置 +ENV = 'development' + +# 开发环境 +VITE_BASE_API = '/api' + +# 本地 +VITE_PROXY_PATH = 'http://127.0.0.1:9999' + +# 测试 +# VITE_PROXY_PATH = 'http://36585.asset-cloud.com.cn:36588' diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..8016f1c --- /dev/null +++ b/.env.production @@ -0,0 +1,6 @@ +# 生产环境配置 +ENV = 'production' + +# 生产环境 +VITE_BASE_API = '/api' +VITE_PROXY_PATH = 'http://127.0.0.1:9999' \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d947597 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# Environment variables +.env.local +.env.*.local + +# Testing +/cypress/videos/ +/cypress/screenshots/ + +# Temporary folders +tmp/ +temp/ \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..c630889 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + 浦江县智慧后勤数据统计 + + +
+ + + diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..5a1f2d2 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "paths": { + "@/*": ["./src/*"] + } + }, + "exclude": ["node_modules", "dist"] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..3473d5f --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "biz-pc-cockpit", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite --host", + "build": "vite build", + "build:prod": "vite build --mode production", + "preview": "vite preview" + }, + "dependencies": { + "@element-plus/icons-vue": "^2.3.2", + "axios": "^1.12.2", + "dayjs": "^1.11.18", + "echarts": "^6.0.0", + "element-plus": "^2.11.4", + "js-cookie": "^3.0.5", + "vue": "^3.5.13", + "vue-router": "^4.5.1" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.2.1", + "less": "^4.4.1", + "vite": "^6.1.0" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..0402ca8 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1370 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@element-plus/icons-vue': + specifier: ^2.3.2 + version: 2.3.2(vue@3.5.22) + axios: + specifier: ^1.12.2 + version: 1.12.2 + dayjs: + specifier: ^1.11.18 + version: 1.11.18 + echarts: + specifier: ^6.0.0 + version: 6.0.0 + element-plus: + specifier: ^2.11.4 + version: 2.11.4(vue@3.5.22) + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + vue: + specifier: ^3.5.13 + version: 3.5.22 + vue-router: + specifier: ^4.5.1 + version: 4.5.1(vue@3.5.22) + devDependencies: + '@vitejs/plugin-vue': + specifier: ^5.2.1 + version: 5.2.4(vite@6.3.6(less@4.4.1))(vue@3.5.22) + less: + specifier: ^4.4.1 + version: 4.4.1 + vite: + specifier: ^6.1.0 + version: 6.3.6(less@4.4.1) + +packages: + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} + engines: {node: '>=6.9.0'} + + '@ctrl/tinycolor@3.6.1': + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + + '@element-plus/icons-vue@2.3.2': + resolution: {integrity: sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==} + peerDependencies: + vue: ^3.2.0 + + '@esbuild/aix-ppc64@0.25.10': + resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.10': + resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.10': + resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.10': + resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.10': + resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.10': + resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.10': + resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.10': + resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.10': + resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.10': + resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.10': + resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.10': + resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.10': + resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.10': + resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.10': + resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.10': + resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.10': + resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.10': + resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.10': + resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.10': + resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.10': + resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.10': + resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.10': + resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.10': + resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.10': + resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.10': + resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@rollup/rollup-android-arm-eabi@4.52.3': + resolution: {integrity: sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.52.3': + resolution: {integrity: sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.52.3': + resolution: {integrity: sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.52.3': + resolution: {integrity: sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.52.3': + resolution: {integrity: sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.52.3': + resolution: {integrity: sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.52.3': + resolution: {integrity: sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.52.3': + resolution: {integrity: sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.52.3': + resolution: {integrity: sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.52.3': + resolution: {integrity: sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.52.3': + resolution: {integrity: sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-gnu@4.52.3': + resolution: {integrity: sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-gnu@4.52.3': + resolution: {integrity: sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.52.3': + resolution: {integrity: sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.52.3': + resolution: {integrity: sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.52.3': + resolution: {integrity: sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.52.3': + resolution: {integrity: sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openharmony-arm64@4.52.3': + resolution: {integrity: sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.52.3': + resolution: {integrity: sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.52.3': + resolution: {integrity: sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.52.3': + resolution: {integrity: sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.3': + resolution: {integrity: sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==} + cpu: [x64] + os: [win32] + + '@sxzz/popperjs-es@2.11.7': + resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + + '@types/web-bluetooth@0.0.16': + resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} + + '@vitejs/plugin-vue@5.2.4': + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + + '@vue/compiler-core@3.5.22': + resolution: {integrity: sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==} + + '@vue/compiler-dom@3.5.22': + resolution: {integrity: sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==} + + '@vue/compiler-sfc@3.5.22': + resolution: {integrity: sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==} + + '@vue/compiler-ssr@3.5.22': + resolution: {integrity: sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + + '@vue/reactivity@3.5.22': + resolution: {integrity: sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==} + + '@vue/runtime-core@3.5.22': + resolution: {integrity: sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==} + + '@vue/runtime-dom@3.5.22': + resolution: {integrity: sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==} + + '@vue/server-renderer@3.5.22': + resolution: {integrity: sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==} + peerDependencies: + vue: 3.5.22 + + '@vue/shared@3.5.22': + resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} + + '@vueuse/core@9.13.0': + resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} + + '@vueuse/metadata@9.13.0': + resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} + + '@vueuse/shared@9.13.0': + resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} + + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.12.2: + resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + copy-anything@2.0.6: + resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + dayjs@1.11.18: + resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + echarts@6.0.0: + resolution: {integrity: sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==} + + element-plus@2.11.4: + resolution: {integrity: sha512-sLq+Ypd0cIVilv8wGGMEGvzRVBBsRpJjnAS5PsI/1JU1COZXqzH3N1UYMUc/HCdvdjf6dfrBy80Sj7KcACsT7w==} + peerDependencies: + vue: ^3.2.0 + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + errno@0.1.8: + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + hasBin: true + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.25.10: + resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} + engines: {node: '>=18'} + hasBin: true + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + image-size@0.5.5: + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + is-what@3.14.1: + resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + + less@4.4.1: + resolution: {integrity: sha512-X9HKyiXPi0f/ed0XhgUlBeFfxrlDP3xR4M7768Zl+WXLUViuL9AOPPJP4nCV0tgRWvTYvpNmN0SFhZOQzy16PA==} + engines: {node: '>=14'} + hasBin: true + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash-unified@1.0.3: + resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==} + peerDependencies: + '@types/lodash-es': '*' + lodash: '*' + lodash-es: '*' + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + memoize-one@6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + needle@3.3.1: + resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} + engines: {node: '>= 4.4.x'} + hasBin: true + + normalize-wheel-es@1.2.0: + resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==} + + parse-node-version@1.0.1: + resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} + engines: {node: '>= 0.10'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + prr@1.0.1: + resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + + rollup@4.52.3: + resolution: {integrity: sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + vite@6.3.6: + resolution: {integrity: sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-router@4.5.1: + resolution: {integrity: sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==} + peerDependencies: + vue: ^3.2.0 + + vue@3.5.22: + resolution: {integrity: sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + zrender@6.0.0: + resolution: {integrity: sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==} + +snapshots: + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/parser@7.28.4': + dependencies: + '@babel/types': 7.28.4 + + '@babel/types@7.28.4': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@ctrl/tinycolor@3.6.1': {} + + '@element-plus/icons-vue@2.3.2(vue@3.5.22)': + dependencies: + vue: 3.5.22 + + '@esbuild/aix-ppc64@0.25.10': + optional: true + + '@esbuild/android-arm64@0.25.10': + optional: true + + '@esbuild/android-arm@0.25.10': + optional: true + + '@esbuild/android-x64@0.25.10': + optional: true + + '@esbuild/darwin-arm64@0.25.10': + optional: true + + '@esbuild/darwin-x64@0.25.10': + optional: true + + '@esbuild/freebsd-arm64@0.25.10': + optional: true + + '@esbuild/freebsd-x64@0.25.10': + optional: true + + '@esbuild/linux-arm64@0.25.10': + optional: true + + '@esbuild/linux-arm@0.25.10': + optional: true + + '@esbuild/linux-ia32@0.25.10': + optional: true + + '@esbuild/linux-loong64@0.25.10': + optional: true + + '@esbuild/linux-mips64el@0.25.10': + optional: true + + '@esbuild/linux-ppc64@0.25.10': + optional: true + + '@esbuild/linux-riscv64@0.25.10': + optional: true + + '@esbuild/linux-s390x@0.25.10': + optional: true + + '@esbuild/linux-x64@0.25.10': + optional: true + + '@esbuild/netbsd-arm64@0.25.10': + optional: true + + '@esbuild/netbsd-x64@0.25.10': + optional: true + + '@esbuild/openbsd-arm64@0.25.10': + optional: true + + '@esbuild/openbsd-x64@0.25.10': + optional: true + + '@esbuild/openharmony-arm64@0.25.10': + optional: true + + '@esbuild/sunos-x64@0.25.10': + optional: true + + '@esbuild/win32-arm64@0.25.10': + optional: true + + '@esbuild/win32-ia32@0.25.10': + optional: true + + '@esbuild/win32-x64@0.25.10': + optional: true + + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 + + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 + + '@floating-ui/utils@0.2.10': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@rollup/rollup-android-arm-eabi@4.52.3': + optional: true + + '@rollup/rollup-android-arm64@4.52.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.52.3': + optional: true + + '@rollup/rollup-darwin-x64@4.52.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.52.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.52.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.52.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.52.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.52.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.52.3': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.52.3': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.52.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.52.3': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.52.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.52.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.52.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.52.3': + optional: true + + '@rollup/rollup-openharmony-arm64@4.52.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.52.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.52.3': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.52.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.3': + optional: true + + '@sxzz/popperjs-es@2.11.7': {} + + '@types/estree@1.0.8': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.20 + + '@types/lodash@4.17.20': {} + + '@types/web-bluetooth@0.0.16': {} + + '@vitejs/plugin-vue@5.2.4(vite@6.3.6(less@4.4.1))(vue@3.5.22)': + dependencies: + vite: 6.3.6(less@4.4.1) + vue: 3.5.22 + + '@vue/compiler-core@3.5.22': + dependencies: + '@babel/parser': 7.28.4 + '@vue/shared': 3.5.22 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.22': + dependencies: + '@vue/compiler-core': 3.5.22 + '@vue/shared': 3.5.22 + + '@vue/compiler-sfc@3.5.22': + dependencies: + '@babel/parser': 7.28.4 + '@vue/compiler-core': 3.5.22 + '@vue/compiler-dom': 3.5.22 + '@vue/compiler-ssr': 3.5.22 + '@vue/shared': 3.5.22 + estree-walker: 2.0.2 + magic-string: 0.30.19 + postcss: 8.5.6 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.22': + dependencies: + '@vue/compiler-dom': 3.5.22 + '@vue/shared': 3.5.22 + + '@vue/devtools-api@6.6.4': {} + + '@vue/reactivity@3.5.22': + dependencies: + '@vue/shared': 3.5.22 + + '@vue/runtime-core@3.5.22': + dependencies: + '@vue/reactivity': 3.5.22 + '@vue/shared': 3.5.22 + + '@vue/runtime-dom@3.5.22': + dependencies: + '@vue/reactivity': 3.5.22 + '@vue/runtime-core': 3.5.22 + '@vue/shared': 3.5.22 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.22(vue@3.5.22)': + dependencies: + '@vue/compiler-ssr': 3.5.22 + '@vue/shared': 3.5.22 + vue: 3.5.22 + + '@vue/shared@3.5.22': {} + + '@vueuse/core@9.13.0(vue@3.5.22)': + dependencies: + '@types/web-bluetooth': 0.0.16 + '@vueuse/metadata': 9.13.0 + '@vueuse/shared': 9.13.0(vue@3.5.22) + vue-demi: 0.14.10(vue@3.5.22) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@9.13.0': {} + + '@vueuse/shared@9.13.0(vue@3.5.22)': + dependencies: + vue-demi: 0.14.10(vue@3.5.22) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + async-validator@4.2.5: {} + + asynckit@0.4.0: {} + + axios@1.12.2: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + copy-anything@2.0.6: + dependencies: + is-what: 3.14.1 + + csstype@3.1.3: {} + + dayjs@1.11.18: {} + + delayed-stream@1.0.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + echarts@6.0.0: + dependencies: + tslib: 2.3.0 + zrender: 6.0.0 + + element-plus@2.11.4(vue@3.5.22): + dependencies: + '@ctrl/tinycolor': 3.6.1 + '@element-plus/icons-vue': 2.3.2(vue@3.5.22) + '@floating-ui/dom': 1.7.4 + '@popperjs/core': '@sxzz/popperjs-es@2.11.7' + '@types/lodash': 4.17.20 + '@types/lodash-es': 4.17.12 + '@vueuse/core': 9.13.0(vue@3.5.22) + async-validator: 4.2.5 + dayjs: 1.11.18 + escape-html: 1.0.3 + lodash: 4.17.21 + lodash-es: 4.17.21 + lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21) + memoize-one: 6.0.0 + normalize-wheel-es: 1.2.0 + vue: 3.5.22 + transitivePeerDependencies: + - '@vue/composition-api' + + entities@4.5.0: {} + + errno@0.1.8: + dependencies: + prr: 1.0.1 + optional: true + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.25.10: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.10 + '@esbuild/android-arm': 0.25.10 + '@esbuild/android-arm64': 0.25.10 + '@esbuild/android-x64': 0.25.10 + '@esbuild/darwin-arm64': 0.25.10 + '@esbuild/darwin-x64': 0.25.10 + '@esbuild/freebsd-arm64': 0.25.10 + '@esbuild/freebsd-x64': 0.25.10 + '@esbuild/linux-arm': 0.25.10 + '@esbuild/linux-arm64': 0.25.10 + '@esbuild/linux-ia32': 0.25.10 + '@esbuild/linux-loong64': 0.25.10 + '@esbuild/linux-mips64el': 0.25.10 + '@esbuild/linux-ppc64': 0.25.10 + '@esbuild/linux-riscv64': 0.25.10 + '@esbuild/linux-s390x': 0.25.10 + '@esbuild/linux-x64': 0.25.10 + '@esbuild/netbsd-arm64': 0.25.10 + '@esbuild/netbsd-x64': 0.25.10 + '@esbuild/openbsd-arm64': 0.25.10 + '@esbuild/openbsd-x64': 0.25.10 + '@esbuild/openharmony-arm64': 0.25.10 + '@esbuild/sunos-x64': 0.25.10 + '@esbuild/win32-arm64': 0.25.10 + '@esbuild/win32-ia32': 0.25.10 + '@esbuild/win32-x64': 0.25.10 + + escape-html@1.0.3: {} + + estree-walker@2.0.2: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + follow-redirects@1.15.11: {} + + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + 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 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: + optional: true + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + + image-size@0.5.5: + optional: true + + is-what@3.14.1: {} + + js-cookie@3.0.5: {} + + less@4.4.1: + dependencies: + copy-anything: 2.0.6 + parse-node-version: 1.0.1 + tslib: 2.8.1 + optionalDependencies: + errno: 0.1.8 + graceful-fs: 4.2.11 + image-size: 0.5.5 + make-dir: 2.1.0 + mime: 1.6.0 + needle: 3.3.1 + source-map: 0.6.1 + + lodash-es@4.17.21: {} + + lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21): + dependencies: + '@types/lodash-es': 4.17.12 + lodash: 4.17.21 + lodash-es: 4.17.21 + + lodash@4.17.21: {} + + magic-string@0.30.19: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + optional: true + + math-intrinsics@1.1.0: {} + + memoize-one@6.0.0: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: + optional: true + + nanoid@3.3.11: {} + + needle@3.3.1: + dependencies: + iconv-lite: 0.6.3 + sax: 1.4.1 + optional: true + + normalize-wheel-es@1.2.0: {} + + parse-node-version@1.0.1: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + pify@4.0.1: + optional: true + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + proxy-from-env@1.1.0: {} + + prr@1.0.1: + optional: true + + rollup@4.52.3: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.52.3 + '@rollup/rollup-android-arm64': 4.52.3 + '@rollup/rollup-darwin-arm64': 4.52.3 + '@rollup/rollup-darwin-x64': 4.52.3 + '@rollup/rollup-freebsd-arm64': 4.52.3 + '@rollup/rollup-freebsd-x64': 4.52.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.3 + '@rollup/rollup-linux-arm-musleabihf': 4.52.3 + '@rollup/rollup-linux-arm64-gnu': 4.52.3 + '@rollup/rollup-linux-arm64-musl': 4.52.3 + '@rollup/rollup-linux-loong64-gnu': 4.52.3 + '@rollup/rollup-linux-ppc64-gnu': 4.52.3 + '@rollup/rollup-linux-riscv64-gnu': 4.52.3 + '@rollup/rollup-linux-riscv64-musl': 4.52.3 + '@rollup/rollup-linux-s390x-gnu': 4.52.3 + '@rollup/rollup-linux-x64-gnu': 4.52.3 + '@rollup/rollup-linux-x64-musl': 4.52.3 + '@rollup/rollup-openharmony-arm64': 4.52.3 + '@rollup/rollup-win32-arm64-msvc': 4.52.3 + '@rollup/rollup-win32-ia32-msvc': 4.52.3 + '@rollup/rollup-win32-x64-gnu': 4.52.3 + '@rollup/rollup-win32-x64-msvc': 4.52.3 + fsevents: 2.3.3 + + safer-buffer@2.1.2: + optional: true + + sax@1.4.1: + optional: true + + semver@5.7.2: + optional: true + + source-map-js@1.2.1: {} + + source-map@0.6.1: + optional: true + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tslib@2.3.0: {} + + tslib@2.8.1: {} + + vite@6.3.6(less@4.4.1): + dependencies: + esbuild: 0.25.10 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.52.3 + tinyglobby: 0.2.15 + optionalDependencies: + fsevents: 2.3.3 + less: 4.4.1 + + vue-demi@0.14.10(vue@3.5.22): + dependencies: + vue: 3.5.22 + + vue-router@4.5.1(vue@3.5.22): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.22 + + vue@3.5.22: + dependencies: + '@vue/compiler-dom': 3.5.22 + '@vue/compiler-sfc': 3.5.22 + '@vue/runtime-dom': 3.5.22 + '@vue/server-renderer': 3.5.22(vue@3.5.22) + '@vue/shared': 3.5.22 + + zrender@6.0.0: + dependencies: + tslib: 2.3.0 diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..54d8ca4 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,14 @@ + + + diff --git a/src/api/canteen.js b/src/api/canteen.js new file mode 100644 index 0000000..071435c --- /dev/null +++ b/src/api/canteen.js @@ -0,0 +1,90 @@ +import { service } from "./share/request" + +/** + * 用餐数据统计(根据时间段和日期分类统计) + */ +export const groupByTimeAndHourType = (data) => { + return service({ + url: 'hard/panel-canteen/group/by-time-and-hour-type', + method: 'post', + data, + }) +} + +/** + * 各个食堂的用餐人数 + */ +export const mchPayPersonCount = (data) => { + return service({ + url: 'hard/panel-canteen/mch-pay-person-count', + method: 'post', + data, + }) +} + +/** + * 各个食堂的用餐人数(趋势) + */ +export const payPersonCountTrend = (data) => { + return service({ + url: 'hard/panel-canteen/pay-person-count-trend', + method: 'post', + data, + }) +} + + +/** + * 用餐数据统计(根据自定义时间段和日期分类统计) + */ +export const groupByTimeAndCustomHour = (data) => { + return service({ + url: "hard/panel-canteen/group/by-time-and-custom-hour", + method: 'post', + data, + }) +} + +/** + * 排行榜 + */ +export const mchPayCountTop = (data) => { + return service({ + url: 'hard/panel-canteen/mch-pay-count-top', + method: 'post', + data, + }) +} + +/** + * 食堂报表 + */ +export const canteenReport = (data) => { + return service({ + url: 'hard/panel-canteen/report', + method: 'post', + data, + }) +} + +/** + * 最新的吃饭数据 + */ +export const newPage = (data) => { + return service({ + url: 'hard/panel-canteen/new-page', + method: 'post', + data, + }) +} + +/** + * 最近吃饭数据 + */ +export const recentlyCanteen = (data) => { + return service({ + url: 'hard/panel-canteen/recently', + method: 'post', + data, + }) +} \ No newline at end of file diff --git a/src/api/index.js b/src/api/index.js new file mode 100644 index 0000000..c6d0988 --- /dev/null +++ b/src/api/index.js @@ -0,0 +1,8 @@ + +export * as canteenApi from "./canteen" + +export * as shopApi from "./shop" + +export * as nutritionApi from "./nutrition" + +export * as userApi from "./user" \ No newline at end of file diff --git a/src/api/nutrition.js b/src/api/nutrition.js new file mode 100644 index 0000000..43e4257 --- /dev/null +++ b/src/api/nutrition.js @@ -0,0 +1,68 @@ +import { service } from "./share/request" + +/** + * 食堂用餐分类统计 + */ +export const classCount = (data) => { + return service({ + url: 'hard/panel-nutrition/class-count', + method: 'post', + data, + }) +} + +/** + * 食堂用餐分类统计 + */ +export const cuisineTop = (data) => { + return service({ + url: 'hard/panel-nutrition/cuisine-top', + method: 'post', + data, + }) +} + +/** + * 营养分析(按照购买时间统计) + */ +export const nutritionByTime = (data) => { + return service({ + url: 'hard/panel-nutrition/nutrition/by-time', + method: 'post', + data, + }) +} + +/** + * 营养分析(总数统计) + */ +export const nutritionTotal = (data) => { + return service({ + url: 'hard/panel-nutrition/nutrition/total', + method: 'post', + data, + }) +} + + +/** + * 营养分析(趋势) + */ +export const nutritionTrend = (data) => { + return service({ + url: 'hard/panel-nutrition/nutrition/trend', + method: 'post', + data, + }) +} + +/** + * 复购排行榜(top5) + */ +export const repurchase = (data) => { + return service({ + url: 'hard/panel-nutrition/repurchase', + method: 'post', + data, + }) +} \ No newline at end of file diff --git a/src/api/share/request.js b/src/api/share/request.js new file mode 100644 index 0000000..7d8a6c7 --- /dev/null +++ b/src/api/share/request.js @@ -0,0 +1,76 @@ +import axios from "axios"; +import Cookies from 'js-cookie'; +import router from '@/router'; + +export const service = axios.create({ + baseURL: import.meta.env.VITE_BASE_API, + // 请求超时时间 + timeout: 20000, + headers: { + "Content-Type": "application/json", + }, + withCredentials: false, +}); + +// 请求拦截 +service.interceptors.request.use( + (config) => { + // get请求映射params参数 + if (config.method === "get" && config.params) { + let url = config.url + "?" + tansParams(config.params); + url = url.slice(0, -1); + config.params = {}; + config.url = url; + } + // 加token + const token = Cookies.get("panel_token") ?? "" + if (token) { + config.headers["Authorization"] = `Bearer ${token}`; + } + return config; + }, + (error) => { + return Promise.reject(error); + } +); + +// 响应拦截 +service.interceptors.response.use( + (res) => { + + return res.data; + }, + (error) => { + console.log(error); + // 登录失效 + if (error.status == 424) { + // 清除token + // Cookies.remove("panel_token") + // Cookies.remove("panel_refresh_token") + // router.replace("/no-permission") + } + return Promise.reject(error); + } +); + +function tansParams(params) { + let result = ""; + for (const propName of Object.keys(params)) { + const value = params[propName]; + var part = encodeURIComponent(propName) + "="; + if (value !== null && value !== "" && typeof value !== "undefined") { + if (typeof value === "object") { + for (const key of Object.keys(value)) { + if (value[key] !== null && value[key] !== "" && typeof value[key] !== "undefined") { + let params = propName + "[" + key + "]"; + var subPart = encodeURIComponent(params) + "="; + result += subPart + encodeURIComponent(value[key]) + "&"; + } + } + } else { + result += part + encodeURIComponent(value) + "&"; + } + } + } + return result; +} diff --git a/src/api/shop.js b/src/api/shop.js new file mode 100644 index 0000000..1b03e91 --- /dev/null +++ b/src/api/shop.js @@ -0,0 +1,67 @@ +import { service } from "./share/request" + +/** + * 各个超市的购买数量统计 + */ +export const mchPayPersonCount = (data) => { + return service({ + url: 'hard/panel-shop/mch-pay-count', + method: 'post', + data, + }) +} + +/** + * 各个自营超市的统计数据 + */ +export const mchPayCountTrend = (data) => { + return service({ + url: 'hard/panel-shop/mch-pay-count-trend', + method: 'post', + data, + }) +} + +/** + * 超市报表 + */ +export const canteenReport = (data) => { + return service({ + url: 'hard/panel-shop/report', + method: 'post', + data, + }) +} + +/** + * 最新的超市购买数据 + */ +export const newPage = (data) => { + return service({ + url: 'hard/panel-shop/new-page', + method: 'post', + data, + }) +} + +/** + * 最近的超市购买数据 + */ +export const recentlyShop = (data) => { + return service({ + url: 'hard/panel-shop/recently', + method: 'post', + data, + }) +} + +/** + * 排行榜 + */ +export const mchPayCountTop = (data) => { + return service({ + url: 'hard/panel-shop/mch-pay-count-top', + method: 'post', + data, + }) +} \ No newline at end of file diff --git a/src/api/user.js b/src/api/user.js new file mode 100644 index 0000000..e03e6b7 --- /dev/null +++ b/src/api/user.js @@ -0,0 +1,45 @@ +import { service } from "./share/request" + +/** + * 获取个人信息 + */ +export const getUserInfo = (params) => { + return service({ + url: '/admin/user/info', + method: 'get', + params, + }) +} + +/** + * 刷新token + */ +export const refreshToken = (refresh_token) => { + const basicAuth = 'Basic ' + window.btoa('pig:pig'); + const grant_type = 'refresh_token'; + const scope = 'server'; + return service({ + url: '/auth/oauth2/token', + method: 'post', + headers: { + skipToken: true, + Authorization: basicAuth, + 'Content-Type': "application/x-www-form-urlencoded", + }, + params: { refresh_token, grant_type, scope }, + }) +} + +export const checkToken = (token) => { + const basicAuth = 'Basic ' + window.btoa('pig:pig'); + return service({ + url: '/auth/token/check_token', + method: 'get', + headers: { + skipToken: true, + Authorization: basicAuth, + 'Content-Type': 'application/x-www-form-urlencoded', + }, + params: { token }, + }) +} \ No newline at end of file diff --git a/src/app-panel.vue b/src/app-panel.vue new file mode 100644 index 0000000..8f66360 --- /dev/null +++ b/src/app-panel.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/src/assets/images/barrier-gate-percent.png b/src/assets/images/barrier-gate-percent.png new file mode 100644 index 0000000..c468fdc Binary files /dev/null and b/src/assets/images/barrier-gate-percent.png differ diff --git a/src/assets/images/barrier-gate.png b/src/assets/images/barrier-gate.png new file mode 100644 index 0000000..9469abe Binary files /dev/null and b/src/assets/images/barrier-gate.png differ diff --git a/src/assets/images/be-late-bg.png b/src/assets/images/be-late-bg.png new file mode 100644 index 0000000..601e939 Binary files /dev/null and b/src/assets/images/be-late-bg.png differ diff --git a/src/assets/images/bg-image.png b/src/assets/images/bg-image.png new file mode 100644 index 0000000..ba38308 Binary files /dev/null and b/src/assets/images/bg-image.png differ diff --git a/src/assets/images/box-title.png b/src/assets/images/box-title.png new file mode 100644 index 0000000..d9cf6f7 Binary files /dev/null and b/src/assets/images/box-title.png differ diff --git a/src/assets/images/car-alarm-list-item-bg.png b/src/assets/images/car-alarm-list-item-bg.png new file mode 100644 index 0000000..6c0eec0 Binary files /dev/null and b/src/assets/images/car-alarm-list-item-bg.png differ diff --git a/src/assets/images/car-alarm-type-blue.png b/src/assets/images/car-alarm-type-blue.png new file mode 100644 index 0000000..bf5f012 Binary files /dev/null and b/src/assets/images/car-alarm-type-blue.png differ diff --git a/src/assets/images/car-alarm-type-green.png b/src/assets/images/car-alarm-type-green.png new file mode 100644 index 0000000..05db51c Binary files /dev/null and b/src/assets/images/car-alarm-type-green.png differ diff --git a/src/assets/images/car-count-in-bg.png b/src/assets/images/car-count-in-bg.png new file mode 100644 index 0000000..5f4f517 Binary files /dev/null and b/src/assets/images/car-count-in-bg.png differ diff --git a/src/assets/images/car-count-not-in-bg.png b/src/assets/images/car-count-not-in-bg.png new file mode 100644 index 0000000..6b37987 Binary files /dev/null and b/src/assets/images/car-count-not-in-bg.png differ diff --git a/src/assets/images/car-out-statue-item-bg.png b/src/assets/images/car-out-statue-item-bg.png new file mode 100644 index 0000000..f126a18 Binary files /dev/null and b/src/assets/images/car-out-statue-item-bg.png differ diff --git a/src/assets/images/car-status-info-bg.png b/src/assets/images/car-status-info-bg.png new file mode 100644 index 0000000..770474a Binary files /dev/null and b/src/assets/images/car-status-info-bg.png differ diff --git a/src/assets/images/car-status.png b/src/assets/images/car-status.png new file mode 100644 index 0000000..e90e208 Binary files /dev/null and b/src/assets/images/car-status.png differ diff --git a/src/assets/images/date-dimension-tab-select.png b/src/assets/images/date-dimension-tab-select.png new file mode 100644 index 0000000..ef45ada Binary files /dev/null and b/src/assets/images/date-dimension-tab-select.png differ diff --git a/src/assets/images/date-dimension-tab.png b/src/assets/images/date-dimension-tab.png new file mode 100644 index 0000000..e14a596 Binary files /dev/null and b/src/assets/images/date-dimension-tab.png differ diff --git a/src/assets/images/device-alarm-list-index-bg.png b/src/assets/images/device-alarm-list-index-bg.png new file mode 100644 index 0000000..9efbc4e Binary files /dev/null and b/src/assets/images/device-alarm-list-index-bg.png differ diff --git a/src/assets/images/device-alarm-list-total-bg.png b/src/assets/images/device-alarm-list-total-bg.png new file mode 100644 index 0000000..323efe7 Binary files /dev/null and b/src/assets/images/device-alarm-list-total-bg.png differ diff --git a/src/assets/images/device-status-bg.png b/src/assets/images/device-status-bg.png new file mode 100644 index 0000000..a36b77b Binary files /dev/null and b/src/assets/images/device-status-bg.png differ diff --git a/src/assets/images/entrance-guard-percent.png b/src/assets/images/entrance-guard-percent.png new file mode 100644 index 0000000..82db3d4 Binary files /dev/null and b/src/assets/images/entrance-guard-percent.png differ diff --git a/src/assets/images/entrance-guard.png b/src/assets/images/entrance-guard.png new file mode 100644 index 0000000..0ff3af9 Binary files /dev/null and b/src/assets/images/entrance-guard.png differ diff --git a/src/assets/images/header-bg.png b/src/assets/images/header-bg.png new file mode 100644 index 0000000..660ce05 Binary files /dev/null and b/src/assets/images/header-bg.png differ diff --git a/src/assets/images/leave-early-bg.png b/src/assets/images/leave-early-bg.png new file mode 100644 index 0000000..14a6d3a Binary files /dev/null and b/src/assets/images/leave-early-bg.png differ diff --git a/src/assets/images/monitoring-percent.png b/src/assets/images/monitoring-percent.png new file mode 100644 index 0000000..d4ff236 Binary files /dev/null and b/src/assets/images/monitoring-percent.png differ diff --git a/src/assets/images/monitoring.png b/src/assets/images/monitoring.png new file mode 100644 index 0000000..238a9ba Binary files /dev/null and b/src/assets/images/monitoring.png differ diff --git a/src/assets/images/nav-active-button-bg.png b/src/assets/images/nav-active-button-bg.png new file mode 100644 index 0000000..8e64903 Binary files /dev/null and b/src/assets/images/nav-active-button-bg.png differ diff --git a/src/assets/images/on-job-bg.png b/src/assets/images/on-job-bg.png new file mode 100644 index 0000000..e849564 Binary files /dev/null and b/src/assets/images/on-job-bg.png differ diff --git a/src/assets/images/weather-sunny.png b/src/assets/images/weather-sunny.png new file mode 100644 index 0000000..2084398 Binary files /dev/null and b/src/assets/images/weather-sunny.png differ diff --git a/src/components/abnormal-event-list.vue b/src/components/abnormal-event-list.vue new file mode 100644 index 0000000..3c82eec --- /dev/null +++ b/src/components/abnormal-event-list.vue @@ -0,0 +1,212 @@ + + + + + diff --git a/src/components/abnormal-event-type-status.vue b/src/components/abnormal-event-type-status.vue new file mode 100644 index 0000000..ebe3375 --- /dev/null +++ b/src/components/abnormal-event-type-status.vue @@ -0,0 +1,253 @@ + + + + + diff --git a/src/components/aside-block.vue b/src/components/aside-block.vue new file mode 100644 index 0000000..fb67027 --- /dev/null +++ b/src/components/aside-block.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/components/attendance-statistic/index.vue b/src/components/attendance-statistic/index.vue new file mode 100644 index 0000000..d10029b --- /dev/null +++ b/src/components/attendance-statistic/index.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/src/components/attendance-statistic/month-statistics.vue b/src/components/attendance-statistic/month-statistics.vue new file mode 100644 index 0000000..00ac074 --- /dev/null +++ b/src/components/attendance-statistic/month-statistics.vue @@ -0,0 +1,203 @@ + + + + + diff --git a/src/components/attendance-statistic/week-statistics.vue b/src/components/attendance-statistic/week-statistics.vue new file mode 100644 index 0000000..32d0e31 --- /dev/null +++ b/src/components/attendance-statistic/week-statistics.vue @@ -0,0 +1,205 @@ + + + diff --git a/src/components/attendance-statistic/year-statistics.vue b/src/components/attendance-statistic/year-statistics.vue new file mode 100644 index 0000000..f205515 --- /dev/null +++ b/src/components/attendance-statistic/year-statistics.vue @@ -0,0 +1,187 @@ + + + diff --git a/src/components/attendance-statistic/yesterday-statistics.vue b/src/components/attendance-statistic/yesterday-statistics.vue new file mode 100644 index 0000000..038161e --- /dev/null +++ b/src/components/attendance-statistic/yesterday-statistics.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/src/components/canteen-report.vue b/src/components/canteen-report.vue new file mode 100644 index 0000000..11c72e0 --- /dev/null +++ b/src/components/canteen-report.vue @@ -0,0 +1,136 @@ + + + + + \ No newline at end of file diff --git a/src/components/car-abnormal-through-line-chart.vue b/src/components/car-abnormal-through-line-chart.vue new file mode 100644 index 0000000..69367c4 --- /dev/null +++ b/src/components/car-abnormal-through-line-chart.vue @@ -0,0 +1,240 @@ + + + diff --git a/src/components/car-go-out-status.vue b/src/components/car-go-out-status.vue new file mode 100644 index 0000000..af5c5c3 --- /dev/null +++ b/src/components/car-go-out-status.vue @@ -0,0 +1,191 @@ + + + + + diff --git a/src/components/car-out-quantity.vue b/src/components/car-out-quantity.vue new file mode 100644 index 0000000..a09c8b0 --- /dev/null +++ b/src/components/car-out-quantity.vue @@ -0,0 +1,213 @@ + + + + + diff --git a/src/components/car-status.vue b/src/components/car-status.vue new file mode 100644 index 0000000..8057984 --- /dev/null +++ b/src/components/car-status.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/src/components/device-alarm-line-chart.vue b/src/components/device-alarm-line-chart.vue new file mode 100644 index 0000000..c52bb32 --- /dev/null +++ b/src/components/device-alarm-line-chart.vue @@ -0,0 +1,168 @@ + + + diff --git a/src/components/device-alarm-list.vue b/src/components/device-alarm-list.vue new file mode 100644 index 0000000..84b65b9 --- /dev/null +++ b/src/components/device-alarm-list.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/src/components/device-monitored-area-status.vue b/src/components/device-monitored-area-status.vue new file mode 100644 index 0000000..9071ac3 --- /dev/null +++ b/src/components/device-monitored-area-status.vue @@ -0,0 +1,197 @@ + + + + + diff --git a/src/components/device-monitoring-quantity.vue b/src/components/device-monitoring-quantity.vue new file mode 100644 index 0000000..737b050 --- /dev/null +++ b/src/components/device-monitoring-quantity.vue @@ -0,0 +1,139 @@ + + + diff --git a/src/components/device-online-line-chart.vue b/src/components/device-online-line-chart.vue new file mode 100644 index 0000000..b5dd765 --- /dev/null +++ b/src/components/device-online-line-chart.vue @@ -0,0 +1,170 @@ + + + diff --git a/src/components/device-status.vue b/src/components/device-status.vue new file mode 100644 index 0000000..6695a75 --- /dev/null +++ b/src/components/device-status.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/src/components/device-video.vue b/src/components/device-video.vue new file mode 100644 index 0000000..593e5c6 --- /dev/null +++ b/src/components/device-video.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/src/components/notification/index.js b/src/components/notification/index.js new file mode 100644 index 0000000..a1c5a33 --- /dev/null +++ b/src/components/notification/index.js @@ -0,0 +1,21 @@ +import { h, render } from "vue"; +import NotificationProvider from "./notificationProvider.vue"; + +let vnode; +const useNotification = () => { + if (!vnode) { + const container = document.createElement("div"); + document.body.appendChild(container); + vnode = h(NotificationProvider, {}); + render(vnode, container); + } + + const { add: notificationAdd, remove: notificationRemove, clear: notificationClear } = (vnode.component && vnode.component.exposed) || {}; + return { + notificationAdd, + notificationRemove, + notificationClear, + }; +}; + +export default useNotification; diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue new file mode 100644 index 0000000..9b0911d --- /dev/null +++ b/src/components/notification/notification.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/src/components/notification/notificationProvider.vue b/src/components/notification/notificationProvider.vue new file mode 100644 index 0000000..5d88350 --- /dev/null +++ b/src/components/notification/notificationProvider.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/notification/useList.js b/src/components/notification/useList.js new file mode 100644 index 0000000..3029c05 --- /dev/null +++ b/src/components/notification/useList.js @@ -0,0 +1,23 @@ +import { ref } from "vue"; + +let count = 0; + +const useList = () => { + const notificationList = ref([]); + + const add = (optionProps) => { + notificationList.value.push({ id: count++, ...optionProps }); + }; + + const remove = (id) => { + notificationList.value = notificationList.value.filter((item) => item.id !== id); + }; + + const clear = () => { + notificationList.value = []; + } + + return { notificationList, add, remove, clear }; +}; + +export default useList; diff --git a/src/components/nutrition-analyse/index.vue b/src/components/nutrition-analyse/index.vue new file mode 100644 index 0000000..a3124d1 --- /dev/null +++ b/src/components/nutrition-analyse/index.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/components/nutrition-analyse/month-statistics.vue b/src/components/nutrition-analyse/month-statistics.vue new file mode 100644 index 0000000..486f6a4 --- /dev/null +++ b/src/components/nutrition-analyse/month-statistics.vue @@ -0,0 +1,241 @@ + + + + + diff --git a/src/components/nutrition-analyse/week-statistics.vue b/src/components/nutrition-analyse/week-statistics.vue new file mode 100644 index 0000000..834bb8e --- /dev/null +++ b/src/components/nutrition-analyse/week-statistics.vue @@ -0,0 +1,208 @@ + + + diff --git a/src/components/nutrition-analyse/year-statistics.vue b/src/components/nutrition-analyse/year-statistics.vue new file mode 100644 index 0000000..6710940 --- /dev/null +++ b/src/components/nutrition-analyse/year-statistics.vue @@ -0,0 +1,208 @@ + + + diff --git a/src/components/nutrition-analyse/yesterday-statistics.vue b/src/components/nutrition-analyse/yesterday-statistics.vue new file mode 100644 index 0000000..b09ac9d --- /dev/null +++ b/src/components/nutrition-analyse/yesterday-statistics.vue @@ -0,0 +1,173 @@ + + + + + \ No newline at end of file diff --git a/src/components/nutrition-report.vue b/src/components/nutrition-report.vue new file mode 100644 index 0000000..11c72e0 --- /dev/null +++ b/src/components/nutrition-report.vue @@ -0,0 +1,136 @@ + + + + + \ No newline at end of file diff --git a/src/components/nutrition-top.vue b/src/components/nutrition-top.vue new file mode 100644 index 0000000..e3a5a88 --- /dev/null +++ b/src/components/nutrition-top.vue @@ -0,0 +1,185 @@ + + + + + \ No newline at end of file diff --git a/src/components/person-abnormal-event-line-chart.vue b/src/components/person-abnormal-event-line-chart.vue new file mode 100644 index 0000000..3379f2f --- /dev/null +++ b/src/components/person-abnormal-event-line-chart.vue @@ -0,0 +1,333 @@ + + + diff --git a/src/components/person-through-rank.vue b/src/components/person-through-rank.vue new file mode 100644 index 0000000..de68594 --- /dev/null +++ b/src/components/person-through-rank.vue @@ -0,0 +1,129 @@ + + + diff --git a/src/components/person-today-clock-status.vue b/src/components/person-today-clock-status.vue new file mode 100644 index 0000000..4de7705 --- /dev/null +++ b/src/components/person-today-clock-status.vue @@ -0,0 +1,235 @@ + + + diff --git a/src/components/shop-report.vue b/src/components/shop-report.vue new file mode 100644 index 0000000..2916d2d --- /dev/null +++ b/src/components/shop-report.vue @@ -0,0 +1,136 @@ + + + + + \ No newline at end of file diff --git a/src/constant/table-constant.js b/src/constant/table-constant.js new file mode 100644 index 0000000..af43b24 --- /dev/null +++ b/src/constant/table-constant.js @@ -0,0 +1,19 @@ +export const TABLE = { + SIZE: "small", + STYLE: { + width: "100%", + height: "100%", + }, + CELL_STYLE: { + background: "#1d283477", + borderColor: "#121F33", + }, + ROW_STYLE: { + background: "#1d283477", + borderColor: "#121F33", + }, + HEADER_CELL_STYLE: { + background: "#1d283477", + borderColor: "#121F33", + } +} \ No newline at end of file diff --git a/src/global.less b/src/global.less new file mode 100644 index 0000000..6017443 --- /dev/null +++ b/src/global.less @@ -0,0 +1,30 @@ +@background-color: #222222; +@text-color: #ffffff; +@text-color-primary: #419ce3; + +:root { + ::selection { + background: #45b2fe; + } + ::-moz-selection { + background: #45b2fe; + } +} + +body, +html { + width: 100vw; + height: 100vh; + margin: 0; + padding: 0; + + background-color: @background-color; + color: @text-color; +} + +.background(@url: "", @size: auto auto, @position: 0% 0%, @repeat: no-repeat) { + background-image: url(@url); + background-size: @size; + background-position: @position; + background-repeat: @repeat; +} diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..8881b7e --- /dev/null +++ b/src/main.js @@ -0,0 +1,15 @@ +import { createApp } from "vue"; +import ElementPlus from "element-plus"; +import "element-plus/dist/index.css"; +import "element-plus/theme-chalk/dark/css-vars.css"; +import "./global.less"; +import zhCn from "element-plus/es/locale/lang/zh-cn"; + +import App from "./App.vue"; +import router from "./router"; + +const app = createApp(App); + +app.use(ElementPlus, { locale: zhCn }); +app.use(router); +app.mount("#app"); diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..600a5b0 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,73 @@ +import { createWebHashHistory } from "vue-router"; +import { createRouter } from "vue-router"; +import Cookies from 'js-cookie'; + +import { getUserInfo, checkToken } from "@/utils/auth" + +const routes = [ + { + path: "/", + redirect: "/canteen", + component: () => import("@/app-panel.vue"), + children: [ + { + path: "/canteen", + name: "canteen", + component: () => import("@/views/canteen.vue"), + }, + { + path: "/shop", + name: "shop", + component: () => import("@/views/shop.vue"), + }, + { + path: "/service", + name: "service", + component: () => import("@/views/service.vue"), + }, + { + path: "/through", + name: "through", + component: () => import("@/views/through.vue"), + }, + { + path: "/nutrition", + name: "nutrition", + component: () => import("@/views/nutrition.vue"), + }, + ], + }, + { + path: "/no-permission", + name: "noPermission", + component: () => import("@/views/auth-unknown.vue"), + }, +]; + +const router = createRouter({ + history: createWebHashHistory(import.meta.env.BASE_URL), + routes, + // 路由切换时滚动到顶部 + scrollBehavior(to, from, savedPosition) { + if (savedPosition) { + return savedPosition; + } else { + return { top: 0 }; + } + }, +}); + +router.beforeEach(async (to, from, next) => { + const { query } = to + // 处理URL中的token参数 + if (query.token && query.refresh_token) { + Cookies.set("panel_token", query.token) + Cookies.set("panel_refresh_token", query.refresh_token) + await getUserInfo() + await checkToken() + next() + } + next() +}) + +export default router; diff --git a/src/utils/auth.js b/src/utils/auth.js new file mode 100644 index 0000000..e44857c --- /dev/null +++ b/src/utils/auth.js @@ -0,0 +1,38 @@ +import Cookies from 'js-cookie'; + +import { userApi } from "@/api/index" + +// 获取用户信息 +export async function getUserInfo() { + try { + const { code, data } = await userApi.getUserInfo() + if (code != 0) throw new Error("code!=0") + console.log("获取用户信息", data); + window.localStorage.setItem("panel_user_info", JSON.stringify(data)) + } catch (error) { + console.log("获取用户信息:", error); + } +} + +// 检查用户token +export async function checkToken() { + try { + const token = Cookies.get("panel_token") ?? "" + const refresh_token = Cookies.get("panel_refresh_token") ?? ""; + if (!token || !refresh_token) return + // 检查token + const { code: checkCode, data: checkData } = await userApi.checkToken(token) + if (checkCode != 0) throw new Error("checkCode!=0") + const expire = Date.parse(checkData.expiresAt); + if (!expire) throw new Error("时间解析错误") + const expiredPeriod = expire - new Date().getTime(); + if (expiredPeriod <= 30 * 60 * 1000) { + const res = await userApi.refreshToken(refresh_token) + if (!res) throw new Error("refreshCode!=0") + Cookies.set('panel_token', res.access_token); + Cookies.set('panel_refresh_token', res.refresh_token); + } + } catch (error) { + console.error("检查用户token:", error); + } +} \ No newline at end of file diff --git a/src/utils/date.js b/src/utils/date.js new file mode 100644 index 0000000..6ec0fad --- /dev/null +++ b/src/utils/date.js @@ -0,0 +1,107 @@ +/** + * 获取当前日期 + * @returns {string} 获取当前日期,如 '2024/1/15' + */ +export const getDate = () => { + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, "0"); + const day = String(now.getDate()).padStart(2, "0"); + return `${year}/${month}/${day}`; +}; +/** + * 获取当前时间 + * @returns {string} 获取当前日期,如 '00:00:00' + */ +export const getTime = () => { + const now = new Date(); + const hours = String(now.getHours()).padStart(2, "0"); + const minutes = String(now.getMinutes()).padStart(2, "0"); + const seconds = String(now.getSeconds()).padStart(2, "0"); + return `${hours}:${minutes}:${seconds}`; +}; +/** + * 获取最近8天的周 + * @returns {Array} 获取最近8天的周 + */ +export function getRecentWeeks() { + const weekArr = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]; + + const result = []; + const today = new Date(); + for (let i = 7; i >= 0; i--) { + const d = new Date(today); + d.setDate(today.getDate() - i); + result.push(weekArr[d.getDay()]); + } + return result; +} +/** + * 获取最近的前8天日期(包括今天) + * @param {number} days - 要获取的天数,默认为8 + * @returns {string[]} - 格式为 'MM-DD' 的日期数组 + */ +export function getRecentDays(days = 8) { + const today = new Date(); + const dates = []; + + for (let i = days - 1; i >= 0; i--) { + const date = new Date(today); + date.setDate(today.getDate() - i); + // 修改日期格式为MM-DD + const formattedDate = date.toISOString().split("T")[0].split("-").slice(1).join("-"); + dates.push(formattedDate); + } + + return dates; +} + +/** + * 获取最近的前12个月日期(包含当月) + * @param {number} months - 要获取的月数,默认为12 + * @returns {string[]} - 格式为 'YYYY-MM' 的日期数组 + */ +export function getRecentMonths(months = 12) { + const today = new Date(); + const dates = []; + + for (let i = months - 1; i >= 0; i--) { + const date = new Date(today); + date.setMonth(today.getMonth() - i); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始 + const formattedDate = `${year}-${month}`; + dates.push(formattedDate); + } + + return dates; +} + +/** + * 获取当前月份的所有日期 + * @returns {string[]} - 格式为 'DD' 的当前月份全部日期数组 + */ +export function getMonthDays() { + const today = new Date(); + const year = today.getFullYear(); + const month = today.getMonth(); + + // 获取当月第一天 + const firstDay = new Date(year, month, 1); + // 获取当月最后一天 + const lastDay = new Date(year, month + 1, 0); + + const dates = []; + let currentDate = firstDay; + + while (currentDate <= lastDay) { + // const formattedDate = `${year}-${String(month + 1).padStart(2, "0")}-${String(currentDate.getDate()).padStart(2, "0")}`; + const formattedDate = `${String(currentDate.getDate()).padStart(2, "0")}`; + dates.push(formattedDate); + + // 下一天 + currentDate = new Date(year, month, currentDate.getDate() + 1); + } + + return dates; +} diff --git a/src/utils/dateRange.js b/src/utils/dateRange.js new file mode 100644 index 0000000..b900d6c --- /dev/null +++ b/src/utils/dateRange.js @@ -0,0 +1,95 @@ +/** + * 日期范围类型枚举 + * @typedef {'YESTERDAY' | 'TODAY' | 'THIS_WEEK' | 'THIS_MONTH' | 'CURRENT_SEASON' | 'HALF_YEAR' | 'THIS_YEAR'} DateRangeTypeEnum + */ + +import dayjs from 'dayjs'; +import quarterOfYear from 'dayjs/plugin/quarterOfYear'; +import isoWeek from 'dayjs/plugin/isoWeek'; + +// 注册插件 +dayjs.extend(quarterOfYear); +dayjs.extend(isoWeek); + +/** + * 日期工具类 - 转换日期类型为日期范围 + */ +export const DateTool = { + /** + * 将日期类型转换为日期数组 + * @param {DateRangeTypeEnum} dateType - 日期类型枚举 + * @returns {Array} - 日期数组 [开始日期, 结束日期],格式为 YYYY-MM-DD + */ + transitionDateTypeToDateList(dateType) { + const localDateTimes = this.transitionDateTypeToDateTimeList(dateType); + return [ + localDateTimes[0].format('YYYY-MM-DD'), + localDateTimes[1].format('YYYY-MM-DD') + ]; + }, + + /** + * 将日期类型转换为日期时间数组 + * @param {DateRangeTypeEnum} dateType - 日期类型枚举 + * @returns {Array} - 日期时间数组 [开始日期时间, 结束日期时间] + */ + transitionDateTypeToDateTimeList(dateType) { + const now = dayjs(); + + switch (dateType) { + case 'YESTERDAY': + return [ + dayjs().subtract(1, 'day').startOf('day'), + dayjs().subtract(1, 'day').endOf('day') + ]; + case 'TODAY': + return [ + dayjs().startOf('day'), + dayjs().endOf('day') + ]; + case 'THIS_WEEK': + return [ + dayjs().subtract(7, 'day').startOf('day'), + dayjs().endOf('day') + ]; + case 'THIS_MONTH': + return [ + dayjs().startOf('month'), + dayjs().endOf('month') + ]; + case 'CURRENT_SEASON': + return [ + dayjs().startOf('quarter'), + dayjs().endOf('quarter') + ]; + case 'HALF_YEAR': + // 半年期间(从当前季度开始的6个月) + const halfYearStart = dayjs().startOf('quarter'); + return [ + halfYearStart, + halfYearStart.add(5, 'month').endOf('month') + ]; + case 'THIS_YEAR': + return [ + dayjs().startOf('year'), + dayjs().endOf('year') + ]; + default: + return [null, null]; + } + }, + + /** + * 将日期类型转换为格式化的日期时间数组 + * @param {DateRangeTypeEnum} dateType - 日期类型枚举 + * @param {string} format - 日期格式,默认为 'YYYY-MM-DD HH:mm:ss' + * @returns {Array} - 格式化的日期时间数组 [开始日期时间, 结束日期时间] + */ + getFormattedDateTimeRange(dateType, format = 'YYYY-MM-DD HH:mm:ss') { + const dateTimeRange = this.transitionDateTypeToDateTimeList(dateType); + return [ + dateTimeRange[0]?.format(format) || '', + dateTimeRange[1]?.format(format) || '' + ]; + } +}; diff --git a/src/utils/format-money.js b/src/utils/format-money.js new file mode 100644 index 0000000..6ce87a0 --- /dev/null +++ b/src/utils/format-money.js @@ -0,0 +1,8 @@ +/** + * 显示价格把分转换到元 + */ +export function displayPrice(price, suffix = "元", fixed = 2) { + if (typeof price === "undefined") return "0.00" + suffix + const parsedNumber = typeof price === "string" ? parseFloat(price) : price + return (parsedNumber / 100.0).toFixed(fixed) + suffix +} diff --git a/src/utils/poll.js b/src/utils/poll.js new file mode 100644 index 0000000..7bd4d11 --- /dev/null +++ b/src/utils/poll.js @@ -0,0 +1,236 @@ +/** + * 轮询类 - 用于管理定时轮询任务 + */ +class Poll { + /** + * 构造函数 + * @param {Object} options 配置选项 + * @param {Function} options.callback 轮询回调函数 + * @param {number} options.interval 轮询间隔时间(毫秒),默认1000ms + * @param {boolean} options.immediate 是否立即执行一次,默认true + * @param {number} options.maxRetries 最大重试次数,默认3次 + * @param {Function} options.onError 错误处理回调 + */ + constructor(options = {}) { + this.callback = options.callback || (() => { }); + this.interval = options.interval || 1000 + Math.random() * 1000; + this.immediate = options.immediate || true; + this.maxRetries = options.maxRetries || 3; + this.onError = options.onError || ((error) => console.error("轮询错误:", error)); + + // 内部状态 + this.timerId = null; + this.isRunning = false; + this.isPaused = false; + this.retryCount = 0; + this.executionCount = 0; + + // 绑定this上下文 + this._execute = this._execute.bind(this); + } + + /** + * 初始化轮询配置 + * @param {Function} callback 轮询回调函数 + * @param {number} interval 轮询间隔时间(毫秒) + * @param {Object} options 其他配置选项 + */ + init(callback, interval, options = {}) { + // 如果正在运行,先停止 + if (this.isRunning) { + this.stop(); + } + this.callback = callback || this.callback; + this.interval = interval || this.interval; + this.immediate = options.immediate !== undefined ? options.immediate : this.immediate; + this.maxRetries = options.maxRetries !== undefined ? options.maxRetries : this.maxRetries; + this.onError = options.onError || this.onError; + // 重置状态 + this.retryCount = 0; + this.executionCount = 0; + return this; + } + + // 开始轮询 + start() { + if (this.isRunning) { + return this; + } + if (!this.callback || typeof this.callback !== "function") { + throw new Error("轮询回调函数未定义或不是函数"); + } + this.isRunning = true; + this.isPaused = false; + // 如果设置了立即执行,先执行一次 + if (this.immediate) { + this._execute(); + } else { + this._scheduleNext(); + } + return this; + } + + // 暂停轮询 + pause() { + if (!this.isRunning) { + return this; + } + + this.isPaused = true; + this._clearTimer(); + return this; + } + + // 恢复轮询 + resume() { + if (!this.isRunning) { + return this; + } + + if (!this.isPaused) { + return this; + } + + this.isPaused = false; + this._scheduleNext(); + return this; + } + + // 停止轮询 + stop() { + if (!this.isRunning) { + return this; + } + + this.isRunning = false; + this.isPaused = false; + this._clearTimer(); + return this; + } + + // 销毁轮询实例 + destroy() { + this.stop(); + this.callback = null; + this.onError = null; + this.retryCount = 0; + this.executionCount = 0; + } + + // 立即执行一次轮询(不影响定时器) + executeOnce() { + if (typeof this.callback === "function") { + this._execute(false); // false表示不调度下一次 + } + return this; + } + + /** + * 更新轮询间隔 + * @param {number} newInterval 新的间隔时间(毫秒) + */ + updateInterval(newInterval) { + if (typeof newInterval !== "number" || newInterval <= 0) { + throw new Error("间隔时间必须是正数"); + } + + this.interval = newInterval; + + // 如果正在运行且未暂停,重新调度 + if (this.isRunning && !this.isPaused) { + this._clearTimer(); + this._scheduleNext(); + } + return this; + } + + // 获取轮询状态 + getStatus() { + return { + isRunning: this.isRunning, + isPaused: this.isPaused, + interval: this.interval, + executionCount: this.executionCount, + retryCount: this.retryCount, + }; + } + + /** + * 内部方法:执行轮询回调 + * @param {boolean} scheduleNext 是否调度下一次执行 + */ + async _execute(scheduleNext = true) { + if (!this.isRunning || this.isPaused) { + return; + } + + try { + this.executionCount++; + + // 执行回调函数 + await this.callback(); + + // 重置重试计数 + this.retryCount = 0; + + // 调度下一次执行 + if (scheduleNext && this.isRunning && !this.isPaused) { + this._scheduleNext(); + } + } catch (error) { + this.retryCount++; + console.error(`轮询执行失败 (第${this.retryCount}次重试):`, error); + + // 调用错误处理回调 + if (typeof this.onError === "function") { + try { + await this.onError(error, this.retryCount, this.executionCount); + } catch (errorHandlerError) { + console.error("错误处理回调执行失败:", errorHandlerError); + } + } + + // 检查是否需要重试 + if (this.retryCount < this.maxRetries) { + if (scheduleNext && this.isRunning && !this.isPaused) { + this._scheduleNext(); + } + } else { + console.error(`达到最大重试次数 (${this.maxRetries}),停止轮询`); + this.stop(); + } + } + } + + // 内部方法:调度下一次执行 + _scheduleNext() { + this._clearTimer(); + this.timerId = setTimeout(this._execute, this.interval); + } + + // 内部方法:清除定时器 + _clearTimer() { + if (this.timerId) { + clearTimeout(this.timerId); + this.timerId = null; + } + } +} + +export default Poll; + +// 也可以导出一个工厂函数,方便快速创建轮询实例 +export function createPoll(callback, interval, options = {}) { + return new Poll({ + callback, + interval, + ...options, + }); +} + +// 导出一个简化的轮询函数,用于简单场景 +export function simplePoll(callback, interval = 1000) { + const poll = new Poll({ callback, interval }); + poll.start(); + return poll; +} diff --git a/src/views/auth-unknown.vue b/src/views/auth-unknown.vue new file mode 100644 index 0000000..653b664 --- /dev/null +++ b/src/views/auth-unknown.vue @@ -0,0 +1,79 @@ + + + + + \ No newline at end of file diff --git a/src/views/canteen.vue b/src/views/canteen.vue new file mode 100644 index 0000000..7dbc828 --- /dev/null +++ b/src/views/canteen.vue @@ -0,0 +1,495 @@ + + + + + diff --git a/src/views/nutrition.vue b/src/views/nutrition.vue new file mode 100644 index 0000000..5a61194 --- /dev/null +++ b/src/views/nutrition.vue @@ -0,0 +1,372 @@ + + + + + \ No newline at end of file diff --git a/src/views/service.vue b/src/views/service.vue new file mode 100644 index 0000000..80bf60a --- /dev/null +++ b/src/views/service.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/src/views/shop.vue b/src/views/shop.vue new file mode 100644 index 0000000..b946d96 --- /dev/null +++ b/src/views/shop.vue @@ -0,0 +1,384 @@ + + + + + diff --git a/src/views/through.vue b/src/views/through.vue new file mode 100644 index 0000000..517d36f --- /dev/null +++ b/src/views/through.vue @@ -0,0 +1,375 @@ + + + + + diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..86ae2e3 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,34 @@ +import { fileURLToPath, URL } from "node:url"; +import { loadEnv, defineConfig } from "vite"; +import vue from "@vitejs/plugin-vue"; + +// https://vite.dev/config/ +export default defineConfig((mode) => { + const env = loadEnv(mode.mode, process.cwd()); + + return { + plugins: [vue()], + resolve: { + alias: { + "@": fileURLToPath(new URL("./src", import.meta.url)), + }, + }, + server: { + proxy: { + [env.VITE_BASE_API]: { + target: env.VITE_PROXY_PATH, + ws: false, + changeOrigin: true, + rewrite: (path) => path.replace(new RegExp("^" + env.VITE_BASE_API), ""), + }, + }, + }, + css: { + preprocessorOptions: { + less: { + additionalData: '@import "@/global.less";', + }, + }, + }, + }; +});