|
|
@@ -4,57 +4,216 @@
|
|
|
<a-card :bordered="false">
|
|
|
<div class="account-center-avatarHolder">
|
|
|
<div class="avatar">
|
|
|
- <img :src="userInfo.avatar" />
|
|
|
+ <a-spin size="small" :spinning="avatarLoading">
|
|
|
+ <img :src="userInfo.avatar" />
|
|
|
+ </a-spin>
|
|
|
+ <a @click="uploadLogo">
|
|
|
+ <div :class="userInfo.avatar ? 'mask' : 'mask-notImg'"><upload-outlined /></div>
|
|
|
+ </a>
|
|
|
</div>
|
|
|
<div class="username">{{ userInfo.name }}</div>
|
|
|
<div class="bio">{{ userInfo.nickname }}</div>
|
|
|
</div>
|
|
|
- <div class="account-center-detail">
|
|
|
- <p>{{ userInfo.gradesIdName }}</p>
|
|
|
- <p>{{ userInfo.majorIdName }}</p>
|
|
|
+ <div>
|
|
|
+ <p>班级:{{ userInfo.gradesIdName }}</p>
|
|
|
+ <p>专业:{{ userInfo.majorIdName }}</p>
|
|
|
</div>
|
|
|
</a-card>
|
|
|
</a-col>
|
|
|
<a-col :xs="24" :sm="24" :md="17" :lg="17" :xl="17">
|
|
|
<a-card>
|
|
|
- <a-descriptions :title="`${userInfo.name}个人信息`" :column="1">
|
|
|
- <a-descriptions-item label="性别">{{ userInfo.gender }}</a-descriptions-item>
|
|
|
- <a-descriptions-item label="邮箱">{{ userInfo.email }}</a-descriptions-item>
|
|
|
- <a-descriptions-item label="手机">{{ userInfo.phone }}</a-descriptions-item>
|
|
|
- <a-descriptions-item label="生日">{{ userInfo.birthday }}</a-descriptions-item>
|
|
|
- <a-descriptions-item label="学号">{{ userInfo.studentNum }}</a-descriptions-item>
|
|
|
- <a-descriptions-item label="入学时间">{{ userInfo.fallDue }}</a-descriptions-item>
|
|
|
- <a-descriptions-item label="班级">{{ userInfo.gradesIdName }}</a-descriptions-item>
|
|
|
- <a-descriptions-item label="专业">{{ userInfo.majorIdName }}</a-descriptions-item>
|
|
|
- </a-descriptions>
|
|
|
+ <a-form
|
|
|
+ ref="formRef"
|
|
|
+ :model="formData"
|
|
|
+ :rules="formRules"
|
|
|
+ v-bind="layout"
|
|
|
+ :label-col="{ ...layout.labelCol, offset: 0 }"
|
|
|
+ :wrapper-col="{ ...layout.wrapperCol, offset: 0 }"
|
|
|
+ >
|
|
|
+ <a-form-item label="账号:" name="account">
|
|
|
+ <span>{{ formData.account }}</span>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="学号" name="account">
|
|
|
+ <span>{{ formData.studentNum }}</span>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="班级" name="account">
|
|
|
+ <span>{{ formData.gradesIdName }}</span>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="专业" name="account">
|
|
|
+ <span>{{ formData.majorIdName }}</span>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="入学时间:" name="account">
|
|
|
+ <span>{{ formData.fallDue }}</span>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="姓名:" name="name">
|
|
|
+ <a-input v-model:value="formData.name" placeholder="请输入姓名" allow-clear />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="手机:" name="phone">
|
|
|
+ <a-input v-model:value="formData.phone" :maxlength="11" placeholder="请输入手机" allow-clear />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="性别:" name="sex">
|
|
|
+ <a-radio-group v-model:value="formData.gender" :options="genderOptions" />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="生日:" name="birthday">
|
|
|
+ <a-date-picker v-model:value="formData.birthday" value-format="YYYY-MM-DD" style="width: 100%" />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="邮箱:" name="email">
|
|
|
+ <a-input v-model:value="formData.email" :maxlength="200" placeholder="请输入邮箱" allow-clear />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="教育程度:" name="leval">
|
|
|
+ <a-select
|
|
|
+ v-model:value="formData.leval"
|
|
|
+ placeholder="请选择教育程度"
|
|
|
+ style="width: 100%"
|
|
|
+ :options="typeOptions"
|
|
|
+ allow-clear
|
|
|
+ ></a-select>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="所属单位:" name="unit">
|
|
|
+ <a-input v-model:value="formData.unit" :maxlength="200" placeholder="请输入所属单位" allow-clear />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="兴趣爱好:" name="interests">
|
|
|
+ <a-input v-model:value="formData.interests" :maxlength="200" placeholder="请输入兴趣爱好" allow-clear />
|
|
|
+ </a-form-item>
|
|
|
+
|
|
|
+ <a-form-item :wrapper-col="{ ...layout.wrapperCol, offset: layout.labelCol.span }">
|
|
|
+ <a-button type="primary" :loading="submitLoading" @click="onSubmit">保存基本信息</a-button>
|
|
|
+ </a-form-item>
|
|
|
+ </a-form>
|
|
|
</a-card>
|
|
|
</a-col>
|
|
|
+ <CropUpload ref="cropUpload" :img-src="userInfo.avatar" @successful="cropUploadSuccess" />
|
|
|
</a-row>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
+ import CropUpload from '@/components/CropUpload/index.vue'
|
|
|
+ import userCenterApi from '@/api/sys/userCenterApi'
|
|
|
import tool from '@/utils/tool'
|
|
|
- const userInfo = tool.data.get('USER_INFO')
|
|
|
-</script>
|
|
|
+ import { cloneDeep } from 'lodash-es'
|
|
|
+ import { globalStore } from '@/store'
|
|
|
+ import { required } from '@/utils/formRules'
|
|
|
+ const global_store = globalStore()
|
|
|
+ const userInfo = computed(() => {
|
|
|
+ return global_store.userInfo
|
|
|
+ })
|
|
|
+ const typeOptions = tool.dictList('LEVAL').sort(function (a, b) {
|
|
|
+ return a.value - b.value
|
|
|
+ })
|
|
|
+ const cropUpload = ref()
|
|
|
+ const avatarLoading = ref(false)
|
|
|
+ const uploadLogo = () => {
|
|
|
+ cropUpload.value.show()
|
|
|
+ }
|
|
|
+ // 头像裁剪图片回调
|
|
|
+ const cropUploadSuccess = (data) => {
|
|
|
+ // 转换为file类型
|
|
|
+ const result = new File([data.blobData], data.fileName, { type: 'image/jpeg', lastModified: Date.now() })
|
|
|
+ const fileData = new FormData()
|
|
|
+ fileData.append('file', result)
|
|
|
+ avatarLoading.value = true
|
|
|
+ userCenterApi.userUpdateAvatar(fileData).then((data) => {
|
|
|
+ avatarLoading.value = false
|
|
|
+ userInfo.value.avatar = data
|
|
|
+ // 更新缓存
|
|
|
+ tool.data.set('USER_INFO', userInfo.value)
|
|
|
+ global_store.setUserInfo(userInfo.value)
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
-<style lang="less" scoped>
|
|
|
- .avatar {
|
|
|
- margin: 0 auto;
|
|
|
- width: 104px;
|
|
|
- height: 104px;
|
|
|
- margin-bottom: 20px;
|
|
|
- border-radius: 50%;
|
|
|
- overflow: hidden;
|
|
|
- img {
|
|
|
- height: 100%;
|
|
|
- width: 100%;
|
|
|
+ const formRef = ref()
|
|
|
+ let formData = ref({})
|
|
|
+ formData.value = cloneDeep(global_store.userInfo)
|
|
|
+ const submitLoading = ref(false)
|
|
|
+ // 默认要校验的
|
|
|
+ const formRules = {
|
|
|
+ name: [required('请输入姓名')],
|
|
|
+ gender: [required('请选择性别')]
|
|
|
+ }
|
|
|
+ const genderOptions = tool.dictList('GENDER')
|
|
|
+ // 验证并提交数据
|
|
|
+ const onSubmit = () => {
|
|
|
+ formRef.value
|
|
|
+ .validate()
|
|
|
+ .then(() => {
|
|
|
+ submitLoading.value = true
|
|
|
+ userCenterApi.userUpdateUserInfo(formData.value).then(() => {
|
|
|
+ submitLoading.value = false
|
|
|
+ // 更新前端缓存
|
|
|
+ global_store.setUserInfo(cloneDeep(formData.value))
|
|
|
+ tool.data.set('USER_INFO', formData.value)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ submitLoading.value = false
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const layout = {
|
|
|
+ labelCol: {
|
|
|
+ span: 3
|
|
|
+ },
|
|
|
+ wrapperCol: {
|
|
|
+ span: 21
|
|
|
}
|
|
|
}
|
|
|
- .username {
|
|
|
- font-size: 20px;
|
|
|
- line-height: 28px;
|
|
|
- font-weight: 500;
|
|
|
- margin-bottom: 4px;
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+ .account-center-avatarHolder {
|
|
|
text-align: center;
|
|
|
+ margin-bottom: 24px;
|
|
|
+ & > .avatar {
|
|
|
+ margin: 0 auto;
|
|
|
+ width: 104px;
|
|
|
+ height: 104px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ border-radius: 50%;
|
|
|
+ overflow: hidden;
|
|
|
+ img {
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .mask {
|
|
|
+ border-radius: 50%;
|
|
|
+ position: absolute;
|
|
|
+ margin-top: -104px;
|
|
|
+ width: 104px;
|
|
|
+ height: 104px;
|
|
|
+ background: rgba(101, 101, 101, 0.6);
|
|
|
+ color: #ffffff;
|
|
|
+ opacity: 0;
|
|
|
+ font-size: 25px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ .mask-notImg {
|
|
|
+ border-radius: 50%;
|
|
|
+ position: absolute;
|
|
|
+ margin-top: -24px;
|
|
|
+ width: 104px;
|
|
|
+ height: 104px;
|
|
|
+ background: rgba(101, 101, 101, 0.6);
|
|
|
+ color: #ffffff;
|
|
|
+ opacity: 0;
|
|
|
+ font-size: 25px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ .avatar a:hover .mask {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ .avatar a:hover .mask-notImg {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ .username {
|
|
|
+ font-size: 20px;
|
|
|
+ line-height: 28px;
|
|
|
+ font-weight: 500;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|