优化:优化表单校验相关代码,拆分安全设置组件,完善登录页面 slogan 和插图
This commit is contained in:
parent
a08fd7773e
commit
73fadb8315
@ -216,7 +216,8 @@ continew-admin
|
||||
│ ├─ views # 页面模板
|
||||
│ │ ├─ login # 登录模块
|
||||
│ │ └─ system # 系统管理模块
|
||||
│ │ └─ user # 用户模块(用户中心)
|
||||
│ │ └─ user # 用户模块
|
||||
│ │ └─ center # 个人中心
|
||||
│ ├─ App.vue # 视图入口
|
||||
│ └─ main.ts # 入口文件
|
||||
├─ .env.development
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 62 KiB |
BIN
continew-admin-ui/src/assets/images/login/banner1.png
Normal file
BIN
continew-admin-ui/src/assets/images/login/banner1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
BIN
continew-admin-ui/src/assets/images/login/banner2.png
Normal file
BIN
continew-admin-ui/src/assets/images/login/banner2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
BIN
continew-admin-ui/src/assets/images/login/banner3.png
Normal file
BIN
continew-admin-ui/src/assets/images/login/banner3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
@ -10,7 +10,7 @@
|
||||
:style="{ margin: 0, fontSize: '18px' }"
|
||||
:heading="5"
|
||||
>
|
||||
ContiNew Admin
|
||||
{{ $t('title') }}
|
||||
</a-typography-title>
|
||||
<icon-menu-fold
|
||||
v-if="!topMenu && appStore.device === 'mobile'"
|
||||
|
@ -1,15 +1,17 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
|
||||
import { useLoginStore } from '@/store';
|
||||
|
||||
export default function useUser() {
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const loginStore = useLoginStore();
|
||||
const logout = async (logoutTo?: string) => {
|
||||
await loginStore.logout();
|
||||
const currentRoute = router.currentRoute.value;
|
||||
Message.success('退出成功');
|
||||
Message.success(t('login.form.logout.success'));
|
||||
router.push({
|
||||
name: logoutTo && typeof logoutTo === 'string' ? logoutTo : 'login',
|
||||
query: {
|
||||
|
@ -28,6 +28,7 @@ import localeUserCenter from '@/views/system/user/center/locale/en-US';
|
||||
import localeSettings from './en-US/settings';
|
||||
|
||||
export default {
|
||||
'title': 'ContiNew Admin',
|
||||
'menu.dashboard': 'Dashboard',
|
||||
'menu.server.dashboard': 'Dashboard-Server',
|
||||
'menu.server.workplace': 'Workplace-Server',
|
||||
|
@ -28,6 +28,7 @@ import localeUserCenter from '@/views/system/user/center/locale/zh-CN';
|
||||
import localeSettings from './zh-CN/settings';
|
||||
|
||||
export default {
|
||||
'title': 'ContiNew Admin',
|
||||
'menu.dashboard': '仪表盘',
|
||||
'menu.server.dashboard': '仪表盘-服务端',
|
||||
'menu.server.workplace': '工作台-服务端',
|
||||
|
@ -17,24 +17,26 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import bannerImage from '@/assets/images/login-banner.png';
|
||||
import bannerImage1 from '@/assets/images/login/banner1.png';
|
||||
import bannerImage2 from '@/assets/images/login/banner2.png';
|
||||
import bannerImage3 from '@/assets/images/login/banner3.png';
|
||||
|
||||
const { t } = useI18n();
|
||||
const carouselItem = computed(() => [
|
||||
{
|
||||
slogan: t('login.banner.slogan1'),
|
||||
subSlogan: t('login.banner.subSlogan1'),
|
||||
image: bannerImage,
|
||||
image: bannerImage1,
|
||||
},
|
||||
{
|
||||
slogan: t('login.banner.slogan2'),
|
||||
subSlogan: t('login.banner.subSlogan2'),
|
||||
image: bannerImage,
|
||||
image: bannerImage2,
|
||||
},
|
||||
{
|
||||
slogan: t('login.banner.slogan3'),
|
||||
subSlogan: t('login.banner.subSlogan3'),
|
||||
image: bannerImage,
|
||||
image: bannerImage3,
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
@ -71,13 +73,14 @@
|
||||
|
||||
&-sub-title {
|
||||
margin-top: 8px;
|
||||
margin-left: 30px;
|
||||
color: var(--color-text-3);
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
&-image {
|
||||
width: 320px;
|
||||
width: 360px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
|
@ -4,21 +4,21 @@
|
||||
<div class="login-form-sub-title">{{ $t('login.form.subTitle') }}</div>
|
||||
<div class="login-form-error-msg">{{ errorMessage }}</div>
|
||||
<a-form
|
||||
ref="loginFormRef"
|
||||
:model="loginForm"
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="rules"
|
||||
class="login-form"
|
||||
layout="vertical"
|
||||
@submit="handleLogin"
|
||||
>
|
||||
<a-form-item
|
||||
field="username"
|
||||
:rules="[{ required: true, message: $t('login.form.username.errMsg') }]"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
hide-label
|
||||
>
|
||||
<a-input
|
||||
v-model="loginForm.username"
|
||||
:placeholder="$t('login.form.username.placeholder')"
|
||||
v-model="formData.username"
|
||||
:placeholder="$t('login.form.placeholder.username')"
|
||||
size="large"
|
||||
max-length="50"
|
||||
>
|
||||
@ -29,13 +29,12 @@
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="password"
|
||||
:rules="[{ required: true, message: $t('login.form.password.errMsg') }]"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
hide-label
|
||||
>
|
||||
<a-input-password
|
||||
v-model="loginForm.password"
|
||||
:placeholder="$t('login.form.password.placeholder')"
|
||||
v-model="formData.password"
|
||||
:placeholder="$t('login.form.placeholder.password')"
|
||||
size="large"
|
||||
allow-clear
|
||||
max-length="50"
|
||||
@ -48,13 +47,12 @@
|
||||
<a-form-item
|
||||
class="login-form-captcha"
|
||||
field="captcha"
|
||||
:rules="[{ required: true, message: $t('login.form.captcha.errMsg') }]"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
hide-label
|
||||
>
|
||||
<a-input
|
||||
v-model="loginForm.captcha"
|
||||
:placeholder="$t('login.form.captcha.placeholder')"
|
||||
v-model="formData.captcha"
|
||||
:placeholder="$t('login.form.placeholder.captcha')"
|
||||
size="large"
|
||||
style="width: 63%"
|
||||
allow-clear
|
||||
@ -63,7 +61,7 @@
|
||||
<icon-check-circle />
|
||||
</template>
|
||||
</a-input>
|
||||
<img :src="captchaImgBase64" @click="getCaptcha" :alt="$t('login.form.captcha.placeholder')">
|
||||
<img :src="captchaImgBase64" @click="getCaptcha" :alt="$t('login.form.captcha')">
|
||||
</a-form-item>
|
||||
<a-space :size="16" direction="vertical">
|
||||
<div class="login-form-remember-me">
|
||||
@ -84,9 +82,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ref, reactive, computed, onMounted } from "vue";
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { FieldRule, Message } from "@arco-design/web-vue";
|
||||
import { ValidatedError } from '@arco-design/web-vue/es/form/interface';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
// import debug from '@/utils/env';
|
||||
@ -95,13 +93,12 @@
|
||||
import { useLoginStore } from '@/store';
|
||||
import useLoading from '@/hooks/loading';
|
||||
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const errorMessage = ref('');
|
||||
const captchaImgBase64 = ref('');
|
||||
const router = useRouter();
|
||||
const { loading, setLoading } = useLoading();
|
||||
const loginStore = useLoginStore();
|
||||
|
||||
const errorMessage = ref('');
|
||||
const captchaImgBase64 = ref('');
|
||||
const loginConfig = useStorage('login-config', {
|
||||
rememberMe: true,
|
||||
username: 'admin', // 演示默认值
|
||||
@ -109,18 +106,30 @@
|
||||
// username: !debug ? '' : 'admin', // 演示默认值
|
||||
// password: !debug ? '' : 'admin123', // 演示默认值
|
||||
});
|
||||
|
||||
const loginForm = reactive({
|
||||
const formData = reactive({
|
||||
username: loginConfig.value.username,
|
||||
password: loginConfig.value.password,
|
||||
captcha: '',
|
||||
uuid: '',
|
||||
});
|
||||
const rules = computed((): Record<string, FieldRule[]> => {
|
||||
return {
|
||||
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 getCaptcha = async () => {
|
||||
const { data } = await loginStore.getImgCaptcha()
|
||||
loginForm.uuid = data.uuid
|
||||
formData.uuid = data.uuid
|
||||
captchaImgBase64.value = data.img
|
||||
}
|
||||
onMounted(() => {
|
||||
@ -162,7 +171,6 @@
|
||||
const { username } = values;
|
||||
loginConfig.value.username = rememberMe ? username : '';
|
||||
} catch (err) {
|
||||
// errorMessage.value = (err as Error).message;
|
||||
await getCaptcha();
|
||||
} finally {
|
||||
setLoading(false);
|
||||
|
@ -5,7 +5,7 @@
|
||||
alt="logo"
|
||||
src="/logo.svg"
|
||||
/>
|
||||
<div class="logo-text">ContiNew Admin</div>
|
||||
<div class="logo-text">{{ $t('title') }}</div>
|
||||
</div>
|
||||
<LoginBanner />
|
||||
<div class="content">
|
||||
@ -70,7 +70,6 @@
|
||||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
// responsive
|
||||
@media (max-width: @screen-lg) {
|
||||
.container {
|
||||
.banner {
|
||||
|
@ -1,25 +1,31 @@
|
||||
export default {
|
||||
'login.form.title': 'Login to ContiNew Admin',
|
||||
'login.form.subTitle': 'Continue to build the latest popular technology stack in the background management framework',
|
||||
'login.form.username.placeholder': 'Please enter username',
|
||||
'login.form.username.errMsg': 'Please enter username',
|
||||
'login.form.password.placeholder': 'Please enter password',
|
||||
'login.form.password.errMsg': 'Please enter password',
|
||||
'login.form.captcha.placeholder': 'Please enter captcha',
|
||||
'login.form.captcha.errMsg': 'Please enter captcha',
|
||||
|
||||
'login.form.placeholder.username': 'Please enter username',
|
||||
'login.form.placeholder.password': 'Please enter password',
|
||||
'login.form.placeholder.captcha': 'Please enter captcha',
|
||||
|
||||
'login.form.error.required.username': 'Please enter username',
|
||||
'login.form.error.required.password': 'Please enter password',
|
||||
'login.form.error.required.captcha': 'Please enter captcha',
|
||||
|
||||
'login.form.captcha': 'Captcha',
|
||||
'login.form.rememberMe': 'Remember me',
|
||||
'login.form.login': 'Login',
|
||||
'login.form.register': 'Register account',
|
||||
'login.form.forgetPassword': 'Forgot password',
|
||||
'login.form.login.success': 'Welcome to use',
|
||||
'login.form.login.errMsg': 'Login error, refresh and try again',
|
||||
|
||||
'login.banner.slogan1': 'Out-of-the-box high-quality template',
|
||||
'login.form.login.success': 'Welcome to use',
|
||||
'login.form.login.error': 'Login error, refresh and try again',
|
||||
'login.form.logout.success': 'Logout success',
|
||||
|
||||
'login.banner.slogan1': 'Middle and background management framework',
|
||||
'login.banner.subSlogan1':
|
||||
'Rich page templates, covering most typical business scenarios',
|
||||
'Continue New Admin, continue to build on the latest popular technology stack',
|
||||
'login.banner.slogan2': 'Built-in solutions to common problems',
|
||||
'login.banner.subSlogan2':
|
||||
'Internationalization, routing configuration, state management everything',
|
||||
'login.banner.slogan3': 'Access visualization enhancement tool AUX',
|
||||
'login.banner.subSlogan3': 'Realize flexible block development',
|
||||
'Rich basic functions, low threshold to use, enterprise rapid development scaffolding',
|
||||
'login.banner.slogan3': 'The code is standard and open source and free',
|
||||
'login.banner.subSlogan3': 'The backend code is fully compliant with the Alibaba coding specification, and the frontend code is strictly ESLint checked',
|
||||
};
|
||||
|
@ -1,23 +1,29 @@
|
||||
export default {
|
||||
'login.form.title': '登录 ContiNew Admin',
|
||||
'login.form.subTitle': '持续以最新流行技术栈构建的中后台管理框架',
|
||||
'login.form.username.placeholder': '请输入用户名',
|
||||
'login.form.username.errMsg': '请输入用户名',
|
||||
'login.form.password.placeholder': '请输入密码',
|
||||
'login.form.password.errMsg': '请输入密码',
|
||||
'login.form.captcha.placeholder': '请输入验证码',
|
||||
'login.form.captcha.errMsg': '请输入验证码',
|
||||
|
||||
'login.form.placeholder.username': '请输入用户名',
|
||||
'login.form.placeholder.password': '请输入密码',
|
||||
'login.form.placeholder.captcha': '请输入验证码',
|
||||
|
||||
'login.form.error.required.username': '请输入用户名',
|
||||
'login.form.error.required.password': '请输入密码',
|
||||
'login.form.error.required.captcha': '请输入验证码',
|
||||
|
||||
'login.form.captcha': '验证码',
|
||||
'login.form.rememberMe': '记住我',
|
||||
'login.form.login': '登录',
|
||||
'login.form.register': '注册账号',
|
||||
'login.form.forgetPassword': '忘记密码',
|
||||
|
||||
'login.form.login.success': '欢迎使用',
|
||||
'login.form.login.errMsg': '登录出错,请刷新重试',
|
||||
'login.form.login.error': '登录出错,请刷新重试',
|
||||
'login.form.logout.success': '退出成功',
|
||||
|
||||
'login.banner.slogan1': '中后台管理框架',
|
||||
'login.banner.subSlogan1': 'Continue New Admin,持续以最新流行技术栈构建',
|
||||
'login.banner.slogan2': '内置了常见问题的解决方案',
|
||||
'login.banner.subSlogan2': '国际化,路由配置,状态管理应有尽有',
|
||||
'login.banner.slogan3': '接入可视化增强工具AUX',
|
||||
'login.banner.subSlogan3': '实现灵活的区块式开发',
|
||||
'login.banner.subSlogan2': '基础功能丰富,使用门槛低,企业级快速开发脚手架',
|
||||
'login.banner.slogan3': '代码规范且开源免费',
|
||||
'login.banner.subSlogan3': '后端代码完全遵循阿里巴巴编码规范,前端代码使用严格的 ESLint 检查',
|
||||
};
|
||||
|
@ -2,23 +2,18 @@
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="rules"
|
||||
class="form"
|
||||
:label-col-props="{ span: 8 }"
|
||||
:wrapper-col-props="{ span: 16 }"
|
||||
>
|
||||
<a-form-item
|
||||
:label="$t('userCenter.basicInfo.form.label.username')"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: $t('userCenter.form.error.username.required'),
|
||||
},
|
||||
]"
|
||||
disabled
|
||||
>
|
||||
<a-input
|
||||
v-model="formData.username"
|
||||
:placeholder="$t('userCenter.basicInfo.placeholder.username')"
|
||||
:placeholder="$t('userCenter.basicInfo.form.placeholder.username')"
|
||||
size="large"
|
||||
max-length="50"
|
||||
/>
|
||||
@ -26,16 +21,10 @@
|
||||
<a-form-item
|
||||
field="nickname"
|
||||
:label="$t('userCenter.basicInfo.form.label.nickname')"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: $t('userCenter.form.error.nickname.required'),
|
||||
},
|
||||
]"
|
||||
>
|
||||
<a-input
|
||||
v-model="formData.nickname"
|
||||
:placeholder="$t('userCenter.basicInfo.placeholder.nickname')"
|
||||
:placeholder="$t('userCenter.basicInfo.form.placeholder.nickname')"
|
||||
size="large"
|
||||
max-length="32"
|
||||
/>
|
||||
@ -53,10 +42,10 @@
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button type="primary" :loading="loading" @click="save">
|
||||
{{ $t('userCenter.save') }}
|
||||
{{ $t('userCenter.basicInfo.form.save') }}
|
||||
</a-button>
|
||||
<a-button type="secondary" @click="reset">
|
||||
{{ $t('userCenter.reset') }}
|
||||
{{ $t('userCenter.basicInfo.form.reset') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
@ -64,14 +53,16 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { ref, computed } from "vue";
|
||||
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 { Message } from "@arco-design/web-vue";
|
||||
import { FieldRule, Message } from "@arco-design/web-vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { loading, setLoading } = useLoading();
|
||||
const loginStore = useLoginStore();
|
||||
const formRef = ref<FormInstance>();
|
||||
@ -80,6 +71,16 @@
|
||||
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 save = async () => {
|
@ -1,199 +1,21 @@
|
||||
<template>
|
||||
<a-modal v-model:visible="updatePasswordVisible" :title="$t('userCenter.SecuritySettings.form.password.modal.title')" @cancel="handleCancelUpdatePassword" @before-ok="handleBeforeOkUpdatePassword">
|
||||
<a-form
|
||||
ref="formPasswordRef"
|
||||
:model="formPasswordData"
|
||||
>
|
||||
<a-form-item
|
||||
field="oldPassword"
|
||||
:rules="{ required: true, message: $t('userCenter.SecuritySettings.form.password.oldPassword.placeholder') }"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
:label="$t('userCenter.SecuritySettings.form.password.oldPassword.label')"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="formPasswordData.oldPassword"
|
||||
:placeholder="$t('userCenter.SecuritySettings.form.password.oldPassword.placeholder')"
|
||||
size="large"
|
||||
allow-clear
|
||||
max-length="50"
|
||||
>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="newPassword"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: $t('userCenter.SecuritySettings.form.password.error.newPassword.required'),
|
||||
},
|
||||
{
|
||||
match: /^(?=.*\d)(?=.*[a-z]).{6,32}$/,
|
||||
message: $t('userCenter.SecuritySettings.form.password.newPassword.placeholder')
|
||||
}
|
||||
]"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
:label="$t('userCenter.SecuritySettings.form.password.newPassword.label')"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="formPasswordData.newPassword"
|
||||
:placeholder="$t('userCenter.SecuritySettings.form.password.newPassword.placeholder')"
|
||||
size="large"
|
||||
allow-clear
|
||||
max-length="50"
|
||||
>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="rePassword"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: $t('userCenter.SecuritySettings.form.password.rePassword.placeholder'),
|
||||
},
|
||||
{
|
||||
validator: (value, callback) => {
|
||||
if (value !== formPasswordData.newPassword) {
|
||||
callback($t('userCenter.SecuritySettings.form.password.error.rePassword.notequal'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
]"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
:label="$t('userCenter.SecuritySettings.form.password.rePassword.label')"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="formPasswordData.rePassword"
|
||||
:placeholder="$t('userCenter.SecuritySettings.form.password.rePassword.placeholder')"
|
||||
size="large"
|
||||
allow-clear
|
||||
max-length="50"
|
||||
>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
<a-list :bordered="false">
|
||||
<a-list-item>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.SecuritySettings.label.password') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="loginStore.pwdResetTime">
|
||||
已设置
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.SecuritySettings.placeholder.password') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link @click="handleClickUpdatePassword">
|
||||
{{ $t('userCenter.SecuritySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
<UpdatePwd />
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.SecuritySettings.form.label.phone') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="loginStore.phone">
|
||||
已绑定:{{ loginStore.phone }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.SecuritySettings.placeholder.phone') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link>
|
||||
{{ $t('userCenter.SecuritySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
<UpdatePhone />
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.SecuritySettings.form.label.email') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="loginStore.email">
|
||||
已绑定:{{ loginStore.email }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.SecuritySettings.placeholder.email') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link>
|
||||
{{ $t('userCenter.SecuritySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
<UpdateEmail />
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { useLoginStore } from '@/store';
|
||||
import { FormInstance } from "@arco-design/web-vue/es/form";
|
||||
import useLoading from "@/hooks/loading";
|
||||
import { updatePassword } from "@/api/system/user-center";
|
||||
import { Message } from "@arco-design/web-vue";
|
||||
import { encryptByRsa } from "@/utils/encrypt";
|
||||
|
||||
const { loading, setLoading } = useLoading();
|
||||
const loginStore = useLoginStore();
|
||||
const formPasswordRef = ref<FormInstance>();
|
||||
const updatePasswordVisible = ref(false);
|
||||
const formPasswordData = reactive({
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
rePassword: '',
|
||||
});
|
||||
|
||||
const handleClickUpdatePassword = () => {
|
||||
updatePasswordVisible.value = true;
|
||||
};
|
||||
|
||||
const handleBeforeOkUpdatePassword = async () => {
|
||||
const errors = await formPasswordRef.value?.validate();
|
||||
if (loading.value) return false;
|
||||
if (errors) return false;
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await updatePassword({
|
||||
oldPassword: encryptByRsa(formPasswordData.oldPassword) || '',
|
||||
newPassword: encryptByRsa(formPasswordData.newPassword) || '',
|
||||
});
|
||||
if (res.success) Message.success(res.msg);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleCancelUpdatePassword = () => {
|
||||
updatePasswordVisible.value = false;
|
||||
formPasswordRef.value?.resetFields()
|
||||
};
|
||||
import UpdatePwd from './security-settings/update-pwd.vue';
|
||||
import UpdatePhone from './security-settings/update-phone.vue';
|
||||
import UpdateEmail from './security-settings/update-email.vue';
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.securitySettings.updateEmail.label.email') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="loginStore.email">
|
||||
{{ $t('userCenter.securitySettings.updateEmail.placeholder.success.email') }}:{{ loginStore.email }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.securitySettings.updateEmail.placeholder.error.email') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link>
|
||||
{{ $t('userCenter.securitySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useLoginStore } from '@/store';
|
||||
|
||||
const loginStore = useLoginStore();
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.securitySettings.updatePhone.label.phone') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="loginStore.phone">
|
||||
{{ $t('userCenter.securitySettings.updatePhone.placeholder.success.phone') }}:{{ loginStore.phone }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.securitySettings.updatePhone.placeholder.error.phone') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link>
|
||||
{{ $t('userCenter.securitySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useLoginStore } from '@/store';
|
||||
|
||||
const loginStore = useLoginStore();
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<a-list-item-meta>
|
||||
<template #avatar>
|
||||
<a-typography-paragraph>
|
||||
{{ $t('userCenter.securitySettings.updatePwd.label.password') }}
|
||||
</a-typography-paragraph>
|
||||
</template>
|
||||
<template #description>
|
||||
<div class="content">
|
||||
<a-typography-paragraph v-if="loginStore.pwdResetTime">
|
||||
{{ $t('userCenter.securitySettings.updatePwd.placeholder.success.password') }}
|
||||
</a-typography-paragraph>
|
||||
<a-typography-paragraph v-else class="tip">
|
||||
{{ $t('userCenter.securitySettings.updatePwd.placeholder.error.password') }}
|
||||
</a-typography-paragraph>
|
||||
</div>
|
||||
<div class="operation">
|
||||
<a-link @click="toUpdate">
|
||||
{{ $t('userCenter.securitySettings.button.update') }}
|
||||
</a-link>
|
||||
</div>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
|
||||
<a-modal v-model:visible="visible" :title="$t('userCenter.securitySettings.updatePwd.modal.title')" @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-input-password
|
||||
v-model="formData.oldPassword"
|
||||
:placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.oldPassword')"
|
||||
size="large"
|
||||
allow-clear
|
||||
max-length="50"
|
||||
>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="newPassword"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
:label="$t('userCenter.securitySettings.updatePwd.form.label.newPassword')"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="formData.newPassword"
|
||||
:placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.newPassword')"
|
||||
size="large"
|
||||
allow-clear
|
||||
max-length="50"
|
||||
>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="rePassword"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
:label="$t('userCenter.securitySettings.updatePwd.form.label.rePassword')"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="formData.rePassword"
|
||||
:placeholder="$t('userCenter.securitySettings.updatePwd.form.placeholder.rePassword')"
|
||||
size="large"
|
||||
allow-clear
|
||||
max-length="50"
|
||||
>
|
||||
</a-input-password>
|
||||
</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 { updatePassword } from "@/api/system/user-center";
|
||||
import { encryptByRsa } from "@/utils/encrypt";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { loading, setLoading } = useLoading();
|
||||
const loginStore = useLoginStore();
|
||||
const visible = ref(false);
|
||||
const formRef = ref<FormInstance>();
|
||||
const formData = reactive({
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
rePassword: '',
|
||||
});
|
||||
const rules = computed((): Record<string, FieldRule[]> => {
|
||||
return {
|
||||
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) {
|
||||
callback(t('userCenter.securitySettings.updatePwd.form.error.validator.newPassword'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
rePassword: [
|
||||
{ required: true, message: t('userCenter.securitySettings.updatePwd.form.error.required.rePassword') },
|
||||
{
|
||||
validator: (value, callback) => {
|
||||
if (value !== formData.newPassword) {
|
||||
callback(t('userCenter.securitySettings.updatePwd.form.error.validator.rePassword'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
}
|
||||
});
|
||||
|
||||
// 确定修改
|
||||
const handleUpdate = async () => {
|
||||
const errors = await formRef.value?.validate();
|
||||
if (loading.value) return false;
|
||||
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()
|
||||
};
|
||||
|
||||
// 打开修改窗口
|
||||
const toUpdate = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
@ -14,7 +14,7 @@
|
||||
<template #trigger-icon>
|
||||
<icon-camera />
|
||||
</template>
|
||||
<img v-if="avatarList.length" :src="avatarList[0].url" />
|
||||
<img v-if="avatarList.length" :src="avatarList[0].url" :alt="$t('userCenter.panel.avatar')"/>
|
||||
</a-avatar>
|
||||
</template>
|
||||
</a-upload>
|
||||
@ -33,21 +33,21 @@
|
||||
textAlign: 'left',
|
||||
}"
|
||||
>
|
||||
<a-descriptions-item :label="$t('userCenter.label.nickname')">{{ loginStore.nickname }}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('userCenter.label.gender')">
|
||||
<a-descriptions-item :label="$t('userCenter.panel.label.nickname')">{{ loginStore.nickname }}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('userCenter.panel.label.gender')">
|
||||
<div v-if="loginStore.gender === 1">
|
||||
男
|
||||
{{ $t('userCenter.panel.male') }}
|
||||
<icon-man style="color: #19BBF1" />
|
||||
</div>
|
||||
<div v-else-if="loginStore.gender === 2">
|
||||
女
|
||||
{{ $t('userCenter.panel.female') }}
|
||||
<icon-woman style="color: #FA7FA9" />
|
||||
</div>
|
||||
<div v-else>未知</div>
|
||||
<div v-else>{{ $t('userCenter.panel.unknown') }}</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('userCenter.label.phone')">{{ loginStore.phone }}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('userCenter.label.email')">{{ loginStore.email }}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('userCenter.label.registrationDate')">{{ loginStore.registrationDate }}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('userCenter.panel.label.phone')">{{ loginStore.phone }}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('userCenter.panel.label.email')">{{ loginStore.email }}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('userCenter.panel.label.registrationDate')">{{ loginStore.registrationDate }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-space>
|
||||
</a-card>
|
||||
|
@ -9,8 +9,8 @@
|
||||
<a-row class="wrapper">
|
||||
<a-col :span="24">
|
||||
<a-tabs default-active-key="1" type="rounded">
|
||||
<a-tab-pane key="1" :title="$t('userCenter.tab.basicInformation')">
|
||||
<BasicInformation />
|
||||
<a-tab-pane key="1" :title="$t('userCenter.tab.basicInfo')">
|
||||
<BasicInfo />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" :title="$t('userCenter.tab.securitySettings')">
|
||||
<SecuritySettings />
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import UserPanel from './components/user-panel.vue';
|
||||
import BasicInformation from './components/basic-information.vue';
|
||||
import BasicInfo from './components/basic-info.vue';
|
||||
import SecuritySettings from './components/security-settings.vue';
|
||||
</script>
|
||||
|
||||
|
@ -1,41 +1,67 @@
|
||||
export default {
|
||||
'menu.user.center': 'User Center',
|
||||
'userCenter.label.nickname': 'Nick Name :',
|
||||
'userCenter.label.gender': 'Gender :',
|
||||
'userCenter.label.phone': 'Phone :',
|
||||
'userCenter.label.email': 'Email :',
|
||||
'userCenter.label.registrationDate': 'Registration Date :',
|
||||
|
||||
'userCenter.tab.basicInformation': 'Basic Information',
|
||||
'userCenter.basicInfo.form.label.username': 'Username',
|
||||
'userCenter.basicInfo.placeholder.username': 'Please enter username',
|
||||
'userCenter.form.error.username.required': 'Please enter username',
|
||||
'userCenter.basicInfo.form.label.nickname': 'Nickname',
|
||||
'userCenter.basicInfo.placeholder.nickname': 'Please enter nickname',
|
||||
'userCenter.form.error.nickname.required': 'Please enter nickname',
|
||||
'userCenter.basicInfo.form.label.gender': 'Gender',
|
||||
'userCenter.save': 'Save',
|
||||
'userCenter.reset': 'Reset',
|
||||
|
||||
'userCenter.tab.basicInfo': 'Basic Information',
|
||||
'userCenter.tab.securitySettings': 'Security Settings',
|
||||
'userCenter.SecuritySettings.label.password': 'Login Password',
|
||||
'userCenter.SecuritySettings.placeholder.password':
|
||||
'You have not set a password yet. The password must contain at least six letters, digits, and special characters except Spaces.',
|
||||
'userCenter.SecuritySettings.form.password.modal.title': 'Update login password',
|
||||
'userCenter.SecuritySettings.form.password.oldPassword.label': 'Old password',
|
||||
'userCenter.SecuritySettings.form.password.oldPassword.placeholder': 'Please enter old password',
|
||||
'userCenter.SecuritySettings.form.password.newPassword.label': 'New password',
|
||||
'userCenter.SecuritySettings.form.password.error.newPassword.required': 'Please enter new password',
|
||||
'userCenter.SecuritySettings.form.password.newPassword.placeholder': 'Password contains 6 to 32 digits and letters',
|
||||
'userCenter.SecuritySettings.form.password.rePassword.label': 'Confirm password',
|
||||
'userCenter.SecuritySettings.form.password.rePassword.placeholder': 'Please enter new password again',
|
||||
'userCenter.SecuritySettings.form.password.error.rePassword.notequal': 'Two passwords are different',
|
||||
|
||||
'userCenter.SecuritySettings.form.label.phone': 'Phone',
|
||||
'userCenter.SecuritySettings.placeholder.phone':
|
||||
// user-panel
|
||||
'userCenter.panel.avatar': 'Avatar',
|
||||
'userCenter.panel.label.nickname': 'Nick Name :',
|
||||
'userCenter.panel.label.gender': 'Gender :',
|
||||
'userCenter.panel.label.phone': 'Phone :',
|
||||
'userCenter.panel.label.email': 'Email :',
|
||||
'userCenter.panel.label.registrationDate': 'Registration Date :',
|
||||
'userCenter.panel.male': 'male',
|
||||
'userCenter.panel.female': 'female',
|
||||
'userCenter.panel.unknown': 'unknown',
|
||||
|
||||
// basic-info
|
||||
'userCenter.basicInfo.form.label.username': 'Username',
|
||||
'userCenter.basicInfo.form.label.nickname': 'Nickname',
|
||||
'userCenter.basicInfo.form.label.gender': 'Gender',
|
||||
|
||||
'userCenter.basicInfo.form.placeholder.username': 'Please enter username',
|
||||
'userCenter.basicInfo.form.placeholder.nickname': 'Please enter nickname',
|
||||
|
||||
'userCenter.basicInfo.form.error.required.username': 'Please enter username',
|
||||
'userCenter.basicInfo.form.error.required.nickname': 'Please enter nickname',
|
||||
|
||||
'userCenter.basicInfo.form.save': 'Save',
|
||||
'userCenter.basicInfo.form.reset': 'Reset',
|
||||
|
||||
// security-settings
|
||||
// update-pwd
|
||||
'userCenter.securitySettings.updatePwd.label.password': 'Login Password',
|
||||
'userCenter.securitySettings.updatePwd.placeholder.success.password': 'Has been set',
|
||||
'userCenter.securitySettings.updatePwd.placeholder.error.password':
|
||||
'You have not set a password yet. The password must contain at least six letters, digits, and special characters except Spaces.',
|
||||
|
||||
'userCenter.securitySettings.updatePwd.modal.title': 'Update login password',
|
||||
'userCenter.securitySettings.updatePwd.form.label.oldPassword': 'Old password',
|
||||
'userCenter.securitySettings.updatePwd.form.label.newPassword': 'New password',
|
||||
'userCenter.securitySettings.updatePwd.form.label.rePassword': 'Confirm password',
|
||||
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.oldPassword': 'Please enter old password',
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.newPassword': 'Password contains 6 to 32 digits and letters',
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.rePassword': 'Please enter new password again',
|
||||
|
||||
'userCenter.securitySettings.updatePwd.form.error.required.oldPassword': 'Please enter old password',
|
||||
'userCenter.securitySettings.updatePwd.form.error.required.newPassword': 'Please enter new password',
|
||||
'userCenter.securitySettings.updatePwd.form.error.match.newPassword': 'Password contains 6 to 32 digits and letters',
|
||||
'userCenter.securitySettings.updatePwd.form.error.validator.newPassword': 'New password cannot be the same as the old password',
|
||||
'userCenter.securitySettings.updatePwd.form.error.required.rePassword': 'Please enter new password again',
|
||||
'userCenter.securitySettings.updatePwd.form.error.validator.rePassword': 'Two passwords are different',
|
||||
|
||||
// update-phone
|
||||
'userCenter.securitySettings.updatePhone.label.phone': 'Phone',
|
||||
'userCenter.securitySettings.updatePhone.placeholder.success.phone': 'Has been bound',
|
||||
'userCenter.securitySettings.updatePhone.placeholder.error.phone':
|
||||
'You have not set a phone yet. The phone binding can be used to retrieve passwords and receive notifications and SMS login.',
|
||||
'userCenter.SecuritySettings.form.label.email': 'Email',
|
||||
'userCenter.SecuritySettings.placeholder.email':
|
||||
|
||||
// update-email
|
||||
'userCenter.securitySettings.updateEmail.label.email': 'Email',
|
||||
'userCenter.securitySettings.updateEmail.placeholder.success.email': 'Has been bound',
|
||||
'userCenter.securitySettings.updateEmail.placeholder.error.email':
|
||||
'You have not set a mailbox yet. The mailbox binding can be used to retrieve passwords and receive notifications.',
|
||||
'userCenter.SecuritySettings.button.update': 'Update',
|
||||
|
||||
'userCenter.securitySettings.button.update': 'Update',
|
||||
};
|
||||
|
@ -1,41 +1,67 @@
|
||||
export default {
|
||||
'menu.user.center': '个人中心',
|
||||
'userCenter.label.nickname': '昵称 :',
|
||||
'userCenter.label.gender': '性别 :',
|
||||
'userCenter.label.phone': '手机号码 :',
|
||||
'userCenter.label.email': '邮箱 :',
|
||||
'userCenter.label.registrationDate': '注册日期 :',
|
||||
|
||||
'userCenter.tab.basicInformation': '基础信息',
|
||||
'userCenter.basicInfo.form.label.username': '用户名',
|
||||
'userCenter.basicInfo.placeholder.username': '请输入用户名',
|
||||
'userCenter.form.error.username.required': '请输入用户名',
|
||||
'userCenter.basicInfo.form.label.nickname': '昵称',
|
||||
'userCenter.basicInfo.placeholder.nickname': '请输入昵称',
|
||||
'userCenter.form.error.nickname.required': '请输入昵称',
|
||||
'userCenter.basicInfo.form.label.gender': '性别',
|
||||
'userCenter.save': '保存',
|
||||
'userCenter.reset': '重置',
|
||||
|
||||
'userCenter.tab.basicInfo': '基础信息',
|
||||
'userCenter.tab.securitySettings': '安全设置',
|
||||
'userCenter.SecuritySettings.label.password': '登录密码',
|
||||
'userCenter.SecuritySettings.placeholder.password':
|
||||
'您暂未设置密码,密码至少6位字符,支持数字、字母和除空格外的特殊字符。',
|
||||
'userCenter.SecuritySettings.form.password.modal.title': '修改登录密码',
|
||||
'userCenter.SecuritySettings.form.password.oldPassword.label': '当前密码',
|
||||
'userCenter.SecuritySettings.form.password.oldPassword.placeholder': '请输入当前密码',
|
||||
'userCenter.SecuritySettings.form.password.newPassword.label': '新密码',
|
||||
'userCenter.SecuritySettings.form.password.error.newPassword.required': '请输入新密码',
|
||||
'userCenter.SecuritySettings.form.password.newPassword.placeholder': '密码长度6到32位,同时包含数字和字母',
|
||||
'userCenter.SecuritySettings.form.password.rePassword.label': '确认新密码',
|
||||
'userCenter.SecuritySettings.form.password.rePassword.placeholder': '请再次输入新密码',
|
||||
'userCenter.SecuritySettings.form.password.error.rePassword.notequal': '两次输入的密码不一致',
|
||||
|
||||
'userCenter.SecuritySettings.form.label.phone': '安全手机',
|
||||
'userCenter.SecuritySettings.placeholder.phone':
|
||||
// user-panel
|
||||
'userCenter.panel.avatar': '头像',
|
||||
'userCenter.panel.label.nickname': '昵称 :',
|
||||
'userCenter.panel.label.gender': '性别 :',
|
||||
'userCenter.panel.label.phone': '手机号码 :',
|
||||
'userCenter.panel.label.email': '邮箱 :',
|
||||
'userCenter.panel.label.registrationDate': '注册日期 :',
|
||||
'userCenter.panel.male': '男',
|
||||
'userCenter.panel.female': '女',
|
||||
'userCenter.panel.unknown': '未知',
|
||||
|
||||
// basic-info
|
||||
'userCenter.basicInfo.form.label.username': '用户名',
|
||||
'userCenter.basicInfo.form.label.nickname': '昵称',
|
||||
'userCenter.basicInfo.form.label.gender': '性别',
|
||||
|
||||
'userCenter.basicInfo.form.placeholder.username': '请输入用户名',
|
||||
'userCenter.basicInfo.form.placeholder.nickname': '请输入昵称',
|
||||
|
||||
'userCenter.basicInfo.form.error.required.username': '请输入用户名',
|
||||
'userCenter.basicInfo.form.error.required.nickname': '请输入昵称',
|
||||
|
||||
'userCenter.basicInfo.form.save': '保存',
|
||||
'userCenter.basicInfo.form.reset': '重置',
|
||||
|
||||
// security-settings
|
||||
// update-pwd
|
||||
'userCenter.securitySettings.updatePwd.label.password': '登录密码',
|
||||
'userCenter.securitySettings.updatePwd.placeholder.success.password': '已设置',
|
||||
'userCenter.securitySettings.updatePwd.placeholder.error.password':
|
||||
'您暂未设置密码,密码至少6位字符,支持数字、字母和除空格外的特殊字符。',
|
||||
|
||||
'userCenter.securitySettings.updatePwd.modal.title': '修改登录密码',
|
||||
'userCenter.securitySettings.updatePwd.form.label.oldPassword': '当前密码',
|
||||
'userCenter.securitySettings.updatePwd.form.label.newPassword': '新密码',
|
||||
'userCenter.securitySettings.updatePwd.form.label.rePassword': '确认新密码',
|
||||
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.oldPassword': '请输入当前密码',
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.newPassword': '密码长度 6 到 32 位,同时包含数字和字母',
|
||||
'userCenter.securitySettings.updatePwd.form.placeholder.rePassword': '请再次输入新密码',
|
||||
|
||||
'userCenter.securitySettings.updatePwd.form.error.required.oldPassword': '请输入当前密码',
|
||||
'userCenter.securitySettings.updatePwd.form.error.required.newPassword': '请输入新密码',
|
||||
'userCenter.securitySettings.updatePwd.form.error.match.newPassword': '密码长度 6 到 32 位,同时包含数字和字母',
|
||||
'userCenter.securitySettings.updatePwd.form.error.validator.newPassword': '新密码不能与当前密码相同',
|
||||
'userCenter.securitySettings.updatePwd.form.error.required.rePassword': '请再次输入新密码',
|
||||
'userCenter.securitySettings.updatePwd.form.error.validator.rePassword': '两次输入的密码不一致',
|
||||
|
||||
// update-phone
|
||||
'userCenter.securitySettings.updatePhone.label.phone': '安全手机',
|
||||
'userCenter.securitySettings.updatePhone.placeholder.success.phone': '已绑定',
|
||||
'userCenter.securitySettings.updatePhone.placeholder.error.phone':
|
||||
'您暂未设置手机号,绑定手机号可以用来找回密码、接收通知、短信登录等。',
|
||||
'userCenter.SecuritySettings.form.label.email': '安全邮箱',
|
||||
'userCenter.SecuritySettings.placeholder.email':
|
||||
|
||||
// update-email
|
||||
'userCenter.securitySettings.updateEmail.label.email': '安全邮箱',
|
||||
'userCenter.securitySettings.updateEmail.placeholder.success.email': '已绑定',
|
||||
'userCenter.securitySettings.updateEmail.placeholder.error.email':
|
||||
'您暂未设置邮箱,绑定邮箱可以用来找回密码、接收通知等。',
|
||||
'userCenter.SecuritySettings.button.update': '修改',
|
||||
|
||||
'userCenter.securitySettings.button.update': '修改',
|
||||
};
|
||||
|
@ -104,7 +104,8 @@ public class UserCenterController {
|
||||
|
||||
// 校验
|
||||
ValidationUtils.exIfCondition(() -> !ReUtil.isMatch(RegExpConstants.PASSWORD, rawNewPassword),
|
||||
"密码长度6到32位,同时包含数字和字母");
|
||||
"密码长度 6 到 32 位,同时包含数字和字母");
|
||||
ValidationUtils.exIfEqual(rawNewPassword, rawOldPassword, "新密码不能与当前密码相同");
|
||||
|
||||
// 修改密码
|
||||
userService.updatePassword(rawOldPassword, rawNewPassword, LoginHelper.getUserId());
|
||||
|
Loading…
Reference in New Issue
Block a user