282 lines
6.7 KiB
Vue
282 lines
6.7 KiB
Vue
<script setup lang="tsx">
|
|
import { Tag } from 'ant-design-vue';
|
|
import { useTable } from '@/hooks/common/table';
|
|
import { SimpleScrollbar } from '~/packages/materials/src';
|
|
import UserSearch from './modules/user-search.vue';
|
|
import { computed, shallowRef } from 'vue';
|
|
import { useElementSize } from '@vueuse/core';
|
|
import { doGetUserList } from '@/service/api/user';
|
|
import type { UserInfo, SearchModel } from '@/views/user-center/user/type';
|
|
import { useI18n } from 'vue-i18n';
|
|
const { t } = useI18n();
|
|
// 修改API函数实现
|
|
const doGetUserInfo = async (params: SearchModel) => {
|
|
try {
|
|
console.log('API function received params:', params);
|
|
|
|
const apiParams: Api.SystemManage.UserSearchParams = {
|
|
userName: params.username,
|
|
email: params.email,
|
|
pageNum: params.pageNum,
|
|
pageSize: params.pageSize
|
|
};
|
|
|
|
console.log('Sending API request with params:', apiParams);
|
|
|
|
const response = await doGetUserList(apiParams);
|
|
|
|
if (!response.data) {
|
|
return {
|
|
data: {
|
|
rows: [],
|
|
total: 0
|
|
}
|
|
};
|
|
}
|
|
|
|
return {
|
|
data: {
|
|
rows: response.data.rows.map(user => ({
|
|
userId: user.userId,
|
|
username: user.userName,
|
|
fullname: user.nickName,
|
|
sex: user.sex === '1' ? 'M' : 'F',
|
|
birthdate: user.createTime?.split(' ')[0] || '-',
|
|
age: calculateAge(user.createTime),
|
|
email: user.email,
|
|
phonenumber: user.phonenumber,
|
|
kycStatus: user.kycStatus
|
|
})),
|
|
total: response.data.total
|
|
}
|
|
};
|
|
} catch (err) {
|
|
return {
|
|
data: {
|
|
rows: [],
|
|
total: 0
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
const wrapperEl = shallowRef<HTMLElement | null>(null);
|
|
const { height: wrapperElHeight } = useElementSize(wrapperEl);
|
|
|
|
const scrollConfig = computed(() => {
|
|
return {
|
|
y: wrapperElHeight.value - 72,
|
|
x: 1000
|
|
};
|
|
});
|
|
|
|
const {
|
|
columns,
|
|
columnChecks,
|
|
data,
|
|
loading,
|
|
getData,
|
|
mobilePagination,
|
|
searchParams,
|
|
updateSearchParams,
|
|
|
|
} = useTable({
|
|
apiFn: doGetUserInfo,
|
|
immediate: true,
|
|
apiParams: {
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
username: undefined,
|
|
email: undefined
|
|
} as SearchModel,
|
|
rowKey: 'userId',
|
|
columns: (): AntDesign.TableColumn<AntDesign.TableDataWithIndex<UserInfo>>[] => [
|
|
{
|
|
key: 'username',
|
|
dataIndex: 'username',
|
|
title: t('page.user.username'),
|
|
align: 'center'
|
|
},
|
|
{
|
|
key: 'fullname',
|
|
dataIndex: 'fullname',
|
|
title: t('page.user.fullname'),
|
|
align: 'center'
|
|
},
|
|
{
|
|
key: 'sex',
|
|
dataIndex: 'sex',
|
|
title: t('page.user.sex'),
|
|
align: 'center',
|
|
width: 80,
|
|
customRender: ({ record }: { record: UserInfo }) => {
|
|
const sexMap = {
|
|
'M': t('page.user.man'),
|
|
'F': t('page.user.woman')
|
|
};
|
|
return sexMap[record.sex] || '-';
|
|
}
|
|
},
|
|
{
|
|
key: 'birthdate',
|
|
dataIndex: 'birthdate',
|
|
title: t('page.user.birthdate'),
|
|
align: 'center'
|
|
},
|
|
{
|
|
key: 'age',
|
|
dataIndex: 'age',
|
|
title: t('page.user.age'),
|
|
align: 'center',
|
|
width: 80
|
|
},
|
|
{
|
|
key: 'email',
|
|
dataIndex: 'email',
|
|
title: t('page.user.email'),
|
|
align: 'center'
|
|
},
|
|
{
|
|
key: 'phonenumber',
|
|
dataIndex: 'phonenumber',
|
|
title: t('page.user.phone'),
|
|
align: 'center'
|
|
},
|
|
{
|
|
key: 'kycStatus',
|
|
dataIndex: 'kycStatus',
|
|
title: t('page.user.kyc'),
|
|
align: 'center',
|
|
customRender: ({ record }: { record: UserInfo }) => {
|
|
const getKycStatusColor = (status: string | null) => {
|
|
switch (status) {
|
|
case 'VERIFIED':
|
|
return 'success';
|
|
case 'PENDING':
|
|
return 'warning';
|
|
case 'REJECTED':
|
|
return 'error';
|
|
case 'UNVERIFIED':
|
|
default:
|
|
return 'default';
|
|
}
|
|
};
|
|
|
|
const getKycStatusText = (status: string | null) => {
|
|
switch (status) {
|
|
case 'VERIFIED':
|
|
return t('page.user.ver');
|
|
case 'PENDING':
|
|
return t('page.user.pending');
|
|
case 'REJECTED':
|
|
return t('page.user.rejected');
|
|
case 'UNVERIFIED':
|
|
return t('page.user.unver');
|
|
default:
|
|
return t('page.user.unver');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Tag color={getKycStatusColor(record.kycStatus)}>
|
|
{getKycStatusText(record.kycStatus)}
|
|
</Tag>
|
|
);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
|
|
const handUpdateModel = (item: SearchModel) => {
|
|
console.log('Received updated model:', item);
|
|
// 更新搜索参数
|
|
updateSearchParams({
|
|
...item,
|
|
pageNum: 1 // 每次搜索条件改变时重置页码
|
|
});
|
|
};
|
|
|
|
// 处理搜索
|
|
const handleSearch = () => {
|
|
// 直接使用已更新的搜索参数
|
|
console.log('Executing search with params:', searchParams.value);
|
|
getData();
|
|
};
|
|
|
|
// 处理重置
|
|
const handleReset = () => {
|
|
// 定义默认参数
|
|
const defaultParams: SearchModel = {
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
username: undefined,
|
|
email: undefined
|
|
};
|
|
|
|
console.log('Resetting search params to:', defaultParams);
|
|
|
|
// 更新搜索参数到默认值
|
|
updateSearchParams(defaultParams);
|
|
|
|
// 重新获取数据
|
|
getData();
|
|
};
|
|
|
|
const calculateAge = (birthDate: string): number => {
|
|
if (!birthDate) return 0;
|
|
const birth = new Date(birthDate);
|
|
const today = new Date();
|
|
let age = today.getFullYear() - birth.getFullYear();
|
|
const monthDiff = today.getMonth() - birth.getMonth();
|
|
|
|
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
|
|
age--;
|
|
}
|
|
|
|
return age;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<SimpleScrollbar>
|
|
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
|
<UserSearch
|
|
v-model:model="searchParams"
|
|
@updateModel="handUpdateModel"
|
|
@reset="handleReset"
|
|
@search="handleSearch"
|
|
/>
|
|
<ACard
|
|
:title="t('page.user.title')"
|
|
:bordered="false"
|
|
:body-style="{ flex: 1, overflow: 'hidden' }"
|
|
class="flex-col-stretch sm:flex-1-hidden card-wrapper"
|
|
>
|
|
<template #extra>
|
|
<TableHeaderOperation
|
|
v-model:columns="columnChecks"
|
|
:loading="loading"
|
|
:not-show-add="true"
|
|
:show-add="false"
|
|
:show-delete="false"
|
|
@refresh="getData"
|
|
/>
|
|
</template>
|
|
<ATable
|
|
ref="wrapperEl"
|
|
:columns="columns"
|
|
:data-source="data"
|
|
:loading="loading"
|
|
row-key="userId"
|
|
size="small"
|
|
:pagination="mobilePagination"
|
|
:scroll="scrollConfig"
|
|
class="h-full"
|
|
/>
|
|
</ACard>
|
|
</div>
|
|
</SimpleScrollbar>
|
|
</template>
|
|
|
|
<style scoped></style>
|