From d21ff858073cb130c388ef1157675c5dfe8bd911 Mon Sep 17 00:00:00 2001 From: ChengCan <783785929@qq.com> Date: Thu, 30 Apr 2026 00:57:35 +0800 Subject: [PATCH] feat(banban): add standalone entry and mini app base wiring --- banban-mini/config/dev.js | 2 +- banban-mini/config/prod.js | 2 +- banban-mini/src/pages/login/index.tsx | 8 ++-- banban-mini/src/services/api.ts | 16 +++---- banban-mini/src/services/auth.ts | 6 +-- talkingq-url/banban_main.py | 61 +++++++++++++++++++++++++++ 6 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 talkingq-url/banban_main.py diff --git a/banban-mini/config/dev.js b/banban-mini/config/dev.js index 7dcc8a3..d5d5438 100644 --- a/banban-mini/config/dev.js +++ b/banban-mini/config/dev.js @@ -5,7 +5,7 @@ module.exports = { defineConstants: { __APP_ENV__: '"development"', // 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: {}, h5: {} diff --git a/banban-mini/config/prod.js b/banban-mini/config/prod.js index a0664a7..c1a10af 100644 --- a/banban-mini/config/prod.js +++ b/banban-mini/config/prod.js @@ -5,7 +5,7 @@ module.exports = { defineConstants: { __APP_ENV__: '"production"', // 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: {}, h5: {} diff --git a/banban-mini/src/pages/login/index.tsx b/banban-mini/src/pages/login/index.tsx index f0b98c8..1bc9834 100644 --- a/banban-mini/src/pages/login/index.tsx +++ b/banban-mini/src/pages/login/index.tsx @@ -62,9 +62,11 @@ export default function Login() { }, 300) } catch (error: any) { console.error('[login] failed:', error) - Taro.showToast({ - title: error?.message || '登录失败,请重试', - icon: 'none', + const message = String(error?.message || '登录失败,请重试') + Taro.showModal({ + title: '登录失败', + content: message, + showCancel: false, }) } finally { Taro.hideLoading() diff --git a/banban-mini/src/services/api.ts b/banban-mini/src/services/api.ts index bda8f4d..c6ff480 100644 --- a/banban-mini/src/services/api.ts +++ b/banban-mini/src/services/api.ts @@ -13,6 +13,7 @@ class ApiError extends Error { function getErrorDetail(data: any): string { if (!data) return 'Request failed' + if (typeof data.errMsg === 'string') return data.errMsg if (typeof data.detail === 'string') return data.detail if (Array.isArray(data.detail)) { return data.detail.map((item: any) => String(item?.msg || item)).join('; ') @@ -30,6 +31,8 @@ async function request( } = {} ): Promise { const token = getToken() + const requestUrl = `${BASE_URL}${url}` + const requestMethod = options.method || 'GET' const headers: Record = { 'Content-Type': 'application/json', ...options.headers, @@ -41,22 +44,19 @@ async function request( let response try { response = await Taro.request({ - url: `${BASE_URL}${url}`, - method: options.method || 'GET', + url: requestUrl, + method: requestMethod, data: options.data, header: headers, timeout: REQUEST_TIMEOUT_MS, }) } catch (error: any) { - const message = String(error?.errMsg || error?.message || '') - const detail = message.includes('timeout') - ? '请求超时,请检查后端服务是否可访问' - : '网络请求失败,请检查后端地址和网络连接' - throw new ApiError(0, detail) + const message = String(error?.errMsg || error?.message || 'request:fail') + throw new ApiError(0, message) } if (response.statusCode === 401) { - handleUnauthorized({ redirect: !url.startsWith('/auth/') }) + handleUnauthorized({ redirect: !url.startsWith('/banban/auth/') }) } if (response.statusCode >= 400) { diff --git a/banban-mini/src/services/auth.ts b/banban-mini/src/services/auth.ts index 9b2ef9a..cc09b57 100644 --- a/banban-mini/src/services/auth.ts +++ b/banban-mini/src/services/auth.ts @@ -30,7 +30,7 @@ export interface Parent { } export async function wechatLogin(data: WechatLoginPayload): Promise { - const session = await request('/auth/login', { + const session = await request('/banban/auth/login', { method: 'POST', data, }) @@ -39,14 +39,14 @@ export async function wechatLogin(data: WechatLoginPayload): Promise { - return request(`/parents/${userId}`) + return request(`/banban/parents/${userId}`) } export async function updateParent( userId: number, data: { nickname?: string; avatar_url?: string; phone?: string } ): Promise { - return request(`/parents/${userId}`, { + return request(`/banban/parents/${userId}`, { method: 'PATCH', data, }) diff --git a/talkingq-url/banban_main.py b/talkingq-url/banban_main.py new file mode 100644 index 0000000..844d72a --- /dev/null +++ b/talkingq-url/banban_main.py @@ -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)