Compare commits
3 Commits
93c9c3185a
...
5b8bc70e72
| Author | SHA1 | Date |
|---|---|---|
|
|
5b8bc70e72 | |
|
|
2ae413ccb2 | |
|
|
c84da369cf |
2
.env
2
.env
|
|
@ -6,7 +6,7 @@ VITE_TITLE = 绝弹项目管理
|
|||
# 网站副标题
|
||||
VITE_SUBTITLE = 快速开发web应用的模板工具
|
||||
# 接口前缀 说明:参见 axios 的 baseURL
|
||||
VITE_API = /
|
||||
VITE_API = http://127.0.0.1:3030/
|
||||
|
||||
# =====================================================================================
|
||||
# 开发设置
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ jobs:
|
|||
|
||||
- name: 登陆到部署环境执行更新命令
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
if: false
|
||||
with:
|
||||
host: ${{ env.deploy_host }}
|
||||
port: ${{ env.deploy_port }}
|
||||
|
|
|
|||
16
Dockerfile
16
Dockerfile
|
|
@ -1,15 +1,23 @@
|
|||
FROM node:20-alpine as builder
|
||||
|
||||
# 指定工作目录方便下一阶段引用
|
||||
WORKDIR /app
|
||||
COPY package.json .
|
||||
COPY pnpm-lock.yaml .
|
||||
COPY .npmrc .
|
||||
# 启用pnpm功能(v16+)
|
||||
RUN corepack enable
|
||||
RUN pnpm install
|
||||
# 仅复制依赖相关文件
|
||||
COPY .npmrc package.json pnpm-lock.yaml .
|
||||
# 安装依赖,利用docker的缓存机制
|
||||
RUN --mount=type=cache,id=pnpm-store,target=/root/.pnpm-store pnpm install --frozen-lockfile
|
||||
# 复制其他文件
|
||||
COPY . .
|
||||
# 进行打包
|
||||
RUN pnpm build
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
# 复制产物
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
# 复制nginx配置
|
||||
COPY --from=builder /app/.github/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
EXPOSE 80
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
"release": "release-it --config ./scripts/release/index.cjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@apidevtools/swagger-parser": "^10.1.0",
|
||||
"@arco-design/web-vue": "^2.51.1",
|
||||
"@iconify-json/icon-park-outline": "^1.1.12",
|
||||
"@release-it/conventional-changelog": "^5.1.1",
|
||||
|
|
@ -34,19 +33,17 @@
|
|||
"pinia-plugin-persistedstate": "^3.2.0",
|
||||
"plop": "^3.1.2",
|
||||
"release-it": "^15.11.0",
|
||||
"rollup-plugin-visualizer": "^5.9.2",
|
||||
"swagger-typescript-api": "^12.0.4",
|
||||
"tsx": "^3.12.9",
|
||||
"typescript": "^4.9.5",
|
||||
"unocss": "^0.49.8",
|
||||
"unplugin-auto-import": "^0.13.0",
|
||||
"unplugin-vue-components": "^0.23.0",
|
||||
"unplugin-vue-router": "^0.7.0",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-mock": "^3.0.0",
|
||||
"vite-plugin-pages": "^0.28.0",
|
||||
"vite-plugin-style-import": "^2.0.0",
|
||||
"vue": "^3.3.4",
|
||||
"vue-drag-resize": "^2.0.3",
|
||||
"vue-router": "^4.2.4",
|
||||
"vue-tsc": "^1.8.11"
|
||||
}
|
||||
|
|
|
|||
384
pnpm-lock.yaml
384
pnpm-lock.yaml
|
|
@ -1,9 +1,6 @@
|
|||
lockfileVersion: '6.0'
|
||||
|
||||
devDependencies:
|
||||
'@apidevtools/swagger-parser':
|
||||
specifier: ^10.1.0
|
||||
version: 10.1.0
|
||||
'@arco-design/web-vue':
|
||||
specifier: ^2.51.1
|
||||
version: 2.51.1(vue@3.3.4)
|
||||
|
|
@ -67,6 +64,9 @@ devDependencies:
|
|||
release-it:
|
||||
specifier: ^15.11.0
|
||||
version: 15.11.0
|
||||
rollup-plugin-visualizer:
|
||||
specifier: ^5.9.2
|
||||
version: 5.9.2
|
||||
swagger-typescript-api:
|
||||
specifier: ^12.0.4
|
||||
version: 12.0.4
|
||||
|
|
@ -85,15 +85,9 @@ devDependencies:
|
|||
unplugin-vue-components:
|
||||
specifier: ^0.23.0
|
||||
version: 0.23.0(vue@3.3.4)
|
||||
unplugin-vue-router:
|
||||
specifier: ^0.7.0
|
||||
version: 0.7.0(vue-router@4.2.4)(vue@3.3.4)
|
||||
vite:
|
||||
specifier: ^4.4.9
|
||||
version: 4.4.9(less@4.2.0)
|
||||
vite-plugin-mock:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(vite@4.4.9)
|
||||
vite-plugin-pages:
|
||||
specifier: ^0.28.0
|
||||
version: 0.28.0(vite@4.4.9)
|
||||
|
|
@ -103,9 +97,6 @@ devDependencies:
|
|||
vue:
|
||||
specifier: ^3.3.4
|
||||
version: 3.3.4
|
||||
vue-drag-resize:
|
||||
specifier: ^2.0.3
|
||||
version: 2.0.3
|
||||
vue-router:
|
||||
specifier: ^4.2.4
|
||||
version: 4.2.4(vue@3.3.4)
|
||||
|
|
@ -134,37 +125,6 @@ packages:
|
|||
resolution: {integrity: sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w==}
|
||||
dev: true
|
||||
|
||||
/@apidevtools/json-schema-ref-parser@9.0.6:
|
||||
resolution: {integrity: sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg==}
|
||||
dependencies:
|
||||
'@jsdevtools/ono': 7.1.3
|
||||
call-me-maybe: 1.0.2
|
||||
js-yaml: 3.14.1
|
||||
dev: true
|
||||
|
||||
/@apidevtools/openapi-schemas@2.1.0:
|
||||
resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/@apidevtools/swagger-methods@3.0.2:
|
||||
resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==}
|
||||
dev: true
|
||||
|
||||
/@apidevtools/swagger-parser@10.1.0:
|
||||
resolution: {integrity: sha512-9Kt7EuS/7WbMAUv2gSziqjvxwDbFSg3Xeyfuj5laUODX8o/k/CpsAKiQ8W7/R88eXFTMbJYg6+7uAmOWNKmwnw==}
|
||||
peerDependencies:
|
||||
openapi-types: '>=7'
|
||||
dependencies:
|
||||
'@apidevtools/json-schema-ref-parser': 9.0.6
|
||||
'@apidevtools/openapi-schemas': 2.1.0
|
||||
'@apidevtools/swagger-methods': 3.0.2
|
||||
'@jsdevtools/ono': 7.1.3
|
||||
ajv: 8.12.0
|
||||
ajv-draft-04: 1.0.0(ajv@8.12.0)
|
||||
call-me-maybe: 1.0.2
|
||||
dev: true
|
||||
|
||||
/@arco-design/color@0.4.0:
|
||||
resolution: {integrity: sha512-s7p9MSwJgHeL8DwcATaXvWT3m2SigKpxx4JA1BGPHL4gfvaQsmQfrLBDpjOJFJuJ2jG2dMt3R3P8Pm9E65q18g==}
|
||||
dependencies:
|
||||
|
|
@ -764,10 +724,6 @@ packages:
|
|||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
dev: true
|
||||
|
||||
/@jsdevtools/ono@7.1.3:
|
||||
resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==}
|
||||
dev: true
|
||||
|
||||
/@nodelib/fs.scandir@2.1.5:
|
||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||
engines: {node: '>= 8'}
|
||||
|
|
@ -1023,6 +979,20 @@ packages:
|
|||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/@rollup/pluginutils@5.0.5:
|
||||
resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/estree': 1.0.1
|
||||
estree-walker: 2.0.2
|
||||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/@sindresorhus/is@5.6.0:
|
||||
resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
|
@ -1085,10 +1055,6 @@ packages:
|
|||
resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
|
||||
dev: true
|
||||
|
||||
/@types/mockjs@1.0.7:
|
||||
resolution: {integrity: sha512-OCxXz6hEaJOVpRwuJMiVY5a6LtJcih+br9gwB/Q8ooOBikvk5FpBQ31OlNimXo3EqKha1Z7PFBni+q9m+8NCWg==}
|
||||
dev: true
|
||||
|
||||
/@types/ms@0.7.31:
|
||||
resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
|
||||
dev: true
|
||||
|
|
@ -1140,7 +1106,7 @@ packages:
|
|||
hasBin: true
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.2.1
|
||||
'@rollup/pluginutils': 5.0.4
|
||||
'@rollup/pluginutils': 5.0.5
|
||||
'@unocss/config': 0.49.8
|
||||
'@unocss/core': 0.49.8
|
||||
'@unocss/preset-uno': 0.49.8
|
||||
|
|
@ -1270,7 +1236,7 @@ packages:
|
|||
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.2.1
|
||||
'@rollup/pluginutils': 5.0.4
|
||||
'@rollup/pluginutils': 5.0.5
|
||||
'@unocss/config': 0.49.8
|
||||
'@unocss/core': 0.49.8
|
||||
'@unocss/inspector': 0.49.8
|
||||
|
|
@ -1329,26 +1295,6 @@ packages:
|
|||
'@volar/language-core': 1.10.1
|
||||
dev: true
|
||||
|
||||
/@vue-macros/common@1.8.0(vue@3.3.4):
|
||||
resolution: {integrity: sha512-auDJJzE0z3uRe3867e0DsqcseKImktNf5ojCZgUKqiVxb2yTlwlgOVAYCgoep9oITqxkXQymSvFeKhedi8PhaA==}
|
||||
engines: {node: '>=16.14.0'}
|
||||
peerDependencies:
|
||||
vue: ^2.7.0 || ^3.2.25
|
||||
peerDependenciesMeta:
|
||||
vue:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/types': 7.23.0
|
||||
'@rollup/pluginutils': 5.0.4
|
||||
'@vue/compiler-sfc': 3.3.4
|
||||
ast-kit: 0.11.2
|
||||
local-pkg: 0.4.3
|
||||
magic-string-ast: 0.3.0
|
||||
vue: 3.3.4
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
dev: true
|
||||
|
||||
/@vue/babel-helper-vue-transform-on@1.1.5:
|
||||
resolution: {integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==}
|
||||
dev: true
|
||||
|
|
@ -1561,26 +1507,6 @@ packages:
|
|||
indent-string: 4.0.0
|
||||
dev: true
|
||||
|
||||
/ajv-draft-04@1.0.0(ajv@8.12.0):
|
||||
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
|
||||
peerDependencies:
|
||||
ajv: ^8.5.0
|
||||
peerDependenciesMeta:
|
||||
ajv:
|
||||
optional: true
|
||||
dependencies:
|
||||
ajv: 8.12.0
|
||||
dev: true
|
||||
|
||||
/ajv@8.12.0:
|
||||
resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
json-schema-traverse: 1.0.0
|
||||
require-from-string: 2.0.2
|
||||
uri-js: 4.4.1
|
||||
dev: true
|
||||
|
||||
/ansi-align@3.0.1:
|
||||
resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
|
||||
dependencies:
|
||||
|
|
@ -1631,12 +1557,6 @@ packages:
|
|||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/argparse@1.0.10:
|
||||
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
|
||||
dependencies:
|
||||
sprintf-js: 1.0.3
|
||||
dev: true
|
||||
|
||||
/argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: true
|
||||
|
|
@ -1696,28 +1616,6 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/ast-kit@0.11.2:
|
||||
resolution: {integrity: sha512-Q0DjXK4ApbVoIf9GLyCo252tUH44iTnD/hiJ2TQaJeydYWSpKk0sI34+WMel8S9Wt5pbLgG02oJ+gkgX5DV3sQ==}
|
||||
engines: {node: '>=16.14.0'}
|
||||
dependencies:
|
||||
'@babel/parser': 7.22.16
|
||||
'@rollup/pluginutils': 5.0.4
|
||||
pathe: 1.1.1
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
dev: true
|
||||
|
||||
/ast-kit@0.9.5:
|
||||
resolution: {integrity: sha512-kbL7ERlqjXubdDd+szuwdlQ1xUxEz9mCz1+m07ftNVStgwRb2RWw+U6oKo08PAvOishMxiqz1mlJyLl8yQx2Qg==}
|
||||
engines: {node: '>=16.14.0'}
|
||||
dependencies:
|
||||
'@babel/parser': 7.22.16
|
||||
'@rollup/pluginutils': 5.0.4
|
||||
pathe: 1.1.1
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
dev: true
|
||||
|
||||
/ast-types@0.13.4:
|
||||
resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
|
||||
engines: {node: '>=4'}
|
||||
|
|
@ -1725,16 +1623,6 @@ packages:
|
|||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/ast-walker-scope@0.5.0:
|
||||
resolution: {integrity: sha512-NsyHMxBh4dmdEHjBo1/TBZvCKxffmZxRYhmclfu0PP6Aftre47jOHYaYaNqJcV0bxihxFXhDkzLHUwHc0ocd0Q==}
|
||||
engines: {node: '>=16.14.0'}
|
||||
dependencies:
|
||||
'@babel/parser': 7.22.16
|
||||
ast-kit: 0.9.5
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
dev: true
|
||||
|
||||
/async-retry@1.3.3:
|
||||
resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==}
|
||||
dependencies:
|
||||
|
|
@ -1892,15 +1780,6 @@ packages:
|
|||
run-applescript: 5.0.0
|
||||
dev: true
|
||||
|
||||
/bundle-require@4.0.1:
|
||||
resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
peerDependencies:
|
||||
esbuild: '>=0.17'
|
||||
dependencies:
|
||||
load-tsconfig: 0.2.5
|
||||
dev: true
|
||||
|
||||
/c12@1.4.2:
|
||||
resolution: {integrity: sha512-3IP/MuamSVRVw8W8+CHWAz9gKN4gd+voF2zm/Ln6D25C2RhytEZ1ABbC8MjKr4BR9rhoV1JQ7jJA158LDiTkLg==}
|
||||
dependencies:
|
||||
|
|
@ -2224,18 +2103,6 @@ packages:
|
|||
xdg-basedir: 5.1.0
|
||||
dev: true
|
||||
|
||||
/connect@3.7.0:
|
||||
resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
dependencies:
|
||||
debug: 2.6.9
|
||||
finalhandler: 1.1.2
|
||||
parseurl: 1.3.3
|
||||
utils-merge: 1.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/consola@2.15.3:
|
||||
resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
|
||||
dev: true
|
||||
|
|
@ -2508,17 +2375,6 @@ packages:
|
|||
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
|
||||
dev: true
|
||||
|
||||
/debug@2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.0.0
|
||||
dev: true
|
||||
|
||||
/debug@3.2.7:
|
||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -2624,6 +2480,11 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/define-lazy-prop@2.0.0:
|
||||
resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/define-lazy-prop@3.0.0:
|
||||
resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
@ -2728,10 +2589,6 @@ packages:
|
|||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
dev: true
|
||||
|
||||
/ee-first@1.1.1:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
dev: true
|
||||
|
||||
/ejs@3.1.9:
|
||||
resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -2752,11 +2609,6 @@ packages:
|
|||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||
dev: true
|
||||
|
||||
/encodeurl@1.0.2:
|
||||
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: true
|
||||
|
||||
/enhanced-resolve@4.5.0:
|
||||
resolution: {integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
|
@ -2908,10 +2760,6 @@ packages:
|
|||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/escape-html@1.0.3:
|
||||
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
|
||||
dev: true
|
||||
|
||||
/escape-string-regexp@1.0.5:
|
||||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
|
@ -3031,10 +2879,6 @@ packages:
|
|||
parse-code-context: 1.0.0
|
||||
dev: true
|
||||
|
||||
/fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: true
|
||||
|
||||
/fast-glob@3.3.1:
|
||||
resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
|
|
@ -3096,21 +2940,6 @@ packages:
|
|||
to-regex-range: 5.0.1
|
||||
dev: true
|
||||
|
||||
/finalhandler@1.1.2:
|
||||
resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
debug: 2.6.9
|
||||
encodeurl: 1.0.2
|
||||
escape-html: 1.0.3
|
||||
on-finished: 2.3.0
|
||||
parseurl: 1.3.3
|
||||
statuses: 1.5.0
|
||||
unpipe: 1.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/find-up@2.1.0:
|
||||
resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
|
@ -4208,14 +4037,6 @@ packages:
|
|||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
dev: true
|
||||
|
||||
/js-yaml@3.14.1:
|
||||
resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
argparse: 1.0.10
|
||||
esprima: 4.0.1
|
||||
dev: true
|
||||
|
||||
/js-yaml@4.1.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
|
|
@ -4241,10 +4062,6 @@ packages:
|
|||
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
|
||||
dev: true
|
||||
|
||||
/json-schema-traverse@1.0.0:
|
||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||
dev: true
|
||||
|
||||
/json-stringify-safe@5.0.1:
|
||||
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
|
||||
dev: true
|
||||
|
|
@ -4360,11 +4177,6 @@ packages:
|
|||
strip-bom: 3.0.0
|
||||
dev: true
|
||||
|
||||
/load-tsconfig@0.2.5:
|
||||
resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/local-pkg@0.4.3:
|
||||
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
|
||||
engines: {node: '>=14'}
|
||||
|
|
@ -4478,13 +4290,6 @@ packages:
|
|||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/magic-string-ast@0.3.0:
|
||||
resolution: {integrity: sha512-0shqecEPgdFpnI3AP90epXyxZy9g6CRZ+SZ7BcqFwYmtFEnZ1jpevcV5HoyVnlDS9gCnc1UIg3Rsvp3Ci7r8OA==}
|
||||
engines: {node: '>=16.14.0'}
|
||||
dependencies:
|
||||
magic-string: 0.30.3
|
||||
dev: true
|
||||
|
||||
/magic-string@0.25.9:
|
||||
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
|
||||
dependencies:
|
||||
|
|
@ -4736,10 +4541,6 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/ms@2.0.0:
|
||||
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
|
||||
dev: true
|
||||
|
||||
/ms@2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
dev: true
|
||||
|
|
@ -5053,13 +4854,6 @@ packages:
|
|||
resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==}
|
||||
dev: true
|
||||
|
||||
/on-finished@2.3.0:
|
||||
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
ee-first: 1.1.1
|
||||
dev: true
|
||||
|
||||
/once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
|
|
@ -5080,6 +4874,15 @@ packages:
|
|||
mimic-fn: 4.0.0
|
||||
dev: true
|
||||
|
||||
/open@8.4.2:
|
||||
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
define-lazy-prop: 2.0.0
|
||||
is-docker: 2.2.1
|
||||
is-wsl: 2.2.0
|
||||
dev: true
|
||||
|
||||
/open@9.1.0:
|
||||
resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
|
@ -5311,11 +5114,6 @@ packages:
|
|||
parse-path: 7.0.0
|
||||
dev: true
|
||||
|
||||
/parseurl@1.3.3:
|
||||
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: true
|
||||
|
||||
/pascal-case@3.1.2:
|
||||
resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
|
||||
dependencies:
|
||||
|
|
@ -5371,10 +5169,6 @@ packages:
|
|||
path-root-regex: 0.1.2
|
||||
dev: true
|
||||
|
||||
/path-to-regexp@6.2.1:
|
||||
resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
|
||||
dev: true
|
||||
|
||||
/path-type@3.0.0:
|
||||
resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==}
|
||||
engines: {node: '>=4'}
|
||||
|
|
@ -5551,11 +5345,6 @@ packages:
|
|||
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
|
||||
dev: true
|
||||
|
||||
/punycode@2.3.0:
|
||||
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/pupa@3.1.0:
|
||||
resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==}
|
||||
engines: {node: '>=12.20'}
|
||||
|
|
@ -5755,11 +5544,6 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/require-from-string@2.0.2:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/resize-observer-polyfill@1.5.1:
|
||||
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
|
||||
dev: true
|
||||
|
|
@ -5834,6 +5618,22 @@ packages:
|
|||
glob: 7.2.3
|
||||
dev: true
|
||||
|
||||
/rollup-plugin-visualizer@5.9.2:
|
||||
resolution: {integrity: sha512-waHktD5mlWrYFrhOLbti4YgQCn1uR24nYsNuXxg7LkPH8KdTXVWR9DNY1WU0QqokyMixVXJS4J04HNrVTMP01A==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
rollup: 2.x || 3.x
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
dependencies:
|
||||
open: 8.4.2
|
||||
picomatch: 2.3.1
|
||||
source-map: 0.7.4
|
||||
yargs: 17.7.2
|
||||
dev: true
|
||||
|
||||
/rollup@3.29.1:
|
||||
resolution: {integrity: sha512-c+ebvQz0VIH4KhhCpDsI+Bik0eT8ZFEVZEYw0cGMVqIP8zc+gnwl7iXCamTw7vzv2MeuZFZfdx5JJIq+ehzDlg==}
|
||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||
|
|
@ -6110,6 +5910,11 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/source-map@0.7.4:
|
||||
resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
|
||||
engines: {node: '>= 8'}
|
||||
dev: true
|
||||
|
||||
/sourcemap-codec@1.4.8:
|
||||
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
||||
deprecated: Please use @jridgewell/sourcemap-codec instead
|
||||
|
|
@ -6149,15 +5954,6 @@ packages:
|
|||
through: 2.3.8
|
||||
dev: true
|
||||
|
||||
/sprintf-js@1.0.3:
|
||||
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
|
||||
dev: true
|
||||
|
||||
/statuses@1.5.0:
|
||||
resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
/std-env@3.4.3:
|
||||
resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==}
|
||||
dev: true
|
||||
|
|
@ -6588,7 +6384,7 @@ packages:
|
|||
/unimport@2.2.4:
|
||||
resolution: {integrity: sha512-qMgmeEGqqrrmEtm0dqxMG37J6xBtrriqxq9hILvDb+e6l2F0yTnJomLoCCp0eghLR7bYGeBsUU5Y0oyiUYhViw==}
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.0.4
|
||||
'@rollup/pluginutils': 5.0.5
|
||||
escape-string-regexp: 5.0.0
|
||||
fast-glob: 3.3.1
|
||||
local-pkg: 0.4.3
|
||||
|
|
@ -6606,7 +6402,7 @@ packages:
|
|||
/unimport@3.3.0:
|
||||
resolution: {integrity: sha512-3jhq3ZG5hFZzrWGDCpx83kjPzefP/EeuKkIO1T0MA4Zwj+dO/Og1mFvZ4aZ5WSDm0FVbbdVIRH1zKBG7c4wOpg==}
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.0.4
|
||||
'@rollup/pluginutils': 5.0.5
|
||||
escape-string-regexp: 5.0.0
|
||||
fast-glob: 3.3.1
|
||||
local-pkg: 0.4.3
|
||||
|
|
@ -6674,11 +6470,6 @@ packages:
|
|||
- vite
|
||||
dev: true
|
||||
|
||||
/unpipe@1.0.0:
|
||||
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: true
|
||||
|
||||
/unplugin-auto-import@0.13.0(@vueuse/core@9.13.0):
|
||||
resolution: {integrity: sha512-nKMxDbkjM4FRPInFfm7sWrJOKgxfKKwb5yLPP+DEGl/SG0/FtBoW1LnZL4PQfx0FXjertoHO1P/5nDf+RSip2Q==}
|
||||
engines: {node: '>=14'}
|
||||
|
|
@ -6726,33 +6517,6 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/unplugin-vue-router@0.7.0(vue-router@4.2.4)(vue@3.3.4):
|
||||
resolution: {integrity: sha512-ddRreGq0t5vlSB7OMy4e4cfU1w2AwBQCwmvW3oP/0IHQiokzbx4hd3TpwBu3eIAFVuhX2cwNQwp1U32UybTVCw==}
|
||||
peerDependencies:
|
||||
vue-router: ^4.1.0
|
||||
peerDependenciesMeta:
|
||||
vue-router:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/types': 7.23.0
|
||||
'@rollup/pluginutils': 5.0.4
|
||||
'@vue-macros/common': 1.8.0(vue@3.3.4)
|
||||
ast-walker-scope: 0.5.0
|
||||
chokidar: 3.5.3
|
||||
fast-glob: 3.3.1
|
||||
json5: 2.2.3
|
||||
local-pkg: 0.4.3
|
||||
mlly: 1.4.2
|
||||
pathe: 1.1.1
|
||||
scule: 1.0.0
|
||||
unplugin: 1.5.0
|
||||
vue-router: 4.2.4(vue@3.3.4)
|
||||
yaml: 2.3.2
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
- vue
|
||||
dev: true
|
||||
|
||||
/unplugin@1.4.0:
|
||||
resolution: {integrity: sha512-5x4eIEL6WgbzqGtF9UV8VEC/ehKptPXDS6L2b0mv4FRMkJxRtjaJfOWDd6a8+kYbqsjklix7yWP0N3SUepjXcg==}
|
||||
dependencies:
|
||||
|
|
@ -6834,12 +6598,6 @@ packages:
|
|||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/uri-js@4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
dependencies:
|
||||
punycode: 2.3.0
|
||||
dev: true
|
||||
|
||||
/url-join@5.0.0:
|
||||
resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
|
@ -6849,11 +6607,6 @@ packages:
|
|||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
dev: true
|
||||
|
||||
/utils-merge@1.0.1:
|
||||
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
||||
engines: {node: '>= 0.4.0'}
|
||||
dev: true
|
||||
|
||||
/v8flags@4.0.1:
|
||||
resolution: {integrity: sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
|
|
@ -6866,27 +6619,6 @@ packages:
|
|||
spdx-expression-parse: 3.0.1
|
||||
dev: true
|
||||
|
||||
/vite-plugin-mock@3.0.0(vite@4.4.9):
|
||||
resolution: {integrity: sha512-Ibwlga2CSgkoFHFtPW3T/l0fwsGVz9Ss5i7HauBQDyDFfMKgbQXh9wKDLksLZHyai9rkDanxJtIcxbD0bUHCfw==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
peerDependencies:
|
||||
mockjs: '>=1.1.0'
|
||||
vite: '>=4.0.0'
|
||||
dependencies:
|
||||
'@types/mockjs': 1.0.7
|
||||
bundle-require: 4.0.1
|
||||
chokidar: 3.5.3
|
||||
connect: 3.7.0
|
||||
debug: 4.3.4
|
||||
fast-glob: 3.3.1
|
||||
path-to-regexp: 6.2.1
|
||||
picocolors: 1.0.0
|
||||
vite: 4.4.9(less@4.2.0)
|
||||
transitivePeerDependencies:
|
||||
- esbuild
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite-plugin-pages@0.28.0(vite@4.4.9):
|
||||
resolution: {integrity: sha512-yncDncFVnjUzhqJnwCgGDZoZ/wO6MEOMe93f2MQjplKXm1MpmHCrTkFCPnQyYGZTVKPAN+y7BQcIpNWPFLQ4+w==}
|
||||
peerDependencies:
|
||||
|
|
@ -6986,10 +6718,6 @@ packages:
|
|||
vue: 3.3.4
|
||||
dev: true
|
||||
|
||||
/vue-drag-resize@2.0.3:
|
||||
resolution: {integrity: sha512-5q03tZ/LyvQsg1iHRcqs+wI2OKNbNIWl9+7V8rVL6MxJhZLCIYSSgbAUaDE38LhD6dFd5aJhdgNmES61AxjXuw==}
|
||||
dev: true
|
||||
|
||||
/vue-router@4.2.4(vue@3.3.4):
|
||||
resolution: {integrity: sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ==}
|
||||
peerDependencies:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const run = async () => {
|
|||
const output = await generateApi({
|
||||
url: "http://localhost:3030/openapi.json",
|
||||
templates: path.resolve(__dirname, "./template"),
|
||||
output: path.resolve(process.cwd(), "src/api/service"),
|
||||
output: path.resolve(process.cwd(), "src/api/generated"),
|
||||
name: "Api.ts",
|
||||
singleHttpClient: false,
|
||||
httpClientType: "axios",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -152,7 +152,7 @@ export interface CreateRoleDto {
|
|||
* 角色标识
|
||||
* @example "admin"
|
||||
*/
|
||||
slug: string;
|
||||
code: string;
|
||||
/**
|
||||
* 角色描述
|
||||
* @example "一段很长的描述"
|
||||
|
|
@ -175,7 +175,7 @@ export interface UpdateRoleDto {
|
|||
* 角色标识
|
||||
* @example "admin"
|
||||
*/
|
||||
slug?: string;
|
||||
code?: string;
|
||||
/**
|
||||
* 角色描述
|
||||
* @example "一段很长的描述"
|
||||
|
|
@ -310,7 +310,7 @@ export interface File {
|
|||
mimetype: string;
|
||||
/**
|
||||
* 文件路径
|
||||
* @example "/upload/2021/10/01/xxx.jpg"
|
||||
* @example "/upload/2021-10-01/xxx.jpg"
|
||||
*/
|
||||
path: string;
|
||||
/**
|
||||
|
|
@ -323,6 +323,11 @@ export interface File {
|
|||
* @example ".jpg"
|
||||
*/
|
||||
extension: string;
|
||||
/**
|
||||
* 分类ID
|
||||
* @example 0
|
||||
*/
|
||||
categoryId: number;
|
||||
/**
|
||||
* 自增ID
|
||||
* @example 1
|
||||
|
|
@ -357,12 +362,110 @@ export interface UpdateFileDto {
|
|||
* 文件名
|
||||
* @example "头像.jpg"
|
||||
*/
|
||||
name: string;
|
||||
name?: string;
|
||||
/**
|
||||
* 描述
|
||||
* @example "一段很长的描述"
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 分类ID
|
||||
* @example 1
|
||||
*/
|
||||
categoryId?: number;
|
||||
}
|
||||
|
||||
export interface CreateFileCategoryDto {
|
||||
/**
|
||||
* 分类名称
|
||||
* @example "风景"
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 分类编码
|
||||
* @example "view"
|
||||
*/
|
||||
code: string;
|
||||
/**
|
||||
* 分类描述
|
||||
* @example "这是一段很长的描述"
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 父级ID
|
||||
* @example 0
|
||||
*/
|
||||
parentId?: number;
|
||||
}
|
||||
|
||||
export interface FileCategory {
|
||||
/**
|
||||
* 分类名称
|
||||
* @example "风景"
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 分类编码
|
||||
* @example "view"
|
||||
*/
|
||||
code: string;
|
||||
/**
|
||||
* 分类描述
|
||||
* @example "这是一段很长的描述"
|
||||
*/
|
||||
description?: string;
|
||||
/** 父级ID */
|
||||
parentId?: number;
|
||||
/**
|
||||
* 自增ID
|
||||
* @example 1
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* 创建时间
|
||||
* @format date-time
|
||||
* @example "2022-01-01 10:10:10"
|
||||
*/
|
||||
createdAt: string;
|
||||
/**
|
||||
* 创建人
|
||||
* @example "绝弹"
|
||||
*/
|
||||
createdBy: string;
|
||||
/**
|
||||
* 更新时间
|
||||
* @format date-time
|
||||
* @example "2022-01-02 11:11:11"
|
||||
*/
|
||||
updatedAt: string;
|
||||
/**
|
||||
* 更新人
|
||||
* @example "绝弹"
|
||||
*/
|
||||
updatedBy: string;
|
||||
}
|
||||
|
||||
export interface UpdateFileCategoryDto {
|
||||
/**
|
||||
* 分类名称
|
||||
* @example "风景"
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 分类编码
|
||||
* @example "view"
|
||||
*/
|
||||
code?: string;
|
||||
/**
|
||||
* 分类描述
|
||||
* @example "这是一段很长的描述"
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* 父级ID
|
||||
* @example 0
|
||||
*/
|
||||
parentId?: number;
|
||||
}
|
||||
|
||||
export interface CreatePostDto {
|
||||
|
|
@ -985,6 +1088,75 @@ export interface GetLoginLogsParams {
|
|||
createdFrom?: string;
|
||||
}
|
||||
|
||||
export interface GetFilesParams {
|
||||
/**
|
||||
* 文件名称
|
||||
* @example "风景"
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 分类ID
|
||||
* @example 1
|
||||
*/
|
||||
categoryId?: number;
|
||||
/**
|
||||
* 排序规则
|
||||
* @default "id:desc"
|
||||
* @pattern /^(\w+:\w+,)*\w+:\w+$/
|
||||
* @example "id:desc"
|
||||
*/
|
||||
sort?: string;
|
||||
/**
|
||||
* 页码
|
||||
* @min 1
|
||||
* @example 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* 每页条数
|
||||
* @min 0
|
||||
* @example 10
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 创建起始事件
|
||||
* @example "2020-02-02 02:02:02"
|
||||
*/
|
||||
createdFrom?: string;
|
||||
}
|
||||
|
||||
export interface GetFileCategorysParams {
|
||||
/**
|
||||
* 分类名称
|
||||
* @example "风景"
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 排序规则
|
||||
* @default "id:desc"
|
||||
* @pattern /^(\w+:\w+,)*\w+:\w+$/
|
||||
* @example "id:desc"
|
||||
*/
|
||||
sort?: string;
|
||||
/**
|
||||
* 页码
|
||||
* @min 1
|
||||
* @example 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* 每页条数
|
||||
* @min 0
|
||||
* @example 10
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 创建起始事件
|
||||
* @example "2020-02-02 02:02:02"
|
||||
*/
|
||||
createdFrom?: string;
|
||||
}
|
||||
|
||||
export interface GetPostsParams {
|
||||
/**
|
||||
* 排序规则
|
||||
|
|
@ -1685,10 +1857,84 @@ export namespace File {
|
|||
*/
|
||||
export namespace GetFiles {
|
||||
export type RequestParams = {};
|
||||
export type RequestQuery = {};
|
||||
export type RequestQuery = {
|
||||
/**
|
||||
* 文件名称
|
||||
* @example "风景"
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 分类ID
|
||||
* @example 1
|
||||
*/
|
||||
categoryId?: number;
|
||||
/**
|
||||
* 排序规则
|
||||
* @default "id:desc"
|
||||
* @pattern /^(\w+:\w+,)*\w+:\w+$/
|
||||
* @example "id:desc"
|
||||
*/
|
||||
sort?: string;
|
||||
/**
|
||||
* 页码
|
||||
* @min 1
|
||||
* @example 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* 每页条数
|
||||
* @min 0
|
||||
* @example 10
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 创建起始事件
|
||||
* @example "2020-02-02 02:02:02"
|
||||
*/
|
||||
createdFrom?: string;
|
||||
};
|
||||
export type RequestBody = never;
|
||||
export type RequestHeaders = {};
|
||||
export type ResponseBody = Response;
|
||||
export type ResponseBody = {
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: object;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @description 批量删除文件
|
||||
* @tags file
|
||||
* @name DelFiles
|
||||
* @request DELETE:/api/v1/file
|
||||
*/
|
||||
export namespace DelFiles {
|
||||
export type RequestParams = {};
|
||||
export type RequestQuery = {};
|
||||
export type RequestBody = string[];
|
||||
export type RequestHeaders = {};
|
||||
export type ResponseBody = {
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: object;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @description 查询
|
||||
|
|
@ -1731,20 +1977,7 @@ export namespace File {
|
|||
export type RequestQuery = {};
|
||||
export type RequestBody = UpdateFileDto;
|
||||
export type RequestHeaders = {};
|
||||
export type ResponseBody = {
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: string;
|
||||
};
|
||||
export type ResponseBody = Response;
|
||||
}
|
||||
/**
|
||||
* @description 删除
|
||||
|
|
@ -1791,6 +2024,149 @@ export namespace File {
|
|||
}
|
||||
}
|
||||
|
||||
export namespace FileCategory {
|
||||
/**
|
||||
* @description 新增文件分类
|
||||
* @tags fileCategory
|
||||
* @name AddFileCategory
|
||||
* @request POST:/api/v1/fileCategorys
|
||||
*/
|
||||
export namespace AddFileCategory {
|
||||
export type RequestParams = {};
|
||||
export type RequestQuery = {};
|
||||
export type RequestBody = CreateFileCategoryDto;
|
||||
export type RequestHeaders = {};
|
||||
export type ResponseBody = {
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: number;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @description 查询文件分类
|
||||
* @tags fileCategory
|
||||
* @name GetFileCategorys
|
||||
* @request GET:/api/v1/fileCategorys
|
||||
*/
|
||||
export namespace GetFileCategorys {
|
||||
export type RequestParams = {};
|
||||
export type RequestQuery = {
|
||||
/**
|
||||
* 分类名称
|
||||
* @example "风景"
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 排序规则
|
||||
* @default "id:desc"
|
||||
* @pattern /^(\w+:\w+,)*\w+:\w+$/
|
||||
* @example "id:desc"
|
||||
*/
|
||||
sort?: string;
|
||||
/**
|
||||
* 页码
|
||||
* @min 1
|
||||
* @example 1
|
||||
*/
|
||||
page?: number;
|
||||
/**
|
||||
* 每页条数
|
||||
* @min 0
|
||||
* @example 10
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* 创建起始事件
|
||||
* @example "2020-02-02 02:02:02"
|
||||
*/
|
||||
createdFrom?: string;
|
||||
};
|
||||
export type RequestBody = never;
|
||||
export type RequestHeaders = {};
|
||||
export type ResponseBody = {
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: FileCategory[];
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @description 获取文件分类
|
||||
* @tags fileCategory
|
||||
* @name GetFileCategory
|
||||
* @request GET:/api/v1/fileCategorys/{id}
|
||||
*/
|
||||
export namespace GetFileCategory {
|
||||
export type RequestParams = {
|
||||
id: number;
|
||||
};
|
||||
export type RequestQuery = {};
|
||||
export type RequestBody = never;
|
||||
export type RequestHeaders = {};
|
||||
export type ResponseBody = {
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: FileCategory;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @description 更新文件分类
|
||||
* @tags fileCategory
|
||||
* @name SetFileCategory
|
||||
* @request PATCH:/api/v1/fileCategorys/{id}
|
||||
*/
|
||||
export namespace SetFileCategory {
|
||||
export type RequestParams = {
|
||||
id: number;
|
||||
};
|
||||
export type RequestQuery = {};
|
||||
export type RequestBody = UpdateFileCategoryDto;
|
||||
export type RequestHeaders = {};
|
||||
export type ResponseBody = Response;
|
||||
}
|
||||
/**
|
||||
* @description 删除文件分类
|
||||
* @tags fileCategory
|
||||
* @name DelFileCategory
|
||||
* @request DELETE:/api/v1/fileCategorys/{id}
|
||||
*/
|
||||
export namespace DelFileCategory {
|
||||
export type RequestParams = {
|
||||
id: number;
|
||||
};
|
||||
export type RequestQuery = {};
|
||||
export type RequestBody = never;
|
||||
export type RequestHeaders = {};
|
||||
export type ResponseBody = Response;
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Post {
|
||||
/**
|
||||
* @description 创建文章
|
||||
|
|
@ -3183,10 +3559,61 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|||
* @name GetFiles
|
||||
* @request GET:/api/v1/file
|
||||
*/
|
||||
getFiles: (params: RequestParams = {}) => {
|
||||
return this.request<Response, any>({
|
||||
getFiles: (query: GetFilesParams, params: RequestParams = {}) => {
|
||||
return this.request<
|
||||
{
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: object;
|
||||
},
|
||||
any
|
||||
>({
|
||||
path: `/api/v1/file`,
|
||||
method: "GET",
|
||||
query: query,
|
||||
format: "json",
|
||||
...params,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 批量删除文件
|
||||
*
|
||||
* @tags file
|
||||
* @name DelFiles
|
||||
* @request DELETE:/api/v1/file
|
||||
*/
|
||||
delFiles: (data: string[], params: RequestParams = {}) => {
|
||||
return this.request<
|
||||
{
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: object;
|
||||
},
|
||||
any
|
||||
>({
|
||||
path: `/api/v1/file`,
|
||||
method: "DELETE",
|
||||
body: data,
|
||||
type: ContentType.Json,
|
||||
format: "json",
|
||||
...params,
|
||||
});
|
||||
|
|
@ -3232,23 +3659,7 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|||
* @request PATCH:/api/v1/file/{id}
|
||||
*/
|
||||
setFile: (id: number, data: UpdateFileDto, params: RequestParams = {}) => {
|
||||
return this.request<
|
||||
{
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: string;
|
||||
},
|
||||
any
|
||||
>({
|
||||
return this.request<Response, any>({
|
||||
path: `/api/v1/file/${id}`,
|
||||
method: "PATCH",
|
||||
body: data,
|
||||
|
|
@ -3306,6 +3717,140 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
|
|||
});
|
||||
},
|
||||
};
|
||||
fileCategory = {
|
||||
/**
|
||||
* 新增文件分类
|
||||
*
|
||||
* @tags fileCategory
|
||||
* @name AddFileCategory
|
||||
* @request POST:/api/v1/fileCategorys
|
||||
*/
|
||||
addFileCategory: (data: CreateFileCategoryDto, params: RequestParams = {}) => {
|
||||
return this.request<
|
||||
{
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: number;
|
||||
},
|
||||
any
|
||||
>({
|
||||
path: `/api/v1/fileCategorys`,
|
||||
method: "POST",
|
||||
body: data,
|
||||
type: ContentType.Json,
|
||||
format: "json",
|
||||
...params,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查询文件分类
|
||||
*
|
||||
* @tags fileCategory
|
||||
* @name GetFileCategorys
|
||||
* @request GET:/api/v1/fileCategorys
|
||||
*/
|
||||
getFileCategorys: (query: GetFileCategorysParams, params: RequestParams = {}) => {
|
||||
return this.request<
|
||||
{
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: FileCategory[];
|
||||
},
|
||||
any
|
||||
>({
|
||||
path: `/api/v1/fileCategorys`,
|
||||
method: "GET",
|
||||
query: query,
|
||||
format: "json",
|
||||
...params,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取文件分类
|
||||
*
|
||||
* @tags fileCategory
|
||||
* @name GetFileCategory
|
||||
* @request GET:/api/v1/fileCategorys/{id}
|
||||
*/
|
||||
getFileCategory: (id: number, params: RequestParams = {}) => {
|
||||
return this.request<
|
||||
{
|
||||
/**
|
||||
* 状态码
|
||||
* @format int32
|
||||
* @example 2000
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* 提示信息
|
||||
* @example "请求成功"
|
||||
*/
|
||||
message: string;
|
||||
data?: FileCategory;
|
||||
},
|
||||
any
|
||||
>({
|
||||
path: `/api/v1/fileCategorys/${id}`,
|
||||
method: "GET",
|
||||
format: "json",
|
||||
...params,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新文件分类
|
||||
*
|
||||
* @tags fileCategory
|
||||
* @name SetFileCategory
|
||||
* @request PATCH:/api/v1/fileCategorys/{id}
|
||||
*/
|
||||
setFileCategory: (id: number, data: UpdateFileCategoryDto, params: RequestParams = {}) => {
|
||||
return this.request<Response, any>({
|
||||
path: `/api/v1/fileCategorys/${id}`,
|
||||
method: "PATCH",
|
||||
body: data,
|
||||
type: ContentType.Json,
|
||||
format: "json",
|
||||
...params,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除文件分类
|
||||
*
|
||||
* @tags fileCategory
|
||||
* @name DelFileCategory
|
||||
* @request DELETE:/api/v1/fileCategorys/{id}
|
||||
*/
|
||||
delFileCategory: (id: number, params: RequestParams = {}) => {
|
||||
return this.request<Response, any>({
|
||||
path: `/api/v1/fileCategorys/${id}`,
|
||||
method: "DELETE",
|
||||
format: "json",
|
||||
...params,
|
||||
});
|
||||
},
|
||||
};
|
||||
post = {
|
||||
/**
|
||||
* 创建文章
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
export * from "./instance/api";
|
||||
export * from "./service/Api";
|
||||
export * from "./helper/useRequest";
|
||||
export * from "./generated/Api";
|
||||
export * from "./instance/useRequest";
|
||||
|
|
|
|||
|
|
@ -1,21 +1,7 @@
|
|||
import { IToastOptions, toast } from "@/components";
|
||||
import { store, useUserStore } from "@/store";
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
import { Api } from "../service/Api";
|
||||
|
||||
class Service extends Api<unknown> {
|
||||
/**
|
||||
* 登陆过期处理函数
|
||||
*/
|
||||
tokenExpiredHandler: () => void = () => {};
|
||||
/**
|
||||
* 设置登陆过期后的处理函数
|
||||
* @param handler
|
||||
*/
|
||||
setTokenExpiredHandler(handler: () => void) {
|
||||
this.tokenExpiredHandler = handler;
|
||||
}
|
||||
}
|
||||
import { Service } from "./service";
|
||||
import { addToastInterceptor } from "../interceptors/toast";
|
||||
import { addAuthInterceptor } from "../interceptors/auth";
|
||||
import { addExceptionInterceptor } from "../interceptors/exception";
|
||||
|
||||
/**
|
||||
* API 接口实例
|
||||
|
|
@ -26,59 +12,18 @@ const api = new Service({
|
|||
});
|
||||
|
||||
/**
|
||||
* 请求拦截器
|
||||
* 添加请求提示拦截器
|
||||
*/
|
||||
api.instance.interceptors.request.use(
|
||||
(config) => {
|
||||
const userStore = useUserStore(store);
|
||||
if (userStore.accessToken) {
|
||||
config.headers.Authorization = `Bearer ${userStore.accessToken}`;
|
||||
}
|
||||
if (config.toast) {
|
||||
let options: IToastOptions = {};
|
||||
if (typeof config.toast === "string") {
|
||||
options = { message: config.toast };
|
||||
}
|
||||
if (typeof config.toast === "object") {
|
||||
options = config.toast;
|
||||
}
|
||||
config.closeToast = toast(options);
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
error.config?.closeToast?.();
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
addToastInterceptor(api.instance);
|
||||
|
||||
/**
|
||||
* 响应拦截器
|
||||
* 添加登陆令牌拦截器
|
||||
*/
|
||||
api.instance.interceptors.response.use(
|
||||
(res) => {
|
||||
res.config.closeToast?.();
|
||||
if (res.data?.code && res.data.code !== 2000) {
|
||||
return Promise.reject(res);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
(error) => {
|
||||
error.config.closeToast?.();
|
||||
const userStore = useUserStore(store);
|
||||
if (error.response) {
|
||||
const code = error.response.data?.code;
|
||||
if (code === 4050 || code === 4051) {
|
||||
Message.warning('提示:登陆过期,请重新登陆!')
|
||||
userStore.clearUser();
|
||||
api.tokenExpiredHandler?.();
|
||||
}
|
||||
} else if (error.request) {
|
||||
console.log("request error", error.request);
|
||||
Message.error(`提示:网络异常,请检查网络是否正常或稍后重试!`);
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
addAuthInterceptor(api.instance);
|
||||
|
||||
/**
|
||||
* 添加异常处理拦截器
|
||||
*/
|
||||
addExceptionInterceptor(api.instance, () => api.expireHandler?.());
|
||||
|
||||
export { api };
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import { Api } from "../generated/Api";
|
||||
|
||||
/**
|
||||
* 扩展生成的API类
|
||||
*/
|
||||
export class Service extends Api<unknown> {
|
||||
/**
|
||||
* 登陆过期处理函数
|
||||
* @description 勿动
|
||||
*/
|
||||
expireHandler: () => void = () => {};
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import { store, useUserStore } from "@/store";
|
||||
import { AxiosInstance } from "axios";
|
||||
|
||||
/**
|
||||
* 登陆令牌拦截器
|
||||
* @param axios Axios实例
|
||||
*/
|
||||
export function addAuthInterceptor(axios: AxiosInstance) {
|
||||
axios.interceptors.request.use((config) => {
|
||||
const userStore = useUserStore(store);
|
||||
if (userStore.accessToken) {
|
||||
config.headers.Authorization = `Bearer ${userStore.accessToken}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
import { Notification } from "@arco-design/web-vue";
|
||||
import { AxiosInstance } from "axios";
|
||||
|
||||
const successCodes = [2000];
|
||||
const expiredCodes = [4050, 4051];
|
||||
let tipShowing = false;
|
||||
|
||||
/**
|
||||
* 异常拦截器
|
||||
* @param axios Axios实例
|
||||
*/
|
||||
export function addExceptionInterceptor(axios: AxiosInstance, exipreHandler?: (...args: any[]) => any) {
|
||||
axios.interceptors.response.use(
|
||||
(res) => {
|
||||
const code = res.data?.code;
|
||||
if (code && !successCodes.includes(code)) {
|
||||
return Promise.reject(res);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
(error) => {
|
||||
// 服务端响应错误
|
||||
if (error.response) {
|
||||
const code = error.response.data?.code;
|
||||
if (expiredCodes.includes(code)) {
|
||||
Notification.warning({
|
||||
title: "登陆提示",
|
||||
content: "当前登陆已过期,请重新登陆!",
|
||||
});
|
||||
exipreHandler?.(error);
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
// 客户端请求错误
|
||||
if (error.request) {
|
||||
if (!tipShowing) {
|
||||
tipShowing = true;
|
||||
Notification.error({
|
||||
title: "请求提示",
|
||||
content: `请求服务器失败,请检查网络或稍后重试!`,
|
||||
onClose: () => (tipShowing = false),
|
||||
});
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import { IToastOptions, toast } from "@/components";
|
||||
import { AxiosInstance } from "axios";
|
||||
|
||||
/**
|
||||
* 提示拦截器
|
||||
* @param axios Axios实例
|
||||
*/
|
||||
export function addToastInterceptor(axios: AxiosInstance) {
|
||||
axios.interceptors.request.use(
|
||||
(config) => {
|
||||
if (config.toast) {
|
||||
let options: IToastOptions = {};
|
||||
if (typeof config.toast === "string") {
|
||||
options = { message: config.toast };
|
||||
}
|
||||
if (typeof config.toast === "object") {
|
||||
options = config.toast;
|
||||
}
|
||||
config.closeToast = toast(options);
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
error.config.closeToast?.();
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
axios.interceptors.response.use(
|
||||
(response) => {
|
||||
response.config.closeToast?.();
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
error.config.closeToast?.();
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -75,3 +75,32 @@ export const config = {
|
|||
return data;
|
||||
},
|
||||
};
|
||||
|
||||
export function initOptions({ item, model }: any, key = "options") {
|
||||
if (Array.isArray(item.options)) {
|
||||
item.nodeProps[key] = item.options;
|
||||
}
|
||||
if (item.options && typeof item.options === "object") {
|
||||
const { value, source } = item.options;
|
||||
item._updateOptions = async () => {};
|
||||
}
|
||||
if (typeof item.options === "function") {
|
||||
const loadData = item.options;
|
||||
item.nodeProps[key] = reactive([]);
|
||||
item._updateOptions = async () => {
|
||||
let data = await loadData({ item, model });
|
||||
if (Array.isArray(data?.data?.data)) {
|
||||
data = data.data.data.map((i: any) => ({
|
||||
...i,
|
||||
label: i.name,
|
||||
value: i.id,
|
||||
}));
|
||||
}
|
||||
if (Array.isArray(data)) {
|
||||
item.nodeProps[key].splice(0);
|
||||
item.nodeProps[key].push(...data);
|
||||
}
|
||||
};
|
||||
item._updateOptions();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,27 +16,7 @@ import {
|
|||
TimePicker,
|
||||
TreeSelect,
|
||||
} from "@arco-design/web-vue";
|
||||
|
||||
const initOptions = ({ item, model }: any, key = "options") => {
|
||||
if (Array.isArray(item.options)) {
|
||||
item.nodeProps[key] = item.options;
|
||||
}
|
||||
if (typeof item.options === "function") {
|
||||
const loadData = item.options;
|
||||
item.nodeProps[key] = reactive([]);
|
||||
item._updateOptions = async () => {
|
||||
let data = await loadData({ item, model });
|
||||
if (Array.isArray(data?.data?.data)) {
|
||||
data = data.data.data.map((i: any) => ({ label: i.name, value: i.id }));
|
||||
}
|
||||
if (Array.isArray(data)) {
|
||||
item.nodeProps[key].splice(0);
|
||||
item.nodeProps[key].push(...data);
|
||||
}
|
||||
};
|
||||
item._updateOptions();
|
||||
}
|
||||
};
|
||||
import { initOptions } from "./form-config";
|
||||
|
||||
/**
|
||||
* 表单项组件映射
|
||||
|
|
@ -114,7 +94,10 @@ export const nodeMap = {
|
|||
placeholder: "请选择",
|
||||
allowClear: true,
|
||||
allowSearch: true,
|
||||
options: [{}],
|
||||
options: [],
|
||||
onChange(value) {
|
||||
value;
|
||||
},
|
||||
} as InstanceType<typeof TreeSelect>["$props"],
|
||||
init: (arg: any) => initOptions(arg, "data"),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const defineColumn = <T extends TableColumn>(column: T) => {
|
|||
};
|
||||
|
||||
export const updateColumn = defineColumn({
|
||||
title: "更新者",
|
||||
title: "更新用户",
|
||||
dataIndex: "createdAt",
|
||||
width: 190,
|
||||
render({ record }) {
|
||||
|
|
@ -22,7 +22,7 @@ export const updateColumn = defineColumn({
|
|||
});
|
||||
|
||||
export const createColumn = defineColumn({
|
||||
title: "创建者",
|
||||
title: "创建用户",
|
||||
dataIndex: "createdAt",
|
||||
width: 190,
|
||||
render({ record }) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
import {
|
||||
TableColumnData as BaseColumn,
|
||||
TableData as BaseData,
|
||||
Table as BaseTable,
|
||||
Message,
|
||||
} from "@arco-design/web-vue";
|
||||
import { TableColumnData as BaseColumn, TableData as BaseData, Table as BaseTable } from "@arco-design/web-vue";
|
||||
import { merge } from "lodash-es";
|
||||
import { PropType, computed, defineComponent, reactive, ref, watch } from "vue";
|
||||
import { PropType, computed, defineComponent, reactive, ref } from "vue";
|
||||
import { Form, FormInstance, FormModal, FormModalInstance, FormModalProps, FormProps } from "../form";
|
||||
import { config } from "./table.config";
|
||||
|
||||
|
|
@ -72,7 +67,7 @@ export const Table = defineComponent({
|
|||
},
|
||||
setup(props) {
|
||||
const loading = ref(false);
|
||||
const tableRef = ref<InstanceType<typeof BaseTable>>()
|
||||
const tableRef = ref<InstanceType<typeof BaseTable>>();
|
||||
const searchRef = ref<FormInstance>();
|
||||
const createRef = ref<FormModalInstance>();
|
||||
const modifyRef = ref<FormModalInstance>();
|
||||
|
|
@ -81,10 +76,16 @@ export const Table = defineComponent({
|
|||
const reloadData = () => loadData({ current: 1, pageSize: 10 });
|
||||
const openModifyModal = (data: any) => modifyRef.value?.open(data);
|
||||
|
||||
/**
|
||||
* 加载数据
|
||||
* @param pagination 自定义分页
|
||||
*/
|
||||
const loadData = async (pagination: Partial<any> = {}) => {
|
||||
const merged = { ...props.pagination, ...pagination };
|
||||
const paging = { page: merged.current, size: merged.pageSize };
|
||||
const model = searchRef.value?.getModel() ?? {};
|
||||
|
||||
// 本地加载
|
||||
if (Array.isArray(props.data)) {
|
||||
const filters = Object.entries(model);
|
||||
const data = props.data.filter((item) => {
|
||||
|
|
@ -99,6 +100,8 @@ export const Table = defineComponent({
|
|||
props.pagination.total = renderData.value.length;
|
||||
props.pagination.current = 1;
|
||||
}
|
||||
|
||||
// 远程加载
|
||||
if (typeof props.data === "function") {
|
||||
try {
|
||||
loading.value = true;
|
||||
|
|
@ -107,30 +110,19 @@ export const Table = defineComponent({
|
|||
renderData.value = data;
|
||||
props.pagination.total = total;
|
||||
props.pagination.current = paging.page;
|
||||
} catch (error) {
|
||||
const message = config.getApiErrorMessage(error);
|
||||
if (message) {
|
||||
Message.error(`提示:${message}`);
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(data) => {
|
||||
if (Array.isArray(data)) {
|
||||
renderData.value = data;
|
||||
props.pagination.total = data.length;
|
||||
props.pagination.current = 1;
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
watchEffect(() => {
|
||||
if (Array.isArray(props.data)) {
|
||||
renderData.value = props.data;
|
||||
props.pagination.total = props.data.length;
|
||||
props.pagination.current = 1;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
loadData();
|
||||
|
|
|
|||
|
|
@ -248,12 +248,39 @@ export const useAniTable = (options: UseTableOptions): TableReturnType => {
|
|||
props,
|
||||
tableRef,
|
||||
refresh: () => tableRef.value?.reloadData(),
|
||||
getTableInstance() {
|
||||
return tableRef.value?.tableRef;
|
||||
},
|
||||
getSearchInstance() {
|
||||
return tableRef.value?.searchRef;
|
||||
},
|
||||
getCreateInstance() {
|
||||
return tableRef.value?.createRef;
|
||||
},
|
||||
/**
|
||||
* 获取创建表单组件实例
|
||||
*/
|
||||
getCreateFormInstance() {
|
||||
return this.getCreateInstance()?.formRef;
|
||||
},
|
||||
/**
|
||||
* 获取修改表单弹窗组件实例
|
||||
*/
|
||||
getModifyInstance() {
|
||||
return tableRef.value?.modifyRef;
|
||||
},
|
||||
/**
|
||||
* 获取修改表单组件实例
|
||||
*/
|
||||
getModifyFormInstance() {
|
||||
return this.getModifyInstance()?.formRef;
|
||||
},
|
||||
};
|
||||
const aniTable = defineComponent({
|
||||
name: "AniTableWrapper",
|
||||
setup() {
|
||||
setup(p, { slots }) {
|
||||
const onRef = (el: TableInstance) => (tableRef.value = el);
|
||||
return () => <Table ref={onRef} {...props}></Table>;
|
||||
return () => <Table ref={onRef} {...props}>{slots}</Table>;
|
||||
},
|
||||
});
|
||||
return [aniTable, context];
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
export * from './nprogress';
|
||||
export * from './dayjs';
|
||||
|
|
@ -93,13 +93,6 @@ const buttons = [
|
|||
Message.info("暂无通知");
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: "icon-park-outline-moon",
|
||||
tooltip: "主题",
|
||||
onClick: () => {
|
||||
appStore.toggleDark();
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: "icon-park-outline-config",
|
||||
tooltip: "设置",
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { api } from "@/api";
|
||||
import { dayjs } from "@/libs";
|
||||
import { dayjs } from "@/libs/dayjs";
|
||||
import { useAppStore, useUserStore } from "@/store";
|
||||
import { FieldRule, Form, Message, Modal, Notification } from "@arco-design/web-vue";
|
||||
import { reactive } from "vue";
|
||||
|
|
@ -103,8 +103,8 @@ const onSubmitForm = async () => {
|
|||
const res = await api.auth.login(model);
|
||||
userStore.setAccessToken(res.data.data as unknown as string);
|
||||
Notification.success({
|
||||
title: "提示",
|
||||
content: `登陆成功!`,
|
||||
title: "登陆提示",
|
||||
content: `欢迎,您已成功登陆系统!`,
|
||||
});
|
||||
router.push({ path: (route.query.redirect as string) || "/" });
|
||||
} catch (error: any) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div class="w-[210px] h-full overflow-hidden grid grid-rows-[auto_1fr]">
|
||||
<div class="flex gap-2">
|
||||
<a-input-search allow-clear placeholder="分组名称..." class="mb-2"></a-input-search>
|
||||
<a-button @click="onCreateRow">
|
||||
<a-input-search allow-clear placeholder="文件分类" class="mb-2"></a-input-search>
|
||||
<a-button @click="formCtx.open">
|
||||
<template #icon>
|
||||
<i class="icon-park-outline-add"></i>
|
||||
</template>
|
||||
|
|
@ -13,15 +13,15 @@
|
|||
<ul class="pl-0 mt-0">
|
||||
<li
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
:key="item.code"
|
||||
:class="{ active: item.id === current?.id }"
|
||||
class="group flex items-center justify-between gap-1 h-8 rounded mb-2 pl-3 hover:bg-gray-100 cursor-pointer"
|
||||
>
|
||||
<div>
|
||||
<div class="flex-1 h-full flex items-center gap-2 overflow-hidden" @click="emit('change', item)">
|
||||
<i class="icon-park-outline-folder-close align-[-2px]"></i>
|
||||
{{ item.title }}
|
||||
<span class="text-xs text-gray-500"> ({{ item.count }}) </span>
|
||||
<span class="flex-1 truncate">{{ item.name }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="">
|
||||
<a-dropdown>
|
||||
<a-button size="small" type="text">
|
||||
<template #icon>
|
||||
|
|
@ -29,13 +29,13 @@
|
|||
</template>
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-doption @click="onModifyRow(item)">
|
||||
<a-doption @click="formCtx.open(item)">
|
||||
<template #icon>
|
||||
<i class="icon-park-outline-edit"></i>
|
||||
</template>
|
||||
修改
|
||||
</a-doption>
|
||||
<a-doption class="!text-red-500" @click="onDeleteRow">
|
||||
<a-doption class="!text-red-500" @click="onDeleteRow(item)">
|
||||
<template #icon>
|
||||
<i class="icon-park-outline-delete"></i>
|
||||
</template>
|
||||
|
|
@ -51,86 +51,78 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { FileCategory, api } from "@/api";
|
||||
import { useAniFormModal } from "@/components";
|
||||
import { delConfirm } from "@/utils";
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
import { PropType } from "vue";
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: 1,
|
||||
title: "生活笔记",
|
||||
count: 23,
|
||||
defineProps({
|
||||
current: {
|
||||
type: Object as PropType<FileCategory>,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "微信头像",
|
||||
count: 52,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "文章封面",
|
||||
count: 19,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "山水诗画",
|
||||
count: 81,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "虾米沙雕",
|
||||
count: 12,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const list = ref(data);
|
||||
const emit = defineEmits(["change"]);
|
||||
const list = ref<FileCategory[]>([]);
|
||||
|
||||
const onModifyRow = (row: any) => {
|
||||
formCtx.props.title = "修改分组";
|
||||
formCtx.open(row);
|
||||
const updateFileCategories = async () => {
|
||||
const res = await api.fileCategory.getFileCategorys({ size: 0 });
|
||||
list.value = res.data.data ?? [];
|
||||
list.value.unshift({ id: undefined, name: '全部' } as any)
|
||||
list.value.length && emit("change", list.value[0]);
|
||||
};
|
||||
|
||||
const onCreateRow = () => {
|
||||
formCtx.props.title = "新建分组";
|
||||
formCtx.open();
|
||||
};
|
||||
onMounted(updateFileCategories);
|
||||
|
||||
const onDeleteRow = async () => {
|
||||
const onDeleteRow = async (row: FileCategory) => {
|
||||
await delConfirm();
|
||||
const res = await api.dictType.delDictType(row.id);
|
||||
Message.success(res.data.message);
|
||||
};
|
||||
|
||||
const [formModal, formCtx] = useAniFormModal({
|
||||
title: "修改分组",
|
||||
title: ({ model }) => (!model.id ? "新建分类" : "修改分类"),
|
||||
trigger: false,
|
||||
modalProps: {
|
||||
width: 432,
|
||||
width: 580,
|
||||
},
|
||||
model: {
|
||||
id: undefined,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
field: "title",
|
||||
label: "分组名称",
|
||||
field: "name",
|
||||
label: "分类名称",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
field: "code",
|
||||
label: "分类编码",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
field: "description",
|
||||
label: "备注",
|
||||
type: "textarea",
|
||||
},
|
||||
],
|
||||
submit: async ({ model }) => {
|
||||
let res;
|
||||
if (model.id) {
|
||||
const item = list.value.find((i) => i.id === model.id);
|
||||
if (item) {
|
||||
item.title = model.title;
|
||||
}
|
||||
res = await api.fileCategory.setFileCategory(model.id, model);
|
||||
} else {
|
||||
const ids = list.value.map((i) => i.id);
|
||||
const maxId = Math.max.apply(null, ids);
|
||||
list.value.push({
|
||||
id: maxId,
|
||||
title: model.title,
|
||||
count: 0,
|
||||
});
|
||||
res = await api.fileCategory.addFileCategory(model);
|
||||
}
|
||||
updateFileCategories();
|
||||
return res;
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style lang="less" scoped>
|
||||
.active {
|
||||
color: rgb(var(--primary-6));
|
||||
background-color: rgb(var(--primary-1));
|
||||
}
|
||||
</style>
|
||||
|
|
@ -36,11 +36,14 @@
|
|||
<ul v-if="fileList.length" class="h-[424px] overflow-hidden p-0 m-0">
|
||||
<a-scrollbar outer-class="h-full overflow-hidden" class="h-full overflow-auto pr-[20px] divide-y">
|
||||
<li v-for="item in fileList" :key="item.uid" class="flex items-center gap-2 py-3">
|
||||
<div class="text-4xl rounded pr-0.5 flex justify-center">
|
||||
<i :class="getIcon(item.file?.type ?? 'video')"></i>
|
||||
</div>
|
||||
<div class="flex-1 overflow-hidden">
|
||||
<div class="truncate text-slate-900">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2 text-gray-400 mb-[-4px] mt-1">
|
||||
<div class="flex items-center justify-between gap-2 text-gray-400 mb-[-4px] mt-0.5">
|
||||
<span class="text-xs text-gray-400">
|
||||
{{ numeral(item.file?.size).format("0 b") }}
|
||||
</span>
|
||||
|
|
@ -48,14 +51,14 @@
|
|||
<span v-if="item.status === 'init'"> </span>
|
||||
<span v-else-if="item.status === 'uploading'">
|
||||
<span class="text-xs">
|
||||
速度:{{ numeral(fileMap.get(item.uid)?.speed || 0).format("0 b") }}/s, 进度:{{
|
||||
Math.floor((item.percent || 0) * 100)
|
||||
}}
|
||||
%
|
||||
速度:{{ numeral(fileMap.get(item.uid)?.speed || 0).format("0 b") }}/s,
|
||||
进度:{{ Math.floor((item.percent || 0) * 100) }}%
|
||||
</span>
|
||||
</span>
|
||||
<span v-else-if="item.status === 'done'" class="text-green-600">
|
||||
完成(耗时:{{ fileMap.get(item.uid)?.cost || 0 }}秒)
|
||||
完成(
|
||||
耗时:{{ fileMap.get(item.uid)?.cost || 0 }}秒,
|
||||
平均:{{ numeral(fileMap.get(item.uid)?.aspeed || 0).format("0 b") }}/s)
|
||||
</span>
|
||||
<span v-else="item.status === 'error'" class="text-red-500">
|
||||
失败(原因:{{ fileMap.get(item.uid)?.error }})
|
||||
|
|
@ -99,6 +102,7 @@ import { delConfirm } from "@/utils";
|
|||
import { FileItem, Message, RequestOption, UploadInstance } from "@arco-design/web-vue";
|
||||
import axios from "axios";
|
||||
import numeral from "numeral";
|
||||
import { getIcon } from "./util";
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: "success", item: FileItem): void;
|
||||
|
|
@ -115,12 +119,16 @@ const fileMap = reactive<
|
|||
lastTime: number;
|
||||
lastLoaded: number;
|
||||
speed: number;
|
||||
aspeed: number;
|
||||
cost: number;
|
||||
error: string;
|
||||
} | null
|
||||
>
|
||||
>(new Map());
|
||||
|
||||
/**
|
||||
* 统计信息
|
||||
*/
|
||||
const stat = computed(() => {
|
||||
const result = {
|
||||
initCount: 0,
|
||||
|
|
@ -237,6 +245,7 @@ const upload = (option: RequestOption) => {
|
|||
lastLoaded: 0,
|
||||
cost: 0,
|
||||
speed: 0,
|
||||
aspeed: 0,
|
||||
error: "网络异常",
|
||||
});
|
||||
}
|
||||
|
|
@ -253,6 +262,7 @@ const upload = (option: RequestOption) => {
|
|||
const nowTime = Date.now();
|
||||
const diff = (e.loaded - lastLoaded) / (nowTime - lastTime);
|
||||
const speed = Math.floor(diff * 1000);
|
||||
item.aspeed = (item.speed + speed) / 2
|
||||
item.speed = speed;
|
||||
item.lastLoaded = e.loaded;
|
||||
item.lastTime = nowTime;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
const typeIconMap: Record<string, string> = {
|
||||
video: "icon-park-outline-video-file",
|
||||
audio: "icon-park-outline-audio-file",
|
||||
image: "icon-park-outline-file-pdf",
|
||||
text: "icon-park-outline-file-txt",
|
||||
application: "icon-park-outline-file-code",
|
||||
unknown: "icon-park-outline-file-question",
|
||||
};
|
||||
|
||||
function getIconnameByMimetype(mimetype: string) {
|
||||
const [type, subtype] = mimetype.split("/");
|
||||
return typeIconMap[type] || typeIconMap.unknown;
|
||||
}
|
||||
|
||||
function getIcon(mimetype: string) {
|
||||
if (mimetype.startsWith("image")) {
|
||||
return "icon-fmt-png";
|
||||
}
|
||||
if (mimetype.startsWith("video")) {
|
||||
return "icon-fmt-video";
|
||||
}
|
||||
if (mimetype.startsWith("text")) {
|
||||
return "icon-fmt-txt";
|
||||
}
|
||||
if (mimetype.startsWith("audio")) {
|
||||
return "icon-fmt-mp";
|
||||
}
|
||||
return "icon-fmt-visio";
|
||||
}
|
||||
|
||||
export { getIcon, getIconnameByMimetype };
|
||||
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
<template>
|
||||
<BreadPage>
|
||||
<div class="overflow-hidden h-full grid grid-cols-[auto_1fr] gap-4">
|
||||
<ani-group></ani-group>
|
||||
<ani-group :current="current" @change="onCategoryChange"></ani-group>
|
||||
<div>
|
||||
<Table v-bind="table">
|
||||
<file-table>
|
||||
<template #action>
|
||||
<ani-upload></ani-upload>
|
||||
<a-button type="outline" status="danger" :disabled="!selected.length" @click="onDeleteMany">
|
||||
<ani-upload @close="onUploadClose"></ani-upload>
|
||||
<a-button type="primary" status="danger" :disabled="!selected.length" @click="onDeleteMany">
|
||||
批量删除
|
||||
</a-button>
|
||||
</template>
|
||||
</Table>
|
||||
</file-table>
|
||||
<a-image-preview v-model:visible="visible" :src="image"></a-image-preview>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -18,16 +18,19 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { api } from "@/api";
|
||||
import { Table, createColumn, updateColumn, useTable } from "@/components";
|
||||
import { FileCategory, api } from "@/api";
|
||||
import { createColumn, updateColumn, useAniTable } from "@/components";
|
||||
import { delConfirm } from "@/utils";
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
import numeral from "numeral";
|
||||
import AniGroup from "./components/group.vue";
|
||||
import AniUpload from "./components/upload.vue";
|
||||
import { getIcon } from "./components/util";
|
||||
|
||||
const visible = ref(false);
|
||||
const image = ref("");
|
||||
const selected = ref<number[]>([]);
|
||||
const current = ref<FileCategory>();
|
||||
const preview = (record: any) => {
|
||||
if (!record.mimetype.startsWith("image")) {
|
||||
window.open(record.path, "_blank");
|
||||
|
|
@ -37,29 +40,31 @@ const preview = (record: any) => {
|
|||
visible.value = true;
|
||||
};
|
||||
|
||||
const onUploadClose = (count: number) => {
|
||||
if (count) {
|
||||
fileCtx.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
const onDeleteMany = async () => {
|
||||
await delConfirm();
|
||||
const res = await api.file.delFiles(selected.value as any[]);
|
||||
selected.value = [];
|
||||
Message.success(res.data.message);
|
||||
fileCtx.refresh();
|
||||
};
|
||||
|
||||
const getIcon = (mimetype: string) => {
|
||||
if (mimetype.startsWith("image")) {
|
||||
return "icon-file-iimage";
|
||||
const onCategoryChange = (category: FileCategory) => {
|
||||
if (fileCtx.props.search?.model) {
|
||||
fileCtx.props.search.model.categoryId = category.id;
|
||||
}
|
||||
if (mimetype.startsWith("video")) {
|
||||
return "icon-file-ivideo";
|
||||
}
|
||||
if (mimetype.startsWith("text")) {
|
||||
return "icon-file-itxt";
|
||||
}
|
||||
if (mimetype.startsWith("audio")) {
|
||||
return "icon-file-iaudio";
|
||||
}
|
||||
return "icon-file-iunknown";
|
||||
current.value = category;
|
||||
fileCtx.refresh();
|
||||
};
|
||||
|
||||
const table = useTable({
|
||||
const [fileTable, fileCtx] = useAniTable({
|
||||
data: async (model, paging) => {
|
||||
return api.file.getFiles();
|
||||
return api.file.getFiles({ ...model, ...paging });
|
||||
},
|
||||
tableProps: {
|
||||
rowSelection: {
|
||||
|
|
@ -73,30 +78,31 @@ const table = useTable({
|
|||
{
|
||||
title: "文件名称",
|
||||
dataIndex: "name",
|
||||
render({ record }) {
|
||||
return (
|
||||
<div class="flex items-center gap-2">
|
||||
<div>
|
||||
{record.mimetype.startsWith("image") ? (
|
||||
<a-avatar size={32} shape="square">
|
||||
<img src={record.path}></img>
|
||||
</a-avatar>
|
||||
) : (
|
||||
<i class={`${getIcon(record.mimetype)} text-3xl mr-2`}></i>
|
||||
)}
|
||||
</div>
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<span
|
||||
class="hover:text-brand-500 hover:decoration-underline underline-offset-2 cursor-pointer"
|
||||
onClick={() => preview(record)}
|
||||
>
|
||||
{record.name}
|
||||
</span>
|
||||
<span class="text-gray-400 text-xs truncate">{numeral(record.size).format("0 b")}</span>
|
||||
</div>
|
||||
render: ({ record }) => (
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-8 flex justify-center">
|
||||
{record.mimetype.startsWith("image") ? (
|
||||
<a-avatar size={26} shape="square">
|
||||
<img src={record.path}></img>
|
||||
</a-avatar>
|
||||
) : (
|
||||
<i class={`${getIcon(record.mimetype)} text-4xl`}></i>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<span
|
||||
class="hover:text-brand-500 hover:decoration-underline underline-offset-2 cursor-pointer"
|
||||
onClick={() => preview(record)}
|
||||
>
|
||||
{record.name}
|
||||
</span>
|
||||
<span class="text-gray-400 text-xs truncate">
|
||||
{numeral(record.size).format("0 b")}
|
||||
<span class="ml-2">{record.category?.name}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
createColumn,
|
||||
updateColumn,
|
||||
|
|
@ -121,6 +127,9 @@ const table = useTable({
|
|||
],
|
||||
search: {
|
||||
button: false,
|
||||
model: {
|
||||
categoryId: undefined,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
field: "name",
|
||||
|
|
@ -143,6 +152,12 @@ const table = useTable({
|
|||
width: 580,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
field: "categoryId",
|
||||
label: "分类",
|
||||
type: "select",
|
||||
options: () => api.fileCategory.getFileCategorys({ size: 0 }),
|
||||
},
|
||||
{
|
||||
field: "name",
|
||||
label: "名称",
|
||||
|
|
@ -167,7 +182,7 @@ const table = useTable({
|
|||
<route lang="json">
|
||||
{
|
||||
"meta": {
|
||||
"sort": 10304,
|
||||
"sort": 10305,
|
||||
"title": "素材管理",
|
||||
"icon": "icon-park-outline-movie-board"
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
<route lang="json">
|
||||
{
|
||||
"meta": {
|
||||
"sort": 10300,
|
||||
"sort": 10301,
|
||||
"title": "文章管理",
|
||||
"icon": "icon-park-outline-editor"
|
||||
}
|
||||
|
|
@ -114,6 +114,7 @@ const onOpen = () => {
|
|||
|
||||
<route lang="json">
|
||||
{
|
||||
"only": "dev",
|
||||
"meta": {
|
||||
"sort": 20010,
|
||||
"title": "接口生成",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"only": "dev",
|
||||
"meta": {
|
||||
"sort": 20010,
|
||||
"title": "开发相关",
|
||||
"icon": "icon-park-outline-home"
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
|
@ -16,15 +16,11 @@
|
|||
|
||||
<route lang="json">
|
||||
{
|
||||
"only": "dev",
|
||||
"meta": {
|
||||
"sort": 20010,
|
||||
"title": "接口文档",
|
||||
"icon": "icon-park-outline-api"
|
||||
},
|
||||
"parentMeta": {
|
||||
"sort": 20010,
|
||||
"title": "开发相关",
|
||||
"icon": "icon-park-outline-home"
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
|
@ -37,16 +37,14 @@ const [dictTable, dict] = useAniTable({
|
|||
{
|
||||
title: "字典项",
|
||||
dataIndex: "name",
|
||||
render: ({ record }) => {
|
||||
return (
|
||||
render: ({ record }) => (
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
<span class="text-gray-900">{record.name}</span>: {record.code}
|
||||
</div>
|
||||
<div class="text-gray-400 text-xs">{record.description}</div>
|
||||
{record.name}<span class="text-gray-400 ml-2 text-xs">{record.code}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
<div class="text-gray-400 text-xs">{record.description}</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
createColumn,
|
||||
updateColumn,
|
||||
|
|
@ -88,7 +86,7 @@ const [dictTable, dict] = useAniTable({
|
|||
],
|
||||
},
|
||||
create: {
|
||||
title: '新增字典',
|
||||
title: "新增字典",
|
||||
model: {
|
||||
typeId: undefined,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
<template>
|
||||
<bread-page class="">
|
||||
<menu-table>
|
||||
<template #action>
|
||||
<a-button type="outline">展开/折叠</a-button>
|
||||
</template>
|
||||
</menu-table>
|
||||
<menu-table> </menu-table>
|
||||
</bread-page>
|
||||
</template>
|
||||
|
||||
|
|
@ -13,6 +9,7 @@ import { api } from "@/api";
|
|||
import { createColumn, updateColumn, useAniTable } from "@/components";
|
||||
import { MenuTypes, MenuType } from "@/constants/menu";
|
||||
import { flatedMenus } from "@/router";
|
||||
import { listToTree } from "@/utils/listToTree";
|
||||
|
||||
const menuArr = flatedMenus.map((i) => ({ label: i.title, value: i.id }));
|
||||
|
||||
|
|
@ -24,23 +21,21 @@ const toggleExpand = () => {
|
|||
|
||||
const [menuTable, menu] = useAniTable({
|
||||
data: (search, paging) => {
|
||||
return api.menu.getMenus({ ...search, ...paging, tree: true });
|
||||
return api.menu.getMenus({ ...search, ...paging, tree: true, size: 0 });
|
||||
},
|
||||
tableProps: {
|
||||
defaultExpandAllRows: true,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: () => {
|
||||
return (
|
||||
<span>
|
||||
菜单名称
|
||||
<a-link class="ml-1 select-none" onClick={toggleExpand}>
|
||||
{expanded.value ? "收起全部" : "展开全部"}
|
||||
</a-link>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
title: () => (
|
||||
<span>
|
||||
菜单名称
|
||||
<a-link class="ml-1 select-none" onClick={toggleExpand}>
|
||||
{expanded.value ? "收起全部" : "展开全部"}
|
||||
</a-link>
|
||||
</span>
|
||||
),
|
||||
dataIndex: "name",
|
||||
render({ record }) {
|
||||
let id = "";
|
||||
|
|
@ -125,19 +120,24 @@ const [menuTable, menu] = useAniTable({
|
|||
label: "父级",
|
||||
type: "treeSelect",
|
||||
async options() {
|
||||
const res = await api.menu.getMenus({ size: 0, tree: true });
|
||||
const data = res.data.data;
|
||||
const res = await api.menu.getMenus({ size: 0 });
|
||||
const data = res.data.data?.filter((i) => i.type !== MenuType.BUTTON) ?? [];
|
||||
for (const item of data) {
|
||||
const type = MenuTypes.fmt(item.type);
|
||||
// @ts-ignore
|
||||
item.icon = () => `[${type}]`;
|
||||
}
|
||||
const list = listToTree(data);
|
||||
return [
|
||||
{
|
||||
id: 0,
|
||||
name: "主类目",
|
||||
children: data,
|
||||
children: list,
|
||||
},
|
||||
];
|
||||
},
|
||||
nodeProps: {
|
||||
fieldNames: {
|
||||
icon: undefined,
|
||||
key: "id",
|
||||
title: "name",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { progressGuard } from "../guards/guard-progress";
|
|||
import { titleGuard } from "../guards/guard-title";
|
||||
import { routes } from "../routes";
|
||||
import { api } from "@/api";
|
||||
import { store, useUserStore } from "@/store";
|
||||
|
||||
export const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
|
|
@ -21,7 +22,9 @@ router.afterEach(progressGuard.after);
|
|||
router.beforeEach(authGuard);
|
||||
router.afterEach(titleGuard);
|
||||
|
||||
api.setTokenExpiredHandler(() => {
|
||||
api.expireHandler = () => {
|
||||
const userStore = useUserStore(store);
|
||||
userStore.clearUser();
|
||||
const redirect = router.currentRoute.value.path;
|
||||
router.push({ path: "/login", query: { redirect } });
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
"vite.config.ts",
|
||||
"scripts/vite/**/*.ts",
|
||||
"scripts/vite/file.json",
|
||||
"scripts/vite/fmt.json",
|
||||
"package.json",
|
||||
"src/types/env.d.ts"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ import { defineConfig, loadEnv } from "vite";
|
|||
import Page from "vite-plugin-pages";
|
||||
import { arcoToUnoColor } from "./scripts/vite/color";
|
||||
import iconFile from "./scripts/vite/file.json";
|
||||
import iconFmt from "./scripts/vite/fmt.json";
|
||||
import plugin from "./scripts/vite/plugin";
|
||||
import { visualizer } from "rollup-plugin-visualizer";
|
||||
|
||||
/**
|
||||
* vite 配置
|
||||
|
|
@ -63,7 +65,14 @@ export default defineConfig(({ mode }) => {
|
|||
* @see https://github.com/hannoeru/vite-plugin-pages
|
||||
*/
|
||||
Page({
|
||||
exclude: ["**/components/*.vue", "**/*.*.vue"],
|
||||
exclude: ["**/components/*", "**/*.*.*"],
|
||||
importMode: "async",
|
||||
onRoutesGenerated(routes) {
|
||||
// if (env.DEV) {
|
||||
// return routes;
|
||||
// }
|
||||
return routes.filter((route) => route.only !== "dev");
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
|
|
@ -83,11 +92,21 @@ export default defineConfig(({ mode }) => {
|
|||
prefix: "",
|
||||
collections: {
|
||||
"icon-file": iconFile,
|
||||
"icon-fmt": iconFmt,
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
||||
/**
|
||||
* 产物分析
|
||||
* @see https://github.com/btd/rollup-plugin-visualizer
|
||||
*/
|
||||
visualizer({
|
||||
title: "产物分析 | 自动生成",
|
||||
filename: ".gitea/stat.html",
|
||||
}),
|
||||
|
||||
/**
|
||||
* 项目插件,打包时注入版本信息、基于文件后缀打包等
|
||||
* @see ./scripts/vite/plugin.ts
|
||||
|
|
|
|||
Loading…
Reference in New Issue