finance-pay-admin/pc/pages/user/info.vue

203 lines
6.5 KiB
Vue
Executable File

<template>
<div class="px-[30px] py-5 user-info">
<div class="border-b border-br pb-5">
<span class="text-2xl font-medium">个人信息</span>
</div>
<div class="mt-5">
<div class="info-item">
<div class="item-name">头像</div>
<div class="avatar">
<ElAvatar :size="60" :src="userInfo.avatar"></ElAvatar>
<div class="change-btn">
<CropperUpload
@change="setUserInfo($event, UserFieldEnum.AVATAR)"
>
<span class="text-xs text-white">修改</span>
</CropperUpload>
</div>
</div>
</div>
<div class="info-item leading-10">
<div class="item-name">账号</div>
<div>
{{ userInfo.account }}
<ClientOnly>
<PopoverInput
class="inline-block"
@confirm="
setUserInfo($event, UserFieldEnum.USERNAME)
"
:limit="30"
show-limit
>
<ElButton link>
<Icon name="el-icon-Edit" :size="16" />
</ElButton>
</PopoverInput>
</ClientOnly>
</div>
</div>
<div class="info-item leading-10">
<div class="item-name">昵称</div>
<div>
{{ userInfo.nickname }}
<ClientOnly>
<PopoverInput
class="inline-block"
@confirm="
setUserInfo($event, UserFieldEnum.NICKNAME)
"
:limit="30"
show-limit
>
<ElButton link>
<Icon name="el-icon-Edit" :size="16" />
</ElButton>
</PopoverInput>
</ClientOnly>
</div>
</div>
<div class="info-item leading-10">
<div class="item-name">性别</div>
<div>
<span>
{{ userInfo.sex }}
</span>
<ClientOnly>
<PopoverInput
class="inline-block"
type="select"
:teleported="false"
:options="[
{
label: '未知',
value: 0
},
{
label: '男',
value: 1
},
{
label: '女',
value: 2
}
]"
@confirm="setUserInfo($event, UserFieldEnum.SEX)"
>
<ElButton link>
<Icon name="el-icon-Edit" :size="16" />
</ElButton>
</PopoverInput>
</ClientOnly>
</div>
</div>
<div class="info-item leading-10">
<div class="item-name">手机号</div>
<div v-if="userInfo.mobile">
{{ userInfo.mobile }}
</div>
<ElButton link type="primary" @click="changeMobile">
{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}
</ElButton>
</div>
<div class="info-item leading-10">
<div class="item-name">注册时间</div>
<div>
{{ userInfo.create_time }}
</div>
</div>
</div>
<div class="mt-[60px] flex justify-center">
<ElButton type="primary" @click="handleLogut">退出登录</ElButton>
</div>
</div>
</template>
<script lang="ts" setup>
import { ElAvatar, ElButton } from 'element-plus'
import { getUserInfo, userEdit } from '@/api/user'
import CropperUpload from '@/components/cropper-upload/index.vue'
import PopoverInput from '@/components/popover-input/index.vue'
import {
useAccount,
PopupTypeEnum
} from '@/layouts/components/account/useAccount'
import { logout } from '~~/api/account'
import feedback from '~~/utils/feedback'
import { useUserStore } from '~~/stores/user'
const { setPopupType, toggleShowPopup, showPopup } = useAccount()
const userStore = useUserStore()
// 用户资料
enum UserFieldEnum {
NONE = '',
AVATAR = 'avatar',
USERNAME = 'account',
NICKNAME = 'nickname',
SEX = 'sex'
}
const { data: userInfo, refresh } = await useAsyncData(() => getUserInfo(), {
initialCache: false
})
const setUserInfo = async (
value: string,
type: UserFieldEnum
): Promise<void> => {
await userEdit({
field: type,
value: value
})
refresh()
}
const changeMobile = () => {
setPopupType(PopupTypeEnum.BIND_MOBILE)
toggleShowPopup(true)
}
watch(showPopup, (value) => {
if (!value) {
refresh()
}
})
const handleLogut = async () => {
await feedback.confirm('确定退出登录吗?')
await logout()
userStore.logout()
}
definePageMeta({
module: 'personal',
auth: true
})
</script>
<style lang="scss" scoped>
.user-info {
.info-item {
display: flex;
align-items: center;
border-bottom: 1px solid var(--el-border-color);
padding: 10px 0;
.item-name {
width: 80px;
color: var(--el-text-color-regular);
}
}
.avatar {
@apply relative flex cursor-pointer;
.change-btn {
display: none;
height: 50%;
line-height: 30px;
@apply absolute bg-[rgba(0,0,0,0.5)] w-full text-center bottom-0 rounded-b-full;
}
&:hover {
.change-btn {
display: block;
}
}
}
}
</style>