Commit d45633ef authored by youjie's avatar youjie

忘记密码

parent 8b0a34f7
...@@ -95,6 +95,9 @@ export default { ...@@ -95,6 +95,9 @@ export default {
verifyCodeLength: '请输入4位验证码', verifyCodeLength: '请输入4位验证码',
loginSuccess: '登录成功', loginSuccess: '登录成功',
loginFailed: '登录失败', loginFailed: '登录失败',
resetSuccess: '密码重置成功',
resetFailed: '密码重置失败',
emailRequiredReset: '请输入邮箱',
}, },
common: { common: {
language: '语言', language: '语言',
......
...@@ -7,14 +7,6 @@ import OtaRequest,{ type HttpResponse} from '@/api/OtaRequest' ...@@ -7,14 +7,6 @@ import OtaRequest,{ type HttpResponse} from '@/api/OtaRequest'
// ==================== 枚举定义 ==================== // ==================== 枚举定义 ====================
/**
* 分销商类型枚举
*/
export enum DistributorType {
Enterprise = 'Enterprise', // 企业
Individual = 'Individual' // 个人
}
/** /**
* 申请状态枚举 * 申请状态枚举
*/ */
...@@ -103,7 +95,7 @@ export interface DistributorSelfRegisterDto { ...@@ -103,7 +95,7 @@ export interface DistributorSelfRegisterDto {
// ==================== 响应 DTO ==================== // ==================== 响应 DTO ====================
/** /**
* 分销商等级信息 * 等级信息
*/ */
export interface DistributorLevelDto { export interface DistributorLevelDto {
/** ID */ /** ID */
...@@ -132,128 +124,68 @@ export interface DistributorLevelDto { ...@@ -132,128 +124,68 @@ export interface DistributorLevelDto {
* 登录响应 * 登录响应
*/ */
export interface DistributorLoginResultDto { export interface DistributorLoginResultDto {
/** 分销商类型 */ /*** 域名*/
domain: DistributorType domain?: null | string;
/** 公司/品牌名称 */ /*** 令牌过期时间*/
companyOrBrandName?: string expireTime?: Date;
/** 统一编号 */ /*** 会员基础信息*/
unifiedNumber?: string memberData?: null;
/** 联络人姓名 */ /*** 🆕 权限列表*/
contactPerson?: string permissions?: string[] | null;
/** 联络电话/手机 */ /*** 🆕 刷新令牌*/
contactPhone?: string refreshToken?: null | string;
/** 联络地址 */ /*** 租户ID(ABP 多租户)*/
contactAddress?: string tenantId?: null | string;
/** LINE ID */ /*** JWT访问令牌*/
lineId?: string token?: null | string;
/** 微信ID */ /*** 🆕 用户基础信息*/
wechatId?: string userInfo?: null;
/** 电子邮箱 */
email?: string
/** 密码 */
password?: string
/** 会员等级 */
memberLevel?: string
/** 等级信息 */
level?: DistributorLevelDto
/** 公司登记证明/身份影本/名片 */
documentFilePath?: string
/** 禁用状态 */
disableStatus: DisableStatus
/** 禁用备注 */
disableRemarks?: string
/** 禁用操作人 */
disableId?: number
/** 禁用时间 */
disableTime?: string
/** 申请状态 */
status: ApplicationStatus
/** 审核时间 */
reviewTime?: string
/** 审核备注 */
reviewRemarks?: string
/** 审核人id */
reviewId?: number
/** 主键id */
id: number
/** 类型显示 */
typeDiaplay?: string
/** 申请状态显示 */
applicationStatusDiaplay?: string
/** 禁用状态显示 */
disableStatusDiaplay?: string
/** 开户支行名称 */
openBankName?: string
/** 银行名称(所属银行全称) */
bankName?: string
/** 账户持有人姓名 */
accountHolder?: string
/** 银行卡号 */
cardNum?: string
/** 税务登记号 */
dutyNo?: string
/** 结算账户id */
clientBankAccountId?: number
/** 银行账户id */
bankId?: number
/** JWT访问令牌 */
token: string
/** 刷新令牌 */
refreshToken?: string
/** 令牌过期时间 */
expireTime: string
/** 用户基础信息 */
userInfo?: any
/** 权限列表 */
permissions?: string[]
/** 租户ID(ABP 多租户) */
tenantId?: string
/** 集团(已废弃,使用 TenantId 代替) */
rB_Group_Id?: number
/** 额外数据 */
extraData?: any
}
/**
* ABP 错误验证信息
*/
export interface RemoteServiceValidationErrorInfo {
message?: string
members?: string[]
}
/**
* ABP 错误信息
*/
export interface RemoteServiceErrorInfo {
code?: string
message?: string
details?: string
data?: Record<string, string>
validationErrors?: RemoteServiceValidationErrorInfo[]
} }
/** /**
* ABP 错误响应 * 注册返回结果
*/
export interface RemoteServiceErrorResponse {
error: RemoteServiceErrorInfo
}
/**
* 代理商自助注册返回结果
*/ */
export interface DistributorSelfRegisterResultDto { export interface DistributorSelfRegisterResultDto {
/** 是否成功 */ /*** 出生日期*/
success: boolean birthday?: Date | null;
/** 消息 */ /*** 确认密码*/
message?: string confirmPassword: string;
/** 代理商ID */ /*** 分销商推广码*/
distributorId?: number distributorCode?: null | string;
/** 用户ID */ /*** 分销商ID*/
userId?: string distributorID?: number;
/** 申请状态 */ /*** 电子邮箱(需要判断唯一,作为登录账号)*/
status: ApplicationStatus email: string;
/*** 授权登录 对应的账号名称*/
externalName?: null | string;
/*** 勾選「我願意接收優惠與電子報」 1是*/
isReceivePush?: number;
/*** LINE ID*/
lineID?: null | string;
/*** 会员昵称*/
name?: null | string;
/*** 授权登录唯一ID*/
openID?: null | string;
/*** 父级会员ID*/
parentID?: null | string;
/*** 密码*/
password: string;
/*** 电话*/
phone?: null | string;
/*** 电话区号*/
phoneCode?: null | string;
/*** 居住地區*/
residentialArea?: null | string;
/*** 注册类型 0邮箱验证码 1谷歌授权 3LINE授权 7FaceBook授权*/
reType?: number;
/*** 性别 1男 2女*/
sex?: number;
/*** 临时令牌token*/
temporaryToken?: null | string;
/*** 租户ID(手动传入,用于多租户隔离)*/
tenantID: string;
/*** 微信ID*/
wechatID?: null | string;
} }
/** /**
...@@ -545,47 +477,6 @@ class UserService { ...@@ -545,47 +477,6 @@ class UserService {
return response as unknown as VerifyEmailCodeResponseDto return response as unknown as VerifyEmailCodeResponseDto
} }
/**
* 发送忘记密码验证码
* @param email 邮箱地址
* @param tenantId 租户ID(可选)
* @returns 发送结果
*/
static async sendForgotPasswordCodeAsync(
email: string
): Promise<SendVerificationCodeResponseDto> {
const data: SendVerificationCodeDto = {
email
}
const response = await OtaRequest.post(
'/account/email-captcha-for-reset-password',
data
)
return response as unknown as SendVerificationCodeResponseDto
}
/**
* 验证忘记密码验证码
* @param email 邮箱地址
* @param code 验证码
* @param tenantId 租户ID(可选)
* @returns 验证结果
*/
static async verifyForgotPasswordCodeAsync(
email: string,
code: string
): Promise<VerifyEmailCodeResponseDto> {
const data: VerifyEmailCodeDto = {
email,
code
}
const response = await OtaRequest.post(
'/account/verify-email-code-and-generate-token',
data
)
return response as unknown as VerifyEmailCodeResponseDto
}
/** /**
* 重置密码 * 重置密码
* @param email 邮箱地址 * @param email 邮箱地址
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
<a-form-item field="email" :label="t('login.account')"> <a-form-item field="email" :label="t('login.account')">
<a-input class="loginMsg-input" <a-input class="loginMsg-input"
v-model="loginMsg.email" v-model="loginMsg.email"
:placeholder="t('login.accountPlaceholder')" :placeholder="t('login.emailRequiredReset')"
:maxLength="16" size="large"> size="large">
<!-- <template #prefix> <!-- <template #prefix>
<icon-user size="16" strokeLinejoin="miter" /> <icon-user size="16" strokeLinejoin="miter" />
</template> --> </template> -->
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
v-model="loginMsg.password" v-model="loginMsg.password"
size="large" size="large"
:placeholder="t('login.passwordPlaceholder')" :placeholder="t('login.passwordPlaceholder')"
:maxLength="50"
:invisible-button="false" :invisible-button="false"
> >
<!-- <template #prefix> <!-- <template #prefix>
...@@ -157,8 +156,8 @@ const loginMsg = reactive({ ...@@ -157,8 +156,8 @@ const loginMsg = reactive({
tenantId: systemConfigStore.tenantId || null, tenantId: systemConfigStore.tenantId || null,
reType: 0,//登录方式 0账号密码 1谷歌授权 3LINE授权 7FaceBook授权 reType: 0,//登录方式 0账号密码 1谷歌授权 3LINE授权 7FaceBook授权
openId: "", openId: "",
email: "",//2310721242@qq.com email: "2310721242@qq.com",//
password: '',//123456 password: 'yj950815',//123456
distributorId: systemConfigStore.distributorId as any, distributorId: systemConfigStore.distributorId as any,
parentId: null, parentId: null,
redirectUri: '', redirectUri: '',
...@@ -248,6 +247,8 @@ const renderGoogleButton = () => { ...@@ -248,6 +247,8 @@ const renderGoogleButton = () => {
// Google 登录回调 // Google 登录回调
const handleSignInSuccess = async (googleUser:any) => { const handleSignInSuccess = async (googleUser:any) => {
loading.value = true
try {
// 获取授权码 // 获取授权码
const response = await userStore.setUserGoogleLoginAsync(loginMsg.tenantId?.toString() || '', googleUser.credential, loginMsg.distributorId,loginMsg.parentId,loginMsg.redirectUri) const response = await userStore.setUserGoogleLoginAsync(loginMsg.tenantId?.toString() || '', googleUser.credential, loginMsg.distributorId,loginMsg.parentId,loginMsg.redirectUri)
if (response.status == 'SUCCESS') { if (response.status == 'SUCCESS') {
...@@ -258,6 +259,12 @@ const handleSignInSuccess = async (googleUser:any) => { ...@@ -258,6 +259,12 @@ const handleSignInSuccess = async (googleUser:any) => {
path: forward ? forward : '/', path: forward ? forward : '/',
}) })
} }
}catch (error: any) {
Message.error(error.message || t('login.googleLoginFailed'))
} finally {
loading.value = false
}
}; };
// 处理登录错误 // 处理登录错误
const handleSignInError = (error: any) => { const handleSignInError = (error: any) => {
...@@ -297,9 +304,10 @@ const handleLogin = async () => { ...@@ -297,9 +304,10 @@ const handleLogin = async () => {
router.push({ router.push({
path: forward ? forward : '/', path: forward ? forward : '/',
}) })
}else Message.error(t('login.loginFailed')) }
} catch (error: any) {
Message.error(error.message || t('login.resetFailed'))
} finally { } finally {
Message.error(t('login.loginFailed'))
loading.value = false loading.value = false
} }
} }
...@@ -381,10 +389,10 @@ onMounted(async () => { ...@@ -381,10 +389,10 @@ onMounted(async () => {
box-shadow: rgba(74,102,77,0.15) 0px 5px 15px; box-shadow: rgba(74,102,77,0.15) 0px 5px 15px;
background-color: var(--primary1-5-hover); background-color: var(--primary1-5-hover);
} }
:deep(.items-center-button .isClick .arco-btn-primary){ :deep(.items-center-button.isClick .arco-btn-primary){
background-color: var(--primary1-5); background-color: var(--primary1-5);
} }
:deep(.items-center-button .isClick .arco-btn-primary:hover){ :deep(.items-center-button.isClick .arco-btn-primary:hover){
background-color: var(--primary1-5); background-color: var(--primary1-5);
} }
// :deep(.arco-btn-primary){ // :deep(.arco-btn-primary){
......
This diff is collapsed.
...@@ -26,12 +26,12 @@ ...@@ -26,12 +26,12 @@
<a-space direction="vertical" class="px-[72px]"> <a-space direction="vertical" class="px-[72px]">
<a-form :model="formData" :rules="rules" layout="vertical" <a-form :model="formData" :rules="rules" layout="vertical"
class="mt-[42px]"> class="mt-[42px]">
<template v-if="currentStep==1"> <div v-show="currentStep==1">
<a-form-item field="email" :label="t('login.email')"> <a-form-item field="email" :label="t('login.email')">
<a-input class="formData-input" <a-input class="formData-input"
v-model="formData.email" v-model="formData.email"
placeholder="" placeholder=""
:maxLength="16" size="large" size="large"
@blur="handleEmailBlur" @input="handleEmailChange"> @blur="handleEmailBlur" @input="handleEmailChange">
</a-input> </a-input>
</a-form-item> </a-form-item>
...@@ -40,9 +40,7 @@ ...@@ -40,9 +40,7 @@
v-model="formData.verificationCode" v-model="formData.verificationCode"
size="large" size="large"
:placeholder="t('login.verifyCodeRequired')" :placeholder="t('login.verifyCodeRequired')"
:defaultVisibility="false" :maxLength="6"
:maxLength="50"
:invisible-button="false"
@input="handleCodeInput" @input="handleCodeInput"
> >
<template #suffix> <template #suffix>
...@@ -65,7 +63,8 @@ ...@@ -65,7 +63,8 @@
v-model="formData.password" v-model="formData.password"
size="large" size="large"
:placeholder="t('login.setPasswordRequired')" :placeholder="t('login.setPasswordRequired')"
:maxLength="50" :maxLength="8"
:defaultVisibility="false"
:invisible-button="false" :invisible-button="false"
> >
<!-- <template #prefix> <!-- <template #prefix>
...@@ -78,18 +77,19 @@ ...@@ -78,18 +77,19 @@
v-model="formData.confirmPassword" v-model="formData.confirmPassword"
size="large" size="large"
:placeholder="t('login.confirmPasswordRequired')" :placeholder="t('login.confirmPasswordRequired')"
:maxLength="50" :maxLength="8"
:defaultVisibility="true"
:invisible-button="false" :invisible-button="false"
> >
</a-input-password> </a-input-password>
</a-form-item> </a-form-item>
</template> </div>
<template v-if="currentStep==2"> <div v-show="currentStep==2">
<a-form-item field="" :label="t('login.bindingName')"> <a-form-item field="" :label="t('login.bindingName')">
<a-input class="formData-input" <a-input class="formData-input"
v-model="formData.name" v-model="formData.name"
:placeholder="t('login.bindingNameRequired')" :placeholder="t('login.bindingNameRequired')"
:maxLength="16" size="large"> size="large">
<!-- <template #prefix> <!-- <template #prefix>
<icon-user size="16" strokeLinejoin="miter" /> <icon-user size="16" strokeLinejoin="miter" />
</template> --> </template> -->
...@@ -99,7 +99,7 @@ ...@@ -99,7 +99,7 @@
<a-input class="formData-input" <a-input class="formData-input"
v-model="formData.phone" v-model="formData.phone"
:placeholder="t('login.bindingPhoneRequired')" :placeholder="t('login.bindingPhoneRequired')"
:maxLength="16" size="large"> size="large">
<template #prefix> <template #prefix>
<a-dropdown position="br" trigger.stop="click"> <a-dropdown position="br" trigger.stop="click">
<div class="flex items-center cursor-pointer"> <div class="flex items-center cursor-pointer">
...@@ -127,8 +127,6 @@ ...@@ -127,8 +127,6 @@
v-model="formData.lineId" v-model="formData.lineId"
size="large" size="large"
:placeholder="t('login.lineId')" :placeholder="t('login.lineId')"
:defaultVisibility="false"
:invisible-button="false"
> >
</a-input> </a-input>
</a-form-item> </a-form-item>
...@@ -137,9 +135,6 @@ ...@@ -137,9 +135,6 @@
v-model="formData.wechatId" v-model="formData.wechatId"
size="large" size="large"
:placeholder="t('login.bindingWechatRequired')" :placeholder="t('login.bindingWechatRequired')"
:defaultVisibility="false"
:maxLength="50"
:invisible-button="false"
> >
<!-- <template #prefix> <!-- <template #prefix>
<icon-key size="16" strokeLinejoin="miter" /> <icon-key size="16" strokeLinejoin="miter" />
...@@ -151,9 +146,6 @@ ...@@ -151,9 +146,6 @@
v-model="formData.distributorCode" v-model="formData.distributorCode"
size="large" size="large"
:placeholder="t('login.bindingRecommendCodeRequired')" :placeholder="t('login.bindingRecommendCodeRequired')"
:defaultVisibility="false"
:maxLength="50"
:invisible-button="false"
> >
<!-- <template #prefix> <!-- <template #prefix>
<icon-key size="16" strokeLinejoin="miter" /> <icon-key size="16" strokeLinejoin="miter" />
...@@ -176,7 +168,7 @@ ...@@ -176,7 +168,7 @@
</div> </div>
<span class="text-[#008AFF] text-sm">{{ t('login.isReceivePush') }}</span> <span class="text-[#008AFF] text-sm">{{ t('login.isReceivePush') }}</span>
</div> </div>
</template> </div>
<div class="mt-[27px] w-full flex flex-col items-center items-center-button"> <div class="mt-[27px] w-full flex flex-col items-center items-center-button">
<div class="w-full mb-[65px]" v-if="currentStep<2" <div class="w-full mb-[65px]" v-if="currentStep<2"
:class="[formData.email&&verificationToken&&formData.password&&formData.password.length>=8&&formData.confirmPassword&&formData.confirmPassword.length>=8?'isClick':'']"> :class="[formData.email&&verificationToken&&formData.password&&formData.password.length>=8&&formData.confirmPassword&&formData.confirmPassword.length>=8?'isClick':'']">
...@@ -195,6 +187,7 @@ ...@@ -195,6 +187,7 @@
:class="[formData.isAgreement?'isClick':'']"> :class="[formData.isAgreement?'isClick':'']">
<a-button <a-button
type="primary" type="primary"
:loading="loading"
size="large" size="large"
html-type="submit" html-type="submit"
class="microsoft-font flex-1 font-bold text-gray-200 !h-[46px] !rounded-[13px] !text-base w-full" class="microsoft-font flex-1 font-bold text-gray-200 !h-[46px] !rounded-[13px] !text-base w-full"
...@@ -687,6 +680,8 @@ const handleAccountLogin = async () => { ...@@ -687,6 +680,8 @@ const handleAccountLogin = async () => {
if (result.status === 'SUCCESS') { if (result.status === 'SUCCESS') {
} }
} catch (error: any) {
Message.error(error.message)
} finally { } finally {
loading.value = false loading.value = false
} }
...@@ -793,4 +788,7 @@ getSimples() ...@@ -793,4 +788,7 @@ getSimples()
:deep(.formData-input .arco-dropdown){ :deep(.formData-input .arco-dropdown){
opacity: 0 !important; opacity: 0 !important;
} }
:deep(.arco-icon){
color: var(--primary1-5);
}
</style> </style>
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