添加登录和后端校验

完成后端设计(未在本仓库体现),通过安全的手段完成了登录鉴权
This commit is contained in:
2026-08-06 16:27:36 +08:00
commit b19a56003f
286 changed files with 51650 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
import { useState, useEffect } from 'react'
import Taro from '@tarojs/taro'
export interface SafeAreaInfo {
statusBarHeight: number
menuButtonTop: number
menuButtonHeight: number
capsuleRight: number
safeInsetTop: number
safeInsetBottom: number
/** 建议给 .page-header 的 paddingTop 像素值 */
headerPaddingTop: number
/** 建议给 .back-btn 的 paddingTop 像素值 */
backBtnPaddingTop: number
}
let cached: SafeAreaInfo | null = null
export function useSafeArea(): SafeAreaInfo {
const [info, setInfo] = useState<SafeAreaInfo>(cached ?? {
statusBarHeight: 20,
menuButtonTop: 26,
menuButtonHeight: 32,
capsuleRight: 368,
safeInsetTop: 20,
safeInsetBottom: 0,
headerPaddingTop: 66,
backBtnPaddingTop: 20
})
useEffect(() => {
if (cached) {
setInfo(cached)
return
}
try {
const sys = Taro.getSystemInfoSync()
const mb = Taro.getMenuButtonBoundingClientRect()
const statusBarHeight = sys.statusBarHeight || 20
const menuButtonTop = mb.top ?? statusBarHeight + 4
const menuButtonHeight = mb.height ?? 32
const capsuleRight = mb.right ?? (sys.windowWidth - 7)
const safeInsetTop = sys.safeArea?.top ?? statusBarHeight
const safeInsetBottom = sys.safeAreaInsetBottom ?? (sys.screenHeight - (sys.safeArea?.bottom ?? sys.screenHeight))
// header 需要排在胶囊按钮下面,稍微留点空隙
const headerPaddingTop = Math.max(menuButtonTop + menuButtonHeight + 6, statusBarHeight + 44)
// back-btn 需要和状态栏底部对齐再加一点
const backBtnPaddingTop = Math.max(statusBarHeight, menuButtonTop - 4)
const data: SafeAreaInfo = {
statusBarHeight,
menuButtonTop,
menuButtonHeight,
capsuleRight,
safeInsetTop,
safeInsetBottom,
headerPaddingTop,
backBtnPaddingTop
}
cached = data
setInfo(data)
} catch {
// fallback 不变
}
}, [])
return info
}
+39
View File
@@ -0,0 +1,39 @@
import { useCallback, useEffect } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
import { applyPageBackground } from '../utils/themeBackground'
export interface UseStatusBarOptions {
/** 顶部系统状态栏(iOS 时间/电量)文字颜色模式:
* - 'auto'(默认):跟随当前 App 主题,浅色黑字、深色白字
* - 'light':强制白字(顶部是深色图片/背景的页面用)
* - 'dark':强制黑字
*/
mode?: 'auto' | 'light' | 'dark'
}
/**
* 同步当前页面的 iOS 系统状态栏(时间、电量)文字颜色。
* 每个页面只调用一次,避免全局 Provider 与页面生命周期竞争写入。
*/
export function useStatusBar(resolvedTheme: 'light' | 'dark', options: UseStatusBarOptions = {}) {
const { mode = 'auto' } = options
const apply = useCallback(() => {
const isDarkText = mode === 'dark' || (mode === 'auto' && resolvedTheme === 'light')
const frontColor = isDarkText ? '#000000' : '#ffffff'
const bgColor = isDarkText ? '#ffffff' : '#1e1e2f'
Taro.setNavigationBarColor({ frontColor, backgroundColor: bgColor })
// 同步页面背景色,确保自定义导航区(状态栏下方、胶囊按钮区域)跟随主题,
// 避免深色模式下顶部残留白色条带。
// 注意:iOS 上顶部/底部窗口背景需分别用 backgroundColorTop / Bottom 指定,
// 仅设置 backgroundColor 在 iOS 上无法覆盖顶部导航区。
applyPageBackground(resolvedTheme, bgColor)
}, [mode, resolvedTheme])
// 主题切换后立即更新当前页面。
useEffect(apply, [apply])
// 导航返回、切换 Tab 或从后台恢复后,以当前页面主题重新覆盖原生默认值。
useDidShow(apply)
}
+8
View File
@@ -0,0 +1,8 @@
import { useContext } from 'react'
import { ThemeContext } from '../context/ThemeContext'
import type { ThemeMode } from '../utils/store'
export function useTheme(): [ThemeMode, (t: ThemeMode) => void] {
const ctx = useContext(ThemeContext)
return [ctx.theme, ctx.setTheme]
}