u
This commit is contained in:
1 parent
4e42a01b97
commit
428d370874
8 files changed
+84
-44
No files matched your search
@@ -2,4 +2,4 @@ server:
|
|||||||
port: 8082
|
port: 8082
|
||||||
jwt:
|
jwt:
|
||||||
secret: 3Bde3BGEbYqtqyEUzW3ry8jKFcaPH17fRmTmqE7MDr05Lwj95uruRKrrkb44TJ4s
|
secret: 3Bde3BGEbYqtqyEUzW3ry8jKFcaPH17fRmTmqE7MDr05Lwj95uruRKrrkb44TJ4s
|
||||||
expiry: 24h
|
expiry: 168h
|
||||||
@@ -2,9 +2,9 @@ package handle
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"base-framework/pkg/config"
|
"base-framework/pkg/config"
|
||||||
|
"base-framework/pkg/reponse"
|
||||||
"base-framework/pkg/router"
|
"base-framework/pkg/router"
|
||||||
"base-framework/pkg/utils/jwt"
|
"base-framework/pkg/utils/jwt"
|
||||||
"base-framework/pkg/utils/response"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Login 登录接口
|
// Login 登录接口
|
||||||
@@ -17,23 +17,23 @@ func Login(c *router.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := c.BindJSON(&req); err != nil {
|
if err := c.BindJSON(&req); err != nil {
|
||||||
response.Error(c).Message("请求体不能为空").Send()
|
reponse.Error(c).Message("请求体不能为空").Send()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.OrgID == "" {
|
if req.OrgID == "" {
|
||||||
response.Error(c).Message("机构码不能为空").Send()
|
reponse.Error(c).Message("机构码不能为空").Send()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 参数校验
|
// 参数校验
|
||||||
if req.UserID == "" {
|
if req.UserID == "" {
|
||||||
response.Error(c).Message("账户不能为空").Send()
|
reponse.Error(c).Message("账户不能为空").Send()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.Password == "" {
|
if req.Password == "" {
|
||||||
response.Error(c).Message("密码不能为空").Send()
|
reponse.Error(c).Message("密码不能为空").Send()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ func Login(c *router.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !hasOrg {
|
if !hasOrg {
|
||||||
response.Error(c).Code(response.CodeInvalidOrgCode).Send()
|
reponse.Error(c).Code(reponse.CodeInvalidOrgCode).Send()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,11 +55,11 @@ func Login(c *router.Context) {
|
|||||||
token, err := jwt.CreateToken(req.OrgID, req.UserID)
|
token, err := jwt.CreateToken(req.OrgID, req.UserID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.Error(c).Message("生成令牌失败")
|
reponse.Error(c).Message("生成令牌失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Success(c).Data(
|
reponse.Success(c).Data(
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"token": token,
|
"token": token,
|
||||||
}).Send()
|
}).Send()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package handle
|
package handle
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"base-framework/pkg/reponse"
|
||||||
"base-framework/pkg/router"
|
"base-framework/pkg/router"
|
||||||
"base-framework/pkg/utils/db"
|
"base-framework/pkg/utils/db"
|
||||||
"base-framework/pkg/utils/response"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -26,5 +26,5 @@ func Test(c *router.Context) {
|
|||||||
fmt.Println(row["id"], row["name"])
|
fmt.Println(row["id"], row["name"])
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Success(c).Data(rows).Send()
|
reponse.Success(c).Data(rows).Send()
|
||||||
}
|
}
|
||||||
@@ -2,9 +2,9 @@ package middleware
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"base-framework/pkg/config"
|
"base-framework/pkg/config"
|
||||||
|
"base-framework/pkg/reponse"
|
||||||
"base-framework/pkg/router"
|
"base-framework/pkg/router"
|
||||||
"base-framework/pkg/utils/jwt"
|
"base-framework/pkg/utils/jwt"
|
||||||
"base-framework/pkg/utils/response"
|
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -20,7 +20,7 @@ func Auth() router.HandlerFunc {
|
|||||||
|
|
||||||
// 缺少登录信息
|
// 缺少登录信息
|
||||||
if tokenHeader == "" || userIdHeader == "" || orgIDHeader == "" {
|
if tokenHeader == "" || userIdHeader == "" || orgIDHeader == "" {
|
||||||
response.Error(c).Code(response.CodeNoLogin).Send()
|
reponse.Error(c).Code(reponse.CodeNoLogin).Send()
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ func Auth() router.HandlerFunc {
|
|||||||
// Bearer token 格式校验
|
// Bearer token 格式校验
|
||||||
parts := strings.Fields(tokenHeader)
|
parts := strings.Fields(tokenHeader)
|
||||||
if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" {
|
if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" {
|
||||||
response.Error(c).Code(response.CodeInvalidToken).Send()
|
reponse.Error(c).Code(reponse.CodeInvalidToken).Send()
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -39,9 +39,9 @@ func Auth() router.HandlerFunc {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(err, jwt.ErrTokenExpired):
|
case errors.Is(err, jwt.ErrTokenExpired):
|
||||||
response.Error(c).Code(response.CodeLoginExpired).Send()
|
reponse.Error(c).Code(reponse.CodeLoginExpired).Send()
|
||||||
default:
|
default:
|
||||||
response.Error(c).Code(response.CodeInvalidToken).Send()
|
reponse.Error(c).Code(reponse.CodeInvalidToken).Send()
|
||||||
}
|
}
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
@@ -49,14 +49,14 @@ func Auth() router.HandlerFunc {
|
|||||||
|
|
||||||
// user_id 校验
|
// user_id 校验
|
||||||
if claims.UserID != userIdHeader {
|
if claims.UserID != userIdHeader {
|
||||||
response.Error(c).Code(response.CodeInvalidToken).Send()
|
reponse.Error(c).Code(reponse.CodeInvalidToken).Send()
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// org_id 校验
|
// org_id 校验
|
||||||
if claims.OrgID != orgIDHeader {
|
if claims.OrgID != orgIDHeader {
|
||||||
response.Error(c).Code(response.CodeInvalidToken).Send()
|
reponse.Error(c).Code(reponse.CodeInvalidToken).Send()
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ func Auth() router.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !hasOrg {
|
if !hasOrg {
|
||||||
response.Error(c).Code(response.CodeInvalidOrgCode).Send()
|
reponse.Error(c).Code(reponse.CodeInvalidOrgCode).Send()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,67 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"base-framework/pkg/reponse"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"base-framework/pkg/router"
|
"base-framework/pkg/router"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Error 中间件:捕获 c.Errors() 并返回统一的 ErrorInfo
|
||||||
func Error() router.HandlerFunc {
|
func Error() router.HandlerFunc {
|
||||||
return func(c *router.Context) {
|
return func(c *router.Context) {
|
||||||
c.Next() // 执行后续 Handler
|
c.Next() // 执行后续 Handler
|
||||||
|
|
||||||
errs := c.Errors()
|
errs := c.Errors()
|
||||||
if len(errs) > 0 {
|
if len(errs) == 0 {
|
||||||
lastErr := errs[len(errs)-1]
|
return
|
||||||
|
|
||||||
// 打印错误信息和堆栈
|
|
||||||
fmt.Printf("[ERROR] %v\nStack trace:\n%s\n", lastErr.Error(), lastErr.StackTrace())
|
|
||||||
|
|
||||||
// 返回前端安全信息
|
|
||||||
c.JSON(http.StatusInternalServerError, map[string]interface{}{
|
|
||||||
"code": "FAIL",
|
|
||||||
"message": lastErr.Error(),
|
|
||||||
})
|
|
||||||
c.Abort()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastErr := errs[len(errs)-1]
|
||||||
|
stack := lastErr.StackTrace()
|
||||||
|
location := extractBusinessLocation(stack)
|
||||||
|
|
||||||
|
info := reponse.ErrorInfo{
|
||||||
|
Method: c.Request.Method,
|
||||||
|
Path: c.Request.URL.Path,
|
||||||
|
Message: lastErr.Error(),
|
||||||
|
Stack: stack, // 完整堆栈
|
||||||
|
Location: location, // 业务 Handler 文件行号
|
||||||
|
}
|
||||||
|
|
||||||
|
reponse.Error(c).ErrorInfo(info).Send()
|
||||||
|
c.Abort()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extractBusinessLocation:获取 AddError 后的业务 Handler 文件行号
|
||||||
|
func extractBusinessLocation(stack string) string {
|
||||||
|
lines := strings.Split(stack, "\n")
|
||||||
|
foundAddError := false
|
||||||
|
countGo := 0
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if strings.Contains(line, "AddError") {
|
||||||
|
foundAddError = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if foundAddError && strings.Contains(line, ".go:") {
|
||||||
|
countGo++
|
||||||
|
if countGo == 2 { // 第2个 .go: 行就是业务 Handler
|
||||||
|
// 去掉 +0x偏移
|
||||||
|
if idx := strings.Index(line, " +"); idx != -1 {
|
||||||
|
line = line[:idx]
|
||||||
|
}
|
||||||
|
// 保留 base-farmework 开头的路径
|
||||||
|
slash := strings.Index(line, "base-farmework")
|
||||||
|
if slash != -1 {
|
||||||
|
line = line[slash:]
|
||||||
|
}
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"base-framework/pkg/reponse"
|
||||||
"base-framework/pkg/router"
|
"base-framework/pkg/router"
|
||||||
"base-framework/pkg/utils/response"
|
|
||||||
"log"
|
"log"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
)
|
)
|
||||||
@@ -14,7 +14,7 @@ func Recovery() router.HandlerFunc {
|
|||||||
// 打印 panic 信息和堆栈
|
// 打印 panic 信息和堆栈
|
||||||
log.Printf("[Recovery] panic recovered: %v\n%s", err, debug.Stack())
|
log.Printf("[Recovery] panic recovered: %v\n%s", err, debug.Stack())
|
||||||
|
|
||||||
response.Error(c).Send()
|
reponse.Error(c).Send()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -1,4 +1,4 @@
|
|||||||
package response
|
package reponse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"base-framework/pkg/router"
|
"base-framework/pkg/router"
|
||||||
@@ -6,10 +6,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ErrorInfo struct {
|
type ErrorInfo struct {
|
||||||
Method string `json:"method,omitempty"`
|
Method string `json:"method,omitempty"`
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
Stack string `json:"stack,omitempty"`
|
Location string `json:"location,omitempty"`
|
||||||
|
Stack string `json:"stack,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Result 统一响应结构体
|
// Result 统一响应结构体
|
||||||
@@ -2,8 +2,8 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"base-framework/pkg/config"
|
"base-framework/pkg/config"
|
||||||
|
"base-framework/pkg/reponse"
|
||||||
"base-framework/pkg/router"
|
"base-framework/pkg/router"
|
||||||
"base-framework/pkg/utils/response"
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
@@ -18,19 +18,19 @@ func NewClient(c *router.Context) *Client {
|
|||||||
val, ok := c.Get("orgId")
|
val, ok := c.Get("orgId")
|
||||||
fmt.Println(val)
|
fmt.Println(val)
|
||||||
if !ok {
|
if !ok {
|
||||||
response.Error(c).Code(response.CodeInvalidOrgCode).Send()
|
reponse.Error(c).Code(reponse.CodeInvalidOrgCode).Send()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
orgId, ok := val.(string)
|
orgId, ok := val.(string)
|
||||||
if !ok || orgId == "" {
|
if !ok || orgId == "" {
|
||||||
response.Error(c).Code(response.CodeInvalidOrgCode).Send()
|
reponse.Error(c).Code(reponse.CodeInvalidOrgCode).Send()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, ok := config.GetDB(orgId)
|
conn, ok := config.GetDB(orgId)
|
||||||
if !ok || conn == nil {
|
if !ok || conn == nil {
|
||||||
response.Error(c).Code(response.CodeInvalidOrgCode).Send()
|
reponse.Error(c).Code(reponse.CodeInvalidOrgCode).Send()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user