Files
wireguard-dashboard/web/src/layout/components/header/components/UserAvatar.vue
coward 13e4006592
All checks were successful
continuous-integration/drone/tag Build is passing
:art:加了一些组件数据监听优化
2024-09-23 17:17:29 +08:00

225 lines
6.2 KiB
Vue

<template>
<n-dropdown :options="options" @select="handleSelect">
<div flex cursor-pointer items-center>
<img :src="userStore.avatar" mr10 h-35 w-35 rounded-full />
<span>{{ userStore.nickname }}</span>
</div>
</n-dropdown>
<n-modal
v-model:show="showChangePwdModel"
transform-origin="center"
preset="card"
title="修改密码"
:bordered="false"
size="large"
style="width: 400px"
header-style="text-align: center"
>
<n-form label-placement="top"
ref="changePasswordFormRef"
:rules="changePasswordFormRules"
:model="changePasswordFormModel">
<n-form-item label="原密码" path="originalPassword">
<n-input type="password" show-password-on="click" v-model:value="changePasswordFormModel.originalPassword"></n-input>
</n-form-item>
<n-form-item label="新密码" path="newPassword">
<n-input type="password" show-password-on="click" v-model:value="changePasswordFormModel.newPassword"></n-input>
</n-form-item>
<n-form-item label="确认密码" path="confirmPassword">
<n-input type="password" show-password-on="click" v-model:value="changePasswordFormModel.confirmPassword"></n-input>
</n-form-item>
<n-button type="primary" @click="changePasswordHandle()">确认</n-button>
</n-form>
</n-modal>
<n-modal
v-model:show="showInfoModel"
transform-origin="center"
preset="card"
:title="infoFormModel.nickname || '个人资料'"
:bordered="false"
size="large"
style="width: 400px"
header-style="text-align: center"
>
<n-form label-placement="top"
ref="infoFormRef"
:rules="infoFormRules"
:model="infoFormModel">
<n-form-item path="avatar">
<n-avatar
round
style="cursor: pointer;margin-left: 36%"
:size="78"
:src="showAvatar"
@click="changeAvatar()"
></n-avatar>
</n-form-item>
<n-form-item label="账号" path="account">
<n-input disabled v-model:value="infoFormModel.account"></n-input>
</n-form-item>
<n-form-item label="昵称" path="nickname">
<n-input v-model:value="infoFormModel.nickname"></n-input>
</n-form-item>
<n-form-item label="联系方式" path="contact">
<n-input v-model:value="infoFormModel.contact"></n-input>
</n-form-item>
<n-button type="primary" @click="updateInfo()">确认</n-button>
</n-form>
</n-modal>
</template>
<script setup>
import { useUserStore } from '@/store'
import { renderIcon } from '@/utils'
import api from '@/api/user'
import event from '@/utils/event/event'
import { router } from '@/router'
const userStore = useUserStore()
const { $bus } = event();
const options = [
{
label: "个人信息",
key: 'info',
icon: renderIcon('streamline:information-desk-solid', { size: '14px' })
},
{
label: "修改密码",
key: 'change-password',
icon: renderIcon('mdi:lock', { size: '14px' }),
},
{
label: '退出登录',
key: 'logout',
icon: renderIcon('mdi:exit-to-app', { size: '14px' }),
}
]
const showAvatar = ref('')
const showChangePwdModel = ref(false)
const showInfoModel = ref(false)
const changePasswordFormRef = ref()
const infoFormRef = ref()
// 表单数据值
const changePasswordFormModel = ref({
originalPassword: '',
newPassword: '',
confirmPassword: ''
})
// 用户信息表单
const infoFormModel = ref({
id: '',
account: '',
nickname: '',
avatar: '',
contact: '',
isAdmin: 0,
status: 1
})
// 表单数据验证规则
const changePasswordFormRules = {
originalPassword: [
{ required: true, message: '原密码不能为空', trigger: 'blur' },
{ min: 8, message: '密码最低8位', trigger: 'blur' },
{ max: 32, message: '密码最长32位', trigger: 'blur' }
],
newPassword: [
{ required: true, message: '新密码不能为空', trigger: 'blur' },
{ min: 8, message: '密码最低8位', trigger: 'blur' },
{ max: 32, message: '密码最长32位', trigger: 'blur' }
],
confirmPassword: [
{ validator: validatePasswordSame, message: '密码不一致', trigger: 'blur' }
]
}
// 个人信息表单验证规则
const infoFormRules = {
avatar: [
{ required: true, message: '头像不能为空', trigger: 'blur' }
],
nickname: [
{ required: true, message: '昵称不能为空', trigger: 'blur' }
]
}
// 验证密码是否一致
function validatePasswordSame(rule, value) {
return value === changePasswordFormModel.value.newPassword;
}
// 根据不同点击事件触发不同
function handleSelect(key) {
switch (key) {
case 'logout':
$dialog.confirm({
title: '提示',
type: 'info',
content: '确认退出?',
confirm() {
userStore.logout()
$message.success('已退出登录')
},
})
break;
case 'change-password':
showChangePwdModel.value = true
break;
case 'info':
infoFormModel.value = useUserStore().localUserInfo
showAvatar.value = infoFormModel.value.avatar
showInfoModel.value = true
break;
}
}
// 修改密码逻辑
async function changePasswordHandle() {
changePasswordFormRef.value.validate(async (errors) => {
if (errors) {
return errors
}
const res = await api.changePassword(changePasswordFormModel.value)
if (res.data.code === 200) {
changePasswordFormModel.value = ref(null)
showChangePwdModel.value = false
}
})
}
// 生成头像
async function changeAvatar() {
const res = await api.generateAvatar()
if (res.data.code === 200) {
showAvatar.value = res.data.data
}
}
async function updateInfo() {
infoFormRef.value.validate(async (errors) => {
if (errors) {
return errors
}
if (showAvatar.value !== infoFormModel.value.avatar) {
infoFormModel.value.avatar = showAvatar.value
}
const res = await api.addOrUpdateUser(infoFormModel.value)
if (res.data.code === 200) {
infoFormModel.value = ref(null)
showInfoModel.value = false
await useUserStore().getUserInfo()
if (router.options.history.location === '/user') {
$bus.emit('refreshUserInfo',true);
}
}
})
}
</script>