173 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // 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.Code(), http.StatusOK, successException.Data(), 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.Code(), http.StatusOK, successException.Data(), 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, responseData)
 | |
| 	responseContentType := getResponseDataType(responseOption.ContentType)
 | |
| 	responseStr := serialize.JSON.MarshalForStringIgnoreError(responseException.Data())
 | |
| 	if responseInstance, err := wrapper.NewJson(responseStr, &wrapper.Option{XmlName: responseOption.XmlName}); nil != err {
 | |
| 		// 接口处理成功, 数据序列化出现异常
 | |
| 		panic(err.Error()) // 直接panic, 交给gin处理
 | |
| 	} else {
 | |
| 		finalResponseData, _ := responseInstance.Marshal(responseContentType)
 | |
| 		ctx.Data(http.StatusOK, responseOption.ContentType, 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, responseOption *define.ResponseOption) {
 | |
| 	if nil == e {
 | |
| 		e = exception.NewSuccess(map[string]any{})
 | |
| 	}
 | |
| 	if !define.GetHttpHandleConfig().DisableDebugStackOutput && nil != e {
 | |
| 		stack := e.GetStack()
 | |
| 		if len(stack) > 0 {
 | |
| 			fmt.Println(stack)
 | |
| 		}
 | |
| 	}
 | |
| 	Send(ctx, e.Code(), http.StatusOK, e.Data(), responseOption)
 | |
| }
 | |
| 
 | |
| // 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)
 | |
| }
 |