feat(banban): add standalone entry and mini app base wiring
This commit is contained in:
@@ -5,7 +5,7 @@ module.exports = {
|
|||||||
defineConstants: {
|
defineConstants: {
|
||||||
__APP_ENV__: '"development"',
|
__APP_ENV__: '"development"',
|
||||||
// Update this to your LAN backend when testing on a real device.
|
// Update this to your LAN backend when testing on a real device.
|
||||||
__API_BASE_URL__: '"http://192.168.101.86:8001"',
|
__API_BASE_URL__: '"http://192.168.10.36:8001"',
|
||||||
},
|
},
|
||||||
mini: {},
|
mini: {},
|
||||||
h5: {}
|
h5: {}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ module.exports = {
|
|||||||
defineConstants: {
|
defineConstants: {
|
||||||
__APP_ENV__: '"production"',
|
__APP_ENV__: '"production"',
|
||||||
// Replace with the production backend before release builds.
|
// Replace with the production backend before release builds.
|
||||||
__API_BASE_URL__: '"http://192.168.101.86:8001"',
|
__API_BASE_URL__: '"http://192.168.10.36:8001"',
|
||||||
},
|
},
|
||||||
mini: {},
|
mini: {},
|
||||||
h5: {}
|
h5: {}
|
||||||
|
|||||||
@@ -62,9 +62,11 @@ export default function Login() {
|
|||||||
}, 300)
|
}, 300)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('[login] failed:', error)
|
console.error('[login] failed:', error)
|
||||||
Taro.showToast({
|
const message = String(error?.message || '登录失败,请重试')
|
||||||
title: error?.message || '登录失败,请重试',
|
Taro.showModal({
|
||||||
icon: 'none',
|
title: '登录失败',
|
||||||
|
content: message,
|
||||||
|
showCancel: false,
|
||||||
})
|
})
|
||||||
} finally {
|
} finally {
|
||||||
Taro.hideLoading()
|
Taro.hideLoading()
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class ApiError extends Error {
|
|||||||
|
|
||||||
function getErrorDetail(data: any): string {
|
function getErrorDetail(data: any): string {
|
||||||
if (!data) return 'Request failed'
|
if (!data) return 'Request failed'
|
||||||
|
if (typeof data.errMsg === 'string') return data.errMsg
|
||||||
if (typeof data.detail === 'string') return data.detail
|
if (typeof data.detail === 'string') return data.detail
|
||||||
if (Array.isArray(data.detail)) {
|
if (Array.isArray(data.detail)) {
|
||||||
return data.detail.map((item: any) => String(item?.msg || item)).join('; ')
|
return data.detail.map((item: any) => String(item?.msg || item)).join('; ')
|
||||||
@@ -30,6 +31,8 @@ async function request<T>(
|
|||||||
} = {}
|
} = {}
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const token = getToken()
|
const token = getToken()
|
||||||
|
const requestUrl = `${BASE_URL}${url}`
|
||||||
|
const requestMethod = options.method || 'GET'
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
...options.headers,
|
...options.headers,
|
||||||
@@ -41,22 +44,19 @@ async function request<T>(
|
|||||||
let response
|
let response
|
||||||
try {
|
try {
|
||||||
response = await Taro.request({
|
response = await Taro.request({
|
||||||
url: `${BASE_URL}${url}`,
|
url: requestUrl,
|
||||||
method: options.method || 'GET',
|
method: requestMethod,
|
||||||
data: options.data,
|
data: options.data,
|
||||||
header: headers,
|
header: headers,
|
||||||
timeout: REQUEST_TIMEOUT_MS,
|
timeout: REQUEST_TIMEOUT_MS,
|
||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const message = String(error?.errMsg || error?.message || '')
|
const message = String(error?.errMsg || error?.message || 'request:fail')
|
||||||
const detail = message.includes('timeout')
|
throw new ApiError(0, message)
|
||||||
? '请求超时,请检查后端服务是否可访问'
|
|
||||||
: '网络请求失败,请检查后端地址和网络连接'
|
|
||||||
throw new ApiError(0, detail)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.statusCode === 401) {
|
if (response.statusCode === 401) {
|
||||||
handleUnauthorized({ redirect: !url.startsWith('/auth/') })
|
handleUnauthorized({ redirect: !url.startsWith('/banban/auth/') })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.statusCode >= 400) {
|
if (response.statusCode >= 400) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export interface Parent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function wechatLogin(data: WechatLoginPayload): Promise<LoginSession> {
|
export async function wechatLogin(data: WechatLoginPayload): Promise<LoginSession> {
|
||||||
const session = await request<LoginSession>('/auth/login', {
|
const session = await request<LoginSession>('/banban/auth/login', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data,
|
data,
|
||||||
})
|
})
|
||||||
@@ -39,14 +39,14 @@ export async function wechatLogin(data: WechatLoginPayload): Promise<LoginSessio
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getParent(userId: number): Promise<Parent> {
|
export async function getParent(userId: number): Promise<Parent> {
|
||||||
return request<Parent>(`/parents/${userId}`)
|
return request<Parent>(`/banban/parents/${userId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateParent(
|
export async function updateParent(
|
||||||
userId: number,
|
userId: number,
|
||||||
data: { nickname?: string; avatar_url?: string; phone?: string }
|
data: { nickname?: string; avatar_url?: string; phone?: string }
|
||||||
): Promise<Parent> {
|
): Promise<Parent> {
|
||||||
return request<Parent>(`/parents/${userId}`, {
|
return request<Parent>(`/banban/parents/${userId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
data,
|
data,
|
||||||
})
|
})
|
||||||
|
|||||||
61
talkingq-url/banban_main.py
Normal file
61
talkingq-url/banban_main.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import os
|
||||||
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
|
from fastapi import APIRouter, FastAPI
|
||||||
|
|
||||||
|
from api.assets import configure_static_assets
|
||||||
|
from banban.middleware.auth import install_auth_middleware
|
||||||
|
from banban.middleware.request_log import install_request_logging_middleware
|
||||||
|
from banban.routers.bindings import router as bindings_router
|
||||||
|
from banban.routers.children import router as children_router
|
||||||
|
from banban.routers.device_im import router as device_im_router
|
||||||
|
from banban.routers.devices import router as devices_router
|
||||||
|
from banban.routers.im import router as im_router
|
||||||
|
from banban.routers.parents import router as parents_router
|
||||||
|
from banban.routers.wechat_auth import router as wechat_auth_router
|
||||||
|
from database.connection import get_db_manager
|
||||||
|
from initialization import init_directories
|
||||||
|
from utils.logger import session_logger
|
||||||
|
|
||||||
|
|
||||||
|
banban_router = APIRouter(prefix="/banban")
|
||||||
|
banban_router.include_router(wechat_auth_router, tags=["banban-auth"])
|
||||||
|
banban_router.include_router(bindings_router, tags=["banban-bindings"])
|
||||||
|
banban_router.include_router(children_router, tags=["banban-children"])
|
||||||
|
banban_router.include_router(devices_router, tags=["banban-devices"])
|
||||||
|
banban_router.include_router(device_im_router, tags=["banban-device-im"])
|
||||||
|
banban_router.include_router(im_router, tags=["banban-im"])
|
||||||
|
banban_router.include_router(parents_router, tags=["banban-parents"])
|
||||||
|
|
||||||
|
|
||||||
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
del app
|
||||||
|
worker_id = os.environ.get("UVICORN_WID", "0")
|
||||||
|
is_main_process = worker_id == "0"
|
||||||
|
db_manager = None
|
||||||
|
|
||||||
|
if is_main_process:
|
||||||
|
session_logger.system_info("startup", "banban standalone API starting")
|
||||||
|
|
||||||
|
init_directories()
|
||||||
|
db_manager = await get_db_manager()
|
||||||
|
|
||||||
|
if is_main_process:
|
||||||
|
session_logger.system_info("startup", "banban standalone API ready")
|
||||||
|
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
if db_manager is not None:
|
||||||
|
await db_manager.close()
|
||||||
|
if is_main_process:
|
||||||
|
session_logger.system_info("shutdown", "banban standalone API stopped")
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI(lifespan=lifespan)
|
||||||
|
|
||||||
|
configure_static_assets(app)
|
||||||
|
install_request_logging_middleware(app)
|
||||||
|
install_auth_middleware(app)
|
||||||
|
app.include_router(banban_router)
|
||||||
Reference in New Issue
Block a user