577 lines
11 KiB
Vue
577 lines
11 KiB
Vue
<template>
|
||
<div class="user-account">
|
||
<div class="user-account-wrap">
|
||
<mf-image-upload
|
||
v-model="avatar"
|
||
content=""
|
||
:image-size="60"
|
||
:limit="1"
|
||
@success="updateAvatar" />
|
||
<!-- <a-avatar :size="60">
|
||
<img
|
||
alt="avatar"
|
||
:src="userInfo.avatar || '/images/avatar.svg'" />
|
||
<div class="user-account-avatar-edit">
|
||
<mf-icon value="icon-edit-photo" />
|
||
</div>
|
||
</a-avatar> -->
|
||
<div class="user-account-list">
|
||
<div class="user-account-item">
|
||
<label>{{ $t('common.userId') }}: </label>
|
||
<span>{{ userInfo.userId }}</span>
|
||
</div>
|
||
<div class="user-account-item">
|
||
<label>{{ $t('common.username') }}: </label>
|
||
<span>{{ userInfo.username }}</span>
|
||
</div>
|
||
<div class="user-account-item">
|
||
<label>{{ $t('common.email') }}: </label>
|
||
<span>{{ userInfo.email }}</span>
|
||
</div>
|
||
<div class="user-account-item">
|
||
<label>{{ $t('common.accountAmount') }}: </label>
|
||
<span>{{ userInfo.balance }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="user-account-btns">
|
||
<mf-button
|
||
type="primary"
|
||
@click="changePasswordVisible = true">
|
||
{{ $t('common.editPassword') }}
|
||
</mf-button>
|
||
<mf-button
|
||
type="primary"
|
||
@click="showEditUser">
|
||
{{ $t('common.editEmail') }}
|
||
</mf-button>
|
||
</div>
|
||
<div class="user-account-contact">
|
||
<a :href="serviceUrl" target="_blank">{{ $t('common.contact') }}</a>
|
||
</div>
|
||
|
||
<ChangePassword
|
||
:visible="changePasswordVisible"
|
||
@cancel="changePasswordVisible = false"
|
||
@back="changePasswordVisible = false" />
|
||
|
||
<mf-dialog
|
||
width="500px"
|
||
modal-class="edit-user-dialog email"
|
||
class="edit-user-dialog-wrapper"
|
||
hideTitle
|
||
:footer="false"
|
||
:maskClosable="false"
|
||
unmountOnClose
|
||
@cancel="cancelEdit"
|
||
:visible="editVisible">
|
||
<div class="edit-user-close">
|
||
<mf-icon
|
||
value="icon-close"
|
||
@click="cancelEdit" />
|
||
</div>
|
||
<div class="edit-user-content">
|
||
<div class="edit-user-title">
|
||
{{ $t('common.editEmail') }}
|
||
</div>
|
||
<mf-input
|
||
v-model="formData.email"
|
||
class="edit-user-input"
|
||
:placeholder="`${$t('common.emailPlaceholder')}`" />
|
||
<mf-input
|
||
v-model="formData.code"
|
||
class="edit-user-input code"
|
||
:placeholder="`${$t('common.codePlaceholder')}`">
|
||
<template #suffix>
|
||
<mf-button
|
||
class="edit-user-input-send"
|
||
@click="sendMsg"
|
||
:disabled="msgCount !== 60"
|
||
:loading="msgLoading">
|
||
{{ msgTextComputed }}
|
||
</mf-button>
|
||
</template>
|
||
</mf-input>
|
||
<!-- <a-form
|
||
layout="vertical"
|
||
:model="formData"
|
||
size="large">
|
||
<a-form-item :label="$t('common.avatar')">
|
||
<mf-image-upload v-model="formData.avatar" />
|
||
</a-form-item>
|
||
<a-form-item
|
||
:label="$t('common.email')"
|
||
field="email">
|
||
<mf-input
|
||
:placeholder="$t('common.input')"
|
||
v-model="formData.email" />
|
||
</a-form-item>
|
||
</a-form> -->
|
||
<div class="edit-user-save">
|
||
<mf-button
|
||
type="primary"
|
||
@click="saveUser">
|
||
{{ $t('common.save') }}
|
||
</mf-button>
|
||
</div>
|
||
</div>
|
||
</mf-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { mapGetters } from 'vuex'
|
||
import ChangePassword from './ChangePassword.vue'
|
||
export default {
|
||
data() {
|
||
return {
|
||
changePasswordVisible: false,
|
||
data: {},
|
||
editVisible: false,
|
||
avatar: null,
|
||
formData: {
|
||
code: '',
|
||
email: ''
|
||
},
|
||
msgLoading: false,
|
||
loading: false,
|
||
msgCount: 60,
|
||
msgInterval: null,
|
||
msgText: this.$t('common.send'),
|
||
serviceUrl: ""
|
||
}
|
||
},
|
||
computed: {
|
||
...mapGetters(['userInfo']),
|
||
msgTextComputed() {
|
||
return this.msgText
|
||
}
|
||
},
|
||
components: { ChangePassword },
|
||
mounted() {
|
||
this.$axios({
|
||
url: 'api/user/getUserInfo',
|
||
method: 'GET'
|
||
}).then((res) => {
|
||
this.avatar = res.data.avatar
|
||
this.$store.dispatch('user/setUserInfo', res.data)
|
||
})
|
||
this.getService();
|
||
},
|
||
beforeUnmount() {
|
||
this.destroyMsgInterval()
|
||
},
|
||
methods: {
|
||
getService() {
|
||
this.$axios({
|
||
url: 'api/service/list',
|
||
method: "GET"
|
||
}).then(res=> {
|
||
this.serviceUrl = res.result.url
|
||
})
|
||
},
|
||
updateAvatar(url) {
|
||
this.$axios({
|
||
url: 'api/user/updateAvatar',
|
||
method: 'PUT',
|
||
data: {
|
||
avatar: url
|
||
}
|
||
}).then((res) => {
|
||
if (res.code == 200) {
|
||
this.$store.dispatch('user/setUserInfo', {
|
||
...this.userInfo,
|
||
avatar: url
|
||
})
|
||
this.$message.success(
|
||
this.$t('common.updateAvatarSuccessfully')
|
||
)
|
||
}
|
||
})
|
||
},
|
||
destroyMsgInterval() {
|
||
if (this.msgInterval) {
|
||
clearInterval(this.msgInterval)
|
||
this.msgInterval = null
|
||
this.msgCount = 60
|
||
}
|
||
},
|
||
sendMsg() {
|
||
let email = this.formData.email
|
||
if (!email || !this.$validate.isEmail(email)) {
|
||
this.$message.error(this.$t('common.emailValidPlaceholder'))
|
||
return
|
||
}
|
||
this.msgLoading = true
|
||
this.$axios({
|
||
url: 'api/user/sendEmailCode',
|
||
method: 'GET',
|
||
data: {
|
||
email: this.formData.email
|
||
}
|
||
})
|
||
.then((res) => {
|
||
this.msgLoading = false
|
||
if (!this.msgInterval) {
|
||
this.msgInterval = setInterval(() => {
|
||
this.msgText = `${this.$t('common.reSend')}(${
|
||
this.msgCount
|
||
}s)`
|
||
this.msgCount -= 1
|
||
if (this.msgCount <= 0) {
|
||
this.msgText = this.$t('common.send')
|
||
this.destroyMsgInterval()
|
||
}
|
||
}, 1000)
|
||
}
|
||
})
|
||
.catch((_) => {
|
||
this.msgLoading = false
|
||
})
|
||
},
|
||
saveUser() {
|
||
if (!this.formData.email) {
|
||
this.$message.error(this.$t('common.emailPlaceholder'))
|
||
return
|
||
}
|
||
if (!this.$validate.isEmail(this.formData.email)) {
|
||
this.$message.error(this.$t('common.emailValidPlaceholder'))
|
||
return
|
||
}
|
||
if (!this.formData.code) {
|
||
this.$message.error(this.$t('common.codePlaceholder'))
|
||
return
|
||
}
|
||
this.loading = true
|
||
this.$axios({
|
||
url: 'api/user/updateEmail',
|
||
method: 'PUT',
|
||
data: {
|
||
email: this.formData.email,
|
||
code: this.formData.code
|
||
}
|
||
})
|
||
.then((res) => {
|
||
this.loading = false
|
||
if (res.code == 200) {
|
||
this.$message.success(
|
||
this.$t('common.editEmailSuccessfully')
|
||
)
|
||
this.cancelEdit()
|
||
}
|
||
})
|
||
.catch((_) => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
showEditUser() {
|
||
this.editVisible = true
|
||
},
|
||
cancelEdit() {
|
||
this.formData = {
|
||
avatar: '',
|
||
email: ''
|
||
}
|
||
this.destroyMsgInterval()
|
||
this.editVisible = false
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style lang="less">
|
||
.edit-user-dialog {
|
||
overflow: hidden;
|
||
background: #0f0f12;
|
||
border-radius: 10px;
|
||
border-radius: 20px;
|
||
border: 1px solid rgba(92, 107, 138, 0.46);
|
||
width: 500px;
|
||
min-height: 400px;
|
||
top: 45% !important;
|
||
transform: translateY(-45%) !important;
|
||
|
||
&-wrapper {
|
||
.arco-modal-mask {
|
||
/* 背景高斯模糊关键属性 */
|
||
backdrop-filter: blur(10px);
|
||
background-color: rgba(0, 0, 0, 0.7);
|
||
}
|
||
}
|
||
|
||
.arco-modal-body {
|
||
padding: 24px 30px 30px 30px;
|
||
}
|
||
|
||
.edit-user-close {
|
||
position: absolute;
|
||
right: 16px;
|
||
top: 12px;
|
||
cursor: pointer;
|
||
color: #fff;
|
||
|
||
.mf-icon {
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
.edit-user-content {
|
||
.edit-user-title {
|
||
font-size: 20px;
|
||
color: #ffffff;
|
||
margin-bottom: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.edit-user-input {
|
||
display: flex;
|
||
align-items: center;
|
||
border-radius: 10px;
|
||
justify-content: center;
|
||
border-radius: 10px;
|
||
border: 1px solid rgba(#ffffff, 0.3);
|
||
height: 40px;
|
||
margin-top: 20px;
|
||
padding: 0 16px;
|
||
font-size: 14px;
|
||
color: #ffffff;
|
||
position: relative;
|
||
cursor: pointer;
|
||
background-color: transparent !important;
|
||
cursor: text;
|
||
font-size: 14px;
|
||
|
||
&.code {
|
||
padding-right: 4px;
|
||
}
|
||
|
||
&-send {
|
||
font-size: 14px;
|
||
color: #000000;
|
||
border-radius: 10px;
|
||
height: 30px;
|
||
}
|
||
|
||
&.arco-input-wrapper:focus-within {
|
||
background-color: transparent;
|
||
}
|
||
|
||
::placeholder {
|
||
color: rgba(#fff, 0.5);
|
||
}
|
||
|
||
&:hover {
|
||
background-color: transparent;
|
||
border-color: #fff;
|
||
}
|
||
|
||
.arco-image {
|
||
position: absolute;
|
||
left: 16px;
|
||
&-img {
|
||
width: 100%;
|
||
height: 100%;
|
||
vertical-align: unset;
|
||
}
|
||
}
|
||
}
|
||
|
||
.edit-user-save {
|
||
margin-top: 30px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
.mf-button {
|
||
width: 120px;
|
||
height: 40px;
|
||
border-radius: 10px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@media (max-width: 576px) {
|
||
.edit-user-dialog {
|
||
&.email {
|
||
width: calc(100% - 16px) !important;
|
||
min-height: auto;
|
||
}
|
||
}
|
||
}
|
||
</style>
|
||
<style lang="less" scoped>
|
||
.user-account {
|
||
padding: 70px 24px 30px 24px;
|
||
overflow: visible;
|
||
|
||
&-wrap {
|
||
background: #1a1b20;
|
||
border-radius: 10px;
|
||
padding: 60px 60px 30px 60px;
|
||
position: relative;
|
||
overflow: visible;
|
||
}
|
||
|
||
:deep(.mf-image-upload-wrap) {
|
||
overflow: visible;
|
||
}
|
||
|
||
:deep(.mf-image-upload) {
|
||
left: 50%;
|
||
position: absolute;
|
||
margin-left: -30px;
|
||
top: -30px;
|
||
cursor: pointer;
|
||
width: 60px;
|
||
height: 60px;
|
||
border-radius: 50%;
|
||
overflow: visible;
|
||
box-sizing: border-box;
|
||
/* 头像外圈:深色底上也能看清边界 */
|
||
border: 2px solid rgba(148, 163, 184, 0.45);
|
||
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.45), inset 0 0 0 1px rgba(255, 255, 255, 0.06);
|
||
background: rgba(15, 20, 28, 0.95);
|
||
|
||
.arco-upload-list-item {
|
||
width: 60px;
|
||
height: 60px;
|
||
margin: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.arco-upload-list-picture {
|
||
width: 56px;
|
||
height: 56px;
|
||
margin: 0;
|
||
border-radius: 50%;
|
||
overflow: hidden;
|
||
flex-shrink: 0;
|
||
border: 1px solid rgba(148, 163, 184, 0.2);
|
||
|
||
img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
display: block;
|
||
border-radius: 50%;
|
||
}
|
||
}
|
||
|
||
.mf-image-upload-btn {
|
||
width: 56px;
|
||
height: 56px;
|
||
margin: 0;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: rgba(30, 41, 59, 0.65);
|
||
border: 1px dashed rgba(148, 163, 184, 0.35);
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.mf-image-upload-btn .arco-image {
|
||
border-radius: 50%;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.arco-upload-list-picture-mask {
|
||
line-height: 56px;
|
||
border-radius: 50%;
|
||
.mf-icon {
|
||
margin-right: 8px;
|
||
}
|
||
}
|
||
}
|
||
|
||
&:hover {
|
||
border-color: rgba(203, 213, 225, 0.55);
|
||
}
|
||
}
|
||
|
||
&-avatar {
|
||
&-edit {
|
||
position: absolute;
|
||
right: -8px;
|
||
bottom: -8px;
|
||
color: #94a3b8;
|
||
// display: none;
|
||
// width: 100%;
|
||
// height: 100%;
|
||
// position: absolute;
|
||
// background-color: rgba(0, 0, 0, 0.5);
|
||
// align-items: center;
|
||
// justify-content: center;
|
||
// left: 50%;
|
||
// margin-left: -30px;
|
||
// top: 0;
|
||
// border-radius: 50%;
|
||
// .mf-icon {
|
||
// color: #fff;
|
||
// }
|
||
}
|
||
}
|
||
|
||
&-list {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-flow: wrap;
|
||
}
|
||
|
||
&-item {
|
||
width: 33.33%;
|
||
color: #fff;
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-bottom: 30px;
|
||
line-height: 22px;
|
||
flex-direction: column;
|
||
label {
|
||
display: inline-block;
|
||
padding-bottom: 8px;
|
||
}
|
||
}
|
||
|
||
&-btns {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-top: 50px;
|
||
.mf-button {
|
||
width: 0;
|
||
margin: 0 10px;
|
||
height: 40px;
|
||
flex: 1;
|
||
border-radius: 10px;
|
||
}
|
||
}
|
||
|
||
&-contact {
|
||
font-size: 14px;
|
||
color: #7a81b1;
|
||
text-decoration-line: underline;
|
||
margin-top: 30px;
|
||
text-align: center;
|
||
|
||
a {
|
||
color: #7a81b1;
|
||
}
|
||
}
|
||
}
|
||
|
||
@media (max-width: 576px) {
|
||
.user-account {
|
||
padding: 50px 0 0 0;
|
||
&-wrap {
|
||
border-radius: 10px;
|
||
padding: 30px 30px 16px 30px;
|
||
}
|
||
|
||
&-item {
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
</style>
|