ai_images/portal-ui/src/layout/components/UserAccount.vue

577 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>