// Package response ... // // Description : response ... // // Author : go_developer@163.com<白茶清欢> // // Date : 2022-06-25 20:52 package response import ( "fmt" "git.zhangdeman.cn/zhangdeman/dynamic-struct/wrapper" "git.zhangdeman.cn/zhangdeman/serialize" "net/http" "strings" "time" "git.zhangdeman.cn/zhangdeman/exception" "git.zhangdeman.cn/zhangdeman/gin/define" "github.com/gin-gonic/gin" ) const ( // hasSendResponseFlag 已经发送响应数据的标识, 一旦识别到, 重复调用不会执行 hasSendResponseFlag = "GIN_PKG_HAS_SEND_RESPONSE" ) var ( // 成功的业务状态码 successBusinessCode any = "200" ) // SetBusinessSuccessCode 设置成状态码 // // Author : go_developer@163.com<白茶清欢> // // Date : 17:01 2024/8/17 func SetBusinessSuccessCode(code any) { successBusinessCode = code } // Success 成功的响应 // // Author : go_developer@163.com<白茶清欢> // // Date : 22:37 2022/6/25 func Success(ctx *gin.Context, data any) { successException := exception.NewSuccess(data) Send(ctx, successException.GetCode(), successException.GetHttpCode(), successException.GetData(), nil) } // SuccessWithExtension 返回扩展数据 // // Author : go_developer@163.com<白茶清欢> // // Date : 14:52 2024/9/24 func SuccessWithExtension(ctx *gin.Context, data any, responseOption *define.ResponseOption) { successException := exception.NewSuccess(data) Send(ctx, successException.GetCode(), successException.GetHttpCode(), successException.GetData(), responseOption) } // Send 基础的发送数据 // // Author : go_developer@163.com<白茶清欢> // // Date : 22:40 2022/6/25 func Send(ctx *gin.Context, code any, httpCode int, data any, responseOption *define.ResponseOption) { if nil == responseOption { responseOption = &define.ResponseOption{ ContentType: "application/json; charset=utf-8", Extension: make(map[string]any), } } if len(responseOption.ContentType) == 0 { responseOption.ContentType = "application/json; charset=utf-8" } if len(responseOption.XmlName) == 0 { responseOption.XmlName = "ResponseData" } // 设置请求是否成功的标识 ctx.Set(define.GetHttpHandleConfig().RequestIsSuccessField, fmt.Sprintf("%v", code) == fmt.Sprintf("%v", successBusinessCode)) if ctx.GetBool(hasSendResponseFlag) { // 已经发送过数据, 后面在发送数据, 不执行 return } // 设置数据已发送的标识 defer ctx.Set(hasSendResponseFlag, true) finishRequestTime := time.Now() responseData := BuildResponseData(ctx, finishRequestTime, code, data, responseOption.Extension) // 记录完成时间 responseConfig := define.GetHttpHandleConfig() ctx.Set(responseConfig.FinishRequestTimeField, finishRequestTime.UnixMilli()) ctx.Set(responseConfig.ResponseDataField, responseData) responseException := exception.New(code, httpCode, responseData) responseContentType := getResponseDataType(responseOption.ContentType) responseInstance, _ := wrapper.NewJson(serialize.JSON.MarshalForStringIgnoreError(responseException.GetData()), &wrapper.Option{XmlName: responseOption.XmlName}) finalResponseData, _ := responseInstance.Marshal(responseContentType) ctx.Data(responseException.GetHttpCode(), responseContentType, finalResponseData) } // getResponseDataType 获取相应数据类型 func getResponseDataType(contentType string) string { if contentType == "" { return "json" } applicationInfo := strings.Split(contentType, ";")[0] applicationInfoArr := strings.Split(applicationInfo, "/") return applicationInfoArr[len(applicationInfoArr)-1] } // BuildResponseData 构建响应数据 func BuildResponseData(ctx *gin.Context, finishTime time.Time, code any, data any, extension map[string]any) map[string]any { responseConfig := define.GetHttpHandleConfig() responseData := map[string]any{ responseConfig.ResponseCodeField: code, responseConfig.ResponseMessageField: exception.GetMessage(code), responseConfig.ResponseTraceIDField: ctx.GetString(responseConfig.ResponseTraceIDField), responseConfig.ResponseDataField: data, responseConfig.HandleRequestCostField: finishTime.UnixMilli() - ctx.GetInt64(responseConfig.StartRequestTimeField), } if responseConfig.EnableExtensionOutput && nil != extension { responseData[responseConfig.ExtensionOutputField] = extension } return responseData } // SendWithStatusOK ... // // Author : go_developer@163.com<白茶清欢> // // Date : 22:41 2022/6/25 func SendWithStatusOK(ctx *gin.Context, code any, data any) { Send(ctx, code, http.StatusOK, data, nil) } // SendWithException 使用exception发送数据 // // Author : go_developer@163.com<白茶清欢> // // Date : 13:08 2022/6/26 func SendWithException(ctx *gin.Context, e exception.IException, data map[string]any) { if nil == e { e = exception.NewSuccess(data) } if !define.GetHttpHandleConfig().DisableDebugStackOutput && nil != e { stack := e.GetStack() if len(stack) > 0 { fmt.Println(stack) } } outputData := map[string]any{ "e_data": e.GetData(), "u_e_data": data, } Send(ctx, e.GetCode(), e.GetHttpCode(), outputData, nil) } // JSON ctx.JSON 的平替, 增加了数据是否已相应的标识 // // Author : go_developer@163.com<白茶清欢> // // Date : 14:51 2023/2/15 func JSON(ctx *gin.Context, httpCode int, data any) { if ctx.GetBool(hasSendResponseFlag) { // 已经发送过数据, 后面在发送数据, 不执行 return } // 设置数据已发送的标识 defer ctx.Set(hasSendResponseFlag, true) ctx.JSON(httpCode, data) }