Files
happy-life-star/web/src/composables/useAuth.ts
T

262 lines
5.6 KiB
TypeScript

/**
* 认证相关组合式函数
*/
import { ref, computed } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useAuthStore } from '@/stores/auth'
import AuthService from '@/services/auth'
import type { LoginRequest, RegisterRequest, CaptchaResponse } from '@/types/auth'
/**
* 使用认证功能
*/
export const useAuth = () => {
const router = useRouter()
const authStore = useAuthStore()
// 加载状态
const loading = ref(false)
// 验证码相关
const captchaData = ref<CaptchaResponse | null>(null)
const captchaImage = computed(() =>
captchaData.value ? `data:image/png;base64,${captchaData.value.captchaImage}` : ''
)
/**
* 获取验证码
*/
const getCaptcha = async () => {
try {
const response = await AuthService.getCaptcha()
captchaData.value = response
return response
} catch (error) {
console.error('获取验证码失败:', error)
ElMessage.error('获取验证码失败')
throw error
}
}
/**
* 刷新验证码
*/
const refreshCaptcha = async () => {
return getCaptcha()
}
/**
* 登录
*/
const login = async (loginData: LoginRequest) => {
try {
loading.value = true
const success = await authStore.login(loginData)
if (success) {
ElMessage.success('登录成功')
return true
}
return false
} catch (error: any) {
console.error('登录失败:', error)
ElMessage.error(error.message || '登录失败')
return false
} finally {
loading.value = false
}
}
/**
* 注册
*/
const register = async (registerData: RegisterRequest) => {
try {
loading.value = true
const success = await authStore.register(registerData)
if (success) {
ElMessage.success('注册成功')
return true
}
return false
} catch (error: any) {
console.error('注册失败:', error)
ElMessage.error(error.message || '注册失败')
return false
} finally {
loading.value = false
}
}
/**
* 登出
*/
const logout = async () => {
try {
await authStore.logout()
router.push('/login')
} catch (error) {
console.error('登出失败:', error)
}
}
/**
* 检查账号是否存在
*/
const checkAccountExists = async (account: string) => {
if (!account || !/^[a-zA-Z0-9_]{4,20}$/.test(account)) {
return false
}
try {
return await AuthService.checkAccountExists(account)
} catch (error) {
console.error('检查账号失败:', error)
return false
}
}
/**
* 检查邮箱是否存在
*/
const checkEmailExists = async (email: string) => {
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
return false
}
try {
return await AuthService.checkEmailExists(email)
} catch (error) {
console.error('检查邮箱失败:', error)
return false
}
}
/**
* 检查手机号是否存在
*/
const checkPhoneExists = async (phone: string) => {
if (!phone || !/^1[3-9]\d{9}$/.test(phone)) {
return false
}
try {
return await AuthService.checkPhoneExists(phone)
} catch (error) {
console.error('检查手机号失败:', error)
return false
}
}
return {
// 状态
loading,
captchaData,
captchaImage,
// 计算属性
isLoggedIn: authStore.isLoggedIn,
userInfo: authStore.userInfo,
// 方法
getCaptcha,
refreshCaptcha,
login,
register,
logout,
checkAccountExists,
checkEmailExists,
checkPhoneExists
}
}
/**
* 使用表单验证
*/
export const useFormValidation = () => {
/**
* 账号验证规则
*/
const validateAccount = (rule: any, value: string, callback: any) => {
if (!value) {
callback(new Error('请输入账号'))
return
}
if (!/^[a-zA-Z0-9_]{4,20}$/.test(value)) {
callback(new Error('账号只能包含字母、数字和下划线,长度4-20位'))
return
}
callback()
}
/**
* 密码验证规则
*/
const validatePassword = (rule: any, value: string, callback: any) => {
if (!value) {
callback(new Error('请输入密码'))
return
}
if (value.length < 6 || value.length > 20) {
callback(new Error('密码长度必须在6-20位之间'))
return
}
callback()
}
/**
* 确认密码验证规则
*/
const validateConfirmPassword = (password: string) => {
return (rule: any, value: string, callback: any) => {
if (!value) {
callback(new Error('请再次输入密码'))
return
}
if (value !== password) {
callback(new Error('两次输入的密码不一致'))
return
}
callback()
}
}
/**
* 邮箱验证规则
*/
const validateEmail = (rule: any, value: string, callback: any) => {
if (!value) {
callback(new Error('请输入邮箱地址'))
return
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!emailRegex.test(value)) {
callback(new Error('请输入正确的邮箱格式'))
return
}
callback()
}
/**
* 手机号验证规则
*/
const validatePhone = (rule: any, value: string, callback: any) => {
if (value && !/^1[3-9]\d{9}$/.test(value)) {
callback(new Error('请输入正确的手机号格式'))
return
}
callback()
}
return {
validateAccount,
validatePassword,
validateConfirmPassword,
validateEmail,
validatePhone
}
}