Commit c5d4c613 authored by youjie's avatar youjie

账号中心

parent 15d9ad15
......@@ -144,9 +144,6 @@ body {
.customColor-text-7{color: var(--customColor-text-7);}
.customColor-text-6{color: var(--customColor-text-6);}
.customColor-text-5{color: var(--customColor-text-5);}
*{
color: var(--customColor-text-10);
}
@font-face{
font-family:'Source Han Sans CN ExtraLight';
......
......@@ -13,6 +13,8 @@
"coupon": "优惠券",
"accountCenter": "账户中心",
"commonPassengerInfo": "常用旅客信息",
"distributionCenter": "分销中心"
"distributionCenter": "分销中心",
"resetPassword": "重置密码",
"editEmail": "绑定/修改邮箱"
}
}
\ No newline at end of file
......@@ -178,14 +178,18 @@ export default {
medium: '中',
high: '高',
passwordSecurityTip: ' 安全性高的密码可以使账号更安全。建议您定期更换密码,且设置一个包含数字和字母,并且长度超过8位以上的密码。',
bindPhoneTip: '绑定手机后,您即可享受手机号登录、动态码登录、找回密码等。为了帐号安全建议您在更换手机号后第一时间更换绑定手机。 ',
bindPhoneTip: '绑定手机。 ',
changeBindData: '更换',
bindEmailTip: '邮箱用于验证码接收,账户登录。',
bindWechatTip: '通过微信账户快速登录,无需输入密码。',
bindGoogleTip: '通过谷歌账户快速登录,无需输入密码。',
bindLineTip: '绑定手机后,您即可享受手机号登录、动态码登录、找回密码等。为了帐号安全建议您在更换手机号后第一时间更换绑定手机。',
bindLineTip: '通过Line账户快速登录,无需输入密码。',
notYetBin: '暂未绑定',
goBind: '去绑定',
confirmChange: '确认修改',
return: '返回',
oldPassword: '旧密码',
placeholderNewPassword: '请输入新密码',
},
// HTTP 错误状态码
httpError: {
......
......@@ -21,7 +21,7 @@ import Headers from './components/Headers.vue'
const { t } = useI18n()
const route = useRoute()
const collapsed = ref(false)
const loading = ref(true)
// 当前激活的菜单
......@@ -70,13 +70,10 @@ const menuList = ref([
}
])
// 菜单点击
const handleMenuClick = (key: string) => {
}
onMounted(() => {
setTimeout(()=>{
loading.value = false
},500)
})
</script>
......
......@@ -54,7 +54,17 @@ const router = createRouter({
component: () => import ('../views/personalCenter/distributionCenter.vue')
},
]
}
},
{
path: '/resetPassword',
meta: { title: "page.resetPassword" },
component: () => import ('../views/personalCenter/resetPassword.vue')
},
{
path: '/editEmail',
meta: { title: "page.editEmail" },
component: () => import ('../views/personalCenter/editEmail.vue')
},
]
},
{
......@@ -70,7 +80,7 @@ const router = createRouter({
meta: { title: "page.register" },
},
{
path: "/forgePassword",
path: "/forgePassword/:email?",
name: "forgePassword",
component: () => import("../views/auth/forgePassword.vue"),
meta: { title: "page.forgotPassword" },
......
......@@ -242,6 +242,20 @@ export interface ResetPasswordDto {
newPassword: string
}
/**
* 更新密码请求参数
*/
export interface NewPasswordResponseDto {
/** 租户ID */
tenantId: string
/** 旧密码 */
oldPassword: string
/** 新密码 */
newPassword: string
}
/**
* 重置密码响应
*/
......@@ -571,6 +585,32 @@ class UserService {
return response as unknown as ResetPasswordResponseDto
}
/**
* 更新密码
* @param email 邮箱地址
* @param code 验证码
* @param newPassword 新密码
* @param confirmPassword 确认密码
* @param tenantId 租户ID(可选)
* @returns 重置结果
*/
static async setNewPasswordAsync(
tenantId: string,
oldPassword: string,
newPassword: string,
): Promise<HttpResponse> {
const data: NewPasswordResponseDto = {
tenantId,
oldPassword,
newPassword,
}
const response = await OtaRequest.post(
'/account/password',
data
)
return response as unknown as HttpResponse
}
/**
* 获取个人中心信息
* @param tenantId 租户ID(可选)
......
<template>
<a-spin :loading="loading" class="login h-screen overflow-hidden">
<div class="login h-screen overflow-hidden">
<a-spin :loading="loading" style="height: 100%;width: 100%;">
<div ref="loginPage"
class="light-login-bg pl-[85px] pr-[98px] pt-[33px] h-full !overflow-y-auto light-login-bg">
<loginHeader />
......@@ -124,6 +125,7 @@
</div>
</div>
</a-spin>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from "vue";
......@@ -391,6 +393,9 @@ const init = async () => {
init()
onMounted(async () => {
setTimeout(()=>{
loading.value = false
})
const queryParams = query()
const code = queryParams.code
if (code) {
......@@ -404,9 +409,7 @@ onMounted(async () => {
await new Promise(resolve => setTimeout(resolve));
renderGoogleButton()
setTimeout(()=>{
loading.value = false
},500)
} catch (error) {
console.error('SDK 初始化失败:', error);
}
......
<template>
<a-spin :loading="loading" class="h-screen overflow-hidden">
<div class="h-screen overflow-hidden">
<a-spin :loading="loading" style="height: 100%;width: 100%;">
<div ref="loginPage"
class="light-login-bg pl-[85px] pr-[98px] pt-[33px] h-full !overflow-y-auto light-login-bgActive">
<loginHeader />
......@@ -51,7 +52,7 @@
</a-form-item>
</div>
<div v-show="currentStep==2">
<a-form-item field="" :label="t('login.newPassword')">
<a-form-item field="password" :label="t('login.newPassword')">
<a-input-password class="formData-input"
v-model="formData.password"
:placeholder="t('login.passwordRequiredReset')"
......@@ -61,7 +62,7 @@
size="large">
</a-input-password>
</a-form-item>
<a-form-item field="" :label="t('login.confirmPassword')" class="">
<a-form-item field="newPassword" :label="t('login.confirmPassword')" class="">
<a-input-password class="formData-input"
v-model="formData.newPassword"
size="large"
......@@ -93,7 +94,7 @@
<div class="mt-[62px] flex justify-center items-center">
<div class="w-[42px] h-[42px] rounded-full bg-[#FFFFFF] flex items-center justify-center
shadow-[0_0_10px_rgba(0,0,0,0.1)] cursor-pointer"
@click="currentStep==1?goLogin('/login'):handlePrevious()">
@click="currentStep==1?goPage('/login'):handlePrevious()">
<icon-left size="24" strokeLinejoin="miter" />
</div>
</div>
......@@ -110,6 +111,7 @@
</div> -->
</div>
</a-spin>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, watch, computed, onMounted } from "vue";
......@@ -125,12 +127,13 @@ import UserService from '@/services/UserService'
const { t } = useI18n();
const router = useRouter()
const { params } = router.currentRoute.value
const userStore = useUserStore()
const systemConfigStore = useSystemConfigStore()
const formData = reactive({
tenantId: systemConfigStore.tenantId || null,
email: '2310721242@qq.com',
email: '',
code: '',
password: '',
newPassword: '',
......@@ -154,7 +157,7 @@ const rules = computed(() => ({
},
{
validator: (value: any, cb: any) => {
if (!/^(?=.*[A-Za-z])(?=.*\d).{8,}$/.test(value)) {
if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d\S]{8,}$/.test(value)) {
cb(t('login.passwordFormat'))
}else {
cb()
......@@ -166,7 +169,7 @@ const rules = computed(() => ({
{ required: true, message: t('login.confirmPasswordRequired') },
{
validator: (value: any, cb: any) => {
if (!/^(?=.*[A-Za-z])(?=.*\d).{8,}$/.test(value)) {
if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d\S]{8,}$/.test(value)) {
cb(t('login.passwordFormat'))
}else {
cb()
......@@ -227,8 +230,12 @@ const handleEmailBlur = async () => {
}else emailValidateStatus.value = 'success'
}
const goLogin = (path:string) => {
const goPage = (path:string) => {
if(!params||!params.email){
router.push(path)
return
}
router.push('/accountCenter')
}
// 验证邮箱是否可用
......@@ -424,7 +431,11 @@ const handleSubmit = async () => {
Message.success(t('login.resetSuccess'))
// 延迟跳转到登录页
setTimeout(() => {
if(params&&params.email){
router.push('/accountCenter')
}else{
router.push('/login')
}
}, 2000)
} catch (error: any) {
Message.error(error.message || t('login.resetFailed'))
......@@ -446,13 +457,16 @@ const init = async () => {
router.replace('/')
}
}
init()
console.log('params',router.currentRoute.value.params.email)
if(!params||!params.email){
init()
}else{
formData.email = params.email
}
onMounted(() => {
setTimeout(()=>{
loading.value = false
},500)
})
})
</script>
<style scoped lang="scss">
......
<template>
<a-spin :loading="loading" class="h-screen overflow-hidden">
<div class="h-screen overflow-hidden">
<a-spin :loading="loading" style="height: 100%;width: 100%;">
<div ref="loginPage"
class="light-login-bg pl-[85px] pr-[98px] pt-[33px] h-full !overflow-y-auto"
:class="[currentStep<3?'light-login-bg':'light-login-bgActive']">
......@@ -222,6 +223,7 @@
<registerSuccess v-if="currentStep==3" />
</div>
</a-spin>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, watch, computed, provide, onMounted } from "vue";
......@@ -302,7 +304,7 @@ const rules = computed(() => ({
},
{
validator: (value: any, cb: any) => {
if (!/^(?=.*[A-Za-z])(?=.*\d).{8,}$/.test(value)) {
if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d\S]{8,}$/.test(value)) {
cb(t('login.passwordFormat'))
}else if (value !== formData.confirmPassword) {
cb(t('login.passwordMismatch'))
......@@ -316,7 +318,7 @@ const rules = computed(() => ({
{ required: true, message: t('login.confirmPasswordRequired') },
{
validator: (value: any, cb: any) => {
if (!/^(?=.*[A-Za-z])(?=.*\d).{8,}$/.test(value)) {
if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d\S]{8,}$/.test(value)) {
cb(t('login.passwordFormat'))
}else if (value !== formData.password) {
cb(t('login.passwordMismatch'))
......@@ -676,7 +678,7 @@ getSimples()
onMounted(() => {
setTimeout(()=>{
loading.value = false
},500)
})
})
</script>
<style>
......
This diff is collapsed.
......@@ -59,7 +59,9 @@
</span>
<a-badge class="ml-[8px]" v-if="item.count"
:count="item.count"
:dotStyle="{ background: '#FF9707', minWidth: '16px', width: '16px', minHeight: '16px', height: '16px',fontSize:'12px',borderRadius:'16px',lineHeight:'15px' }"
:dotStyle="{ background: '#FF9707', minWidth: '16px', width: '16px',
minHeight: '16px', height: '16px',fontSize:'12px',borderRadius:'16px',
lineHeight:'15px', color:'#fff' }"
/>
</div>
</div>
......
......@@ -153,7 +153,7 @@ const rules = computed(() => ({
},
{
validator: (value: any, cb: any) => {
if (!/^(?=.*[A-Za-z])(?=.*\d).{8,}$/.test(value)) {
if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d\S]{8,}$/.test(value)) {
cb(t('login.passwordFormat'))
}else {
cb()
......@@ -165,7 +165,7 @@ const rules = computed(() => ({
{ required: true, message: t('login.newPasswordRequired') },
{
validator: (value: any, cb: any) => {
if (!/^(?=.*[A-Za-z])(?=.*\d).{8,}$/.test(value)) {
if (!/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d\S]{8,}$/.test(value)) {
cb(t('login.passwordFormat'))
}else {
cb()
......
This diff is collapsed.
<template>
<a-spin :loading="loading" class="w-[977px] h-full flex flex-col flex-shrink-0">
<div class="w-[977px] h-full flex flex-col flex-shrink-0">
<a-spin :loading="loading">
<div class="myOrderData rounded-[14px] flex justify-between pt-[22px] pb-[19px] pl-[16px] relative">
<div class="flex items-center p-[20px]">
<div class="bg-[#F3F3F2] rounded-full w-[52px] h-[52px] flex justify-center items-center mr-[16px]">
......@@ -134,6 +135,7 @@
</a-scrollbar>
</div>
</a-spin>
</div>
<Modal class="ModalRef"
ref="ModalRef"
:modal-config="modalConfig"
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment