Browse Source

🚀 适配头像

master
wangxiang 2 years ago
parent
commit
7a6054ffb5
  1. 22
      src/layouts/default/header/components/user-dropdown/index.vue
  2. 5
      src/store/modules/user.ts
  3. 25
      src/views/system/user/userInfo/index.vue

22
src/layouts/default/header/components/user-dropdown/index.vue

@ -1,9 +1,9 @@
<template> <template>
<Dropdown placement="bottomLeft" :trigger="['click', 'hover']" :overlayClassName="`${prefixCls}-dropdown-overlay`"> <Dropdown placement="bottomLeft" :trigger="['click', 'hover']" :overlayClassName="`${prefixCls}-dropdown-overlay`">
<span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex"> <span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex">
<img :class="`${prefixCls}__header`" :src="getUserInfo.avatar"> <img :class="`${prefixCls}__header`" :src="getAvatarUrl">
<span :class="`${prefixCls}__info hidden md:block`"> <span :class="`${prefixCls}__info hidden md:block`">
<span :class="`${prefixCls}__name `" class="truncate"> <span :class="`${prefixCls}__name`" class="truncate">
{{ getUserInfo.nickName }} {{ getUserInfo.nickName }}
</span> </span>
</span> </span>
@ -34,7 +34,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { Dropdown, Menu } from 'ant-design-vue'; import { Dropdown, Menu } from 'ant-design-vue';
import { defineComponent, computed } from 'vue'; import { defineComponent, computed, unref, ref } from 'vue';
import { useUserStore } from '/@/store/modules/user'; import { useUserStore } from '/@/store/modules/user';
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
@ -43,7 +43,11 @@
import { propTypes } from '/@/utils/propTypes'; import { propTypes } from '/@/utils/propTypes';
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { isUrl } from '/@/utils/is';
import { useGlobSetting } from '/@/hooks/setting';
type MenuEvent = 'logout' | 'doc' | 'lock' | 'userInfo'; type MenuEvent = 'logout' | 'doc' | 'lock' | 'userInfo';
import defaultAvatar from '/@/assets/images/defaultAvatar.svg';
import type { User } from '/@/api/platform/core/entity/user';
export default defineComponent({ export default defineComponent({
name: 'UserDropdown', name: 'UserDropdown',
@ -61,11 +65,9 @@
const { t } = useI18n(); const { t } = useI18n();
const { getUseLockPage } = useHeaderSetting(); const { getUseLockPage } = useHeaderSetting();
const userStore = useUserStore(); const userStore = useUserStore();
const { apiUrl } = useGlobSetting();
const getUserInfo = computed(() => { const getUserInfo = computed((): User => userStore.getUserInfo || {});
const { nickName = '', avatar, remarks } = userStore.getUserInfo || {};
return { nickName, avatar: avatar, remarks };
});
const { push } = useRouter(); const { push } = useRouter();
const [register, { openModal }] = useModal(); const [register, { openModal }] = useModal();
@ -78,6 +80,11 @@
userStore.confirmLoginOut(); userStore.confirmLoginOut();
} }
const getAvatarUrl = computed((): string => {
if (!unref(getUserInfo).avatar) return defaultAvatar;
return isUrl(unref(getUserInfo).avatar) ? unref(getUserInfo).avatar : apiUrl + unref(getUserInfo).avatar;
});
function handleMenuClick(e: { key: MenuEvent }) { function handleMenuClick(e: { key: MenuEvent }) {
switch (e.key) { switch (e.key) {
case 'userInfo': case 'userInfo':
@ -99,6 +106,7 @@
handleMenuClick, handleMenuClick,
register, register,
getUseLockPage, getUseLockPage,
getAvatarUrl,
}; };
}, },
}); });

5
src/store/modules/user.ts

