This commit is contained in:
2024-10-12 20:41:55 +08:00
parent 8c09120db6
commit 597e4f1b89
75 changed files with 5009 additions and 823 deletions

9
pkg/errs/api.go Normal file
View File

@@ -0,0 +1,9 @@
package errs
// 常见错误
var (
ErrSystem = NewAppError(1001, "业务失败")
ErrParamDecryption = NewAppError(1002, "参数解密失败")
ErrParamValidation = NewAppError(1003, "校验参数不正确")
ErrDataSource = NewAppError(1004, "数据源异常")
)

20
pkg/errs/err.go Normal file
View File

@@ -0,0 +1,20 @@
package errs
// 定义自定义错误类型
type AppError struct {
Code int // 错误码
Message string // 错误信息
}
// 实现 error 接口的 Error 方法
func (e *AppError) Error() string {
return e.Message
}
// 创建带有错误码和错误信息的 AppError
func NewAppError(code int, message string) *AppError {
return &AppError{
Code: code,
Message: message,
}
}

13
pkg/models/mqs.go Normal file
View File

@@ -0,0 +1,13 @@
package models
import "time"
type ApiRequestMessage struct {
TransactionID string `json:"transactionID"`
UserId int64 `json:"userId"`
ProductCode string `json:"productCode"`
Status string `json:"status"` // 1. success 2. error
Charges bool `json:"charges"` // 是否扣费
Remark string `json:"remark"`
Timestamp time.Time `json:"timestamp"` // 添加时间戳
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"github.com/zeromicro/go-zero/rest/httpx"
"net/http"
"tianyuan-api/pkg/errs"
)
// 定义通用的响应结构
@@ -13,41 +14,43 @@ type Response struct {
Message string `json:"message"`
}
type ResponseWithTransactionID struct {
Response
TransactionID string `json:"transaction_id"`
Code int `json:"code"`
Data interface{} `json:"data,omitempty"`
Message string `json:"message"`
TransactionID string `json:"transaction_id"`
}
// 发送响应(公用函数)
func sendResponse(ctx context.Context, w http.ResponseWriter, code int, message string, data interface{}) {
// 从上下文中获取 TransactionID
transactionID, _ := ctx.Value("transactionID").(string)
if transactionID != "" {
result := ResponseWithTransactionID{
Code: code,
Data: data,
Message: message,
TransactionID: transactionID,
}
httpx.OkJsonCtx(ctx, w, result)
} else {
result := Response{
Code: code,
Data: data,
Message: message,
}
httpx.OkJsonCtx(ctx, w, result)
}
}
// 响应成功
func Success(ctx context.Context, w http.ResponseWriter, data interface{}) {
// 从上下文中获取 TransactionID
transactionID := ctx.Value("TransactionID")
// 判断是否存在 TransactionID
if transactionID != nil {
result := ResponseWithTransactionID{
Response: Response{
Code: http.StatusOK,
Data: data,
Message: "success",
},
TransactionID: transactionID.(string), // 将 TransactionID 添加到响应
}
httpx.OkJsonCtx(ctx, w, result) // 返回带有 TransactionID 的响应
} else {
result := Response{
Code: http.StatusOK,
Data: data,
Message: "success",
}
httpx.OkJsonCtx(ctx, w, result) // 返回没有 TransactionID 的响应
}
ctx = context.WithValue(ctx, "status", "success")
sendResponse(ctx, w, 0, "success", data)
}
// 响应失败
func Fail(ctx context.Context, w http.ResponseWriter, err error) {
result := Response{
Code: -1,
Message: err.Error(),
}
httpx.OkJsonCtx(ctx, w, result)
func Fail(ctx context.Context, w http.ResponseWriter, err *errs.AppError) {
ctx = context.WithValue(ctx, "status", "failed")
ctx = context.WithValue(ctx, "remark", err.Message)
sendResponse(ctx, w, err.Code, err.Message, nil)
}

View File

@@ -1,86 +0,0 @@
package schema
import (
"encoding/json"
"fmt"
"github.com/xeipuuv/gojsonschema"
"os"
"path/filepath"
"strings"
)
// ValidationResult 结构用于保存校验结果
type ValidationResult struct {
Valid bool
Data map[string]interface{}
Errors string
}
// 校验函数:接受 schema 文件路径和 JSON 数据
func ValidateJSONWithSchema(schemaFileName string, data []byte) (ValidationResult, error) {
// 获取项目根目录
rootPath, err := os.Getwd()
if err != nil {
return ValidationResult{}, fmt.Errorf("无法获取项目根目录: %v", err)
}
// 构建本地 Schema 文件路径
schemaPath := filepath.Join(rootPath, "internal", "schema", schemaFileName)
// 将文件路径转换为 file:// URI 格式
schemaURI := "file:///" + filepath.ToSlash(schemaPath)
// 读取 schema 文件,通过 URI 加载
schemaLoader := gojsonschema.NewReferenceLoader(schemaURI)
// 将传入的 []byte 数据转为 JSON Loader
jsonLoader := gojsonschema.NewBytesLoader(data)
// 执行校验
result, err := gojsonschema.Validate(schemaLoader, jsonLoader)
if err != nil {
return ValidationResult{}, fmt.Errorf("校验过程中出错: %v", err)
}
// 初始化返回结果
validationResult := ValidationResult{
Valid: result.Valid(),
Data: make(map[string]interface{}),
Errors: "",
}
// 如果校验失败,收集并自定义错误信息
if !result.Valid() {
errorMessages := collectErrors(result.Errors())
validationResult.Errors = formatErrors(errorMessages)
return validationResult, nil
}
// 校验成功,解析 JSON
if err := json.Unmarshal(data, &validationResult.Data); err != nil {
return validationResult, fmt.Errorf("JSON 解析出错: %v", err)
}
return validationResult, nil
}
// collectErrors 自定义处理错误信息
func collectErrors(errors []gojsonschema.ResultError) []string {
var errorMessages []string
for _, err := range errors {
// 从 Details() 中获取真正的字段名
details := err.Details()
fieldName, ok := details["property"].(string)
if !ok {
fieldName = err.Field() // 默认使用 err.Field(),如果 property 不存在
}
errorMessages = append(errorMessages, fmt.Sprintf("%s: %s", fieldName, err.Description()))
}
return errorMessages
}
// formatErrors 将错误列表格式化为美观的字符串
func formatErrors(errors []string) string {
return strings.Join(errors, ", ") // 用换行符连接每个错误信息
}