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