feat: chat left menu avatar
This commit is contained in:
parent
fe8f87834d
commit
d252a2546e
@ -11,6 +11,7 @@ import {
|
|||||||
} from '@/request/chat/index'
|
} from '@/request/chat/index'
|
||||||
import { type ChatProfile } from '@/api/type/chat'
|
import { type ChatProfile } from '@/api/type/chat'
|
||||||
import { type Ref } from 'vue'
|
import { type Ref } from 'vue'
|
||||||
|
import type { ResetPasswordRequest } from "@/api/type/user.ts";
|
||||||
|
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
import type { LoginRequest } from '@/api/type/user'
|
import type { LoginRequest } from '@/api/type/user'
|
||||||
@ -201,6 +202,23 @@ const pageChatRecord: (
|
|||||||
loading,
|
loading,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登出
|
||||||
|
*/
|
||||||
|
const logout: (loading?: Ref<boolean>) => Promise<Result<boolean>> = (loading) => {
|
||||||
|
return post('/auth/logout', undefined, undefined, loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置密码
|
||||||
|
*/
|
||||||
|
const resetCurrentPassword: (
|
||||||
|
request: ResetPasswordRequest,
|
||||||
|
loading?: Ref<boolean>
|
||||||
|
) => Promise<Result<boolean>> = (request, loading) => {
|
||||||
|
return post('/chat_user/current/reset_password', request, undefined, loading)
|
||||||
|
}
|
||||||
export default {
|
export default {
|
||||||
open,
|
open,
|
||||||
chat,
|
chat,
|
||||||
@ -221,4 +239,6 @@ export default {
|
|||||||
vote,
|
vote,
|
||||||
pageChat,
|
pageChat,
|
||||||
pageChatRecord,
|
pageChatRecord,
|
||||||
|
logout,
|
||||||
|
resetCurrentPassword
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,14 @@ import useStore from '@/stores'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
emitConfirm?: boolean; // 在父级调接口
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'confirm', value: ResetCurrentUserPasswordRequest): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { login } = useStore()
|
const { login } = useStore()
|
||||||
|
|
||||||
@ -133,10 +141,14 @@ const open = () => {
|
|||||||
}
|
}
|
||||||
const resetPassword = () => {
|
const resetPassword = () => {
|
||||||
resetPasswordFormRef1.value?.validate().then(() => {
|
resetPasswordFormRef1.value?.validate().then(() => {
|
||||||
|
if(props.emitConfirm) {
|
||||||
|
emit('confirm', resetPasswordForm.value)
|
||||||
|
} else {
|
||||||
return UserApi.resetCurrentPassword(resetPasswordForm.value).then(() => {
|
return UserApi.resetCurrentPassword(resetPasswordForm.value).then(() => {
|
||||||
login.logout()
|
login.logout()
|
||||||
router.push({ name: 'login' })
|
router.push({ name: 'login' })
|
||||||
})
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const close = () => {
|
const close = () => {
|
||||||
|
|||||||
@ -92,6 +92,14 @@ const useChatUserStore = defineStore('chat-user', {
|
|||||||
return this.token
|
return this.token
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
logout() {
|
||||||
|
return ChatAPI.logout().then(() => {
|
||||||
|
sessionStorage.removeItem(`${this.accessToken}-accessToken`)
|
||||||
|
localStorage.removeItem(`${this.accessToken}-accessToken`)
|
||||||
|
this.token = undefined
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -135,8 +135,44 @@
|
|||||||
<el-text type="info">{{ $t('chat.noHistory') }}</el-text>
|
<el-text type="info">{{ $t('chat.noHistory') }}</el-text>
|
||||||
</div>
|
</div>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
|
<el-dropdown trigger="click" type="primary" class="w-full">
|
||||||
|
<div class="flex align-center user-info">
|
||||||
|
<el-avatar :size="32">
|
||||||
|
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
<!-- TODO -->
|
||||||
|
<span v-show="!isPcCollapse" class="ml-8 color-text-primary">{{ 222 }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu class="avatar-dropdown">
|
||||||
|
<div class="flex align-center" style="padding: 12px;">
|
||||||
|
<div class="mr-8 flex align-center">
|
||||||
|
<el-avatar :size="40">
|
||||||
|
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
|
||||||
|
</el-avatar>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<!-- TODO -->
|
||||||
|
<h4 class="medium mb-4">{{ 111 }}</h4>
|
||||||
|
<div class="color-secondary">{{ `${t('common.username')}: 222` }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-dropdown-item class="border-t" style="padding-top: 8px; padding-bottom: 8px;" @click="openResetPassword">
|
||||||
|
<AppIcon iconName="app-export" />
|
||||||
|
{{ $t('views.login.resetPassword') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item class="border-t" @click="logout">
|
||||||
|
<AppIcon iconName="app-export" />
|
||||||
|
{{ $t('layout.logout') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
|
||||||
</el-menu>
|
</el-menu>
|
||||||
<el-button v-if="!common.isMobile()" class="pc-collapse" circle size="small" @click="isPcCollapse = !isPcCollapse">
|
<el-button v-if="!common.isMobile()" class="pc-collapse" circle size="small"
|
||||||
|
@click="isPcCollapse = !isPcCollapse">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<component :is="isPcCollapse ? 'Fold' : 'Expand'" />
|
<component :is="isPcCollapse ? 'Fold' : 'Expand'" />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@ -200,6 +236,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<EditTitleDialog ref="EditTitleDialogRef" @refresh="refreshFieldTitle" />
|
<EditTitleDialog ref="EditTitleDialogRef" @refresh="refreshFieldTitle" />
|
||||||
|
<ResetPassword ref="resetPasswordRef" emitConfirm @confirm="handleResetPassword"></ResetPassword>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -213,10 +250,15 @@ import useStore from '@/stores'
|
|||||||
import useResize from '@/layout/hooks/useResize'
|
import useResize from '@/layout/hooks/useResize'
|
||||||
import { hexToRgba } from '@/utils/theme'
|
import { hexToRgba } from '@/utils/theme'
|
||||||
import EditTitleDialog from './EditTitleDialog.vue'
|
import EditTitleDialog from './EditTitleDialog.vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import ResetPassword from '@/layout/layout-header/avatar/ResetPassword.vue'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
|
import type { ResetCurrentUserPasswordRequest } from '@/api/type/user'
|
||||||
|
|
||||||
useResize()
|
useResize()
|
||||||
|
|
||||||
const { user, chatLog, common } = useStore()
|
const { user, chatLog, common, chatUser } = useStore()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const EditTitleDialogRef = ref()
|
const EditTitleDialogRef = ref()
|
||||||
|
|
||||||
@ -228,6 +270,23 @@ watch(()=> common.device, () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
chatUser.logout().then(() => {
|
||||||
|
router.push({ name: 'login' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetPasswordRef = ref<InstanceType<typeof ResetPassword>>()
|
||||||
|
const openResetPassword = () => {
|
||||||
|
resetPasswordRef.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleResetPassword = (param: ResetCurrentUserPasswordRequest) => {
|
||||||
|
chatAPI.resetCurrentPassword(param).then(() => {
|
||||||
|
logout()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const customStyle = computed(() => {
|
const customStyle = computed(() => {
|
||||||
return {
|
return {
|
||||||
background: applicationDetail.value?.custom_theme?.theme_color,
|
background: applicationDetail.value?.custom_theme?.theme_color,
|
||||||
@ -472,6 +531,8 @@ onMounted(() => {
|
|||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.el-menu {
|
.el-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
background:
|
background:
|
||||||
linear-gradient(187.61deg, rgba(235, 241, 255, 0.5) 39.6%, rgba(231, 249, 255, 0.5) 94.3%),
|
linear-gradient(187.61deg, rgba(235, 241, 255, 0.5) 39.6%, rgba(231, 249, 255, 0.5) 94.3%),
|
||||||
#eef1f4;
|
#eef1f4;
|
||||||
@ -484,12 +545,31 @@ onMounted(() => {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-dropdown {
|
||||||
|
margin-top: auto;
|
||||||
|
.user-info {
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin: 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
&:hover {
|
||||||
|
background-color: #1F23291A;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.el-menu--collapse {
|
&.el-menu--collapse {
|
||||||
.el-menu-item,.el-menu-tooltip__trigger,.el-sub-menu__title {
|
|
||||||
|
.el-menu-item,
|
||||||
|
.el-menu-tooltip__trigger,
|
||||||
|
.el-sub-menu__title {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-menu-item .el-menu-tooltip__trigger,.el-sub-menu__title {
|
.el-menu-item .el-menu-tooltip__trigger,
|
||||||
|
.el-sub-menu__title {
|
||||||
position: static;
|
position: static;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
@ -498,9 +578,15 @@ onMounted(() => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
.el-menu-item:hover .el-menu-tooltip__trigger,.el-sub-menu__title:hover {
|
|
||||||
|
.el-menu-item:hover .el-menu-tooltip__trigger,
|
||||||
|
.el-sub-menu__title:hover {
|
||||||
background-color: #1F23291A;
|
background-color: #1F23291A;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
margin: 16px 8px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,7 +595,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.left-height {
|
.left-height {
|
||||||
height: calc(100vh - 140px);
|
height: calc(100vh - 212px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pc-collapse {
|
.pc-collapse {
|
||||||
@ -633,3 +719,9 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.avatar-dropdown {
|
||||||
|
min-width: 240px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user