From 23e215b009ef2abef99966cc85d88a2fc448a5d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Sun, 9 Feb 2025 04:42:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20alova.js=E6=9B=BF=E6=8D=A2axios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/.env.development | 2 +- web/package.json | 1 - web/pnpm-lock.yaml | 73 ------- web/src/api/panel/container/index.ts | 50 ++--- web/src/utils/http/helpers.ts | 14 -- web/src/utils/http/index.ts | 20 -- web/src/utils/http/interceptors.ts | 85 --------- web/src/views/container/ContainerCreate.vue | 29 ++- web/src/views/container/ContainerView.vue | 200 ++++++++++---------- web/src/views/container/ImageView.vue | 77 +++----- web/src/views/container/NetworkView.vue | 77 +++----- web/src/views/container/VolumeView.vue | 76 +++----- web/src/views/container/types.ts | 85 --------- web/types/axios.d.ts | 12 -- 14 files changed, 233 insertions(+), 568 deletions(-) delete mode 100644 web/src/utils/http/interceptors.ts delete mode 100644 web/src/views/container/types.ts delete mode 100644 web/types/axios.d.ts diff --git a/web/.env.development b/web/.env.development index 7714a753..aa183cda 100644 --- a/web/.env.development +++ b/web/.env.development @@ -6,7 +6,7 @@ VITE_PUBLIC_PATH = '/' # 是否hash路由模式 VITE_USE_HASH = false -# axios base api +# base api VITE_BASE_API = '/api' # 是否启用代理(只对本地vite server生效) diff --git a/web/package.json b/web/package.json index a85657df..5acee652 100644 --- a/web/package.json +++ b/web/package.json @@ -37,7 +37,6 @@ "@xterm/addon-webgl": "^0.18.0", "@xterm/xterm": "^5.5.0", "alova": "^3.2.7", - "axios": "^1.7.9", "cronstrue": "^2.52.0", "echarts": "^5.6.0", "install": "^0.13.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 8e744f26..063b1608 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -50,9 +50,6 @@ importers: alova: specifier: ^3.2.7 version: 3.2.8 - axios: - specifier: ^1.7.9 - version: 1.7.9 cronstrue: specifier: ^2.52.0 version: 2.54.0 @@ -1595,16 +1592,10 @@ packages: async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.7.9: - resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1728,10 +1719,6 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - commander@13.1.0: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} @@ -1891,10 +1878,6 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - destr@2.0.3: resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} @@ -2169,15 +2152,6 @@ packages: flatted@3.3.2: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - for-each@0.3.4: resolution: {integrity: sha512-kKaIINnFpzW6ffJNDjjyjrk21BkDx38c0xa/klsT8VzLCaMEefv4ZTacrcVR4DmgTeBra++jMDAfS/tS799YDw==} engines: {node: '>= 0.4'} @@ -2186,10 +2160,6 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} - form-data@4.0.1: - resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} - engines: {node: '>= 6'} - fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -2701,14 +2671,6 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - 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'} - minimatch@10.0.1: resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} engines: {node: 20 || >=22} @@ -3029,9 +2991,6 @@ packages: resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} engines: {node: '>=18'} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - punycode.js@2.3.1: resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} engines: {node: '>=6'} @@ -5359,20 +5318,10 @@ snapshots: async@3.2.6: {} - asynckit@0.4.0: {} - available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 - axios@1.7.9: - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.1 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - balanced-match@1.0.2: {} binary-extensions@2.3.0: {} @@ -5515,10 +5464,6 @@ snapshots: colorette@2.0.20: {} - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - commander@13.1.0: {} commander@2.20.3: {} @@ -5673,8 +5618,6 @@ snapshots: defu@6.1.4: {} - delayed-stream@1.0.0: {} - destr@2.0.3: {} detect-libc@1.0.3: @@ -6075,8 +6018,6 @@ snapshots: flatted@3.3.2: {} - follow-redirects@1.15.9: {} - for-each@0.3.4: dependencies: is-callable: 1.2.7 @@ -6086,12 +6027,6 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - form-data@4.0.1: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 @@ -6596,12 +6531,6 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - minimatch@10.0.1: dependencies: brace-expansion: 2.0.1 @@ -6916,8 +6845,6 @@ snapshots: dependencies: parse-ms: 4.0.0 - proxy-from-env@1.1.0: {} - punycode.js@2.3.1: {} punycode@2.3.1: {} diff --git a/web/src/api/panel/container/index.ts b/web/src/api/panel/container/index.ts index 3aabd6f8..3c02b914 100644 --- a/web/src/api/panel/container/index.ts +++ b/web/src/api/panel/container/index.ts @@ -1,57 +1,57 @@ -import { request } from '@/utils' +import { http } from '@/utils' export default { // 获取容器列表 containerList: (page: number, limit: number): any => - request.get('/container/container', { params: { page, limit } }), + http.Get('/container/container', { params: { page, limit } }), // 添加容器 - containerCreate: (config: any): any => request.post('/container/container', config), + containerCreate: (config: any): any => http.Post('/container/container', config), // 删除容器 - containerRemove: (id: string): any => request.delete(`/container/container/${id}`), + containerRemove: (id: string): any => http.Delete(`/container/container/${id}`), // 启动容器 - containerStart: (id: string): any => request.post(`/container/container/${id}/start`), + containerStart: (id: string): any => http.Post(`/container/container/${id}/start`), // 停止容器 - containerStop: (id: string): any => request.post(`/container/container/${id}/stop`), + containerStop: (id: string): any => http.Post(`/container/container/${id}/stop`), // 重启容器 - containerRestart: (id: string): any => request.post(`/container/container/${id}/restart`), + containerRestart: (id: string): any => http.Post(`/container/container/${id}/restart`), // 暂停容器 - containerPause: (id: string): any => request.post(`/container/container/${id}/pause`), + containerPause: (id: string): any => http.Post(`/container/container/${id}/pause`), // 恢复容器 - containerUnpause: (id: string): any => request.post(`/container/container/${id}/unpause`), + containerUnpause: (id: string): any => http.Post(`/container/container/${id}/unpause`), // 杀死容器 - containerKill: (id: string): any => request.post(`/container/container/${id}/kill`), + containerKill: (id: string): any => http.Post(`/container/container/${id}/kill`), // 重命名容器 containerRename: (id: string, name: string): any => - request.post(`/container/container/${id}/rename`, { name }), + http.Post(`/container/container/${id}/rename`, { name }), // 获取容器日志 - containerLogs: (id: string): any => request.get(`/container/container/${id}/logs`), + containerLogs: (id: string): any => http.Get(`/container/container/${id}/logs`), // 清理容器 - containerPrune: (): any => request.post(`/container/container/prune`), + containerPrune: (): any => http.Post(`/container/container/prune`), // 获取网络列表 networkList: (page: number, limit: number): any => - request.get(`/container/network`, { params: { page, limit } }), + http.Get(`/container/network`, { params: { page, limit } }), // 创建网络 - networkCreate: (config: any): any => request.post(`/container/network`, config), + networkCreate: (config: any): any => http.Post(`/container/network`, config), // 删除网络 - networkRemove: (id: string): any => request.delete(`/container/network/${id}`), + networkRemove: (id: string): any => http.Delete(`/container/network/${id}`), // 清理网络 - networkPrune: (): any => request.post(`/container/network/prune`), + networkPrune: (): any => http.Post(`/container/network/prune`), // 获取镜像列表 imageList: (page: number, limit: number): any => - request.get(`/container/image`, { params: { page, limit } }), + http.Get(`/container/image`, { params: { page, limit } }), // 拉取镜像 - imagePull: (config: any): any => request.post(`/container/image`, config), + imagePull: (config: any): any => http.Post(`/container/image`, config), // 删除镜像 - imageRemove: (id: string): any => request.delete(`/container/image/${id}`), + imageRemove: (id: string): any => http.Delete(`/container/image/${id}`), // 清理镜像 - imagePrune: (): any => request.post(`/container/image/prune`), + imagePrune: (): any => http.Post(`/container/image/prune`), // 获取卷列表 volumeList: (page: number, limit: number): any => - request.get(`/container/volume`, { params: { page, limit } }), + http.Get(`/container/volume`, { params: { page, limit } }), // 创建卷 - volumeCreate: (config: any): any => request.post(`/container/volume`, config), + volumeCreate: (config: any): any => http.Post(`/container/volume`, config), // 删除卷 - volumeRemove: (id: string): any => request.delete(`/container/volume/${id}`), + volumeRemove: (id: string): any => http.Delete(`/container/volume/${id}`), // 清理卷 - volumePrune: (): any => request.post(`/container/volume/prune`) + volumePrune: (): any => http.Post(`/container/volume/prune`) } diff --git a/web/src/utils/http/helpers.ts b/web/src/utils/http/helpers.ts index 9e22969e..ccd6df43 100644 --- a/web/src/utils/http/helpers.ts +++ b/web/src/utils/http/helpers.ts @@ -1,18 +1,4 @@ import { useUserStore } from '@/store' -import type { ErrorResolveResponse } from '~/types/axios' - -/** 自定义错误 */ -export class AxiosRejectError extends Error { - code?: number | string - data?: any - - constructor(rejectData: ErrorResolveResponse, options?: ErrorOptions) { - const { code, message, data } = rejectData - super(message, options) - this.code = code - this.data = data - } -} export function resolveResError(code: number | string | undefined, message = ''): string { switch (code) { diff --git a/web/src/utils/http/index.ts b/web/src/utils/http/index.ts index 7c497e04..291e1287 100644 --- a/web/src/utils/http/index.ts +++ b/web/src/utils/http/index.ts @@ -3,26 +3,6 @@ import type { AlovaXHRResponse } from '@alova/adapter-xhr' import { xhrRequestAdapter } from '@alova/adapter-xhr' import { createAlova, Method } from 'alova' import VueHook from 'alova/vue' -import axios from 'axios' -import { reqReject, reqResolve, resReject, resResolve } from './interceptors' - -export function createAxios(options = {}) { - const defaultOptions = { - adapter: 'fetch', - timeout: 0 - } - const service = axios.create({ - ...defaultOptions, - ...options - }) - service.interceptors.request.use(reqResolve, reqReject) - service.interceptors.response.use(resResolve, resReject) - return service -} - -export const request = createAxios({ - baseURL: import.meta.env.VITE_BASE_API -}) export const http = createAlova({ id: 'panel', diff --git a/web/src/utils/http/interceptors.ts b/web/src/utils/http/interceptors.ts deleted file mode 100644 index 0143c77e..00000000 --- a/web/src/utils/http/interceptors.ts +++ /dev/null @@ -1,85 +0,0 @@ -import type { AxiosError, AxiosResponse } from 'axios' -import type { RequestConfig } from '~/types/axios' -import { AxiosRejectError, resolveResError } from './helpers' - -/** 请求拦截 */ -export function reqResolve(config: RequestConfig) { - return config -} - -/** 请求错误拦截 */ -export function reqReject(error: AxiosError) { - return Promise.reject(error) -} - -/** 响应拦截 */ -export function resResolve(response: AxiosResponse) { - const { data, status, config, statusText } = response - if (status !== 200) { - const code = data?.code ?? status - const message = resolveResError(code, data?.message ?? statusText) - const { noNeedTip } = config as RequestConfig - - if (!noNeedTip) { - if (code == 422) { - window.$message.error(message) - } else { - if (code != 401) { - window.$dialog.error({ - title: '请求返回异常', - content: message, - maskClosable: false - }) - } - } - } - - return Promise.reject(new AxiosRejectError({ code, message, data: data || response })) - } - - return Promise.resolve(data) -} - -/** 响应错误拦截 */ -export function resReject(error: AxiosError) { - if (!error || !error.response) { - const code = error?.code - /** 根据code处理对应的操作,并返回处理后的message */ - const message = resolveResError(code, error.message) - window.$dialog.error({ - title: '请求出现异常', - content: message, - maskClosable: false - }) - return Promise.reject(new AxiosRejectError({ code, message, data: error })) - } - const { data, status, config } = error.response - let { code, message } = data as AxiosRejectError - code = code ?? status - message = message ?? error.message - message = resolveResError(code, message) - /** 需要错误提醒 */ - const { noNeedTip } = config as RequestConfig - - if (!noNeedTip) { - if (code == 422) { - window.$message.error(message) - } else { - if (code != 401) { - window.$dialog.error({ - title: '请求返回异常', - content: message, - maskClosable: false - }) - } - } - } - - return Promise.reject( - new AxiosRejectError({ - code, - message, - data: error.response?.data || error.response - }) - ) -} diff --git a/web/src/views/container/ContainerCreate.vue b/web/src/views/container/ContainerCreate.vue index 8035e5b3..e1b7eeee 100644 --- a/web/src/views/container/ContainerCreate.vue +++ b/web/src/views/container/ContainerCreate.vue @@ -82,31 +82,28 @@ const removeVolumeRow = (index: number) => { createModel.volumes.splice(index, 1) } -const getNetworks = async () => { - const { data } = await container.networkList(1, 1000) - networks.value = data.items.map((item: any) => { - return { - label: item.name, - value: item.id +const getNetworks = () => { + useRequest(container.networkList(1, 1000)).onSuccess(({ data }) => { + networks.value = data.items.map((item: any) => { + return { + label: item.name, + value: item.id + } + }) + if (networks.value.length > 0) { + createModel.network = networks.value[0].value } }) - if (networks.value.length > 0) { - createModel.network = networks.value[0].value - } } const handleSubmit = () => { doSubmit.value = true - container - .containerCreate(createModel) - .then(() => { + useRequest(container.containerCreate(createModel)) + .onSuccess(() => { window.$message.success('创建成功') handleClose() }) - .catch(() => { - window.$message.error('创建失败') - }) - .finally(() => { + .onComplete(() => { doSubmit.value = false }) } diff --git a/web/src/views/container/ContainerView.vue b/web/src/views/container/ContainerView.vue index 1f52f4b5..f5b945f1 100644 --- a/web/src/views/container/ContainerView.vue +++ b/web/src/views/container/ContainerView.vue @@ -4,9 +4,6 @@ import { NButton, NDataTable, NDropdown, NFlex, NInput, NSwitch, NTag } from 'na import container from '@/api/panel/container' import ContainerCreate from '@/views/container/ContainerCreate.vue' -import type { ContainerList } from '@/views/container/types' - -const data = ref([] as ContainerList[]) const logModal = ref(false) const logs = ref('') @@ -209,103 +206,86 @@ const columns: any = [ } ] -const pagination = reactive({ - page: 1, - pageCount: 1, - pageSize: 20, - itemCount: 0, - showQuickJumper: true, - showSizePicker: true, - pageSizes: [20, 50, 100, 200] -}) - -const onPageChange = (page: number) => { - pagination.page = page - getContainerList(page, pagination.pageSize).then((res) => { - data.value = res.items - pagination.itemCount = res.total - pagination.pageCount = res.total / pagination.pageSize + 1 - }) -} - -const onPageSizeChange = (pageSize: number) => { - pagination.pageSize = pageSize - onPageChange(1) -} - -const getContainerList = async (page: number, pageSize: number) => { - const { data } = await container.containerList(page, pageSize) - return data -} +const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination( + (page, pageSize) => container.containerList(page, pageSize), + { + initialData: { total: 0, list: [] }, + initialPageSize: 20, + total: (res: any) => res.total, + data: (res: any) => res.items + } +) const handleShowLog = async (row: any) => { - container.containerLogs(row.id).then((res) => { - logs.value = res.data + useRequest(container.containerLogs(row.id)).onSuccess(({ data }) => { + logs.value = data logModal.value = true }) } const handleRename = () => { - container.containerRename(renameModel.value.id, renameModel.value.name).then(() => { - window.$message.success('重命名成功') - renameModal.value = false - onPageChange(pagination.page) - }) + useRequest(container.containerRename(renameModel.value.id, renameModel.value.name)).onSuccess( + () => { + refresh() + renameModal.value = false + window.$message.success('重命名成功') + } + ) } const handleStart = (id: string) => { - container.containerStart(id).then(() => { + useRequest(container.containerStart(id)).onSuccess(() => { + refresh() window.$message.success('启动成功') - onPageChange(pagination.page) }) } const handleStop = (id: string) => { - container.containerStop(id).then(() => { + useRequest(container.containerStop(id)).onSuccess(() => { + refresh() window.$message.success('停止成功') - onPageChange(pagination.page) }) } const handleRestart = (id: string) => { - container.containerRestart(id).then(() => { + useRequest(container.containerRestart(id)).onSuccess(() => { + refresh() window.$message.success('重启成功') - onPageChange(pagination.page) }) } const handleForceStop = (id: string) => { - container.containerKill(id).then(() => { + useRequest(container.containerKill(id)).onSuccess(() => { + refresh() window.$message.success('强制停止成功') - onPageChange(pagination.page) }) } const handlePause = (id: string) => { - container.containerPause(id).then(() => { + useRequest(container.containerPause(id)).onSuccess(() => { + refresh() window.$message.success('暂停成功') - onPageChange(pagination.page) }) } const handleUnpause = (id: string) => { - container.containerUnpause(id).then(() => { + useRequest(container.containerUnpause(id)).onSuccess(() => { + refresh() window.$message.success('恢复成功') - onPageChange(pagination.page) }) } const handleDelete = (id: string) => { - container.containerRemove(id).then(() => { + useRequest(container.containerRemove(id)).onSuccess(() => { + refresh() window.$message.success('删除成功') - onPageChange(pagination.page) }) } const handlePrune = () => { - container.containerPrune().then(() => { + useRequest(container.containerPrune()).onSuccess(() => { + refresh() window.$message.success('清理成功') - onPageChange(pagination.page) }) } @@ -315,14 +295,17 @@ const bulkStart = async () => { return } - for (const id of selectedRowKeys.value) { - await container.containerStart(id).then(() => { - const container = data.value.find((item) => item.id === id) + const promises = selectedRowKeys.value.map((id: any) => + useRequest(container.containerStart(id)).onSuccess(() => { + const container = data.value.find((item: any) => item.id === id) window.$message.success(`${container?.name} 启动成功`) }) - } + ) - onPageChange(pagination.page) + await Promise.all(promises) + + selectedRowKeys.value = [] + await refresh() } const bulkStop = async () => { @@ -331,14 +314,17 @@ const bulkStop = async () => { return } - for (const id of selectedRowKeys.value) { - await container.containerStop(id).then(() => { - const container = data.value.find((item) => item.id === id) + const promises = selectedRowKeys.value.map((id: any) => + useRequest(container.containerStop(id)).onSuccess(() => { + const container = data.value.find((item: any) => item.id === id) window.$message.success(`${container?.name} 停止成功`) }) - } + ) - onPageChange(pagination.page) + await Promise.all(promises) + + selectedRowKeys.value = [] + await refresh() } const bulkRestart = async () => { @@ -347,14 +333,17 @@ const bulkRestart = async () => { return } - for (const id of selectedRowKeys.value) { - await container.containerRestart(id).then(() => { - const container = data.value.find((item) => item.id === id) + const promises = selectedRowKeys.value.map((id: any) => + useRequest(container.containerRestart(id)).onSuccess(() => { + const container = data.value.find((item: any) => item.id === id) window.$message.success(`${container?.name} 重启成功`) }) - } + ) - onPageChange(pagination.page) + await Promise.all(promises) + + selectedRowKeys.value = [] + await refresh() } const bulkForceStop = async () => { @@ -363,14 +352,17 @@ const bulkForceStop = async () => { return } - for (const id of selectedRowKeys.value) { - await container.containerKill(id).then(() => { - const container = data.value.find((item) => item.id === id) + const promises = selectedRowKeys.value.map((id: any) => + useRequest(container.containerKill(id)).onSuccess(() => { + const container = data.value.find((item: any) => item.id === id) window.$message.success(`${container?.name} 强制停止成功`) }) - } + ) - onPageChange(pagination.page) + await Promise.all(promises) + + selectedRowKeys.value = [] + await refresh() } const bulkDelete = async () => { @@ -379,14 +371,17 @@ const bulkDelete = async () => { return } - for (const id of selectedRowKeys.value) { - await container.containerRemove(id).then(() => { - const container = data.value.find((item) => item.id === id) + const promises = selectedRowKeys.value.map((id: any) => + useRequest(container.containerRemove(id)).onSuccess(() => { + const container = data.value.find((item: any) => item.id === id) window.$message.success(`${container?.name} 删除成功`) }) - } + ) - onPageChange(pagination.page) + await Promise.all(promises) + + selectedRowKeys.value = [] + await refresh() } const bulkPause = async () => { @@ -395,14 +390,17 @@ const bulkPause = async () => { return } - for (const id of selectedRowKeys.value) { - await container.containerPause(id).then(() => { - const container = data.value.find((item) => item.id === id) + const promises = selectedRowKeys.value.map((id: any) => + useRequest(container.containerPause(id)).onSuccess(() => { + const container = data.value.find((item: any) => item.id === id) window.$message.success(`${container?.name} 暂停成功`) }) - } + ) - onPageChange(pagination.page) + await Promise.all(promises) + + selectedRowKeys.value = [] + await refresh() } const bulkUnpause = async () => { @@ -411,23 +409,26 @@ const bulkUnpause = async () => { return } - for (const id of selectedRowKeys.value) { - await container.containerUnpause(id).then(() => { - const container = data.value.find((item) => item.id === id) + const promises = selectedRowKeys.value.map((id: any) => + useRequest(container.containerUnpause(id)).onSuccess(() => { + const container = data.value.find((item: any) => item.id === id) window.$message.success(`${container?.name} 恢复成功`) }) - } + ) - onPageChange(pagination.page) + await Promise.all(promises) + + selectedRowKeys.value = [] + await refresh() } const closeContainerCreateModal = () => { containerCreateModal.value = false - onPageChange(pagination.page) + refresh() } onMounted(() => { - onPageChange(pagination.page) + refresh() }) @@ -452,16 +453,23 @@ onMounted(() => { diff --git a/web/src/views/container/ImageView.vue b/web/src/views/container/ImageView.vue index 7540cd5e..44efdf2d 100644 --- a/web/src/views/container/ImageView.vue +++ b/web/src/views/container/ImageView.vue @@ -3,7 +3,6 @@ import { NButton, NDataTable, NFlex, NInput, NPopconfirm, NTag } from 'naive-ui' import container from '@/api/panel/container' import { formatDateTime } from '@/utils' -import type { ImageList } from '@/views/container/types' const pullModel = ref({ name: '', @@ -12,9 +11,6 @@ const pullModel = ref({ password: '' }) const pullModal = ref(false) -const loading = ref(false) - -const data = ref([] as ImageList[]) const selectedRowKeys = ref([]) const onChecked = (rowKeys: any) => { @@ -108,65 +104,45 @@ const columns: any = [ } ] -const pagination = reactive({ - page: 1, - pageCount: 1, - pageSize: 20, - itemCount: 0, - showQuickJumper: true, - showSizePicker: true, - pageSizes: [20, 50, 100, 200] -}) - -const onPageChange = (page: number) => { - pagination.page = page - getImageList(page, pagination.pageSize).then((res) => { - data.value = res.items - pagination.itemCount = res.total - pagination.pageCount = res.total / pagination.pageSize + 1 - }) -} - -const onPageSizeChange = (pageSize: number) => { - pagination.pageSize = pageSize - onPageChange(1) -} - -const getImageList = async (page: number, pageSize: number) => { - const { data } = await container.imageList(page, pageSize) - return data -} +const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination( + (page, pageSize) => container.imageList(page, pageSize), + { + initialData: { total: 0, list: [] }, + initialPageSize: 20, + total: (res: any) => res.total, + data: (res: any) => res.items + } +) const handleDelete = async (row: any) => { - container.imageRemove(row.id).then(() => { + useRequest(container.imageRemove(row.id)).onSuccess(() => { + refresh() window.$message.success('删除成功') - onPageChange(pagination.page) }) } const handlePrune = () => { - container.imagePrune().then(() => { + useRequest(container.imagePrune()).onSuccess(() => { + refresh() window.$message.success('清理成功') - onPageChange(pagination.page) }) } const handlePull = () => { loading.value = true - container - .imagePull(pullModel.value) - .then(() => { + useRequest(container.imagePull(pullModel.value)) + .onSuccess(() => { + refresh() window.$message.success('拉取成功') - onPageChange(pagination.page) }) - .finally(() => { + .onComplete(() => { loading.value = false pullModal.value = false }) } onMounted(() => { - onPageChange(pagination.page) + refresh() }) @@ -182,16 +158,23 @@ onMounted(() => { diff --git a/web/src/views/container/NetworkView.vue b/web/src/views/container/NetworkView.vue index 5d7141ff..e2faeb39 100644 --- a/web/src/views/container/NetworkView.vue +++ b/web/src/views/container/NetworkView.vue @@ -3,7 +3,6 @@ import { NButton, NDataTable, NFlex, NInput, NPopconfirm, NTag } from 'naive-ui' import container from '@/api/panel/container' import { formatDateTime } from '@/utils' -import type { NetworkList } from '@/views/container/types' const createModel = ref({ name: '', @@ -34,9 +33,7 @@ const options = [ ] const createModal = ref(false) -const loading = ref(false) -const data = ref([] as NetworkList[]) const selectedRowKeys = ref([]) const onChecked = (rowKeys: any) => { @@ -147,65 +144,44 @@ const columns: any = [ } ] -const pagination = reactive({ - page: 1, - pageCount: 1, - pageSize: 20, - itemCount: 0, - showQuickJumper: true, - showSizePicker: true, - pageSizes: [20, 50, 100, 200] -}) +const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination( + (page, pageSize) => container.networkList(page, pageSize), + { + initialData: { total: 0, list: [] }, + initialPageSize: 20, + total: (res: any) => res.total, + data: (res: any) => res.items + } +) -const onPageChange = (page: number) => { - pagination.page = page - getNetworkList(page, pagination.pageSize).then((res) => { - data.value = res.items - pagination.itemCount = res.total - pagination.pageCount = res.total / pagination.pageSize + 1 - }) -} - -const onPageSizeChange = (pageSize: number) => { - pagination.pageSize = pageSize - onPageChange(1) -} - -const getNetworkList = async (page: number, pageSize: number) => { - const { data } = await container.networkList(page, pageSize) - return data -} - -const handleDelete = async (row: any) => { - container.networkRemove(row.id).then(() => { +const handleDelete = (row: any) => { + useRequest(container.networkRemove(row.id)).onSuccess(() => { window.$message.success('删除成功') - onPageChange(pagination.page) }) } const handlePrune = () => { - container.networkPrune().then(() => { + useRequest(container.networkPrune()).onSuccess(() => { + refresh() window.$message.success('清理成功') - onPageChange(pagination.page) }) } const handleCreate = () => { loading.value = true - container - .networkCreate(createModel.value) - .then(() => { + useRequest(container.networkCreate(createModel.value)) + .onSuccess(() => { + refresh() window.$message.success('创建成功') - onPageChange(pagination.page) }) - .finally(() => { + .onComplete(() => { loading.value = false createModal.value = false }) } onMounted(() => { - onPageChange(pagination.page) + refresh() }) @@ -221,16 +197,23 @@ onMounted(() => { diff --git a/web/src/views/container/VolumeView.vue b/web/src/views/container/VolumeView.vue index 91bbffa3..42da0bfa 100644 --- a/web/src/views/container/VolumeView.vue +++ b/web/src/views/container/VolumeView.vue @@ -3,7 +3,6 @@ import { NButton, NDataTable, NInput, NPopconfirm } from 'naive-ui' import container from '@/api/panel/container' import { formatDateTime } from '@/utils' -import type { VolumeList } from '@/views/container/types' const createModel = ref({ name: '', @@ -15,9 +14,7 @@ const createModel = ref({ const options = [{ label: 'local', value: 'local' }] const createModal = ref(false) -const loading = ref(false) -const data = ref([] as VolumeList[]) const selectedRowKeys = ref([]) const onChecked = (rowKeys: any) => { @@ -101,65 +98,45 @@ const columns: any = [ } ] -const pagination = reactive({ - page: 1, - pageCount: 1, - pageSize: 20, - itemCount: 0, - showQuickJumper: true, - showSizePicker: true, - pageSizes: [20, 50, 100, 200] -}) - -const onPageChange = (page: number) => { - pagination.page = page - getVolumeList(page, pagination.pageSize).then((res) => { - data.value = res.items - pagination.itemCount = res.total - pagination.pageCount = res.total / pagination.pageSize + 1 - }) -} - -const onPageSizeChange = (pageSize: number) => { - pagination.pageSize = pageSize - onPageChange(1) -} - -const getVolumeList = async (page: number, pageSize: number) => { - const { data } = await container.volumeList(page, pageSize) - return data -} +const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination( + (page, pageSize) => container.volumeList(page, pageSize), + { + initialData: { total: 0, list: [] }, + initialPageSize: 20, + total: (res: any) => res.total, + data: (res: any) => res.items + } +) const handleDelete = async (row: any) => { - container.volumeRemove(row.id).then(() => { + useRequest(container.volumeRemove(row.id)).onSuccess(() => { + refresh() window.$message.success('删除成功') - onPageChange(pagination.page) }) } const handlePrune = () => { - container.volumePrune().then(() => { + useRequest(container.volumePrune()).onSuccess(() => { + refresh() window.$message.success('清理成功') - onPageChange(pagination.page) }) } const handleCreate = () => { loading.value = true - container - .volumeCreate(createModel.value) - .then(() => { + useRequest(container.volumeCreate(createModel.value)) + .onSuccess(() => { + refresh() window.$message.success('创建成功') - onPageChange(pagination.page) }) - .finally(() => { + .onComplete(() => { loading.value = false createModal.value = false }) } onMounted(() => { - onPageChange(pagination.page) + refresh() }) @@ -175,16 +152,23 @@ onMounted(() => { diff --git a/web/src/views/container/types.ts b/web/src/views/container/types.ts deleted file mode 100644 index 8a8fc375..00000000 --- a/web/src/views/container/types.ts +++ /dev/null @@ -1,85 +0,0 @@ -export interface ContainerList { - command: string - created: string - id: string - image: string - image_id: string - labels: { - [key: string]: string - } - name: string - ports: [ - { - IP: string - PrivatePort: number - PublicPort: number - Type: string - } - ] - state: string - status: string -} - -export interface ImageList { - id: string - created: string - containers: number - size: string - labels: { - [key: string]: string - } - repo_tags: string[] - repo_digests: string[] -} - -export interface NetworkList { - id: string - name: string - driver: string - ipv6: boolean - scope: string - internal: boolean - attachable: boolean - ingress: boolean - labels: { - [key: string]: string - } - options: { - [key: string]: string - } - ipam: { - driver: string - config: { - subnet: string - gateway: string - ip_range: string - aux_address: { - [key: string]: string - } - }[] - options: { - [key: string]: string - } - } -} - -export interface VolumeList { - id: string - created: string - driver: string - mount: string - labels: { - [key: string]: string - } - options: { - [key: string]: string - } - scope: string - status: { - [key: string]: string - } - usage: { - ref_count: number - size: string - } -} diff --git a/web/types/axios.d.ts b/web/types/axios.d.ts deleted file mode 100644 index 1901d093..00000000 --- a/web/types/axios.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { InternalAxiosRequestConfig } from 'axios' - -interface RequestConfig extends InternalAxiosRequestConfig { - /** 接口是否需要错误提醒 */ - noNeedTip?: boolean -} - -interface ErrorResolveResponse { - code?: number | string - message: string - data?: any -}