Browse Source

🚀 简化上传头像

master
wangxiang 2 years ago
parent
commit
052e7bb5a8
  1. 106
      src/views/system/user/userInfo/index.vue

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

@ -72,12 +72,39 @@
<CreditCardOutlined/> 资料修改 <CreditCardOutlined/> 资料修改
</template> </template>
<ACard :bordered="false" <ACard :bordered="false"
:tab-list="tabListNoTitle" :tab-list="state.tabList"
:active-tab-key="state.currentCardKey" :active-tab-key="state.currentCardKey"
@tabChange="key => state.currentCardKey = key" @tabChange="key => state.currentCardKey = key"
> >
<BasicForm v-show="state.currentCardKey === 'baseInfo'" @register="registerForm"/> <BasicForm v-show="state.currentCardKey === 'baseInfo'" @register="registerForm"/>
<p v-show="state.currentCardKey === 'uploadAvatar'">上传头像待开发中</p> <AForm v-show="state.currentCardKey === 'uploadAvatar'"
ref="formElRef"
:labelCol="{ style: { width: '120px' } }"
:wrapperCol="{ style: { width: '100%' } }"
:model="state.userInfo"
:scrollToFirstError="true"
@keypress.enter="handleSubmit"
>
<AFormItem name="avatar">
<AUpload list-type="picture-card"
class="avatar-uploader"
accept="image/*"
:multiple="false"
:show-upload-list="false"
:before-upload="beforeUpload"
>
<img v-if="state.imageUrl" :src="state.imageUrl">
<div v-else>
<LoadingOutlined v-if="state.uploadAvatarLoading"/>
<PlusOutlined v-else/>
<div class="ant-upload-text">上传头像</div>
</div>
</AUpload>
</AFormItem>
<AFormItem>
<a-button type="primary">保存</a-button>
</AFormItem>
</AForm>
</ACard> </ACard>
</ACard> </ACard>
</PageWrapper> </PageWrapper>
@ -85,9 +112,9 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Card, Avatar, Descriptions, Divider } from 'ant-design-vue'; import {Avatar, Card, Descriptions, Divider, Form, Upload} from 'ant-design-vue';
import {PageWrapper} from '/@/components/Page'; import {PageWrapper} from '/@/components/Page';
import { UserOutlined, CreditCardOutlined } 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} from 'vue';
import {Icon} from '/@/components/Icon'; import {Icon} from '/@/components/Icon';
@ -97,12 +124,16 @@
import {editUser, getUser} from '/@/api/platform/system/controller/user'; import {editUser, getUser} from '/@/api/platform/system/controller/user';
import type {User} from '/@/api/platform/core/entity/user'; import type {User} from '/@/api/platform/core/entity/user';
import {useUserStore} from '/@/store/modules/user'; import {useUserStore} from '/@/store/modules/user';
const userStore = useUserStore(); import {commonUpload} from '/@/api/platform/core/controller/upload';
import {useGlobSetting} from '/@/hooks/setting';
interface InfoState { interface InfoState {
currentCardKey: string; currentCardKey: string;
baseInfoBtnLoading: boolean; baseInfoBtnLoading: boolean;
userInfo: User | undefined; uploadAvatarLoading: boolean;
userInfo: User | any;
imageUrl?: string;
tabList: Recordable[];
} }
const ACard = Card; const ACard = Card;
@ -110,12 +141,29 @@
const ADescriptions = Descriptions; const ADescriptions = Descriptions;
const ADescriptionsItem = Descriptions.Item; const ADescriptionsItem = Descriptions.Item;
const ADivider = Divider; const ADivider = Divider;
const AForm = Form;
const AFormItem = Form.Item;
const AUpload = Upload;
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const userStore = useUserStore();
const userInfo = userStore.getUserInfo; const userInfo = userStore.getUserInfo;
const { apiUrl } = useGlobSetting();
const state = reactive<InfoState>({ const state = reactive<InfoState>({
currentCardKey: 'baseInfo', currentCardKey: 'baseInfo',
baseInfoBtnLoading: false, baseInfoBtnLoading: false,
userInfo: undefined uploadAvatarLoading: false,
userInfo: undefined,
imageUrl: undefined,
tabList: [
{
key: 'baseInfo',
tab: '基本信息',
},
{
key: 'uploadAvatar',
tab: '上传头像',
}
]
}); });
const [registerForm, { resetFields, setFieldsValue, updateSchema, validate, clearValidate }] = useForm({ const [registerForm, { resetFields, setFieldsValue, updateSchema, validate, clearValidate }] = useForm({
@ -126,7 +174,7 @@
showAdvancedButton: false, showAdvancedButton: false,
submitButtonOptions: { submitButtonOptions: {
text: '保存', text: '保存',
preIcon: '', preIcon: 'fa-regular:save',
loading: state.baseInfoBtnLoading, loading: state.baseInfoBtnLoading,
onClick: handleSubmit onClick: handleSubmit
}, },
@ -169,16 +217,31 @@
'font-size': '14px' 'font-size': '14px'
})); }));
const tabListNoTitle = [ const beforeUpload = async (file: File) => {
{ const isJpgOrPng = file.type?.includes('image/'),
key: 'baseInfo', isLt2M = file.size / 1024 / 1024 < 10;
tab: '基本信息',
}, !isJpgOrPng && createMessage.error('您只能上传 image/* 格式的文件!');
{ !isLt2M && createMessage.error('图片必须小于 10MB!');
key: 'uploadAvatar',
tab: '上传头像', //
if (isJpgOrPng && isLt2M) {
try {
state.uploadAvatarLoading = true;
const { data } = await commonUpload({
file: file,
name: 'file',
}, (progressEvent: ProgressEvent) => {
const complete = ((progressEvent.loaded / progressEvent.total) * 100) | 0;
if (complete >= 100) state.uploadAvatarLoading = false;
});
state.imageUrl = apiUrl + data.url;
} finally {
state.uploadAvatarLoading = false;
}
} }
]; return false;
};
</script> </script>
@ -220,6 +283,15 @@
.info-modify { .info-modify {
margin: 10px 10px 10px 0px; margin: 10px 10px 10px 0px;
::v-deep(.avatar-uploader) > .ant-upload {
width: 128px;
height: 128px;
}
::v-deep(.ant-upload-select-picture-card .ant-upload-text) {
margin-top: 8px;
color: #666;
}
} }
</style> </style>

Loading…
Cancel
Save