小程序前端接入微信登录与环境配置
This commit is contained in:
@@ -3,6 +3,9 @@ module.exports = {
|
|||||||
NODE_ENV: '"development"'
|
NODE_ENV: '"development"'
|
||||||
},
|
},
|
||||||
defineConstants: {
|
defineConstants: {
|
||||||
|
__APP_ENV__: '"development"',
|
||||||
|
// Local backend for daily development.
|
||||||
|
__API_BASE_URL__: '"http://192.168.101.78:8001"'
|
||||||
},
|
},
|
||||||
mini: {},
|
mini: {},
|
||||||
h5: {}
|
h5: {}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
module.exports = {
|
const config = {
|
||||||
projectName: 'banban-mini',
|
projectName: 'banban-mini',
|
||||||
date: '2025-3-3',
|
date: '2025-3-3',
|
||||||
designWidth: 750,
|
designWidth: 750,
|
||||||
@@ -60,3 +60,12 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = function (merge) {
|
||||||
|
const envConfig =
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? require('./dev')
|
||||||
|
: require('./prod')
|
||||||
|
|
||||||
|
return merge({}, config, envConfig)
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ module.exports = {
|
|||||||
NODE_ENV: '"production"'
|
NODE_ENV: '"production"'
|
||||||
},
|
},
|
||||||
defineConstants: {
|
defineConstants: {
|
||||||
|
__APP_ENV__: '"production"',
|
||||||
|
// Replace with the production backend before publishing a release build.
|
||||||
|
__API_BASE_URL__: '"http://192.168.101.78:8001"'
|
||||||
},
|
},
|
||||||
mini: {},
|
mini: {},
|
||||||
h5: {}
|
h5: {}
|
||||||
|
|||||||
14
banban-mini/src/config/env.ts
Normal file
14
banban-mini/src/config/env.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
declare const __APP_ENV__: 'development' | 'production'
|
||||||
|
declare const __API_BASE_URL__: string
|
||||||
|
|
||||||
|
export interface AppConfig {
|
||||||
|
appEnv: 'development' | 'production'
|
||||||
|
apiBaseUrl: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const APP_CONFIG: AppConfig = {
|
||||||
|
appEnv: __APP_ENV__,
|
||||||
|
apiBaseUrl: __API_BASE_URL__,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const API_BASE_URL = APP_CONFIG.apiBaseUrl
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { View, Text, Button } from '@tarojs/components'
|
import { View, Text, Button } from '@tarojs/components'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import { BASE_URL, request } from '@/services/api'
|
import { wechatLogin } from '@/services/auth'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
@@ -25,6 +25,9 @@ export default function Login() {
|
|||||||
const loginRes = await Taro.login()
|
const loginRes = await Taro.login()
|
||||||
const code = loginRes.code
|
const code = loginRes.code
|
||||||
console.log('[Login] Got code:', code ? 'yes' : 'no')
|
console.log('[Login] Got code:', code ? 'yes' : 'no')
|
||||||
|
if (!code) {
|
||||||
|
throw new Error('未获取到微信登录凭证')
|
||||||
|
}
|
||||||
|
|
||||||
// 2. 获取用户头像信息 (可选)
|
// 2. 获取用户头像信息 (可选)
|
||||||
let userInfo = null
|
let userInfo = null
|
||||||
@@ -41,48 +44,26 @@ export default function Login() {
|
|||||||
|
|
||||||
// 3. 调用后端登录接口 (微信登录)
|
// 3. 调用后端登录接口 (微信登录)
|
||||||
console.log('[Login] Step 3: Calling backend /auth/login...')
|
console.log('[Login] Step 3: Calling backend /auth/login...')
|
||||||
const res = await request<{ access_token: string; expires_in: number; user_id: number }>('/auth/login', {
|
const res = await wechatLogin({
|
||||||
method: 'POST',
|
code,
|
||||||
data: {
|
|
||||||
code: code, // 微信 code
|
|
||||||
nickname: userInfo?.nickName,
|
nickname: userInfo?.nickName,
|
||||||
avatar_url: userInfo?.avatarUrl
|
avatar_url: userInfo?.avatarUrl
|
||||||
}
|
|
||||||
})
|
})
|
||||||
console.log('[Login] Backend login success, user_id:', res.user_id)
|
console.log('[Login] Backend login success, user_id:', res.user_id)
|
||||||
|
|
||||||
// 4. 保存 token 和用户信息
|
// 4. 保存用户信息用于显示
|
||||||
console.log('[Login] Step 4: Saving token and user info...')
|
console.log('[Login] Step 4: Saving user info...')
|
||||||
Taro.setStorageSync('token', res.access_token)
|
|
||||||
Taro.setStorageSync('user_id', res.user_id)
|
|
||||||
Taro.setStorageSync('expires_in', res.expires_in)
|
|
||||||
|
|
||||||
// 保存用户信息用于显示
|
|
||||||
if (userInfo) {
|
if (userInfo) {
|
||||||
Taro.setStorageSync('userInfo', {
|
Taro.setStorageSync('userInfo', {
|
||||||
nickname: userInfo.nickName,
|
nickname: userInfo.nickName,
|
||||||
avatar_url: userInfo.avatarUrl
|
avatar_url: userInfo.avatarUrl
|
||||||
})
|
})
|
||||||
}
|
} else {
|
||||||
|
Taro.removeStorageSync('userInfo')
|
||||||
// 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()
|
Taro.hideLoading()
|
||||||
console.log('[Login] Step 6: Login complete, showing success toast')
|
console.log('[Login] Step 5: Login complete, showing success toast')
|
||||||
Taro.showToast({ title: '登录成功', icon: 'success' })
|
Taro.showToast({ title: '登录成功', icon: 'success' })
|
||||||
|
|
||||||
// 6. 跳转到首页
|
// 6. 跳转到首页
|
||||||
@@ -95,7 +76,7 @@ export default function Login() {
|
|||||||
Taro.hideLoading()
|
Taro.hideLoading()
|
||||||
console.error('[Login] Login failed:', err)
|
console.error('[Login] Login failed:', err)
|
||||||
|
|
||||||
// 如果是 401 错误,尝试通过创建新用户登录
|
// 401 通常表示微信 code 失效或已被使用,提示用户重试登录
|
||||||
if (err.status === 401) {
|
if (err.status === 401) {
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: '登录失败,请重试',
|
title: '登录失败,请重试',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
|
import { API_BASE_URL } from '@/config/env'
|
||||||
|
|
||||||
// const BASE_URL = 'http://175.24.73.253:8001' // 改为实际后端IP
|
const BASE_URL = API_BASE_URL
|
||||||
const BASE_URL = 'http://127.0.0.1:8001'
|
|
||||||
|
|
||||||
class ApiError extends Error {
|
class ApiError extends Error {
|
||||||
constructor(public status: number, message: string) {
|
constructor(public status: number, message: string) {
|
||||||
|
|||||||
@@ -1,4 +1,19 @@
|
|||||||
import { request, BASE_URL } from './api'
|
import Taro from '@tarojs/taro'
|
||||||
|
|
||||||
|
import { request } from './api'
|
||||||
|
|
||||||
|
export interface WechatLoginPayload {
|
||||||
|
code: string
|
||||||
|
nickname?: string
|
||||||
|
avatar_url?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LoginSession {
|
||||||
|
access_token: string
|
||||||
|
token_type: string
|
||||||
|
expires_in: number
|
||||||
|
user_id: number
|
||||||
|
}
|
||||||
|
|
||||||
export interface Parent {
|
export interface Parent {
|
||||||
user_id: number
|
user_id: number
|
||||||
@@ -11,22 +26,18 @@ export interface Parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 微信登录
|
// 微信登录
|
||||||
export async function wechatLogin(code: string): Promise<{ token: string; user_id: number }> {
|
export async function wechatLogin(data: WechatLoginPayload): Promise<LoginSession> {
|
||||||
// TODO: 实现微信登录 - 通过 code 换取 openid,然后调用后端
|
const session = await request<LoginSession>('/auth/login', {
|
||||||
// 这里先返回 mock 数据
|
method: 'POST',
|
||||||
const mockParent: Parent = {
|
data,
|
||||||
user_id: 1,
|
})
|
||||||
openid: 'mock_openid_' + code,
|
|
||||||
nickname: '微信用户',
|
|
||||||
status: 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存模拟 token
|
Taro.setStorageSync('token', session.access_token)
|
||||||
const token = 'mock_token_' + Date.now()
|
Taro.setStorageSync('token_type', session.token_type)
|
||||||
Taro.setStorageSync('token', token)
|
Taro.setStorageSync('user_id', session.user_id)
|
||||||
Taro.setStorageSync('user_id', mockParent.user_id)
|
Taro.setStorageSync('expires_in', session.expires_in)
|
||||||
|
|
||||||
return { token, user_id: mockParent.user_id }
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建家长
|
// 创建家长
|
||||||
@@ -66,7 +77,9 @@ export function getToken(): string {
|
|||||||
// 清除 token
|
// 清除 token
|
||||||
export function clearToken(): void {
|
export function clearToken(): void {
|
||||||
Taro.removeStorageSync('token')
|
Taro.removeStorageSync('token')
|
||||||
|
Taro.removeStorageSync('token_type')
|
||||||
Taro.removeStorageSync('user_id')
|
Taro.removeStorageSync('user_id')
|
||||||
|
Taro.removeStorageSync('expires_in')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前用户ID
|
// 获取当前用户ID
|
||||||
|
|||||||
Reference in New Issue
Block a user