Files
mini-programs/src/pages/login/index/index.tsx
2025-09-02 10:00:57 +08:00

240 lines
6.9 KiB
TypeScript

import React, { useState } from 'react';
import { View, Text, Button, Image } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { wechat_auth_login, save_login_state } from '../../../services/loginService';
import './index.scss';
const LoginPage: React.FC = () => {
const [is_loading, set_is_loading] = useState(false);
const [agree_terms, set_agree_terms] = useState(false);
const [show_terms_layer, set_show_terms_layer] = useState(false);
// 微信授权登录
const handle_wechat_login = async (e: any) => {
if (!agree_terms) {
set_show_terms_layer(true);
Taro.showToast({
title: '请先同意用户协议',
icon: 'none',
duration: 2000
});
return;
}
// 检查是否获取到手机号
if (!e.detail || !e.detail.code) {
Taro.showToast({
title: '获取手机号失败,请重试',
icon: 'none',
duration: 2000
});
return;
}
set_is_loading(true);
try {
// 传递手机号code给登录服务
const response = await wechat_auth_login(e.detail.code);
if (response.success) {
save_login_state(response.token!, response.user_info!);
setTimeout(() => {
Taro.redirectTo({ url: '/pages/list/index' });
}, 200);
} else {
Taro.showToast({
title: response.message,
icon: 'none',
duration: 2000
});
}
} catch (error) {
Taro.showToast({
title: '登录失败,请重试',
icon: 'none',
duration: 2000
});
} finally {
set_is_loading(false);
}
};
// 手机号验证码登录
const handle_phone_login = async () => {
if (!agree_terms) {
set_show_terms_layer(true);
Taro.showToast({
title: '请先同意用户协议',
icon: 'none',
duration: 2000
});
return;
}
// 跳转到验证码页面
Taro.navigateTo({
url: '/pages/login/verification/index'
});
};
// 同意协议并关闭浮层
const handle_agree_terms = () => {
set_agree_terms(true);
set_show_terms_layer(false);
};
// 切换协议同意状态(复选框用)
const handle_toggle_terms = () => {
set_agree_terms(!agree_terms);
};
// 查看协议
const handle_view_terms = (type: string = 'terms') => {
Taro.navigateTo({
url: `/pages/login/terms/index?type=${type}`
});
};
// 点击浮层外部关闭浮层
const handle_overlay_click = () => {
set_show_terms_layer(false);
};
// 点击浮层内部阻止事件冒泡
const handle_layer_click = (e: any) => {
e.stopPropagation();
};
return (
<View className="login_page">
<View className="background_image">
<Image
className="bg_img"
src="http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/2e00dea1-8723-42fe-ae42-84fe38e9ac3f.png"
mode="aspectFill"
/>
<View className="bg_overlay"></View>
</View>
{/* 主要内容 */}
<View className="main_content">
{/* 品牌区域 */}
<View className="brand_section">
<View className="logo_container" >
</View>
<View className="slogan_container">
</View>
</View>
{/* 登录按钮区域 */}
<View className="login_section">
{/* 微信快捷登录 */}
<Button
className={`login_button wechat_button ${is_loading ? 'loading' : ''}`}
openType="getPhoneNumber"
onGetPhoneNumber={handle_wechat_login}
disabled={is_loading}
>
<View className="wechat_icon">
<Image className="wechat_logo" src={require('../../../static/login/wechat_icon.svg')} />
</View>
<Text className="button_text">
{is_loading ? '登录中...' : '微信快捷登录'}
</Text>
</Button>
{/* 手机号验证码登录 */}
<Button
className="login_button phone_button"
onClick={handle_phone_login}
>
<View className="phone_icon">
<Image className="phone_logo" src={require('../../../static/login/phone_icon.svg')} />
</View>
<Text className="button_text"></Text>
</Button>
{/* 用户协议复选框 */}
<View className="terms_checkbox_section">
<View className="checkbox_container" onClick={handle_toggle_terms}>
<View className={`checkbox ${agree_terms ? 'checked' : ''}`}>
{agree_terms && <View className="checkmark"></View>}
</View>
</View>
<View className="terms_text_container">
<Text className="terms_text"></Text>
<Text
className="terms_link"
onClick={() => handle_view_terms('terms')}
>
</Text>
<Text
className="terms_link"
onClick={() => handle_view_terms('binding')}
>
</Text>
<Text
className="terms_link"
onClick={() => handle_view_terms('privacy')}
>
</Text>
</View>
</View>
</View>
</View>
{/* 底部条款浮层遮罩 */}
{show_terms_layer && (
<View className="terms_overlay" onClick={handle_overlay_click}>
{/* 底部条款浮层 */}
<View className="terms_float_layer" onClick={handle_layer_click}>
{/* 浮层标题 */}
<View className="float_title">
<Text className="title_text"></Text>
</View>
{/* 条款列表 */}
<View className="terms_list">
<Text
className="terms_item"
onClick={() => handle_view_terms('terms')}
>
</Text>
<Text
className="terms_item"
onClick={() => handle_view_terms('binding')}
>
</Text>
<Text
className="terms_item"
onClick={() => handle_view_terms('privacy')}
>
</Text>
</View>
{/* 同意按钮 */}
<Button
className={`agree_button ${agree_terms ? 'agreed' : ''}`}
onClick={handle_agree_terms}
>
{agree_terms ? '已同意' : '同意并继续'}
</Button>
</View>
</View>
)}
</View>
);
};
export default LoginPage;