feat: refactor user page, fix alova response issue

This commit is contained in:
胡镇 2024-09-26 17:35:10 +08:00
parent f7e1a4aede
commit 88674669e3
11 changed files with 534 additions and 324 deletions

View File

@ -2,7 +2,8 @@
"name": "@sa/alova",
"version": "0.1.0",
"exports": {
".": "./src/index.ts"
".": "./src/index.ts",
"./client": "./src/client.ts"
},
"typesVersions": {
"*": {

View File

@ -0,0 +1 @@
export * from 'alova/client';

View File

@ -62,7 +62,7 @@ export const createAlovaRequest = (customConfig: CustomAlovaConfig<any>, options
!isJSON(resp.headers.get('Content-Type') ?? '') ||
(options.isBackendSuccess && (await options.isBackendSuccess(resp)))
) {
return resp;
return options.transformBackendResponse ? await options.transformBackendResponse(resp) : resp;
}
if (options.onBackendFail) {
const fail = await options.onBackendFail(resp);
@ -70,7 +70,6 @@ export const createAlovaRequest = (customConfig: CustomAlovaConfig<any>, options
return fail;
}
}
return options.transformBackendResponse ? await options.transformBackendResponse(resp) : resp;
}
throw new Error(resp.statusText);
},
@ -84,3 +83,4 @@ export const createAlovaRequest = (customConfig: CustomAlovaConfig<any>, options
export { BACKEND_ERROR_CODE, REQUEST_ID_KEY };
export type * from './type';
export type * from 'alova';

View File

@ -10,7 +10,7 @@
}
},
"dependencies": {
"@sa/axios": "workspace:*",
"@sa/alova": "workspace:*",
"@sa/utils": "workspace:*"
}
}

View File

@ -1,79 +0,0 @@
import { ref } from 'vue';
import type { Ref } from 'vue';
import { createFlatRequest } from '@sa/axios';
import type {
AxiosError,
CreateAxiosDefaults,
CustomAxiosRequestConfig,
MappedType,
RequestOption,
ResponseType
} from '@sa/axios';
import useLoading from './use-loading';
export type HookRequestInstanceResponseSuccessData<T = any> = {
data: Ref<T>;
error: Ref<null>;
};
export type HookRequestInstanceResponseFailData<ResponseData = any> = {
data: Ref<null>;
error: Ref<AxiosError<ResponseData>>;
};
export type HookRequestInstanceResponseData<T = any, ResponseData = any> = {
loading: Ref<boolean>;
} & (HookRequestInstanceResponseSuccessData<T> | HookRequestInstanceResponseFailData<ResponseData>);
export interface HookRequestInstance<ResponseData = any> {
<T = any, R extends ResponseType = 'json'>(
config: CustomAxiosRequestConfig
): HookRequestInstanceResponseData<MappedType<R, T>, ResponseData>;
cancelRequest: (requestId: string) => void;
cancelAllRequest: () => void;
}
/**
* create a hook request instance
*
* @param axiosConfig
* @param options
*/
export default function createHookRequest<ResponseData = any>(
axiosConfig?: CreateAxiosDefaults,
options?: Partial<RequestOption<ResponseData>>
) {
const request = createFlatRequest<ResponseData>(axiosConfig, options);
const hookRequest: HookRequestInstance<ResponseData> = function hookRequest<T = any, R extends ResponseType = 'json'>(
config: CustomAxiosRequestConfig
) {
const { loading, startLoading, endLoading } = useLoading();
const data = ref<MappedType<R, T> | null>(null) as Ref<MappedType<R, T>>;
const error = ref<AxiosError<ResponseData> | null>(null) as Ref<AxiosError<ResponseData> | null>;
startLoading();
request(config).then(res => {
if (res.data) {
data.value = res.data;
} else {
error.value = res.error;
}
endLoading();
});
return {
loading,
data,
error
};
} as HookRequestInstance<ResponseData>;
hookRequest.cancelRequest = request.cancelRequest;
hookRequest.cancelAllRequest = request.cancelAllRequest;
return hookRequest;
}

View File

