重构:重构个人中心前端代码
This commit is contained in:
parent
35e2964b49
commit
86c4350de4
@ -1,5 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const BASE_URL = '/system/user/center';
|
||||||
|
|
||||||
export interface BasicInfoModel {
|
export interface BasicInfoModel {
|
||||||
username: string;
|
username: string;
|
||||||
nickname: string;
|
nickname: string;
|
||||||
@ -9,24 +11,27 @@ export interface BasicInfoModel {
|
|||||||
export interface AvatarRes {
|
export interface AvatarRes {
|
||||||
avatar: string;
|
avatar: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function uploadAvatar(data: FormData) {
|
export function uploadAvatar(data: FormData) {
|
||||||
return axios.post<AvatarRes>('/system/user/center/avatar', data);
|
return axios.post<AvatarRes>(`${BASE_URL}/avatar`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateBasicInfoReq {
|
export interface UpdateBasicInfoReq {
|
||||||
nickname: string;
|
nickname: string;
|
||||||
gender: number;
|
gender: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateBasicInfo(req: UpdateBasicInfoReq) {
|
export function updateBasicInfo(req: UpdateBasicInfoReq) {
|
||||||
return axios.patch('/system/user/center/basic/info', req);
|
return axios.patch(`${BASE_URL}/basic/info`, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdatePasswordReq {
|
export interface UpdatePasswordReq {
|
||||||
oldPassword: string;
|
oldPassword: string;
|
||||||
newPassword: string;
|
newPassword: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updatePassword(req: UpdatePasswordReq) {
|
export function updatePassword(req: UpdatePasswordReq) {
|
||||||
return axios.patch('/system/user/center/password', req);
|
return axios.patch(`${BASE_URL}/password`, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateEmailReq {
|
export interface UpdateEmailReq {
|
||||||
@ -34,6 +39,7 @@ export interface UpdateEmailReq {
|
|||||||
captcha: string;
|
captcha: string;
|
||||||
currentPassword: string;
|
currentPassword: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateEmail(req: UpdateEmailReq) {
|
export function updateEmail(req: UpdateEmailReq) {
|
||||||
return axios.patch('/system/user/center/email', req);
|
return axios.patch(`${BASE_URL}/email`, req);
|
||||||
}
|
}
|
@ -62,7 +62,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { getCurrentInstance, ref, toRefs, reactive, computed } from "vue";
|
import { getCurrentInstance, ref, toRefs, reactive, computed } from 'vue';
|
||||||
import { FieldRule, ValidatedError } from '@arco-design/web-vue';
|
import { FieldRule, ValidatedError } from '@arco-design/web-vue';
|
||||||
import { LoginReq } from '@/api/auth/login';
|
import { LoginReq } from '@/api/auth/login';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
@ -101,7 +101,7 @@ import { getCurrentInstance, ref, toRefs, reactive, computed } from "vue";
|
|||||||
username: [{ required: true, message: t('login.form.error.required.username') }],
|
username: [{ required: true, message: t('login.form.error.required.username') }],
|
||||||
password: [{ required: true, message: t('login.form.error.required.password') }],
|
password: [{ required: true, message: t('login.form.error.required.password') }],
|
||||||
captcha: [{ required: true, message: t('login.form.error.required.captcha') }],
|
captcha: [{ required: true, message: t('login.form.error.required.captcha') }],
|
||||||
}
|
};
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
const { form, rules } = toRefs(data);
|
const { form, rules } = toRefs(data);
|
||||||
|
@ -1,39 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-form
|
<a-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:model="formData"
|
:model="form"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
class="form"
|
|
||||||
:label-col-props="{ span: 8 }"
|
:label-col-props="{ span: 8 }"
|
||||||
:wrapper-col-props="{ span: 16 }"
|
:wrapper-col-props="{ span: 16 }"
|
||||||
|
class="form"
|
||||||
>
|
>
|
||||||
<a-form-item
|
<a-form-item :label="$t('userCenter.basicInfo.form.label.username')" disabled>
|
||||||
:label="$t('userCenter.basicInfo.form.label.username')"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
<a-input
|
<a-input
|
||||||
v-model="formData.username"
|
v-model="form.username"
|
||||||
:placeholder="$t('userCenter.basicInfo.form.placeholder.username')"
|
:placeholder="$t('userCenter.basicInfo.form.placeholder.username')"
|
||||||
size="large"
|
|
||||||
max-length="50"
|
max-length="50"
|
||||||
|
size="large"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item :label="$t('userCenter.basicInfo.form.label.nickname')" field="nickname">
|
||||||
field="nickname"
|
|
||||||
:label="$t('userCenter.basicInfo.form.label.nickname')"
|
|
||||||
>
|
|
||||||
<a-input
|
<a-input
|
||||||
v-model="formData.nickname"
|
v-model="form.nickname"
|
||||||
:placeholder="$t('userCenter.basicInfo.form.placeholder.nickname')"
|
:placeholder="$t('userCenter.basicInfo.form.placeholder.nickname')"
|
||||||
size="large"
|
size="large"
|
||||||
max-length="32"
|
max-length="32"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item :label="$t('userCenter.basicInfo.form.label.gender')" field="gender">
|
||||||
field="gender"
|
<a-radio-group v-model="form.gender">
|
||||||
:label="$t('userCenter.basicInfo.form.label.gender')"
|
|
||||||
>
|
|
||||||
<a-radio-group v-model="formData.gender">
|
|
||||||
<a-radio :value="1">男</a-radio>
|
<a-radio :value="1">男</a-radio>
|
||||||
<a-radio :value="2">女</a-radio>
|
<a-radio :value="2">女</a-radio>
|
||||||
<a-radio :value="0" disabled>未知</a-radio>
|
<a-radio :value="0" disabled>未知</a-radio>
|
||||||
@ -41,10 +32,10 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary" :loading="loading" @click="save">
|
<a-button :loading="loading" type="primary" @click="handleSave">
|
||||||
{{ $t('userCenter.basicInfo.form.save') }}
|
{{ $t('userCenter.basicInfo.form.save') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button type="secondary" @click="reset">
|
<a-button @click="handleReset">
|
||||||
{{ $t('userCenter.basicInfo.form.reset') }}
|
{{ $t('userCenter.basicInfo.form.reset') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
@ -53,57 +44,61 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed } from 'vue';
|
import { getCurrentInstance, ref, toRefs, reactive, computed } from 'vue';
|
||||||
|
import { FieldRule } from '@arco-design/web-vue';
|
||||||
|
import { BasicInfoModel, updateBasicInfo } from "@/api/system/user-center";
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useLoginStore } from '@/store';
|
import { useLoginStore } from '@/store';
|
||||||
import { updateBasicInfo } from '@/api/system/user-center';
|
|
||||||
import useLoading from '@/hooks/loading';
|
const { proxy } = getCurrentInstance() as any;
|
||||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
|
||||||
import { BasicInfoModel } from '@/api/system/user-center';
|
|
||||||
import { FieldRule, Message } from '@arco-design/web-vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { loading, setLoading } = useLoading();
|
|
||||||
const loginStore = useLoginStore();
|
const loginStore = useLoginStore();
|
||||||
const formRef = ref<FormInstance>();
|
const loading = ref(false);
|
||||||
const formData = ref<BasicInfoModel>({
|
|
||||||
username: loginStore.username,
|
|
||||||
nickname: loginStore.nickname,
|
|
||||||
gender: loginStore.gender,
|
|
||||||
});
|
|
||||||
const rules = computed((): Record<string, FieldRule[]> => {
|
|
||||||
return {
|
|
||||||
username: [
|
|
||||||
{ required: true, message: t('userCenter.basicInfo.form.error.required.username') }
|
|
||||||
],
|
|
||||||
nickname: [
|
|
||||||
{ required: true, message: t('userCenter.basicInfo.form.error.required.nickname') }
|
|
||||||
],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 保存
|
const data = reactive({
|
||||||
const save = async () => {
|
// 表单数据
|
||||||
|
form: {
|
||||||
|
username: loginStore.username,
|
||||||
|
nickname: loginStore.nickname,
|
||||||
|
gender: loginStore.gender,
|
||||||
|
} as BasicInfoModel,
|
||||||
|
// 表单验证规则
|
||||||
|
rules: computed((): Record<string, FieldRule[]> => {
|
||||||
|
return {
|
||||||
|
username: [{ required: true, message: t('userCenter.basicInfo.form.error.required.username') }],
|
||||||
|
nickname: [{ required: true, message: t('userCenter.basicInfo.form.error.required.nickname') }],
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const { form, rules } = toRefs(data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存
|
||||||
|
*/
|
||||||
|
const handleSave = () => {
|
||||||
if (loading.value) return;
|
if (loading.value) return;
|
||||||
const errors = await formRef.value?.validate();
|
proxy.$refs.formRef.validate((valid: any) => {
|
||||||
if (!errors) {
|
if (!valid) {
|
||||||
setLoading(true);
|
loading.value = true;
|
||||||
try {
|
updateBasicInfo({
|
||||||
const res = await updateBasicInfo({
|
nickname: form.value.nickname,
|
||||||
nickname: formData.value.nickname,
|
gender: form.value.gender,
|
||||||
gender: formData.value.gender,
|
}).then((res) => {
|
||||||
|
loginStore.getInfo();
|
||||||
|
proxy.$message.success(t('userCenter.basicInfo.form.save.success'));
|
||||||
|
}).finally(() => {
|
||||||
|
loading.value = false;
|
||||||
});
|
});
|
||||||
await loginStore.getInfo();
|
|
||||||
if (res.success) Message.success(res.msg);
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置
|
/**
|
||||||
const reset = async () => {
|
* 重置
|
||||||
await formRef.value?.resetFields();
|
*/
|
||||||
|
const handleReset = () => {
|
||||||
|
proxy.$refs.formRef.resetFields();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@
|
|||||||
listOperationLog(params).then((res) => {
|
listOperationLog(params).then((res) => {
|
||||||
operationLogList.value = res.data.list;
|
operationLogList.value = res.data.list;
|
||||||
total.value = res.data.total;
|
total.value = res.data.total;
|
||||||
|
}).finally(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -125,6 +126,7 @@
|
|||||||
.container {
|
.container {
|
||||||
padding: 0 20px 20px 20px;
|
padding: 0 20px 20px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.arco-table-th) {
|
:deep(.arco-table-th) {
|
||||||
&:last-child {
|
&:last-child {
|
||||||
.arco-table-th-item-title {
|
.arco-table-th-item-title {
|
||||||
@ -132,10 +134,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon {
|
.action-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon:hover {
|
.action-icon:hover {
|
||||||
color: #0960bd;
|
color: #0960bd;
|
||||||
}
|
}
|
||||||
|
@ -21,16 +21,20 @@
|
|||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
:deep(.arco-list-item) {
|
:deep(.arco-list-item) {
|
||||||
border-bottom: none !important;
|
border-bottom: none !important;
|
||||||
|
|
||||||
.arco-typography {
|
.arco-typography {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arco-list-item-meta-avatar {
|
.arco-list-item-meta-avatar {
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arco-list-item-meta {
|
.arco-list-item-meta {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.arco-list-item-meta-content) {
|
:deep(.arco-list-item-meta-content) {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border-bottom: 1px solid var(--color-neutral-3);
|
border-bottom: 1px solid var(--color-neutral-3);
|
||||||
@ -43,6 +47,7 @@
|
|||||||
.tip {
|
.tip {
|
||||||
color: rgb(var(--gray-6));
|
color: rgb(var(--gray-6));
|
||||||
}
|
}
|
||||||
|
|
||||||
.operation {
|
.operation {
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</a-typography-paragraph>
|
</a-typography-paragraph>
|
||||||
</div>
|
</div>
|
||||||
<div class="operation">
|
<div class="operation">
|
||||||
<a-link @click="toUpdate">
|
<a-link :title="$t('userCenter.securitySettings.button.update')" @click="toUpdate">
|
||||||
{{ $t('userCenter.securitySettings.button.update') }}
|
{{ $t('userCenter.securitySettings.button.update') }}
|
||||||
</a-link>
|
</a-link>
|
||||||
</div>
|
</div>
|
||||||
@ -23,96 +23,82 @@
|
|||||||
</a-list-item-meta>
|
</a-list-item-meta>
|
||||||
|
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:visible="visible"
|
|
||||||
:title="$t('userCenter.securitySettings.updateEmail.modal.title')"
|
:title="$t('userCenter.securitySettings.updateEmail.modal.title')"
|
||||||
|
:visible="visible"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
|
@ok="handleUpdate"
|
||||||
@cancel="handleCancel"
|
@cancel="handleCancel"
|
||||||
@before-ok="handleUpdate"
|
|
||||||
>
|
>
|
||||||
<a-form ref="formRef" :model="formData" :rules="rules">
|
<a-form ref="formRef" :model="form" :rules="rules">
|
||||||
<a-form-item
|
<a-form-item :label="$t('userCenter.securitySettings.updateEmail.form.label.newEmail')" field="newEmail">
|
||||||
field="newEmail"
|
|
||||||
:validate-trigger="['change', 'blur']"
|
|
||||||
:label="$t('userCenter.securitySettings.updateEmail.form.label.newEmail')"
|
|
||||||
>
|
|
||||||
<a-input
|
<a-input
|
||||||
v-model="formData.newEmail"
|
v-model="form.newEmail"
|
||||||
:placeholder="$t('userCenter.securitySettings.updateEmail.form.placeholder.newEmail')"
|
:placeholder="$t('userCenter.securitySettings.updateEmail.form.placeholder.newEmail')"
|
||||||
size="large"
|
|
||||||
allow-clear
|
allow-clear
|
||||||
>
|
size="large"
|
||||||
</a-input>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item :label="$t('userCenter.securitySettings.updateEmail.form.label.captcha')" field="captcha">
|
||||||
field="captcha"
|
|
||||||
:validate-trigger="['change', 'blur']"
|
|
||||||
:label="$t('userCenter.securitySettings.updateEmail.form.label.captcha')"
|
|
||||||
>
|
|
||||||
<a-input
|
<a-input
|
||||||
v-model="formData.captcha"
|
v-model="form.captcha"
|
||||||
:placeholder="$t('userCenter.securitySettings.updateEmail.form.placeholder.captcha')"
|
:placeholder="$t('userCenter.securitySettings.updateEmail.form.placeholder.captcha')"
|
||||||
|
max-length="6"
|
||||||
|
allow-clear
|
||||||
size="large"
|
size="large"
|
||||||
style="width: 80%"
|
style="width: 80%"
|
||||||
allow-clear
|
/>
|
||||||
max-length="6"
|
|
||||||
>
|
|
||||||
</a-input>
|
|
||||||
<a-button
|
<a-button
|
||||||
class="captcha-btn"
|
:loading="captchaLoading"
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
:loading="captchaLoading"
|
|
||||||
:disabled="captchaDisable"
|
:disabled="captchaDisable"
|
||||||
@click="sendCaptcha"
|
class="captcha-btn"
|
||||||
|
@click="handleSendCaptcha"
|
||||||
>
|
>
|
||||||
{{ captchaBtnName }}
|
{{ captchaBtnName }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item :label="$t('userCenter.securitySettings.updateEmail.form.label.currentPassword')" field="currentPassword">
|
||||||
field="currentPassword"
|
|
||||||
:validate-trigger="['change', 'blur']"
|
|
||||||
:label="$t('userCenter.securitySettings.updateEmail.form.label.currentPassword')"
|
|
||||||
>
|
|
||||||
<a-input-password
|
<a-input-password
|
||||||
v-model="formData.currentPassword"
|
v-model="form.currentPassword"
|
||||||
:placeholder="$t('userCenter.securitySettings.updateEmail.form.placeholder.currentPassword')"
|
:placeholder="$t('userCenter.securitySettings.updateEmail.form.placeholder.currentPassword')"
|
||||||
size="large"
|
|
||||||
allow-clear
|
|
||||||
max-length="32"
|
max-length="32"
|
||||||
>
|
allow-clear
|
||||||
</a-input-password>
|
size="large"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, computed } from 'vue';
|
import { getCurrentInstance, ref, reactive, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { FieldRule } from '@arco-design/web-vue';
|
||||||
import { useLoginStore } from '@/store';
|
|
||||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
|
||||||
import useLoading from '@/hooks/loading';
|
|
||||||
import { FieldRule, Message } from '@arco-design/web-vue';
|
|
||||||
import { getMailCaptcha } from '@/api/common/captcha';
|
import { getMailCaptcha } from '@/api/common/captcha';
|
||||||
import { updateEmail } from '@/api/system/user-center';
|
import { updateEmail } from '@/api/system/user-center';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useLoginStore } from '@/store';
|
||||||
import { encryptByRsa } from '@/utils/encrypt';
|
import { encryptByRsa } from '@/utils/encrypt';
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() as any;
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { loading, setLoading } = useLoading();
|
|
||||||
const loginStore = useLoginStore();
|
const loginStore = useLoginStore();
|
||||||
|
const captchaTime = ref(60);
|
||||||
|
const captchaTimer = ref();
|
||||||
|
const captchaLoading = ref(false);
|
||||||
|
const captchaDisable = ref(false);
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const captchaBtnNameKey = ref('userCenter.securitySettings.updateEmail.form.sendCaptcha');
|
const captchaBtnNameKey = ref('userCenter.securitySettings.updateEmail.form.sendCaptcha');
|
||||||
const captchaBtnName = computed(() => t(captchaBtnNameKey.value));
|
const captchaBtnName = computed(() => t(captchaBtnNameKey.value));
|
||||||
const captchaLoading = ref(false);
|
|
||||||
const captchaDisable = ref(false);
|
// 表单数据
|
||||||
const captchaTime = ref(60);
|
const form = reactive({
|
||||||
const captchaTimer = ref();
|
|
||||||
const formRef = ref<FormInstance>();
|
|
||||||
const formData = reactive({
|
|
||||||
newEmail: '',
|
newEmail: '',
|
||||||
captcha: '',
|
captcha: '',
|
||||||
currentPassword: '',
|
currentPassword: '',
|
||||||
});
|
});
|
||||||
|
// 表单验证规则
|
||||||
const rules = computed((): Record<string, FieldRule[]> => {
|
const rules = computed((): Record<string, FieldRule[]> => {
|
||||||
return {
|
return {
|
||||||
newEmail: [
|
newEmail: [
|
||||||
@ -134,10 +120,12 @@
|
|||||||
currentPassword: [
|
currentPassword: [
|
||||||
{ required: true, message: t('userCenter.securitySettings.updateEmail.form.error.required.currentPassword') }
|
{ required: true, message: t('userCenter.securitySettings.updateEmail.form.error.required.currentPassword') }
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// 重置验证码相关
|
/**
|
||||||
|
* 重置验证码
|
||||||
|
*/
|
||||||
const resetCaptcha = () => {
|
const resetCaptcha = () => {
|
||||||
window.clearInterval(captchaTimer.value);
|
window.clearInterval(captchaTimer.value);
|
||||||
captchaTime.value = 60;
|
captchaTime.value = 60;
|
||||||
@ -145,69 +133,71 @@
|
|||||||
captchaDisable.value = false;
|
captchaDisable.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送验证码
|
/**
|
||||||
const sendCaptcha = async () => {
|
* 发送验证码
|
||||||
|
*/
|
||||||
|
const handleSendCaptcha = () => {
|
||||||
if (captchaLoading.value) return;
|
if (captchaLoading.value) return;
|
||||||
const errors = await formRef.value?.validateField('newEmail');
|
proxy.$refs.formRef.validateField('newEmail', (valid: any) => {
|
||||||
if (errors) return;
|
if (!valid) {
|
||||||
captchaLoading.value = true;
|
captchaLoading.value = true;
|
||||||
captchaBtnNameKey.value = 'userCenter.securitySettings.updateEmail.form.loading.sendCaptcha';
|
captchaBtnNameKey.value = 'userCenter.securitySettings.updateEmail.form.loading.sendCaptcha';
|
||||||
try {
|
getMailCaptcha({
|
||||||
const res = await getMailCaptcha({
|
email: form.newEmail
|
||||||
email: formData.newEmail
|
}).then((res) => {
|
||||||
});
|
captchaLoading.value = false;
|
||||||
if (res.success) {
|
captchaDisable.value = true;
|
||||||
captchaLoading.value = false;
|
captchaBtnNameKey.value = `${t('userCenter.securitySettings.updateEmail.form.reSendCaptcha')}(${captchaTime.value -= 1}s)`;
|
||||||
captchaDisable.value = true;
|
captchaTimer.value = window.setInterval(function() {
|
||||||
captchaBtnNameKey.value = `${t('userCenter.securitySettings.updateEmail.form.reSendCaptcha')}(${captchaTime.value -= 1}s)`;
|
captchaTime.value -= 1;
|
||||||
Message.success(res.msg);
|
captchaBtnNameKey.value = `${t('userCenter.securitySettings.updateEmail.form.reSendCaptcha')}(${captchaTime.value}s)`;
|
||||||
|
if (captchaTime.value < 0) {
|
||||||
captchaTimer.value = window.setInterval(function() {
|
window.clearInterval(captchaTimer.value);
|
||||||
captchaTime.value -= 1;
|
captchaTime.value = 60;
|
||||||
captchaBtnNameKey.value = `${t('userCenter.securitySettings.updateEmail.form.reSendCaptcha')}(${captchaTime.value}s)`;
|
captchaBtnNameKey.value = t('userCenter.securitySettings.updateEmail.form.reSendCaptcha');
|
||||||
if (captchaTime.value < 0) {
|
captchaDisable.value = false;
|
||||||
window.clearInterval(captchaTimer.value);
|
}
|
||||||
captchaTime.value = 60;
|
}, 1000);
|
||||||
captchaBtnNameKey.value = t('userCenter.securitySettings.updateEmail.form.reSendCaptcha');
|
proxy.$message.success(res.msg);
|
||||||
captchaDisable.value = false;
|
}).catch(() => {
|
||||||
}
|
resetCaptcha();
|
||||||
}, 1000);
|
captchaLoading.value = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
});
|
||||||
resetCaptcha();
|
|
||||||
captchaLoading.value = false;
|
|
||||||
console.log((err as Error));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 确定修改
|
/**
|
||||||
const handleUpdate = async () => {
|
* 取消
|
||||||
if (loading.value) return false;
|
*/
|
||||||
const errors = await formRef.value?.validate();
|
|
||||||
if (errors) return false;
|
|
||||||
setLoading(true);
|
|
||||||
try {
|
|
||||||
const res = await updateEmail({
|
|
||||||
newEmail: formData.newEmail,
|
|
||||||
captcha: formData.captcha,
|
|
||||||
currentPassword: encryptByRsa(formData.currentPassword) || '',
|
|
||||||
});
|
|
||||||
await loginStore.getInfo();
|
|
||||||
if (res.success) Message.success(res.msg);
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 取消修改
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
formRef.value?.resetFields();
|
proxy.$refs.formRef.resetFields();
|
||||||
resetCaptcha();
|
resetCaptcha();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开修改窗口
|
/**
|
||||||
|
* 修改
|
||||||
|
*/
|
||||||
|
const handleUpdate = () => {
|
||||||
|
proxy.$refs.formRef.validate((valid: any) => {
|
||||||
|
if (!valid) {
|
||||||
|
updateEmail({
|
||||||
|
newEmail: form.newEmail,
|
||||||
|
captcha: form.captcha,
|
||||||
|
currentPassword: encryptByRsa(form.currentPassword) || '',
|
||||||
|
}).then((res) => {
|
||||||
|
handleCancel();
|
||||||
|
loginStore.getInfo();
|
||||||
|
proxy.$message.success(res.msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开修改对话框
|
||||||
|
*/
|
||||||
const toUpdate = () => {
|
const toUpdate = () => {
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</a-typography-paragraph>
|
</a-typography-paragraph>
|
||||||
</div>
|
</div>
|
||||||
<div class="operation">
|
<div class="operation">
|
||||||
<a-link>
|
<a-link :title="$t('userCenter.securitySettings.button.update')">
|
||||||
{{ $t('userCenter.securitySettings.button.update') }}
|
{{ $t('userCenter.securitySettings.button.update') }}
|
||||||
</a-link>
|
</a-link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</a-typography-paragraph>
|
</a-typography-paragraph>
|
||||||
</div>
|
</div>
|
||||||
<div class="operation">
|
<div class="operation">
|
||||||
<a-link @click="toUpdate">
|
<a-link :title="$t('userCenter.securitySettings.button.update')" @click="toUpdate">
|
||||||
{{ $t('userCenter.securitySettings.button.update') }}
|
{{ $t('userCenter.securitySettings.button.update') }}
|
||||||
</a-link>
|
</a-link>
|
||||||
</div>
|
</div>
|
||||||
@ -23,90 +23,74 @@
|
|||||||
</a-list-item-meta>
|
</a-list-item-meta>
|
||||||
|
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:visible="visible"
|
|
||||||
:title="$t('userCenter.securitySettings.updatePwd.modal.title')"
|
:title="$t('userCenter.securitySettings.updatePwd.modal.title')"
|
||||||
|
:visible="visible"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
|
@ok="handleUpdate"
|
||||||
@cancel="handleCancel"
|
@cancel="handleCancel"
|
||||||
@before-ok="handleUpdate"
|
|
||||||
>
|
>
|
||||||
<a-form ref="formRef" :model="formData" :rules="rules">
|
<a-form ref="formRef" :model="form" :rules="rules">
|
||||||
<a-form-item
|
<a-form-item :label="$t('userCenter.securitySettings.updatePwd.form.label.oldPassword')" field="oldPassword">
|
||||||
field="oldPassword"
|
|
||||||
:validate-trigger="['change', 'blur']"
|
|
||||||
:label="$t('userCenter.securitySettings.updatePwd.form.label.oldPassword')"
|
|
||||||
>
|
|
||||||
<a-input-password
|
<a-input-password
|
||||||
v-model="formData.oldPassword"
|
v-model="form.oldPassword"
|
||||||
:placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.oldPassword')"
|
:placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.oldPassword')"
|
||||||
size="large"
|
|
||||||
allow-clear
|
|
||||||
max-length="32"
|
max-length="32"
|
||||||
>
|
allow-clear
|
||||||
</a-input-password>
|
size="large"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item :label="$t('userCenter.securitySettings.updatePwd.form.label.newPassword')" field="newPassword">
|
||||||
field="newPassword"
|
|
||||||
:validate-trigger="['change', 'blur']"
|
|
||||||
:label="$t('userCenter.securitySettings.updatePwd.form.label.newPassword')"
|
|
||||||
>
|
|
||||||
<a-input-password
|
<a-input-password
|
||||||
v-model="formData.newPassword"
|
v-model="form.newPassword"
|
||||||
:placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.newPassword')"
|
:placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.newPassword')"
|
||||||
size="large"
|
|
||||||
allow-clear
|
|
||||||
max-length="32"
|
max-length="32"
|
||||||
>
|
allow-clear
|
||||||
</a-input-password>
|
size="large"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item :label="$t('userCenter.securitySettings.updatePwd.form.label.rePassword')" field="rePassword">
|
||||||
field="rePassword"
|
|
||||||
:validate-trigger="['change', 'blur']"
|
|
||||||
:label="$t('userCenter.securitySettings.updatePwd.form.label.rePassword')"
|
|
||||||
>
|
|
||||||
<a-input-password
|
<a-input-password
|
||||||
v-model="formData.rePassword"
|
v-model="form.rePassword"
|
||||||
:placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.rePassword')"
|
:placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.rePassword')"
|
||||||
size="large"
|
|
||||||
allow-clear
|
|
||||||
max-length="32"
|
max-length="32"
|
||||||
>
|
allow-clear
|
||||||
</a-input-password>
|
size="large"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, computed } from 'vue';
|
import { getCurrentInstance, ref, reactive, computed } from 'vue';
|
||||||
|
import { FieldRule } from '@arco-design/web-vue';
|
||||||
|
import { updatePassword } from '@/api/system/user-center';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useLoginStore } from '@/store';
|
import { useLoginStore } from '@/store';
|
||||||
import { FormInstance } from '@arco-design/web-vue/es/form';
|
|
||||||
import useLoading from '@/hooks/loading';
|
|
||||||
import { FieldRule, Message } from '@arco-design/web-vue';
|
|
||||||
import { updatePassword } from '@/api/system/user-center';
|
|
||||||
import { encryptByRsa } from '@/utils/encrypt';
|
import { encryptByRsa } from '@/utils/encrypt';
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() as any;
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { loading, setLoading } = useLoading();
|
|
||||||
const loginStore = useLoginStore();
|
const loginStore = useLoginStore();
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const formRef = ref<FormInstance>();
|
|
||||||
const formData = reactive({
|
// 表单数据
|
||||||
|
const form = reactive({
|
||||||
oldPassword: '',
|
oldPassword: '',
|
||||||
newPassword: '',
|
newPassword: '',
|
||||||
rePassword: '',
|
rePassword: '',
|
||||||
});
|
});
|
||||||
|
// 表单验证规则
|
||||||
const rules = computed((): Record<string, FieldRule[]> => {
|
const rules = computed((): Record<string, FieldRule[]> => {
|
||||||
return {
|
return {
|
||||||
oldPassword: [
|
oldPassword: [{ required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.oldPassword') }],
|
||||||
{ required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.oldPassword') }
|
|
||||||
],
|
|
||||||
newPassword: [
|
newPassword: [
|
||||||
{ required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.newPassword') },
|
{ required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.newPassword') },
|
||||||
{ match: /^(?=.*\d)(?=.*[a-z]).{6,32}$/, message: t('userCenter.securitySettings.updatePwd.form.error.match.newPassword') },
|
{ match: /^(?=.*\d)(?=.*[a-z]).{6,32}$/, message: t('userCenter.securitySettings.updatePwd.form.error.match.newPassword') },
|
||||||
{
|
{
|
||||||
validator: (value, callback) => {
|
validator: (value, callback) => {
|
||||||
if (value === formData.oldPassword) {
|
if (value === form.oldPassword) {
|
||||||
callback(t('userCenter.securitySettings.updatePwd.form.error.validator.newPassword'))
|
callback(t('userCenter.securitySettings.updatePwd.form.error.validator.newPassword'))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
@ -118,7 +102,7 @@
|
|||||||
{ required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.rePassword') },
|
{ required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.rePassword') },
|
||||||
{
|
{
|
||||||
validator: (value, callback) => {
|
validator: (value, callback) => {
|
||||||
if (value !== formData.newPassword) {
|
if (value !== form.newPassword) {
|
||||||
callback(t('userCenter.securitySettings.updatePwd.form.error.validator.rePassword'))
|
callback(t('userCenter.securitySettings.updatePwd.form.error.validator.rePassword'))
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback()
|
||||||
@ -126,34 +110,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// 确定修改
|
/**
|
||||||
const handleUpdate = async () => {
|
* 取消
|
||||||
if (loading.value) return false;
|
*/
|
||||||
const errors = await formRef.value?.validate();
|
|
||||||
if (errors) return false;
|
|
||||||
setLoading(true);
|
|
||||||
try {
|
|
||||||
const res = await updatePassword({
|
|
||||||
oldPassword: encryptByRsa(formData.oldPassword) || '',
|
|
||||||
newPassword: encryptByRsa(formData.newPassword) || '',
|
|
||||||
});
|
|
||||||
if (res.success) Message.success(res.msg);
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 取消修改
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
formRef.value?.resetFields()
|
proxy.$refs.formRef.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开修改窗口
|
/**
|
||||||
|
* 修改
|
||||||
|
*/
|
||||||
|
const handleUpdate = () => {
|
||||||
|
proxy.$refs.formRef.validate((valid: any) => {
|
||||||
|
if (!valid) {
|
||||||
|
updatePassword({
|
||||||
|
oldPassword: encryptByRsa(form.oldPassword) || '',
|
||||||
|
newPassword: encryptByRsa(form.newPassword) || '',
|
||||||
|
}).then((res) => {
|
||||||
|
handleCancel();
|
||||||
|
proxy.$message.success(res.msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开修改对话框
|
||||||
|
*/
|
||||||
const toUpdate = () => {
|
const toUpdate = () => {
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
};
|
};
|
||||||
|
@ -2,26 +2,23 @@
|
|||||||
<a-card :bordered="false">
|
<a-card :bordered="false">
|
||||||
<a-space :size="54">
|
<a-space :size="54">
|
||||||
<a-upload
|
<a-upload
|
||||||
:custom-request="handleUpload"
|
|
||||||
list-type="picture-card"
|
|
||||||
:file-list="avatarList"
|
:file-list="avatarList"
|
||||||
:show-upload-button="true"
|
|
||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
@change="changeAvatar"
|
list-type="picture-card"
|
||||||
|
:show-upload-button="true"
|
||||||
|
:custom-request="handleUpload"
|
||||||
|
@change="handleAvatarChange"
|
||||||
>
|
>
|
||||||
<template #upload-button>
|
<template #upload-button>
|
||||||
<a-avatar :size="100" class="info-avatar">
|
<a-avatar :size="100" class="info-avatar">
|
||||||
<template #trigger-icon>
|
<template #trigger-icon><icon-camera /></template>
|
||||||
<icon-camera />
|
<img v-if="avatarList.length" :src="avatarList[0].url" :alt="$t('userCenter.panel.avatar')" />
|
||||||
</template>
|
|
||||||
<img v-if="avatarList.length" :src="avatarList[0].url" :alt="$t('userCenter.panel.avatar')"/>
|
|
||||||
</a-avatar>
|
</a-avatar>
|
||||||
</template>
|
</template>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
|
|
||||||
<a-descriptions
|
<a-descriptions
|
||||||
:column="2"
|
:column="2"
|
||||||
align="right"
|
|
||||||
layout="inline-horizontal"
|
|
||||||
:label-style="{
|
:label-style="{
|
||||||
width: '140px',
|
width: '140px',
|
||||||
fontWeight: 'normal',
|
fontWeight: 'normal',
|
||||||
@ -32,6 +29,8 @@
|
|||||||
paddingLeft: '8px',
|
paddingLeft: '8px',
|
||||||
textAlign: 'left',
|
textAlign: 'left',
|
||||||
}"
|
}"
|
||||||
|
align="right"
|
||||||
|
layout="inline-horizontal"
|
||||||
>
|
>
|
||||||
<a-descriptions-item :label="$t('userCenter.panel.label.nickname')">{{ loginStore.nickname }}</a-descriptions-item>
|
<a-descriptions-item :label="$t('userCenter.panel.label.nickname')">{{ loginStore.nickname }}</a-descriptions-item>
|
||||||
<a-descriptions-item :label="$t('userCenter.panel.label.gender')">
|
<a-descriptions-item :label="$t('userCenter.panel.label.gender')">
|
||||||
@ -54,15 +53,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { getCurrentInstance, ref } from 'vue';
|
||||||
import type {
|
import { FileItem, RequestOption } from '@arco-design/web-vue';
|
||||||
FileItem,
|
|
||||||
RequestOption,
|
|
||||||
} from '@arco-design/web-vue/es/upload/interfaces';
|
|
||||||
import { useLoginStore } from '@/store';
|
|
||||||
import { uploadAvatar } from '@/api/system/user-center';
|
import { uploadAvatar } from '@/api/system/user-center';
|
||||||
|
import { useLoginStore } from '@/store';
|
||||||
import getAvatar from '@/utils/avatar';
|
import getAvatar from '@/utils/avatar';
|
||||||
import { Message } from '@arco-design/web-vue';
|
|
||||||
|
const { proxy } = getCurrentInstance() as any;
|
||||||
|
|
||||||
const loginStore = useLoginStore();
|
const loginStore = useLoginStore();
|
||||||
const avatar = {
|
const avatar = {
|
||||||
@ -72,12 +69,11 @@
|
|||||||
};
|
};
|
||||||
const avatarList = ref<FileItem[]>([avatar]);
|
const avatarList = ref<FileItem[]>([avatar]);
|
||||||
|
|
||||||
// 切换头像
|
/**
|
||||||
const changeAvatar = (fileItemList: FileItem[], currentFile: FileItem) => {
|
* 上传头像
|
||||||
avatarList.value = [currentFile];
|
*
|
||||||
};
|
* @param options 选项
|
||||||
|
*/
|
||||||
// 上传头像
|
|
||||||
const handleUpload = (options: RequestOption) => {
|
const handleUpload = (options: RequestOption) => {
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
(async function requestWrap() {
|
(async function requestWrap() {
|
||||||
@ -91,15 +87,13 @@
|
|||||||
onProgress(20);
|
onProgress(20);
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append(name as string, fileItem.file as Blob);
|
formData.append(name as string, fileItem.file as Blob);
|
||||||
try {
|
uploadAvatar(formData).then((res) => {
|
||||||
const res = await uploadAvatar(formData);
|
|
||||||
onSuccess(res);
|
onSuccess(res);
|
||||||
if (res.success) Message.success(res.msg);
|
|
||||||
// 更换头像
|
|
||||||
loginStore.avatar = res.data.avatar;
|
loginStore.avatar = res.data.avatar;
|
||||||
} catch (error) {
|
proxy.$message.success(res.msg);
|
||||||
|
}).catch((error) => {
|
||||||
onError(error);
|
onError(error);
|
||||||
}
|
});
|
||||||
})();
|
})();
|
||||||
return {
|
return {
|
||||||
abort() {
|
abort() {
|
||||||
@ -107,6 +101,16 @@
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换头像
|
||||||
|
*
|
||||||
|
* @param fileItemList 文件列表
|
||||||
|
* @param currentFile 当前文件
|
||||||
|
*/
|
||||||
|
const handleAvatarChange = (fileItemList: FileItem[], currentFile: FileItem) => {
|
||||||
|
avatarList.value = [currentFile];
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@ -114,11 +118,13 @@
|
|||||||
padding: 14px 0 4px 4px;
|
padding: 14px 0 4px 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.arco-avatar-trigger-icon-button) {
|
:deep(.arco-avatar-trigger-icon-button) {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
background-color: #e8f3ff;
|
background-color: #e8f3ff;
|
||||||
|
|
||||||
.arco-icon-camera {
|
.arco-icon-camera {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
color: rgb(var(--arcoblue-6));
|
color: rgb(var(--arcoblue-6));
|
||||||
|
@ -27,6 +27,7 @@ export default {
|
|||||||
'userCenter.basicInfo.form.error.required.nickname': 'Please enter nickname',
|
'userCenter.basicInfo.form.error.required.nickname': 'Please enter nickname',
|
||||||
|
|
||||||
'userCenter.basicInfo.form.save': 'Save',
|
'userCenter.basicInfo.form.save': 'Save',
|
||||||
|
'userCenter.basicInfo.form.save.success': 'Save success',
|
||||||
'userCenter.basicInfo.form.reset': 'Reset',
|
'userCenter.basicInfo.form.reset': 'Reset',
|
||||||
|
|
||||||
// security-settings
|
// security-settings
|
||||||
|
@ -27,6 +27,7 @@ export default {
|
|||||||
'userCenter.basicInfo.form.error.required.nickname': '请输入昵称',
|
'userCenter.basicInfo.form.error.required.nickname': '请输入昵称',
|
||||||
|
|
||||||
'userCenter.basicInfo.form.save': '保存',
|
'userCenter.basicInfo.form.save': '保存',
|
||||||
|
'userCenter.basicInfo.form.save.success': '保存成功',
|
||||||
'userCenter.basicInfo.form.reset': '重置',
|
'userCenter.basicInfo.form.reset': '重置',
|
||||||
|
|
||||||
// security-settings
|
// security-settings
|
||||||
|
Loading…
Reference in New Issue
Block a user