新增小程序后端代码,包括数据库、路由、服务层等。

小程序前后端打通,包括登录、注册、绑定设备、查询绑定信息,修改小朋友名称等功能。
This commit is contained in:
HycJack
2026-04-13 01:54:57 +08:00
parent 33715373b0
commit a22fcafea9
46 changed files with 3713 additions and 268 deletions

View File

@@ -1,51 +1,118 @@
import { View, Text, Button } from '@tarojs/components'
import { useEffect } from 'react'
import Taro from '@tarojs/taro'
import { BASE_URL, request } from '@/services/api'
import './index.scss'
export default function Login() {
useEffect(() => {
// 检查是否已登录
const isLoggedIn = Taro.getStorageSync('isLoggedIn')
if (isLoggedIn) {
// 已登录,跳转到首页
console.log('[Login] Page mounted, checking token...')
const token = Taro.getStorageSync('token')
console.log('[Login] Token exists:', !!token)
if (token) {
console.log('[Login] Already logged in, redirecting to device page')
Taro.reLaunch({ url: '/pages/device/index' })
}
}, [])
const handleLogin = () => {
Taro.showLoading({ title: '登录中...' })
// 调用微信登录
Taro.login({
success: (loginRes) => {
console.log('微信登录成功:', loginRes)
// 模拟后端验证 - 实际项目中需要将code发送到服务器
// 这里假设登录成功
Taro.setStorageSync('isLoggedIn', true)
Taro.setStorageSync('userInfo', {
nickName: '微信家长',
avatarUrl: '',
isAdmin: true,
openid: loginRes.code
const doWeChatLogin = async () => {
try {
console.log('[Login] Starting WeChat login...')
Taro.showLoading({ title: '登录中...' })
// 1. 调用微信登录获取 code
console.log('[Login] Step 1: Calling Taro.login()...')
const loginRes = await Taro.login()
const code = loginRes.code
console.log('[Login] Got code:', code ? 'yes' : 'no')
// 2. 获取用户头像信息 (可选)
let userInfo = null
try {
console.log('[Login] Step 2: Calling Taro.getUserProfile()...')
const profileRes = await Taro.getUserProfile({
desc: '用于完善用户资料'
})
Taro.hideLoading()
// 登录成功后跳转到首页
userInfo = profileRes.userInfo
console.log('[Login] Got userInfo:', !!userInfo)
} catch (e) {
console.log('[Login] getUserProfile failed (expected if user denied):', e)
}
// 3. 调用后端登录接口 (微信登录)
console.log('[Login] Step 3: Calling backend /auth/login...')
const res = await request<{ access_token: string; expires_in: number; user_id: number }>('/auth/login', {
method: 'POST',
data: {
code: code, // 微信 code
nickname: userInfo?.nickName,
avatar_url: userInfo?.avatarUrl
}
})
console.log('[Login] Backend login success, user_id:', res.user_id)
// 4. 保存 token 和用户信息
console.log('[Login] Step 4: Saving token and user info...')
Taro.setStorageSync('token', res.access_token)
Taro.setStorageSync('user_id', res.user_id)
Taro.setStorageSync('expires_in', res.expires_in)
// 保存用户信息用于显示
if (userInfo) {
Taro.setStorageSync('userInfo', {
nickname: userInfo.nickName,
avatar_url: userInfo.avatarUrl
})
}
// 5. 如果获取到了用户信息,发送到后端更新
if (userInfo) {
console.log('[Login] Step 5: Updating user profile...')
try {
await request(`/parents/${res.user_id}`, {
method: 'PATCH',
data: {
nickname: userInfo.nickName,
avatar_url: userInfo.avatarUrl
}
})
} catch (e) {
console.log('[Login] Update user profile failed:', e)
}
}
Taro.hideLoading()
console.log('[Login] Step 6: Login complete, showing success toast')
Taro.showToast({ title: '登录成功', icon: 'success' })
// 6. 跳转到首页
console.log('[Login] Redirecting to /pages/device/index...')
setTimeout(() => {
Taro.reLaunch({ url: '/pages/device/index' })
},
fail: (err) => {
Taro.hideLoading()
console.error('微信登录失败:', err)
}, 500)
} catch (err: any) {
Taro.hideLoading()
console.error('[Login] Login failed:', err)
// 如果是 401 错误,尝试通过创建新用户登录
if (err.status === 401) {
Taro.showToast({
title: '登录失败,请重试',
icon: 'none'
})
} else {
Taro.showToast({
title: err.message || '网络错误,请重试',
icon: 'none'
})
}
})
}
}
const handleLogin = () => {
console.log('Button clicked, starting login...')
doWeChatLogin()
}
return (
@@ -77,8 +144,7 @@ export default function Login() {
<View className='login-btn-wrapper'>
<Button
className='login-btn'
openType='getUserInfo'
onGetUserInfo={handleLogin}
onClick={handleLogin}
>
<Text className='btn-icon'>🌐</Text>
<Text className='btn-text'></Text>