@ -1,12 +1,13 @@
import { computed, reactive, ref } from 'vue';
import type { Ref } from 'vue';
import { jsonClone } from '@sa/utils';
import { usePagination } from '@sa/alova/client';
import type { AlovaGenerics, Method } from '@sa/alova';
import useBoolean from './use-boolean';
import useLoading from './use-loading';
export type MaybePromise<T> = T | Promise<T>;
export type ApiFn = (args: any) => Promise<unknown>;
export type ApiFn = (args: any) => Method<AlovaGenerics>;
export type TableColumnCheck = {
key: string;
@ -61,7 +62,6 @@ export type TableConfig<A extends ApiFn, T, C> = {
};
export default function useHookTable<A extends ApiFn, T, C>(config: TableConfig<A, T, C>) {
const { loading, startLoading, endLoading } = useLoading();
const { bool: empty, setBool: setEmpty } = useBoolean();
const { apiFn, apiParams, transformer, immediate = true, getColumnChecks, getColumns } = config;
@ -70,12 +70,22 @@ export default function useHookTable<A extends ApiFn, T, C>(config: TableConfig<
const allColumns = ref(config.columns()) as Ref<C[]>;
const data: Ref<TableDataWithIndex<T>[]> = ref([]);
const columnChecks: Ref<TableColumnCheck[]> = ref(getColumnChecks(config.columns()));
const columns = computed(() => getColumns(allColumns.value, columnChecks.value));
const states = usePagination(
(page, pageSize) => apiFn({ ...formatSearchParams(searchParams), page, size: pageSize }),
{
immediate,
data: transformer,
total: res => res.data.total
}
).onSuccess(event => {
setEmpty(event.data.length === 0);
});
delete states.uploading;
function reloadColumns() {
allColumns.value = config.columns();
@ -89,33 +99,13 @@ export default function useHookTable<A extends ApiFn, T, C>(config: TableConfig<
}));
}
async function getData() {
startLoading();
const formattedParams = formatSearchParams(searchParams);
const response = await apiFn(formattedParams);
const transformed = transformer(response as Awaited<ReturnType<A>>);
data.value = transformed.data;
setEmpty(transformed.data.length === 0);
await config.onFetched?.(transformed);
endLoading();
}
function formatSearchParams(params: Record<string, unknown>) {
const formattedParams: Record<string, unknown> = {};
Object.entries(params).forEach(([key, value]) => {
if (value !== null && value !== undefined) {
formattedParams[key] = value;
}
});
return formattedParams;
}
@ -133,18 +123,13 @@ export default function useHookTable<A extends ApiFn, T, C>(config: TableConfig<
Object.assign(searchParams, jsonClone(apiParams));
}
if (immediate) {
getData();
}
return {
loading,
...states,
empty,
data,
columns,
columnChecks,
reloadColumns,
getData,
getData: states.send,
searchParams,
updateSearchParams,
resetSearchParams

View File

@ -20,6 +20,9 @@ importers:
'@iconify/vue':
specifier: 4.1.2
version: 4.1.2(vue@3.5.3(typescript@5.5.4))
'@sa/alova':
specifier: workspace:*
version: link:packages/alova
'@sa/axios':
specifier: workspace:*
version: link:packages/axios
@ -38,6 +41,9 @@ importers:
'@vueuse/core':
specifier: 11.0.3
version: 11.0.3(vue@3.5.3(typescript@5.5.4))
alova:
specifier: ^3.0.16
version: 3.0.16
clipboard:
specifier: 2.0.11
version: 2.0.11
@ -211,6 +217,15 @@ importers:
specifier: 2.1.6
version: 2.1.6(typescript@5.5.4)
packages/alova:
dependencies:
'@sa/utils':
specifier: workspace:*
version: link:../utils
alova:
specifier: ^3.0.16
version: 3.0.16
packages/axios:
dependencies:
'@sa/utils':
@ -241,9 +256,9 @@ importers:
packages/hooks:
dependencies:
'@sa/axios':
'@sa/alova':
specifier: workspace:*
version: link:../axios
version: link:../alova
'@sa/utils':
specifier: workspace:*
version: link:../utils
@ -326,6 +341,9 @@ importers:
packages:
'@alova/shared@1.0.5':
resolution: {integrity: sha512-/a2Qm+xebQJ1OlIgpslK+UL1J7yhkt1/Mqdq58a22+fSVdANukmUcF4j4w1DF3lxZ04SrqP+2oJprJ8UOvM+9Q==}
'@amap/amap-jsapi-types@0.0.15':
resolution: {integrity: sha512-oqyRqHpVDZh5bUe2mAJh41ZsziSj0eUzwcfIbiaBNB0eiTJnZNhKsTdk77VOklOjwuwNfsblpKW9LjmWNpeQ7A==}
@ -337,6 +355,9 @@ packages:
resolution: {integrity: sha512-LvxY21+ZhpuBf/aHeBUtGQhSEfad4PkNKXKvDOSvukaM3XVTfBhwmHX2EKwAsdq5DlfjbT3qqYyMiueBIO5iDQ==}
engines: {node: '>=18.0.0', npm: '>=9.0.0', pnpm: '>= 8.6.0'}
'@antfu/install-pkg@0.3.3':
resolution: {integrity: sha512-nHHsk3NXQ6xkCfiRRC8Nfrg8pU5kkr3P3Y9s9dKqiuRmBD0Yap7fymNDjGFKeWhZQHqqbCS5CfeMy9wtExM24w==}
'@antfu/install-pkg@0.4.1':
resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==}
@ -897,6 +918,10 @@ packages:
resolution: {integrity: sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/js@9.8.0':
resolution: {integrity: sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/object-schema@2.1.4':
resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -1112,6 +1137,55 @@ packages:
resolution: {integrity: sha512-QQVDFOsAdrYkyE5eEXuwtEi3poIOptkZhA0NxV2dfZoU3ChfFo0pkkuDplgpXaZvx09Omu2i04fdNKxFftAC3w==}
engines: {node: '>=16', pnpm: '>=9'}
'@soybeanjs/eslint-config@1.4.0':
resolution: {integrity: sha512-4GT/4yk6ATLW9CBKJkwXWykaVLsWBp+lOlNWVuHeFmOlywfngWETlBcyTk7cwkKlRqCDAzN1i4hDrokJqfqncA==}
peerDependencies:
'@toml-tools/parser': '*'
'@unocss/eslint-config': '>=0.58.0'
eslint: '>=8.40.0'
eslint-plugin-astro: '>=0.30.0'
eslint-plugin-react: '>=7.0.0'
eslint-plugin-react-hooks: '>=4.0.0'
eslint-plugin-react-native: '>=4.0.0'
eslint-plugin-react-refresh: '>=0.4.0'
eslint-plugin-solid: '>=0.10.0'
eslint-plugin-svelte: '>=2.0.0'
eslint-plugin-vue: '>=9.19.0'
prettier-plugin-astro: '>=0.12.0'
prettier-plugin-svelte: '>=3.0.0'
prettier-plugin-toml: '>=2.0.0'
typescript: '>=5.0.0'
vue-eslint-parser: '>=9.3.2'
peerDependenciesMeta:
'@toml-tools/parser':
optional: true
'@unocss/eslint-config':
optional: true
eslint-plugin-astro:
optional: true
eslint-plugin-react:
optional: true
eslint-plugin-react-hooks:
optional: true
eslint-plugin-react-native:
optional: true
eslint-plugin-react-refresh:
optional: true
eslint-plugin-solid:
optional: true
eslint-plugin-svelte:
optional: true
eslint-plugin-vue:
optional: true
prettier-plugin-astro:
optional: true
prettier-plugin-svelte:
optional: true
prettier-plugin-toml:
optional: true
vue-eslint-parser:
optional: true
'@soybeanjs/eslint-config@1.4.1':
resolution: {integrity: sha512-FztmV23UsvFYiZD1JiDeAzw8o1UoM1WX7/HYSXxrR9eZWswQYZjuwa3n8exWfYsXm6jAjm7AckeWpXuinSLj/g==}
peerDependencies:
@ -1228,6 +1302,17 @@ packages:
'@types/web-bluetooth@0.0.20':
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
'@typescript-eslint/eslint-plugin@7.18.0':
resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
'@typescript-eslint/parser': ^7.0.0
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/eslint-plugin@8.4.0':
resolution: {integrity: sha512-rg8LGdv7ri3oAlenMACk9e+AR4wUV0yrrG+XKsGKOK0EVgeEDqurkXMPILG2836fW4ibokTB5v4b6Z9+GYQDEw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -1239,6 +1324,16 @@ packages:
typescript:
optional: true
'@typescript-eslint/parser@7.18.0':
resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/parser@8.4.0':
resolution: {integrity: sha512-NHgWmKSgJk5K9N16GIhQ4jSobBoJwrmURaLErad0qlLjrpP5bECYg+wxVTGlGZmJbU03jj/dfnb6V9bw+5icsA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -1249,10 +1344,24 @@ packages:
typescript:
optional: true
'@typescript-eslint/scope-manager@7.18.0':
resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/scope-manager@8.4.0':
resolution: {integrity: sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/type-utils@7.18.0':
resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/type-utils@8.4.0':
resolution: {integrity: sha512-pu2PAmNrl9KX6TtirVOrbLPLwDmASpZhK/XU7WvoKoCUkdtq9zF7qQ7gna0GBZFN0hci0vHaSusiL2WpsQk37A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -1262,10 +1371,23 @@ packages:
typescript:
optional: true
'@typescript-eslint/types@7.18.0':
resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/types@8.4.0':
resolution: {integrity: sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@7.18.0':
resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/typescript-estree@8.4.0':
resolution: {integrity: sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -1275,12 +1397,22 @@ packages:
typescript:
optional: true
'@typescript-eslint/utils@7.18.0':
resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
'@typescript-eslint/utils@8.4.0':
resolution: {integrity: sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
'@typescript-eslint/visitor-keys@7.18.0':
resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/visitor-keys@8.4.0':
resolution: {integrity: sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -1469,6 +1601,10 @@ packages:
resolution: {integrity: sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==}
engines: {node: '>=0.10.0'}
alova@3.0.16:
resolution: {integrity: sha512-iCMi/MFAyEU9ukt2Hy/htshT2gpDTa5L4b9IZzrtu/O1Oevj6zES/uC49hNEBuZWyBBky3M6tvynurMYusfFYA==}
engines: {node: '>= 18.0.0'}
amdefine@1.0.1:
resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==}
engines: {node: '>=0.4.2'}
@ -1540,6 +1676,10 @@ packages:
resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==}
engines: {node: '>= 0.4'}
array-union@2.1.0:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
array-unique@0.3.2:
resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==}
engines: {node: '>=0.10.0'}
@ -2330,6 +2470,9 @@ packages:
peerDependencies:
eslint: '>=6.0.0'
eslint-config-flat-gitignore@0.1.8:
resolution: {integrity: sha512-OEUbS2wzzYtUfshjOqzFo4Bl4lHykXUdM08TCnYNl7ki+niW4Q1R0j0FDFDr0vjVsI5ZFOz5LvluxOP+Ew+dYw==}
eslint-config-flat-gitignore@0.3.0:
resolution: {integrity: sha512-0Ndxo4qGhcewjTzw52TK06Mc00aDtHNTdeeW2JfONgDcLkRO/n/BteMRzNVpLQYxdCC/dFEilfM9fjjpGIJ9Og==}
peerDependencies:
@ -2353,12 +2496,24 @@ packages:
peerDependencies:
eslint: '>=8'
eslint-plugin-import-x@3.1.0:
resolution: {integrity: sha512-/UbPA+bYY7nIxcjL3kpcDY3UNdoLHFhyBFzHox2M0ypcUoueTn6woZUUmzzi5et/dXChksasYYFeKE2wshOrhg==}
engines: {node: '>=16'}
peerDependencies:
eslint: ^8.56.0 || ^9.0.0-0
eslint-plugin-import-x@4.2.1:
resolution: {integrity: sha512-WWi2GedccIJa0zXxx3WDnTgouGQTtdYK1nhXMwywbqqAgB0Ov+p1pYBsWh3VaB0bvBOwLse6OfVII7jZD9xo5Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
eslint-plugin-n@17.10.1:
resolution: {integrity: sha512-hm/q37W6efDptJXdwirsm6A257iY6ZNtpoSG0wEzFzjJ3AhL7OhEIhdSR2e4OdYfHO5EDeqlCfFrjf9q208IPw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: '>=8.23.0'
eslint-plugin-n@17.10.2:
resolution: {integrity: sha512-e+s4eAf5NtJaxPhTNu3qMO0Iz40WANS93w9LQgYcvuljgvDmWi/a3rh+OrNyMHeng6aOWGJO0rCg5lH4zi8yTw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@ -2714,6 +2869,10 @@ packages:
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
engines: {node: '>=18'}
globals@15.8.0:
resolution: {integrity: sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==}
engines: {node: '>=18'}
globals@15.9.0:
resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==}
engines: {node: '>=18'}
@ -2722,6 +2881,10 @@ packages:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'}
globby@11.1.0:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
good-listener@1.2.2:
resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==}
@ -3668,6 +3831,10 @@ packages:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
parse-gitignore@2.0.0:
resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==}
engines: {node: '>=14'}
parse-json@5.2.0:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
@ -3907,6 +4074,9 @@ packages:
quickselect@2.0.0:
resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==}
rate-limiter-flexible@5.0.3:
resolution: {integrity: sha512-lWx2y8NBVlTOLPyqs+6y7dxfEpT6YFqKy3MzWbCy95sTTOhOuxufP2QvRyOHpfXpB9OUJPbVLybw3z3AVAS5fA==}
rbush@3.0.1:
resolution: {integrity: sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==}
@ -4144,6 +4314,10 @@ packages:
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
slice-ansi@5.0.0:
resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
engines: {node: '>=12'}
@ -4867,6 +5041,8 @@ packages:
snapshots:
'@alova/shared@1.0.5': {}
'@amap/amap-jsapi-types@0.0.15': {}
'@ampproject/remapping@2.3.0':
@ -4876,6 +5052,10 @@ snapshots:
'@antfu/eslint-define-config@1.23.0-2': {}
'@antfu/install-pkg@0.3.3':
dependencies:
'@jsdevtools/ez-spawn': 3.0.4
'@antfu/install-pkg@0.4.1':
dependencies:
package-manager-detector: 0.2.0
@ -5484,6 +5664,8 @@ snapshots:
'@eslint/js@9.10.0': {}
'@eslint/js@9.8.0': {}
'@eslint/object-schema@2.1.4': {}
'@eslint/plugin-kit@0.1.0':
@ -5697,6 +5879,37 @@ snapshots:
- typescript
- vue-eslint-parser
'@soybeanjs/eslint-config@1.4.0(@unocss/eslint-config@0.62.3(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-vue@9.28.0(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)(vue-eslint-parser@9.4.3(eslint@9.10.0(jiti@1.21.6)))':
dependencies:
'@antfu/eslint-define-config': 1.23.0-2
'@antfu/install-pkg': 0.3.3
'@eslint/eslintrc': 3.1.0
'@eslint/js': 9.8.0
'@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4))(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/parser': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
eslint: 9.10.0(jiti@1.21.6)
eslint-config-flat-gitignore: 0.1.8
eslint-config-prettier: 9.1.0(eslint@9.10.0(jiti@1.21.6))
eslint-parser-plain: 0.1.0
eslint-plugin-import-x: 3.1.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
eslint-plugin-n: 17.10.1(eslint@9.10.0(jiti@1.21.6))
eslint-plugin-prettier: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))(prettier@3.3.3)
eslint-plugin-unicorn: 55.0.0(eslint@9.10.0(jiti@1.21.6))
globals: 15.8.0
local-pkg: 0.5.0
prettier: 3.3.3
prettier-plugin-jsdoc: 1.3.0(prettier@3.3.3)
prettier-plugin-json-sort: 0.0.2(prettier@3.3.3)
prompts: 2.4.2
typescript: 5.5.4
optionalDependencies:
'@unocss/eslint-config': 0.62.3(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
eslint-plugin-vue: 9.28.0(eslint@9.10.0(jiti@1.21.6))
vue-eslint-parser: 9.4.3(eslint@9.10.0(jiti@1.21.6))
transitivePeerDependencies:
- '@types/eslint'
- supports-color
'@soybeanjs/eslint-config@1.4.1(@unocss/eslint-config@0.62.3(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4))(eslint-plugin-vue@9.28.0(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)(vue-eslint-parser@9.4.3(eslint@9.10.0(jiti@1.21.6)))':
dependencies:
'@antfu/eslint-define-config': 1.23.0-2
@ -5784,6 +5997,24 @@ snapshots:
'@types/web-bluetooth@0.0.20': {}
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4))(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@eslint-community/regexpp': 4.11.0
'@typescript-eslint/parser': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/type-utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 7.18.0
eslint: 9.10.0(jiti@1.21.6)
graphemer: 1.4.0
ignore: 5.3.2
natural-compare: 1.4.0
ts-api-utils: 1.3.0(typescript@5.5.4)
optionalDependencies:
typescript: 5.5.4
transitivePeerDependencies:
- supports-color
'@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4))(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@eslint-community/regexpp': 4.11.0
@ -5802,6 +6033,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 7.18.0
debug: 4.3.7
eslint: 9.10.0(jiti@1.21.6)
optionalDependencies:
typescript: 5.5.4
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@8.4.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@typescript-eslint/scope-manager': 8.4.0
@ -5815,11 +6059,28 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/scope-manager@7.18.0':
dependencies:
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0
'@typescript-eslint/scope-manager@8.4.0':
dependencies:
'@typescript-eslint/types': 8.4.0
'@typescript-eslint/visitor-keys': 8.4.0
'@typescript-eslint/type-utils@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
debug: 4.3.7
eslint: 9.10.0(jiti@1.21.6)
ts-api-utils: 1.3.0(typescript@5.5.4)
optionalDependencies:
typescript: 5.5.4
transitivePeerDependencies:
- supports-color
'@typescript-eslint/type-utils@8.4.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4)
@ -5832,8 +6093,25 @@ snapshots:
- eslint
- supports-color
'@typescript-eslint/types@7.18.0': {}
'@typescript-eslint/types@8.4.0': {}
'@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)':
dependencies:
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0
debug: 4.3.7
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.6.3
ts-api-utils: 1.3.0(typescript@5.5.4)
optionalDependencies:
typescript: 5.5.4
transitivePeerDependencies:
- supports-color
'@typescript-eslint/typescript-estree@8.4.0(typescript@5.5.4)':
dependencies:
'@typescript-eslint/types': 8.4.0
@ -5849,6 +6127,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0(jiti@1.21.6))
'@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
eslint: 9.10.0(jiti@1.21.6)
transitivePeerDependencies:
- supports-color
- typescript
'@typescript-eslint/utils@8.4.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0(jiti@1.21.6))
@ -5860,6 +6149,11 @@ snapshots:
- supports-color
- typescript
'@typescript-eslint/visitor-keys@7.18.0':
dependencies:
'@typescript-eslint/types': 7.18.0
eslint-visitor-keys: 3.4.3
'@typescript-eslint/visitor-keys@8.4.0':
dependencies:
'@typescript-eslint/types': 8.4.0
@ -6175,6 +6469,11 @@ snapshots:
longest: 1.0.1
repeat-string: 1.6.1
alova@3.0.16:
dependencies:
'@alova/shared': 1.0.5
rate-limiter-flexible: 5.0.3
amdefine@1.0.1: {}
ansi-colors@4.1.3: {}
@ -6228,6 +6527,8 @@ snapshots:
call-bind: 1.0.7
is-array-buffer: 3.0.4
array-union@2.1.0: {}
array-unique@0.3.2: {}
arraybuffer.prototype.slice@1.0.3:
@ -7128,6 +7429,11 @@ snapshots:
eslint: 9.10.0(jiti@1.21.6)
semver: 7.6.3
eslint-config-flat-gitignore@0.1.8:
dependencies:
find-up-simple: 1.0.0
parse-gitignore: 2.0.0
eslint-config-flat-gitignore@0.3.0(eslint@9.10.0(jiti@1.21.6)):
dependencies:
'@eslint/compat': 1.1.1
@ -7155,6 +7461,23 @@ snapshots:
eslint: 9.10.0(jiti@1.21.6)
eslint-compat-utils: 0.5.1(eslint@9.10.0(jiti@1.21.6))
eslint-plugin-import-x@3.1.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4):
dependencies:
'@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
debug: 4.3.7
doctrine: 3.0.0
eslint: 9.10.0(jiti@1.21.6)
eslint-import-resolver-node: 0.3.9
get-tsconfig: 4.8.0
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.6.3
stable-hash: 0.0.4
tslib: 2.7.0
transitivePeerDependencies:
- supports-color
- typescript
eslint-plugin-import-x@4.2.1(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4):
dependencies:
'@typescript-eslint/utils': 8.4.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.5.4)
@ -7172,6 +7495,18 @@ snapshots:
- supports-color
- typescript
eslint-plugin-n@17.10.1(eslint@9.10.0(jiti@1.21.6)):
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0(jiti@1.21.6))
enhanced-resolve: 5.17.1
eslint: 9.10.0(jiti@1.21.6)
eslint-plugin-es-x: 7.8.0(eslint@9.10.0(jiti@1.21.6))
get-tsconfig: 4.8.0
globals: 15.9.0
ignore: 5.3.2
minimatch: 9.0.5
semver: 7.6.3
eslint-plugin-n@17.10.2(eslint@9.10.0(jiti@1.21.6)):
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0(jiti@1.21.6))
@ -7643,6 +7978,8 @@ snapshots:
globals@14.0.0: {}
globals@15.8.0: {}
globals@15.9.0: {}
globalthis@1.0.4:
@ -7650,6 +7987,15 @@ snapshots:
define-properties: 1.2.1
gopd: 1.0.1
globby@11.1.0:
dependencies:
array-union: 2.1.0
dir-glob: 3.0.1
fast-glob: 3.3.2
ignore: 5.3.2
merge2: 1.4.1
slash: 3.0.0
good-listener@1.2.2:
dependencies:
delegate: 3.2.0
@ -8643,6 +8989,8 @@ snapshots:
dependencies:
callsites: 3.1.0
parse-gitignore@2.0.0: {}
parse-json@5.2.0:
dependencies:
'@babel/code-frame': 7.24.7
@ -8854,6 +9202,8 @@ snapshots:
quickselect@2.0.0: {}
rate-limiter-flexible@5.0.3: {}
rbush@3.0.1:
dependencies:
quickselect: 2.0.0
@ -9122,6 +9472,8 @@ snapshots:
sisteransi@1.0.5: {}
slash@3.0.0: {}
slice-ansi@5.0.0:
dependencies:
ansi-styles: 6.2.1