@ -17,10 +17,6 @@ import { useMessage } from '/@/hooks/web/useMessage';
import { router } from '/@/router'; import { router } from '/@/router';
import { usePermissionStore } from '/@/store/modules/permission'; import { usePermissionStore } from '/@/store/modules/permission';
import { RouteRecordRaw } from 'vue-router'; import { RouteRecordRaw } from 'vue-router';
import defaultAvatar from '/@/assets/images/defaultAvatar.svg';
import { isUrl } from '/@/utils/is';
import { useGlobSetting } from '/@/hooks/setting';
const { apiUrl } = useGlobSetting();
interface UserState { interface UserState {
userInfo: Nullable<User>; userInfo: Nullable<User>;
@ -137,7 +133,6 @@ export const useUserStore = defineStore({
/** 获取用户信息 */ /** 获取用户信息 */
async getUserInfoAction(): Promise<User> { async getUserInfoAction(): Promise<User> {
const userInfo = await getUserInfo().catch(()=> this.resetState()); const userInfo = await getUserInfo().catch(()=> this.resetState());
userInfo.avatar ? (userInfo.avatar = isUrl(userInfo.avatar) ? userInfo.avatar : apiUrl + userInfo.avatar) : (userInfo.avatar = defaultAvatar);
userInfo.tenantIds = String(userInfo.tenantId).split(','); userInfo.tenantIds = String(userInfo.tenantId).split(',');
// 存储用户扩展信息,便于鉴权 // 存储用户扩展信息,便于鉴权
this.setUserInfo(userInfo); this.setUserInfo(userInfo);

25
src/views/system/user/userInfo/index.vue

@ -12,7 +12,7 @@
<div class="user-info-top"> <div class="user-info-top">
<AAvatar draggable <AAvatar draggable
width="32px" width="32px"
:src="getUserInfo.avatar" :src="getAvatarUrl"
:size="80" :size="80"
/> />
<h2>{{ getUserInfo.nickName }}</h2> <h2>{{ getUserInfo.nickName }}</h2>
@ -62,6 +62,7 @@
<template #label> <template #label>
<Icon icon="fa6-solid:robot"/> <Icon icon="fa6-solid:robot"/>
</template> </template>
<a href="#">申请</a>
已认证 已认证
</ADescriptionsItem> </ADescriptionsItem>
</ADescriptions> </ADescriptions>
@ -92,7 +93,7 @@
:customRequest="handleUploadAvatar" :customRequest="handleUploadAvatar"
:before-upload="handleBeforeUpload" :before-upload="handleBeforeUpload"
> >
<img v-if="state.imageUrl" :src="state.imageUrl"> <img v-if="getImageUrl" :src="getImageUrl">
<div v-else> <div v-else>
<LoadingOutlined v-if="state.uploadAvatarLoading"/> <LoadingOutlined v-if="state.uploadAvatarLoading"/>
<PlusOutlined v-else/> <PlusOutlined v-else/>
@ -119,7 +120,7 @@
import {PageWrapper} from '/@/components/Page'; import {PageWrapper} from '/@/components/Page';
import {CreditCardOutlined, LoadingOutlined, PlusOutlined, UserOutlined} from '@ant-design/icons-vue'; import {CreditCardOutlined, LoadingOutlined, PlusOutlined, UserOutlined} from '@ant-design/icons-vue';
import type {CSSProperties} from 'vue'; import type {CSSProperties} from 'vue';
import {computed, reactive} from 'vue'; import {computed, reactive, unref} from 'vue';
import {Icon} from '/@/components/Icon'; import {Icon} from '/@/components/Icon';
import {BasicForm, useForm} from '/@/components/Form/index'; import {BasicForm, useForm} from '/@/components/Form/index';
import {userFormSchema} from './userInfo.data'; import {userFormSchema} from './userInfo.data';
@ -137,7 +138,7 @@
uploadAvatarBtnLoading: boolean; uploadAvatarBtnLoading: boolean;
uploadAvatarLoading: boolean; uploadAvatarLoading: boolean;
userInfo: User | any; userInfo: User | any;
imageUrl?: string; imageUrl: string;
tabList: Recordable[]; tabList: Recordable[];
} }
@ -159,7 +160,7 @@
uploadAvatarLoading: false, uploadAvatarLoading: false,
uploadAvatarBtnLoading: false, uploadAvatarBtnLoading: false,
userInfo: undefined, userInfo: undefined,
imageUrl: undefined, imageUrl: '',
tabList: [ tabList: [
{ {
key: 'baseInfo', key: 'baseInfo',
@ -222,14 +223,16 @@
} }
const getUserInfo = computed((): User & any => { const getUserInfo = computed((): User & any => {
let userInfo = state.userInfo ? state.userInfo : {}; let userInfo = state.userInfo || {};
if (userInfo.avatar) { userInfo.avatar || (userInfo.avatar = defaultAvatarUrl);
userInfo.avatar ? (userInfo.avatar = isUrl(userInfo.avatar) ? userInfo.avatar : apiUrl + userInfo.avatar) : (userInfo.avatar = defaultAvatarUrl); state!.imageUrl = userInfo.avatar;
state!.imageUrl = userInfo.avatar;
}
return userInfo; return userInfo;
}); });
const getAvatarUrl = computed((): string => isUrl(unref(getUserInfo).avatar) ? unref(getUserInfo).avatar : apiUrl + unref(getUserInfo).avatar);
const getImageUrl = computed((): string => isUrl(state.imageUrl) ? state.imageUrl : apiUrl + state.imageUrl);
const getLabelStyle = computed((): CSSProperties => ({ const getLabelStyle = computed((): CSSProperties => ({
fontSize: '14px', fontSize: '14px',
display: 'inline', display: 'inline',
@ -264,7 +267,7 @@
const complete = ((progressEvent.loaded / progressEvent.total) * 100) | 0; const complete = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
if (complete >= 100) state.uploadAvatarLoading = false; if (complete >= 100) state.uploadAvatarLoading = false;
}); });
state.imageUrl = apiUrl + data.url; state.imageUrl = data.url;
} finally { } finally {
state.uploadAvatarLoading = false; state.uploadAvatarLoading = false;
} }

Loading…
Cancel
Save