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