View File

@ -22,40 +22,26 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
const EXPAND_KEY = '__expand__';
const {
loading,
empty,
data,
columns,
columnChecks,
reloadColumns,
getData,
searchParams,
updateSearchParams,
resetSearchParams
} = useHookTable<A, GetTableData<A>, TableColumn<NaiveUI.TableDataWithIndex<GetTableData<A>>>>({
const { reloadColumns, page, pageSize, total, ...rest } = useHookTable<
A,
GetTableData<A>,
TableColumn<NaiveUI.TableDataWithIndex<GetTableData<A>>>
>({
apiFn,
apiParams,
columns: config.columns,
transformer: res => {
const { records = [], current = 1, size = 10, total = 0 } = res.data || {};
const { records = [], current = 1, size = 10 } = res.data || {};
// Ensure that the size is greater than 0, If it is less than 0, it will cause paging calculation errors.
const pageSize = size <= 0 ? 10 : size;
const pageSizeValue = size <= 0 ? 10 : size;
const recordsWithIndex = records.map((item, index) => {
return records.map((item, index) => {
return {
...item,
index: (current - 1) * pageSize + index + 1
index: (current - 1) * pageSizeValue + index + 1
};
});
return {
data: recordsWithIndex,
pageNum: current,
pageSize,
total
};
},
getColumnChecks: cols => {
const checks: NaiveUI.TableColumnCheck[] = [];
@ -103,64 +89,56 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
return filteredColumns;
},
onFetched: async transformed => {
const { pageNum, pageSize, total } = transformed;
updatePagination({
page: pageNum,
pageSize,
itemCount: total
});
},
immediate
});
const pagination: PaginationProps = reactive({
page: 1,
pageSize: 10,
const paginationBase: PaginationProps = reactive({
showSizePicker: true,
pageSizes: [10, 15, 20, 25, 30],
onUpdatePage: async (page: number) => {
pagination.page = page;
updateSearchParams({
current: page,
size: pagination.pageSize!
});
getData();
onUpdatePage: async pageValue => {
page.value = pageValue;
},
onUpdatePageSize: async (pageSize: number) => {
pagination.pageSize = pageSize;
pagination.page = 1;
updateSearchParams({
current: pagination.page,
size: pageSize
});
getData();
onUpdatePageSize: async pageSizeValue => {
pageSize.value = pageSizeValue;
},
...(showTotal
? {
prefix: page => $t('datatable.itemCount', { total: page.itemCount })
prefix: pageProps => $t('datatable.itemCount', { total: pageProps.itemCount })
}
: {})
});
const pagination = computed(
() =>
<PaginationProps>{
...paginationBase,
page: page.value,
pageSize: pageSize.value,
itemCount: total.value
}
);
// this is for mobile, if the system does not support mobile, you can use `pagination` directly
const mobilePagination = computed(() => {
const p: PaginationProps = {
...pagination,
...pagination.value,
pageSlot: isMobile.value ? 3 : 9,
prefix: !isMobile.value && showTotal ? pagination.prefix : undefined
prefix: !isMobile.value && showTotal ? pagination.value.prefix : undefined
};
return p;
});
function updatePagination(update: Partial<PaginationProps>) {
Object.assign(pagination, update);
(['page', 'pageSize', 'itemCount'] as const).forEach(key => {
update[key] &&
({
page,
pageSize,
itemCount: total
}[key].value = update[key]);
});
Object.assign(paginationBase, update);
}
/**
@ -169,16 +147,7 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
* @param pageNum the page number. default is 1
*/
async function getDataByPage(pageNum: number = 1) {
updatePagination({
page: pageNum
});
updateSearchParams({
current: pageNum,
size: pagination.pageSize!
});
await getData();
page.value = pageNum;
}
scope.run(() => {
@ -195,20 +164,12 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
});
return {
loading,
empty,
data,
columns,
columnChecks,
...rest,
reloadColumns,
pagination,
mobilePagination,
updatePagination,
getData,
getDataByPage,
searchParams,
updateSearchParams,
resetSearchParams
getDataByPage
};
}

View File

@ -1,4 +1,4 @@
import { request } from '../request';
import { alova, request } from '../request';
/** get role list */
export function fetchGetRoleList(params?: Api.SystemManage.RoleSearchParams) {
@ -23,12 +23,12 @@ export function fetchGetAllRoles() {
/** get user list */
export function fetchGetUserList(params?: Api.SystemManage.UserSearchParams) {
return request<Api.SystemManage.UserList>({
url: '/systemManage/getUserList',
method: 'get',
params
});
// return alova.Get<Api.SystemManage.UserList>('/systemManage/getUserList', { params });
// return request<Api.SystemManage.UserList>({
// url: '/systemManage/getUserList',
// method: 'get',
// params
// });
return alova.Get<Api.SystemManage.UserList>('/systemManage/getUserList', { params });
}
/** get menu list */

View File

@ -239,7 +239,7 @@ export const alova = createAlovaRequest(
return null;
},
transformBackendResponse(response) {
return response.data.data;
return response.json();
},
onError(error) {
// when the request is fail, you can show error message

View File

@ -10,22 +10,11 @@ import UserSearch from './modules/user-search.vue';
const appStore = useAppStore();
const {
columns,
columnChecks,
data,
getData,
getDataByPage,
loading,
mobilePagination,
searchParams,
resetSearchParams
} = useTable({
const { columns, columnChecks, data, getData, reload, loading, mobilePagination, searchParams, resetSearchParams } =
useTable({
apiFn: fetchGetUserList,
showTotal: true,
apiParams: {
current: 1,
size: 10,
// if you want to use the searchParams in Form, you need to define the following properties, and the value is null
// the value can not be undefined, otherwise the property in Form will not be reactive
status: null,
@ -135,7 +124,7 @@ const {
)
}
]
});
});
const {
drawerVisible,
@ -170,7 +159,7 @@ function edit(id: number) {
<template>
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
<UserSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
<UserSearch v-model:model="searchParams" @reset="resetSearchParams" @search="reload" />
<NCard :title="$t('page.manage.user.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
<template #header-extra>
<TableHeaderOperation
@ -199,7 +188,7 @@ function edit(id: number) {
v-model:visible="drawerVisible"
:operate-type="operateType"
:row-data="editingData"
@submitted="getDataByPage"
@submitted="reload"
/>
</NCard>
</div>