mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-11-16 05:33:41 +08:00
feat: refactor user page, fix alova response issue
This commit is contained in:
@@ -2,7 +2,8 @@
|
||||
"name": "@sa/alova",
|
||||
"version": "0.1.0",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
".": "./src/index.ts",
|
||||
"./client": "./src/client.ts"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
|
||||
1
packages/alova/src/client.ts
Normal file
1
packages/alova/src/client.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from 'alova/client';
|
||||
@@ -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';
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@sa/axios": "workspace:*",
|
||||
"@sa/alova": "workspace:*",
|
||||
"@sa/utils": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user