From be8eaae7c5e6cb04b547320f67fd07eca9043faf Mon Sep 17 00:00:00 2001 From: oneao Date: Thu, 6 Nov 2025 22:50:03 +0800 Subject: [PATCH] u --- .../base-app/src/app/(tabs)/_layout.tsx | 4 +- .../base-app/src/app/auth/login.tsx | 76 +++++---- .../base-app/src/app/auth/register.tsx | 60 +++---- .../src/components/common/ao/Button.tsx | 54 +++++++ .../src/components/common/ao/Checkbox.tsx | 50 ++++++ .../src/components/common/ao/index.ts | 4 + .../base-app/src/hooks/useFormValidation.ts | 90 +++++------ .../base-app/src/request/api/auth.ts | 10 ++ .../base-app/src/request/index.ts | 71 +++++++-- code/base-project/base-app/src/store/user.ts | 2 + .../base-app/src/types/global.d.ts | 1 + .../base-app/src/utils/runOnMain.ts | 8 - .../base-project/base-app/src/utils/toast.tsx | 82 ++-------- code/base-project/base-go-v2/.gitignore | 2 + .../base-go-v2/internal/api/auth/index.go | 6 +- .../internal/api/middleware/error.go | 150 +++++++++++++++--- .../base-go-v2/internal/db/query.go | 8 +- .../base-go-v2/internal/errs/error.go | 42 +++++ .../base-go-v2/internal/router/context.go | 33 ++++ .../base-go-v2/internal/router/router.go | 26 ++- .../logs/error/error-2025-11-06.log | 13 ++ .../base-go-v2/logs/info/info-2025-11-05.log | 9 ++ .../base-go-v2/logs/info/info-2025-11-06.log | 25 +++ .../base-go/internal/app/handle/test.go | 1 - 24 files changed, 595 insertions(+), 232 deletions(-) create mode 100644 code/base-project/base-app/src/components/common/ao/Button.tsx create mode 100644 code/base-project/base-app/src/components/common/ao/Checkbox.tsx delete mode 100644 code/base-project/base-app/src/utils/runOnMain.ts create mode 100644 code/base-project/base-go-v2/.gitignore create mode 100644 code/base-project/base-go-v2/internal/errs/error.go diff --git a/code/base-project/base-app/src/app/(tabs)/_layout.tsx b/code/base-project/base-app/src/app/(tabs)/_layout.tsx index 759ce90d..bafd2e05 100644 --- a/code/base-project/base-app/src/app/(tabs)/_layout.tsx +++ b/code/base-project/base-app/src/app/(tabs)/_layout.tsx @@ -1,10 +1,8 @@ import type { TabbarItem } from '@/components/custom/Tabbar' import CustomTabbar from '@/components/custom/Tabbar' -import { useToast } from '@/utils/toast' +import { toast } from '@/utils/toast' export default function TabsLayout() { - const toast = useToast() - const tabbarOptions: TabbarItem[] = [ { name: 'user', diff --git a/code/base-project/base-app/src/app/auth/login.tsx b/code/base-project/base-app/src/app/auth/login.tsx index 9550c01a..cd76ced3 100644 --- a/code/base-project/base-app/src/app/auth/login.tsx +++ b/code/base-project/base-app/src/app/auth/login.tsx @@ -1,41 +1,39 @@ -import { Lock, UserRound } from 'lucide-react-native' import { useState } from 'react' import { Image, Text, View } from 'react-native' -import { AForm, AFormItem, AInput } from '@/components/common/ao' +import { AButton, ACheckbox, AForm, AFormItem, AInput } from '@/components/common/ao' import { IconQq, IconWeixin, IconZhiwen } from '@/components/iconfont' -import { Button, ButtonText } from '@/components/ui/button' -import { - Checkbox, - CheckboxIcon, - CheckboxIndicator, - CheckboxLabel, -} from '@/components/ui/checkbox' import { Divider } from '@/components/ui/divider' - -import { CheckIcon } from '@/components/ui/icon' - +import useFormValidation from '@/hooks/useFormValidation' import alovaInstance from '@/request' -import { useToast } from '@/utils/toast' +import { toast } from '@/utils/toast' interface LoginForm { username: string password: string - rememberMe?: boolean + rememberMe: boolean socialType?: 'qq' | 'weixin' | 'fingerprint' } export default function AuthLogin() { - const toast = useToast() - const [form, setForm] = useState({ username: '', password: '', rememberMe: true, }) + const handleInputChange = (field: keyof LoginForm, value: string) => { setForm(prev => ({ ...prev, [field]: value })) } - const defaultLogin = () => { + + // 验证规则 + const rules = { + username: { required: true, message: '账号是必填项' }, + password: { required: true, message: '密码是必填项' }, + } + + const { isValid } = useFormValidation(form, rules) + + const loginDefault = () => { alovaInstance.Post('/auth/test', { title: 'foo', body: 'bar', @@ -49,6 +47,16 @@ export default function AuthLogin() { }) } + const loginQq = () => { + toast.show({ title: '功能待开发,请稍等. . .' }) + } + const loginWx = () => { + toast.show({ title: '功能待开发,请稍等. . .' }) + } + const loginZhiwen = () => { + toast.show({ title: '功能待开发,请稍等. . .' }) + } + return ( handleInputChange('username', text)} /> + - - setForm(prev => ({ ...prev, rememberMe: checked }))} - > - - - - 记住我 - + onChange={checked => setForm(prev => ({ ...prev, rememberMe: checked }))} + label="记住我" + /> - - 忘记密码? - + 忘记密码? - + + 登录 + - 社交账号 - - - - + + + - ) } diff --git a/code/base-project/base-app/src/app/auth/register.tsx b/code/base-project/base-app/src/app/auth/register.tsx index 2abe470e..dcb7b292 100644 --- a/code/base-project/base-app/src/app/auth/register.tsx +++ b/code/base-project/base-app/src/app/auth/register.tsx @@ -1,11 +1,12 @@ import type { AFormRef } from '@/components/common/ao' +import { useRouter } from 'expo-router' import { Lock, UserRound } from 'lucide-react-native' import { useRef, useState } from 'react' -import { Image, ScrollView, View } from 'react-native' -import { AForm, AFormItem, AInput } from '@/components/common/ao' -import { Button, ButtonSpinner, ButtonText } from '@/components/ui/button' -import { useToast } from '@/utils/toast' +import { Image, ScrollView, View } from 'react-native' +import { AButton, AForm, AFormItem, AInput } from '@/components/common/ao' +import { registerDefaultApi } from '@/request/api/auth' +import { toast } from '@/utils/toast' interface RegisterForm { username: string @@ -14,8 +15,8 @@ interface RegisterForm { } export default function AuthRegister() { + const router = useRouter() const scrollRef = useRef(null) - const toast = useToast() const [form, setForm] = useState({ username: '', @@ -29,14 +30,30 @@ export default function AuthRegister() { setForm(prev => ({ ...prev, [field]: value })) } - const handleRegister = () => { + const handleRegister = async () => { if (formRef.current?.validate()) { setLoading(true) - toast.show({ title: '校验通过,开始注册', action: 'success' }) - // 模拟注册过程 - setTimeout(() => { + + await registerDefaultApi({ + account: form.username, + password: form.password, + }).then((res) => { + if (res.isSuccess) { + console.log(res) + toast.show({ + title: '注册成功', + }) + // router.replace('/auth/login') + } + else { + toast.show({ + title: res.message || '注册失败', + }) + } + }).catch((_err) => { + }).finally(() => { setLoading(false) - }, 2000) + }) } } @@ -66,10 +83,7 @@ export default function AuthRegister() { val === form.password, message: '两次密码不一致', @@ -101,18 +115,10 @@ export default function AuthRegister() { - + + + 注册 + ) diff --git a/code/base-project/base-app/src/components/common/ao/Button.tsx b/code/base-project/base-app/src/components/common/ao/Button.tsx new file mode 100644 index 00000000..4973cbc1 --- /dev/null +++ b/code/base-project/base-app/src/components/common/ao/Button.tsx @@ -0,0 +1,54 @@ +import type { ViewStyle } from 'react-native' +// components/ui/CustomButton.tsx +import React from 'react' +import { + ButtonSpinner, + ButtonText, + Button as NativeButton, +} from '@/components/ui/button' + +interface CustomButtonProps { + children: React.ReactNode + onPress?: () => void + disabled?: boolean + loading?: boolean + className?: string + style?: ViewStyle + action?: 'primary' | 'secondary' | 'positive' | 'negative' | 'default' + variant?: 'solid' | 'outline' | 'link' + size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' +} + +const Button: React.FC = ({ + children, + onPress, + disabled = false, + loading = false, + className, + style, + action = 'primary', + variant = 'solid', + size = 'md', +}) => { + const isDisabled = disabled || loading + + return ( + + {loading && } + {children} + + ) +} + +export default Button diff --git a/code/base-project/base-app/src/components/common/ao/Checkbox.tsx b/code/base-project/base-app/src/components/common/ao/Checkbox.tsx new file mode 100644 index 00000000..fd18b4f8 --- /dev/null +++ b/code/base-project/base-app/src/components/common/ao/Checkbox.tsx @@ -0,0 +1,50 @@ +// components/ui/CustomCheckbox.tsx +import type { ViewStyle } from 'react-native' +import React from 'react' +import { + CheckboxIcon, + CheckboxIndicator, + CheckboxLabel, + Checkbox as NativeCheckbox, +} from '@/components/ui/checkbox' +import { CheckIcon } from '@/components/ui/icon' + +interface CustomCheckboxProps { + value?: string + isChecked: boolean + onChange: (checked: boolean) => void + label: React.ReactNode + className?: string + style?: ViewStyle + disabled?: boolean + icon?: React.ElementType +} + +const Checkbox: React.FC = ({ + value, + isChecked, + onChange, + label, + className, + style, + disabled, + icon, +}) => { + return ( + + + + + {label} + + ) +} + +export default Checkbox diff --git a/code/base-project/base-app/src/components/common/ao/index.ts b/code/base-project/base-app/src/components/common/ao/index.ts index c9ec8334..9f734aad 100644 --- a/code/base-project/base-app/src/components/common/ao/index.ts +++ b/code/base-project/base-app/src/components/common/ao/index.ts @@ -1,8 +1,12 @@ +import Button from './Button' +import Checkbox from './Checkbox' import Form, { FormRef } from './Form' import FormItem from './FormItem' import Input from './Input' export { + Button as AButton, + Checkbox as ACheckbox, Form as AForm, FormItem as AFormItem, FormRef as AFormRef, diff --git a/code/base-project/base-app/src/hooks/useFormValidation.ts b/code/base-project/base-app/src/hooks/useFormValidation.ts index 9605d215..9353d94a 100644 --- a/code/base-project/base-app/src/hooks/useFormValidation.ts +++ b/code/base-project/base-app/src/hooks/useFormValidation.ts @@ -1,67 +1,61 @@ -import { useEffect, useState } from 'react' +import { useMemo, useState } from 'react' -// 定义表单字段的验证规则类型 -interface ValidationRule { +export interface ValidationRule { required?: boolean pattern?: RegExp minLength?: number maxLength?: number - validator?: (value: string) => boolean // 自定义验证规则 - message?: string // 自定义消息 + validator?: (value: any) => boolean + message?: string } -// 定义返回的数据结构 -interface FormValidationResult { +export interface FormValidationResult { [key: string]: { isValid: boolean errorMessage: string } } -function useFormValidation(values: Record, rules: Record, autoValidate = false) { +export default function useFormValidation>( + values: T, + rules: { [K in keyof T]?: ValidationRule }, // <-- 可选字段,message 可选 +) { const [validationResults, setValidationResults] = useState({}) - const [isValid, setIsValid] = useState(true) // 用于保存整体表单是否有效 - // 验证逻辑 const validate = () => { const newValidationResults: FormValidationResult = {} for (const field in rules) { - const value = values[field] || '' - const fieldRules = rules[field] + const value = values[field] + const strValue = String(value ?? '') + const fieldRules = rules[field as keyof T] + if (!fieldRules) + continue + let isValid = true let errorMessage = '' + const getDefaultMessage = (type: string) => `${field} 是${type}` - // 默认错误消息的函数 - const getDefaultMessage = (type: string) => { - return `${field} 是${type}` - } - - // 验证 required - if (fieldRules.required && !value) { + if (fieldRules.required && (value === undefined || value === null || strValue === '')) { isValid = false errorMessage = fieldRules.message || getDefaultMessage('必填项') } - // 验证 pattern - if (isValid && fieldRules.pattern && !fieldRules.pattern.test(value)) { + if (isValid && fieldRules.pattern && !fieldRules.pattern.test(strValue)) { isValid = false errorMessage = fieldRules.message || '格式不正确' } - // 验证 minLength - if (isValid && fieldRules.minLength && value.length < fieldRules.minLength) { + if (isValid && fieldRules.minLength && strValue.length < fieldRules.minLength) { isValid = false errorMessage = fieldRules.message || `最少输入 ${fieldRules.minLength} 个字符` } - // 验证 maxLength - if (isValid && fieldRules.maxLength && value.length > fieldRules.maxLength) { + if (isValid && fieldRules.maxLength && strValue.length > fieldRules.maxLength) { isValid = false errorMessage = fieldRules.message || `最多输入 ${fieldRules.maxLength} 个字符` } - // 自定义验证 if (isValid && fieldRules.validator && !fieldRules.validator(value)) { isValid = false errorMessage = fieldRules.message || '自定义验证未通过' @@ -71,27 +65,31 @@ function useFormValidation(values: Record, rules: Record !result.isValid) - setIsValid(allValid) - - // 返回是否验证通过(返回true或false) - return allValid + return newValidationResults } - // 如果开启自动验证 - useEffect(() => { - if (autoValidate) { - validate() - } - }, [values, autoValidate]) + const isValid = useMemo(() => { + return Object.keys(rules).every((field) => { + const value = values[field as keyof T] + const strValue = String(value ?? '') + const fieldRules = rules[field as keyof T] + if (!fieldRules) + return true - return { - validationResults, - isValid, - validate, - } + if (fieldRules.required && (value === undefined || value === null || strValue === '')) + return false + if (fieldRules.pattern && !fieldRules.pattern.test(strValue)) + return false + if (fieldRules.minLength && strValue.length < fieldRules.minLength) + return false + if (fieldRules.maxLength && strValue.length > fieldRules.maxLength) + return false + if (fieldRules.validator && !fieldRules.validator(value)) + return false + + return true + }) + }, [values, rules]) + + return { validationResults, isValid, validate } } - -export default useFormValidation diff --git a/code/base-project/base-app/src/request/api/auth.ts b/code/base-project/base-app/src/request/api/auth.ts index e69de29b..57f4942e 100644 --- a/code/base-project/base-app/src/request/api/auth.ts +++ b/code/base-project/base-app/src/request/api/auth.ts @@ -0,0 +1,10 @@ +import alovaInstance from '../index' + +interface RegisterDefaultParams { + account: string + password: string +} + +export function registerDefaultApi(params: RegisterDefaultParams) { + return alovaInstance.Post>('/auth/register/default', params) +} diff --git a/code/base-project/base-app/src/request/index.ts b/code/base-project/base-app/src/request/index.ts index 8fcb7ae8..c8463a29 100644 --- a/code/base-project/base-app/src/request/index.ts +++ b/code/base-project/base-app/src/request/index.ts @@ -30,19 +30,22 @@ function isWhiteListed(url: string) { } const alovaInstance = createAlova({ - baseURL: 'http://192.168.1.136:8085/app', + baseURL: 'http://192.168.5.6:8085/app', requestAdapter: axiosRequestAdapter(), + timeout: 5000, responded: { onSuccess: async (response, method: Method) => { const resData = response.data as ResponseData - if (resData.code === HttpCode.Success) { - return resData.data + const result = { + ...resData, + isSuccess: resData.code === HttpCode.Success, } + console.log(resData) + // Access Token 失效 → 重新登录 if (resData.code === HttpCode.Unauthorized) { - console.log('===到这一步了===') router.replace('/auth/login') return } @@ -77,18 +80,61 @@ const alovaInstance = createAlova({ return } catch (err) { - console.log('===到这一步了===') router.replace('/auth/login') return Promise.reject(err) } } - // 其他错误 - return Promise.reject(resData.message || '请求失败') + return result }, - - onError: (error: AxiosError, method) => { - console.log(error.status) + onError: (error: AxiosError, _method) => { + switch (error.status) { + case 400: + toast.show({ + title: '请求错误,请检查输入参数', + }) + break + case 401: + toast.show({ + title: '未授权,请重新登录', + }) + break + case 403: + toast.show({ + title: '没有权限访问该资源', + }) + break + case 404: + toast.show({ + title: '请求丢失啦,请稍后再试!', + }) + break + case 500: + toast.show({ + title: '服务器出错啦,请稍后重试', + }) + break + case 502: + toast.show({ + title: '网关错误,请稍后重试', + }) + break + case 503: + toast.show({ + title: '服务暂不可用,请稍后再试', + }) + break + case 504: + toast.show({ + title: '网关超时,请稍后再试', + }) + break + default: + toast.show({ + title: `服务器出错啦,请稍后重试`, + }) + break + } return Promise.reject(error) }, }, @@ -98,10 +144,11 @@ const alovaInstance = createAlova({ if (!userStore.getState().isLoggedIn()) { toast.show({ - title: '尚未登录', + title: '尚未登录,请先登录', }) + router.replace('/auth/login') - return + return Promise.reject(new Error('未登录')) } method.config.headers.token = userStore.getState().userInfo?.token ?? '' diff --git a/code/base-project/base-app/src/store/user.ts b/code/base-project/base-app/src/store/user.ts index 9381a9e8..9e220419 100644 --- a/code/base-project/base-app/src/store/user.ts +++ b/code/base-project/base-app/src/store/user.ts @@ -27,6 +27,8 @@ const useUserStore = create()( }, ), ) + +// 在组件外使用 const userStore = useUserStore export { userStore, useUserStore } diff --git a/code/base-project/base-app/src/types/global.d.ts b/code/base-project/base-app/src/types/global.d.ts index 996114a6..36ca2dcc 100644 --- a/code/base-project/base-app/src/types/global.d.ts +++ b/code/base-project/base-app/src/types/global.d.ts @@ -6,6 +6,7 @@ declare global { code: number message: string data: T + isSuccess: boolean } interface UserInfo { diff --git a/code/base-project/base-app/src/utils/runOnMain.ts b/code/base-project/base-app/src/utils/runOnMain.ts deleted file mode 100644 index fc0479c1..00000000 --- a/code/base-project/base-app/src/utils/runOnMain.ts +++ /dev/null @@ -1,8 +0,0 @@ -// utils/runOnMain.ts -// ✅ 安全封装 runOnJS,屏蔽 deprecated 警告 -import { runOnJS as _runOnJS } from 'react-native-worklets' - -// 屏蔽类型定义中的 deprecated 提示 -export const runOnMain = ((fn: (...args: any[]) => void) => { - return _runOnJS(fn) -}) as typeof _runOnJS diff --git a/code/base-project/base-app/src/utils/toast.tsx b/code/base-project/base-app/src/utils/toast.tsx index 44675211..f8847655 100644 --- a/code/base-project/base-app/src/utils/toast.tsx +++ b/code/base-project/base-app/src/utils/toast.tsx @@ -1,5 +1,5 @@ import type { IToastProps } from '@gluestack-ui/core/lib/esm/toast/creator/types' -import React, { createContext, useContext, useRef } from 'react' +import React, { useEffect, useRef } from 'react' import { Toast, ToastDescription, ToastTitle, useToast as useGluestackToast } from '@/components/ui/toast' type ToastVariant = 'solid' | 'outline' @@ -9,29 +9,30 @@ interface ShowToastOptions extends IToastProps { title?: React.ReactNode description?: React.ReactNode variant?: ToastVariant - action?: ToastAction + type?: ToastAction } -// 创建全局 toast 实例 -let globalToast: any = null - -// 创建 Context 用于在组件内部使用 -const ToastContext = createContext | null>(null) +// 全局 toast 实例 +let globalToast: { + show: (options: ShowToastOptions) => string + close: (id: string) => void + closeAll: () => void + isActive: (id: string) => boolean +} | null = null export function ToastProviderWrapper({ children }: { children: React.ReactNode }) { const toast = useGluestackToast() const toastRef = useRef(toast) toastRef.current = toast - // 设置全局实例 - React.useEffect(() => { + useEffect(() => { globalToast = { show: (options: ShowToastOptions) => { const id = Math.random().toString() toast.show({ id, placement: options.placement ?? 'top', - duration: options.duration !== undefined ? options.duration : 3000, + duration: options.duration ?? 3000, avoidKeyboard: options.avoidKeyboard ?? false, containerStyle: options.containerStyle, onCloseComplete: options.onCloseComplete, @@ -41,7 +42,7 @@ export function ToastProviderWrapper({ children }: { children: React.ReactNode } {options.title && {options.title}} {options.description && {options.description}} @@ -60,60 +61,11 @@ export function ToastProviderWrapper({ children }: { children: React.ReactNode } } }, [toast]) - return ( - - {children} - - ) + return <>{children} } /** - * 自定义 Hook,用于 React 组件内部 - */ -export function useToast() { - const toast = useContext(ToastContext) - - if (!toast) { - throw new Error('useToast must be used within a ToastProviderWrapper') - } - - return { - show: (options: ShowToastOptions) => { - const id = Math.random().toString() - toast.show({ - id, - placement: options.placement ?? 'top', - duration: options.duration !== undefined ? options.duration : 3000, - avoidKeyboard: options.avoidKeyboard ?? false, - containerStyle: options.containerStyle, - onCloseComplete: options.onCloseComplete, - render: options.render - ? () => options.render!({ id }) - : ({ id }) => ( - - {options.title && {options.title}} - {options.description && {options.description}} - - ), - }) - return id - }, - close: (id: string) => { - toast.close(id) - }, - closeAll: () => { - toast.closeAll() - }, - isActive: (id: string) => toast.isActive(id), - } -} - -/** - * 全局 toast 实例,可在组件外部使用 + * 全局 toast 对象,组件内外都可以使用 */ export const toast = { show: (options: ShowToastOptions) => { @@ -124,14 +76,12 @@ export const toast = { return globalToast.show(options) }, close: (id: string) => { - if (globalToast) { + if (globalToast) globalToast.close(id) - } }, closeAll: () => { - if (globalToast) { + if (globalToast) globalToast.closeAll() - } }, isActive: (id: string) => { return globalToast ? globalToast.isActive(id) : false diff --git a/code/base-project/base-go-v2/.gitignore b/code/base-project/base-go-v2/.gitignore new file mode 100644 index 00000000..f30e6259 --- /dev/null +++ b/code/base-project/base-go-v2/.gitignore @@ -0,0 +1,2 @@ +logs/ +.idea/ \ No newline at end of file diff --git a/code/base-project/base-go-v2/internal/api/auth/index.go b/code/base-project/base-go-v2/internal/api/auth/index.go index a1abbe14..3f8b4f76 100644 --- a/code/base-project/base-go-v2/internal/api/auth/index.go +++ b/code/base-project/base-go-v2/internal/api/auth/index.go @@ -60,6 +60,7 @@ func loginDefault(c *router.Context) error { // 获取请求体并校验必填字段 bodyData, err := c.GetBodyWithRequired("account", "password") if err != nil { + c.AddError(err) return err } @@ -73,6 +74,7 @@ func loginDefault(c *router.Context) error { ) user, err := db.FindOne("user_info", userQuery) if err != nil { + c.AddError(err) return response.Success(c).Message("查询用户失败,请稍后重试").Send() } @@ -124,7 +126,7 @@ func registerDefault(c *router.Context) error { existingUsers, err := db.Find("user_info", accountQuery) if err != nil { - return err + return c.AddError(err) } if len(existingUsers) > 0 { @@ -141,7 +143,7 @@ func registerDefault(c *router.Context) error { // 插入新用户 insertedRows, err := db.InsertOne("user_info", newUserData) if err != nil { - return err + return c.AddError(err) } if insertedRows != 1 { return response.Fail(c).Message("注册失败").Send() diff --git a/code/base-project/base-go-v2/internal/api/middleware/error.go b/code/base-project/base-go-v2/internal/api/middleware/error.go index ee32d157..049306e5 100644 --- a/code/base-project/base-go-v2/internal/api/middleware/error.go +++ b/code/base-project/base-go-v2/internal/api/middleware/error.go @@ -1,21 +1,26 @@ package middleware import ( - "base-go-v2/internal/errs" "base-go-v2/internal/logx" "base-go-v2/internal/reponse" "base-go-v2/internal/router" - "errors" - "runtime/debug" + "os" + "path/filepath" + "runtime" + "strings" + "sync" +) + +// 仅初始化一次的项目信息 +var ( + initOnce sync.Once + projectBase string // 例:base-farmework + projectAbsPrefix string // 例:/abs/path/to/base-farmework/ + projectAbsPrefixLower string // 小写版,用于不区分大小写前缀比较(Windows 安全) ) func ErrorMiddleware() router.HandlerFunc { - // 可扩展的业务错误类型列表 - businessErrors := []interface{}{ - (*errs.ValidationError)(nil), - // (*errs.BusinessError)(nil), - // (*errs.AuthError)(nil), - } + initOnce.Do(initProjectInfo) return func(c *router.Context) error { err := c.Next() @@ -23,23 +28,132 @@ func ErrorMiddleware() router.HandlerFunc { return nil } - // 判断是否属于业务错误 - for _, be := range businessErrors { - // be 是 nil 指针类型 - if errors.As(err, &be) { - // 业务错误,不记录日志 - return response.Fail(c).Message(err.Error()).Send() - } + errs := c.Errors() + if len(errs) == 0 { + return nil } - // 系统错误,记录日志 - stack := string(debug.Stack()) + lastErr := errs[len(errs)-1] + stack := lastErr.StackTrace() + location := extractBusinessLocation(stack) + logx.Logger.Error("请求错误", logx.String("path", string(c.RequestCtx.Path())), logx.String("method", string(c.RequestCtx.Method())), + logx.String("location", location), logx.String("error", err.Error()), logx.String("stack", stack), ) + return response.Fail(c).Message("服务器内部错误").Send() } } + +// 仅在注册时执行:确定 go.mod 根目录并缓存前缀 +func initProjectInfo() { + // 以当前源文件为起点向上找 go.mod + _, file, _, _ := runtime.Caller(0) + if root, ok := findGoModRoot(file); ok { + projectBase = filepath.Base(root) + + p := filepath.ToSlash(root) + if !strings.HasSuffix(p, "/") { + p += "/" + } + projectAbsPrefix = p + projectAbsPrefixLower = strings.ToLower(p) + } +} + +// extractBusinessLocation:获取 AddError 后的业务 Handler 文件行(仅返回 /.go:) +func extractBusinessLocation(stack string) string { + lines := strings.Split(stack, "\n") + foundAddError := false + countGo := 0 + + for _, raw := range lines { + line := strings.TrimSpace(raw) + + if strings.Contains(line, "AddError") { + foundAddError = true + continue + } + if !foundAddError { + continue + } + + if strings.Contains(line, ".go:") { + countGo++ + if countGo == 2 { + // 去掉 " +0x..." 偏移 + if i := strings.Index(line, " +"); i != -1 { + line = line[:i] + } + return trimToProject(line) + } + } + } + return "" +} + +// 将绝对路径裁剪为 "/.go:" +func trimToProject(goLine string) string { + // 统一斜杠 + line := strings.ReplaceAll(goLine, "\\", "/") + + // 用最后一个冒号分离(避免 Windows 盘符) + idx := strings.LastIndex(line, ":") + if idx == -1 || idx+1 >= len(line) { + return line + } + filePath, lineNo := line[:idx], line[idx+1:] + + // 优先:前缀裁剪(O(1)),比 filepath.Rel 更快 + if projectAbsPrefix != "" { + fp := filepath.ToSlash(filePath) + fpl := strings.ToLower(fp) + if strings.HasPrefix(fpl, projectAbsPrefixLower) { + rel := fp[len(projectAbsPrefix):] + return projectBase + "/" + rel + ":" + lineNo + } + } + + // 其次:internal/cmd/pkg 作为锚点 + segs := strings.Split(filePath, "/") + for i, s := range segs { + if s == "internal" || s == "cmd" || s == "pkg" { + if i > 0 { + return strings.Join(segs[i-1:], "/") + ":" + lineNo + } + } + } + + // 启发式:目录名包含 '-' 或 '_',当作仓库名 + for i, s := range segs { + if strings.ContainsAny(s, "-_") { + return strings.Join(segs[i:], "/") + ":" + lineNo + } + } + + // 兜底:末尾 4 级 + start := len(segs) - 4 + if start < 0 { + start = 0 + } + return strings.Join(segs[start:], "/") + ":" + lineNo +} + +// 从给定文件路径向上查找包含 go.mod 的目录(仅注册时调用一次) +func findGoModRoot(filePath string) (string, bool) { + dir := filepath.Clean(filepath.Dir(filepath.FromSlash(filePath))) + for { + if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil { + return dir, true + } + parent := filepath.Dir(dir) + if parent == dir { + return "", false + } + dir = parent + } +} diff --git a/code/base-project/base-go-v2/internal/db/query.go b/code/base-project/base-go-v2/internal/db/query.go index 154dd90b..315bc499 100644 --- a/code/base-project/base-go-v2/internal/db/query.go +++ b/code/base-project/base-go-v2/internal/db/query.go @@ -60,7 +60,7 @@ func Find(table string, conditions map[string]interface{}, orderBy ...string) ([ query := fmt.Sprintf("SELECT * FROM %s WHERE %s", table, strings.Join(whereParts, " AND ")) - order := "b_id DESC" + order := "id DESC" if len(orderBy) > 0 && orderBy[0] != "" { order = orderBy[0] } @@ -79,7 +79,7 @@ func Find(table string, conditions map[string]interface{}, orderBy ...string) ([ func FindAll(table string, orderBy ...string) ([]mapx.M, error) { query := fmt.Sprintf("SELECT * FROM %s", table) - order := "b_id DESC" + order := "id DESC" if len(orderBy) > 0 && orderBy[0] != "" { order = orderBy[0] } @@ -111,11 +111,11 @@ func FindOne(table string, conditions map[string]interface{}, orderBy ...string) query := fmt.Sprintf("SELECT * FROM %s WHERE %s", table, strings.Join(whereParts, " AND ")) - order := "b_id DESC" + order := "id DESC" if len(orderBy) > 0 && orderBy[0] != "" { order = orderBy[0] } - query += " ORDER BY " + order + " LIMIT 1" // 只取一条记录 + query += " ORDER BY " + order + " LIMIT 1" row := mapx.New() err := DB.Get(&row, query, values...) diff --git a/code/base-project/base-go-v2/internal/errs/error.go b/code/base-project/base-go-v2/internal/errs/error.go new file mode 100644 index 00000000..0b62d056 --- /dev/null +++ b/code/base-project/base-go-v2/internal/errs/error.go @@ -0,0 +1,42 @@ +package errs + +import ( + "errors" + "runtime/debug" +) + +// StackError 保存原始错误和堆栈 +type StackError struct { + err error + stack string +} + +// 实现 error 接口 +func (s *StackError) Error() string { + if s.err == nil { + return "" + } + return s.err.Error() +} + +// StackTrace 返回堆栈信息 +func (s *StackError) StackTrace() string { + return s.stack +} + +// WrapWithStack 给错误附加堆栈,如果已经是 StackError 则直接返回 +func WrapWithStack(err error) *StackError { + if err == nil { + return nil + } + + var se *StackError + if errors.As(err, &se) { + return se + } + + return &StackError{ + err: err, + stack: string(debug.Stack()), + } +} diff --git a/code/base-project/base-go-v2/internal/router/context.go b/code/base-project/base-go-v2/internal/router/context.go index bfbad89a..7b33d54e 100644 --- a/code/base-project/base-go-v2/internal/router/context.go +++ b/code/base-project/base-go-v2/internal/router/context.go @@ -1,6 +1,7 @@ package router import ( + "base-go-v2/internal/errs" "base-go-v2/internal/utils/mapx" "base-go-v2/internal/utils/validate" "encoding/json" @@ -154,3 +155,35 @@ func (c *Context) Text(statusCode int, msg string) error { c.Abort() return nil } + +// AddError 记录错误,自动包装 StackError +func (c *Context) AddError(err error) error { + if err == nil { + return nil + } + + if c.keys == nil { + c.keys = make(map[string]interface{}) + } + + if _, exists := c.keys["errors"]; !exists { + c.keys["errors"] = []*errs.StackError{} + } + + // 统一生成堆栈 + se := errs.WrapWithStack(err) + c.keys["errors"] = append(c.keys["errors"].([]*errs.StackError), se) + + return err +} + +// Errors 返回 []*utils.StackError +func (c *Context) Errors() []*errs.StackError { + if c.keys == nil { + return nil + } + if err, exists := c.keys["errors"]; exists { + return err.([]*errs.StackError) + } + return nil +} diff --git a/code/base-project/base-go-v2/internal/router/router.go b/code/base-project/base-go-v2/internal/router/router.go index d3da0a1d..9bb326c1 100644 --- a/code/base-project/base-go-v2/internal/router/router.go +++ b/code/base-project/base-go-v2/internal/router/router.go @@ -74,6 +74,7 @@ type middlewareEntry struct { // 判断路径是否被排除 func (m *middlewareEntry) IsExcluded(path string) bool { + path = strings.TrimSuffix(path, "/") // 去掉尾部斜杠 if m.excludePaths != nil { if _, ok := m.excludePaths[path]; ok { return true @@ -123,23 +124,36 @@ func (r *Router) Use(handler HandlerFunc) *MiddlewareHandle { } // ExcludePaths 支持 /** 前缀匹配 -func (mh *MiddlewareHandle) ExcludePaths(paths ...string) *Router { - excludeMap := make(map[string]struct{}, 0) +// ExcludePaths 支持 /** 前缀匹配,并自动带上 basePath +func (mh *MiddlewareHandle) ExcludePaths(paths ...string) *MiddlewareHandle { + excludeMap := make(map[string]struct{}) excludePrefix := make([]string, 0) + basePath := strings.TrimSuffix(mh.router.basePath, "/") // 去掉尾部斜杠 + for _, p := range paths { - if strings.HasSuffix(p, "/**") { - base := strings.TrimSuffix(p, "/**") + fullPath := p + if !strings.HasPrefix(p, "/") { + fullPath = "/" + p + } + + // 自动加上 basePath + if basePath != "/" { + fullPath = basePath + fullPath + } + + if strings.HasSuffix(fullPath, "/**") { + base := strings.TrimSuffix(fullPath, "/**") excludePrefix = append(excludePrefix, base) } else { - excludeMap[p] = struct{}{} + excludeMap[fullPath] = struct{}{} } } mh.router.middleware[mh.entryIdx].excludePaths = excludeMap mh.router.middleware[mh.entryIdx].excludePrefix = excludePrefix - return mh.router + return mh } // Group 创建子路由组 diff --git a/code/base-project/base-go-v2/logs/error/error-2025-11-06.log b/code/base-project/base-go-v2/logs/error/error-2025-11-06.log index e69de29b..621195ab 100644 --- a/code/base-project/base-go-v2/logs/error/error-2025-11-06.log +++ b/code/base-project/base-go-v2/logs/error/error-2025-11-06.log @@ -0,0 +1,13 @@ +{"level":"ERROR","ts":"2025-11-06 21:42:52.519","caller":"middleware/error.go:27","msg":"请求错误","path":"/app/auth/register/default","method":"POST","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 19 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/api.InitAppRouter.ErrorMiddleware.func4(0xc00009e080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:26 +0x11e\nbase-go-v2/internal/router.(*Context).Next(0x7ff6a1fa517d?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc00009e080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc00009c060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc00009e080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc00023a0a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc0000b0000?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43\nbase-go-v2/internal/router.(*Router).Handler(0xc000236150, 0xc00009c008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:228 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc00023e008, {0x7ff6a204ca18, 0xc000230058})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc000240000, 0xc00020e220)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377090463208833024"} +{"level":"ERROR","ts":"2025-11-06 21:47:35.525","caller":"middleware/error.go:39","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"base-go-v2/internal/api/middleware/error.go:36 +0x105","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 11 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/api/middleware.ErrorMiddleware.func1(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:36 +0x105\nbase-go-v2/internal/router.(*Context).Next(0x7ff77ad45207?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000096060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0001465a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc0000ae000?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43\nbase-go-v2/internal/router.(*Router).Handler(0xc000177bf0, 0xc000096008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:228 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc000143208, {0x7ff77adecd58, 0xc00006a250})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc000140240, 0xc00006fc80)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377091650259779584"} +{"level":"ERROR","ts":"2025-11-06 21:52:48.952","caller":"middleware/error.go:34","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"D:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 19 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/api.InitAppRouter.ErrorMiddleware.func4(0xc000216080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:31 +0xf4\nbase-go-v2/internal/router.(*Context).Next(0x7ff72ce451fd?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc000216080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000214060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc000216080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0000ba0a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc000228000?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43\nbase-go-v2/internal/router.(*Router).Handler(0xc0000b6150, 0xc000214008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:228 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc0000be008, {0x7ff72ceecb38, 0xc0000b0058})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0000c0000, 0xc000096220)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377092964821762048"} +{"level":"ERROR","ts":"2025-11-06 22:07:55.689","caller":"middleware/error.go:28","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"D:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:15","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 24 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/api.InitAppRouter.ErrorMiddleware.func4(0xc000196080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:33 +0x336\nbase-go-v2/internal/router.(*Context).Next(0x7ff646b952a4?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc000196080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000194060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc000196080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0000f45a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc0001a8000?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43\nbase-go-v2/internal/router.(*Router).Handler(0xc000137bc0, 0xc000194008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:240 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc0000ef208, {0x7ff646c3caf8, 0xc00008c248})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0000ec240, 0xc00008fc60)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377096765834264576"} +{"level":"ERROR","ts":"2025-11-06 22:09:24.117","caller":"middleware/error.go:30","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"D:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:15","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 11 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/api.InitAppRouter.ErrorMiddleware.func4(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:35 +0x376\nbase-go-v2/internal/router.(*Context).Next(0x7ff7230552a4?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000096060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0001465a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc0000ae000?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43\nbase-go-v2/internal/router.(*Router).Handler(0xc000177bf0, 0xc000096008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:240 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc000143208, {0x7ff7230fcb18, 0xc00006a250})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc000140240, 0xc00006fc80)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377097137785143296"} +{"level":"ERROR","ts":"2025-11-06 22:10:00.635","caller":"middleware/error.go:26","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"D:/devtool/golang/go/src/runtime/debug/stack.go:26","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 24 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/api.InitAppRouter.ErrorMiddleware.func4(0xc000030100)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:20 +0x45\nbase-go-v2/internal/router.(*Context).Next(0x7ff6c96052a1?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc000030100)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000204060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc000030100)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0000f45a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc00006e020?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43\nbase-go-v2/internal/router.(*Router).Handler(0xc000137bc0, 0xc000204008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:240 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc0000ef208, {0x7ff6c96acbd8, 0xc00008c248})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0000ec240, 0xc00008fc60)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377097292072615936"} +{"level":"ERROR","ts":"2025-11-06 22:11:11.156","caller":"middleware/error.go:30","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"D:/workspace/code/base-project/base-go-v2/internal/router/context.go:43","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 11 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/api.InitAppRouter.ErrorMiddleware.func4(0xc000031400)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:29 +0xd0\nbase-go-v2/internal/router.(*Context).Next(0x7ff752f352a4?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc000031400)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000164c60?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc000031400)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0001465a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc00006fca0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43\nbase-go-v2/internal/router.(*Router).Handler(0xc000177bf0, 0xc000164c08)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:242 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc000143208, {0x7ff752fdcb18, 0xc00006a250})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc000140240, 0xc00006fc80)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377097587859128320"} +{"level":"ERROR","ts":"2025-11-06 22:11:38.477","caller":"middleware/error.go:30","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"D:/workspace/code/base-project/base-go-v2/internal/router/router.go:196","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 34 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/api.InitAppRouter.ErrorMiddleware.func4(0xc0000f3380)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:29 +0xd0\nbase-go-v2/internal/router.(*Context).Next(0x7ff6e99752a4?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc0000f3380)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000110c60?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc0000f3380)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0000f45a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc00008fc40?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43\nbase-go-v2/internal/router.(*Router).Handler(0xc000137bc0, 0xc000110c08)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:242 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc0000ef208, {0x7ff6e9a1cb18, 0xc000194000})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0000ec240, 0xc000190020)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377097702418153472"} +{"level":"ERROR","ts":"2025-11-06 22:12:17.735","caller":"middleware/error.go:30","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"D:/workspace/code/base-project/base-go-v2/internal/router/router.go:182","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 11 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/api.InitAppRouter.ErrorMiddleware.func4(0xc000210080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:29 +0xd0\nbase-go-v2/internal/router.(*Context).Next(0x7ff7854f52e4?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc000210080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc00020e060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc000210080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0001465a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc000226000?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:43\nbase-go-v2/internal/router.(*Router).Handler(0xc000177bf0, 0xc00020e008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:246 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc000143208, {0x7ff78559cb58, 0xc00006a250})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc000140240, 0xc00006fce0)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377097867082334208"} +{"level":"ERROR","ts":"2025-11-06 22:35:16.172","caller":"middleware/error.go:40","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"base-go-v2/internal/router/router.go:194","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 34 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/errs.WrapWithStack({0x7ff701e980c0, 0xc00008a230})\n\tD:/workspace/code/base-project/base-go-v2/internal/errs/error.go:40 +0x6d\nbase-go-v2/internal/router.(*Context).AddError(0xc0000a4280, {0x7ff701e980c0, 0xc00008a230})\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:174 +0x10d\nbase-go-v2/internal/router.(*Router).handle.func1(0xc0000a4280)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:194 +0x3f\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44\nbase-go-v2/internal/api/middleware.ErrorMiddleware.func1(0xc0000a4280)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:26 +0x54\nbase-go-v2/internal/router.(*Context).Next(0x7ff701df64ef?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc0000a4280)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc0000cc060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc0000a4280)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0000ba0a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc000096200?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44\nbase-go-v2/internal/router.(*Router).Handler(0xc0000b6150, 0xc0000cc008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:238 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc0000c6008, {0x7ff701e9e018, 0xc000214000})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0000c8000, 0xc000210020)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377103648687128576"} +{"level":"ERROR","ts":"2025-11-06 22:37:11.091","caller":"middleware/error.go:40","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"base-go-v2/internal/api/auth/index.go:24","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 5 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/errs.WrapWithStack({0x7ff6b9c380e0, 0xc0000a1bb0})\n\tD:/workspace/code/base-project/base-go-v2/internal/errs/error.go:40 +0x6d\nbase-go-v2/internal/router.(*Context).AddError(0xc0000f3380, {0x7ff6b9c380e0, 0xc0000a1bb0})\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:174 +0x10d\nbase-go-v2/internal/api/auth.InitAuthRouter.WrapHandler.func1(0xc0000f3380)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/auth/index.go:24 +0x3f\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44\nbase-go-v2/internal/api/middleware.ErrorMiddleware.func1(0xc0000f3380)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:26 +0x54\nbase-go-v2/internal/router.(*Context).Next(0x7ff6b9b964ef?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc0000f3380)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000110c60?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc0000f3380)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0000f45a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc00008fc40?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44\nbase-go-v2/internal/router.(*Router).Handler(0xc000137bc0, 0xc000110c08)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:228 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc0000ef208, {0x7ff6b9c3e038, 0xc00006a008})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0000ec240, 0xc00006e040)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377104130746875904"} +{"level":"ERROR","ts":"2025-11-06 22:38:45.572","caller":"middleware/error.go:40","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"base-go-v2/internal/api/auth/index.go:129","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 11 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/errs.WrapWithStack({0x7ff68a658060, 0xc00008a0e0})\n\tD:/workspace/code/base-project/base-go-v2/internal/errs/error.go:40 +0x6d\nbase-go-v2/internal/router.(*Context).AddError(0xc000098080, {0x7ff68a658060, 0xc00008a0e0})\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:174 +0x10d\nbase-go-v2/internal/api/auth.registerDefault(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/auth/index.go:129 +0x50b\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44\nbase-go-v2/internal/api/middleware.ErrorMiddleware.func1(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:26 +0x54\nbase-go-v2/internal/router.(*Context).Next(0x7ff68a5b642f?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000096060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0001465a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc0000ae000?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44\nbase-go-v2/internal/router.(*Router).Handler(0xc000177bf0, 0xc000096008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:228 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc000143208, {0x7ff68a65dfb8, 0xc00006a250})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc000140240, 0xc00006fc80)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377104519802126336"} +{"level":"ERROR","ts":"2025-11-06 22:48:38.411","caller":"middleware/error.go:40","msg":"请求错误","path":"/app/auth/register/default","method":"POST","location":"base-go-v2/internal/api/auth/index.go:129","error":"non-struct dest type map with >1 columns (10)","stack":"goroutine 11 [running]:\nruntime/debug.Stack()\n\tD:/devtool/golang/go/src/runtime/debug/stack.go:26 +0x5e\nbase-go-v2/internal/errs.WrapWithStack({0x7ff7f1e68020, 0xc00008a0e0})\n\tD:/workspace/code/base-project/base-go-v2/internal/errs/error.go:40 +0x6d\nbase-go-v2/internal/router.(*Context).AddError(0xc000098080, {0x7ff7f1e68020, 0xc00008a0e0})\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:174 +0x10d\nbase-go-v2/internal/api/auth.registerDefault(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/auth/index.go:129 +0x505\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44\nbase-go-v2/internal/api/middleware.ErrorMiddleware.func1(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/error.go:26 +0x54\nbase-go-v2/internal/router.(*Context).Next(0x7ff7f1dc642f?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.LoggerMiddleware.func3(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/logger.go:27 +0x77\nbase-go-v2/internal/router.(*Context).Next(0xc000096060?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.CORSMiddleware.func2(0xc000098080)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/cors.go:22 +0x159\nbase-go-v2/internal/router.(*Context).Next(0xc0001465a0?)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44 +0x35\nbase-go-v2/internal/api.InitAppRouter.RecoveryMiddleware.func1(0xc0000ae000?)\n\tD:/workspace/code/base-project/base-go-v2/internal/api/middleware/recovery.go:29 +0x45\nbase-go-v2/internal/router.(*Context).Next(...)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/context.go:44\nbase-go-v2/internal/router.(*Router).Handler(0xc000177bf0, 0xc000096008)\n\tD:/workspace/code/base-project/base-go-v2/internal/router/router.go:228 +0x40e\ngithub.com/valyala/fasthttp.(*Server).serveConn(0xc000143208, {0x7ff7f1e6df78, 0xc00006a250})\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/server.go:2465 +0x124b\ngithub.com/valyala/fasthttp.(*workerPool).workerFunc(0xc000140240, 0xc00006fc80)\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:225 +0x92\ngithub.com/valyala/fasthttp.(*workerPool).getCh.func1()\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:197 +0x32\ncreated by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1\n\tD:/devtool/golang/gopath/pkg/mod/github.com/valyala/fasthttp@v1.68.0/workerpool.go:196 +0x194\n","trackId":"377107013567512576"} diff --git a/code/base-project/base-go-v2/logs/info/info-2025-11-05.log b/code/base-project/base-go-v2/logs/info/info-2025-11-05.log index 25f06665..1062857c 100644 --- a/code/base-project/base-go-v2/logs/info/info-2025-11-05.log +++ b/code/base-project/base-go-v2/logs/info/info-2025-11-05.log @@ -33,3 +33,12 @@ {"level":"INFO","ts":"2025-11-05 21:38:25.864","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0.0005154,"trackId":"376726957276004352"} {"level":"INFO","ts":"2025-11-05 21:38:26.084","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0.0002596,"trackId":"376726958202945536"} {"level":"INFO","ts":"2025-11-05 21:38:26.319","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0,"trackId":"376726959188606976"} +{"level":"INFO","ts":"2025-11-05 21:39:35.357","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0.0001412,"trackId":"376727248754966528"} +{"level":"INFO","ts":"2025-11-05 21:42:15.102","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0,"trackId":"376727918774059008"} +{"level":"INFO","ts":"2025-11-05 21:42:24.954","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0.000409,"trackId":"376727960096342016"} +{"level":"INFO","ts":"2025-11-05 21:42:43.505","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0,"trackId":"376728037904875520"} +{"level":"INFO","ts":"2025-11-05 21:52:23.602","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0,"trackId":"376730471008043008"} +{"level":"INFO","ts":"2025-11-05 22:03:21.901","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0,"trackId":"376733232114171904"} +{"level":"INFO","ts":"2025-11-05 22:03:35.322","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0,"trackId":"376733288405925888"} +{"level":"INFO","ts":"2025-11-05 22:04:01.873","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0,"trackId":"376733399768891392"} +{"level":"INFO","ts":"2025-11-05 22:10:50.807","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/login/default","method":"POST","ip":"192.168.5.3","elapsed":0,"trackId":"376735114962403328"} diff --git a/code/base-project/base-go-v2/logs/info/info-2025-11-06.log b/code/base-project/base-go-v2/logs/info/info-2025-11-06.log index 85257910..49427a59 100644 --- a/code/base-project/base-go-v2/logs/info/info-2025-11-06.log +++ b/code/base-project/base-go-v2/logs/info/info-2025-11-06.log @@ -67,3 +67,28 @@ {"level":"INFO","ts":"2025-11-06 14:25:49.654","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/test","method":"POST","ip":"192.168.1.136","elapsed":0.0009762,"trackId":"376980476906176512"} {"level":"INFO","ts":"2025-11-06 14:26:01.687","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/test","method":"POST","ip":"192.168.1.136","elapsed":0,"trackId":"376980527380430848"} {"level":"INFO","ts":"2025-11-06 16:01:53.899","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/test","method":"POST","ip":"192.168.1.136","elapsed":0.0009752,"trackId":"377004653902036992"} +{"level":"INFO","ts":"2025-11-06 21:16:41.715","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0067722,"trackId":"377083875114876928"} +{"level":"INFO","ts":"2025-11-06 21:17:52.883","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0,"trackId":"377084173648658432"} +{"level":"INFO","ts":"2025-11-06 21:18:54.267","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0,"trackId":"377084431111815168"} +{"level":"INFO","ts":"2025-11-06 21:19:53.098","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0005261,"trackId":"377084677862719488"} +{"level":"INFO","ts":"2025-11-06 21:23:00.479","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0,"trackId":"377085463799791616"} +{"level":"INFO","ts":"2025-11-06 21:31:03.146","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0,"trackId":"377087488251920384"} +{"level":"INFO","ts":"2025-11-06 21:32:16.093","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.1880208,"trackId":"377087793425285120"} +{"level":"INFO","ts":"2025-11-06 21:36:42.337","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0919709,"trackId":"377088910536212480"} +{"level":"INFO","ts":"2025-11-06 21:39:31.387","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0831313,"trackId":"377089619621052416"} +{"level":"INFO","ts":"2025-11-06 21:42:20.054","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.077842,"trackId":"377090327082696704"} +{"level":"INFO","ts":"2025-11-06 21:42:34.452","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0774994,"trackId":"377090387472285696"} +{"level":"INFO","ts":"2025-11-06 21:42:48.021","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0763234,"trackId":"377090444393185280"} +{"level":"INFO","ts":"2025-11-06 21:42:52.519","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0885687,"trackId":"377090463208833024"} +{"level":"INFO","ts":"2025-11-06 21:47:35.525","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0789829,"trackId":"377091650259779584"} +{"level":"INFO","ts":"2025-11-06 21:52:48.953","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0901211,"trackId":"377092964821762048"} +{"level":"INFO","ts":"2025-11-06 22:07:55.689","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.5955457,"trackId":"377096765834264576"} +{"level":"INFO","ts":"2025-11-06 22:09:24.117","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.3433544,"trackId":"377097137785143296"} +{"level":"INFO","ts":"2025-11-06 22:10:00.635","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.075988,"trackId":"377097292072615936"} +{"level":"INFO","ts":"2025-11-06 22:11:11.156","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0763772,"trackId":"377097587859128320"} +{"level":"INFO","ts":"2025-11-06 22:11:38.477","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0844654,"trackId":"377097702418153472"} +{"level":"INFO","ts":"2025-11-06 22:12:17.736","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0836953,"trackId":"377097867082334208"} +{"level":"INFO","ts":"2025-11-06 22:35:16.172","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0778315,"trackId":"377103648687128576"} +{"level":"INFO","ts":"2025-11-06 22:37:11.091","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0653962,"trackId":"377104130746875904"} +{"level":"INFO","ts":"2025-11-06 22:38:45.572","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":1.7876704,"trackId":"377104519802126336"} +{"level":"INFO","ts":"2025-11-06 22:48:38.411","caller":"middleware/logger.go:34","msg":"接口请求","path":"/app/auth/register/default","method":"POST","ip":"192.168.5.6","elapsed":0.0668153,"trackId":"377107013567512576"} diff --git a/code/base-project/base-go/internal/app/handle/test.go b/code/base-project/base-go/internal/app/handle/test.go index 4770b4bf..91a3bcc1 100644 --- a/code/base-project/base-go/internal/app/handle/test.go +++ b/code/base-project/base-go/internal/app/handle/test.go @@ -5,5 +5,4 @@ import ( ) func TestDB(c *router.Context) { - }