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)
 | 
						|
}
 |