响应数据支持根据不同的content_type使用不同的发送方式 #11
| @ -146,3 +146,10 @@ func (logic *LogicAfterResponse) AddFailureHook(f func()) { | |||||||
| 	defer logic.Lock.Unlock() | 	defer logic.Lock.Unlock() | ||||||
| 	logic.FailureHookFuncList = append(logic.FailureHookFuncList, f) | 	logic.FailureHookFuncList = append(logic.FailureHookFuncList, f) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ResponseOption 响应的可用选项 | ||||||
|  | type ResponseOption struct { | ||||||
|  | 	ContentType string         `json:"content_type"` // 响应的contentType | ||||||
|  | 	Extension   map[string]any `json:"extension"`    // 扩展数据 | ||||||
|  | 	XmlName     string         `json:"xml_name"`     // 以xml文件格式响应数据时, Xml文件名(根节点) | ||||||
|  | } | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								go.mod
									
									
									
									
									
								
							| @ -1,16 +1,16 @@ | |||||||
| module git.zhangdeman.cn/zhangdeman/gin | module git.zhangdeman.cn/zhangdeman/gin | ||||||
|  |  | ||||||
| go 1.23.0 | go 1.24.1 | ||||||
|  |  | ||||||
| toolchain go1.24.2 | toolchain go1.24.2 | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	git.zhangdeman.cn/gateway/api-doc v0.0.0-20250220105101-71d6db967dc5 | 	git.zhangdeman.cn/gateway/api-doc v0.0.0-20250220105101-71d6db967dc5 | ||||||
| 	git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c | 	git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250425024726-cc17224cb995 | ||||||
| 	git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091724-ca151fbc1f06 | 	git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091724-ca151fbc1f06 | ||||||
| 	git.zhangdeman.cn/zhangdeman/logger v0.0.0-20241125083316-eab7bab9d7ad | 	git.zhangdeman.cn/zhangdeman/logger v0.0.0-20241125083316-eab7bab9d7ad | ||||||
| 	git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442 | 	git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442 | ||||||
| 	git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd | 	git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250428041157-135850ee8a58 | ||||||
| 	git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740 | 	git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740 | ||||||
| 	github.com/gin-gonic/gin v1.10.0 | 	github.com/gin-gonic/gin v1.10.0 | ||||||
| 	github.com/go-playground/validator/v10 v10.26.0 | 	github.com/go-playground/validator/v10 v10.26.0 | ||||||
| @ -20,6 +20,7 @@ require ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
|  | 	git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20250428131118-7e464374bb4c // indirect | ||||||
| 	git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda // indirect | 	git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda // indirect | ||||||
| 	git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 // indirect | 	git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 // indirect | ||||||
| 	git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect | 	git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.sum
									
									
									
									
									
								
							| @ -10,6 +10,10 @@ git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250215141718-8232f587a6ea h1:6b9bfq | |||||||
| git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250215141718-8232f587a6ea/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250215141718-8232f587a6ea/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= | ||||||
| git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c h1:cl3gQGXQpJ8ugDs0C/hQLfcvF4lGBm5BeABLvROFDoM= | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c h1:cl3gQGXQpJ8ugDs0C/hQLfcvF4lGBm5BeABLvROFDoM= | ||||||
| git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= | ||||||
|  | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250425024726-cc17224cb995 h1:LmPRAf0AsxRVFPibdpZR89ajlsz8hof2IvMMyTqiEq4= | ||||||
|  | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250425024726-cc17224cb995/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc= | ||||||
|  | git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20250428131118-7e464374bb4c h1:vtVIB/AP5MzpHi2onTd0PtQnh0q+svXTtZu41Z529ms= | ||||||
|  | git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20250428131118-7e464374bb4c/go.mod h1:onY+qrB+Uwfuv75JlgHlGdkirAfYcINrvCashtVoBX0= | ||||||
| git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda h1:bMD6r9gjRy7cO+T4zRQVYAesgIblBdTnhzT1vN5wjvI= | git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda h1:bMD6r9gjRy7cO+T4zRQVYAesgIblBdTnhzT1vN5wjvI= | ||||||
| git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda/go.mod h1:dT0rmHcJ9Z9IqWeMIt7YzR88nKkNV2V3dfG0j9Q6lK0= | git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda/go.mod h1:dT0rmHcJ9Z9IqWeMIt7YzR88nKkNV2V3dfG0j9Q6lK0= | ||||||
| git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 h1:s6d4b6yY+NaK1AzoBD1pxqsuygEHQz0Oie86c45geDw= | git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 h1:s6d4b6yY+NaK1AzoBD1pxqsuygEHQz0Oie86c45geDw= | ||||||
| @ -24,6 +28,8 @@ git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQ | |||||||
| git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI= | git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI= | ||||||
| git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7GG14qgXKB4MEXQFOe7/UYebsqMfPaSX80TcPdOosI= | git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7GG14qgXKB4MEXQFOe7/UYebsqMfPaSX80TcPdOosI= | ||||||
| git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs= | git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs= | ||||||
|  | git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250428041157-135850ee8a58 h1:fTkmucGaUoKocoX+ASM4AnwsAVJOtOOLUFSqA+uwVzg= | ||||||
|  | git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250428041157-135850ee8a58/go.mod h1:Ig3GZC2hJDkQp7F8Tm53GvMWLh9bdbbauow/vxGO4YA= | ||||||
| git.zhangdeman.cn/zhangdeman/trace v0.0.0-20250412104923-c1ecb1bfe8d5 h1:dD1Q/MIrRmIhKqfYPH+y167ca9CKwTPuQt3c1hXWGJ8= | git.zhangdeman.cn/zhangdeman/trace v0.0.0-20250412104923-c1ecb1bfe8d5 h1:dD1Q/MIrRmIhKqfYPH+y167ca9CKwTPuQt3c1hXWGJ8= | ||||||
| git.zhangdeman.cn/zhangdeman/trace v0.0.0-20250412104923-c1ecb1bfe8d5/go.mod h1:PB486NC82nuvn5yi+U2i48ogX/9EAETWAHd8O9TwY9k= | git.zhangdeman.cn/zhangdeman/trace v0.0.0-20250412104923-c1ecb1bfe8d5/go.mod h1:PB486NC82nuvn5yi+U2i48ogX/9EAETWAHd8O9TwY9k= | ||||||
| git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI= | git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI= | ||||||
|  | |||||||
| @ -8,8 +8,11 @@ | |||||||
| package response | package response | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"git.zhangdeman.cn/zhangdeman/dynamic-struct/wrapper" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"git.zhangdeman.cn/zhangdeman/serialize" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"git.zhangdeman.cn/zhangdeman/exception" | 	"git.zhangdeman.cn/zhangdeman/exception" | ||||||
| @ -51,9 +54,9 @@ func Success(ctx *gin.Context, data any) { | |||||||
| // Author : go_developer@163.com<白茶清欢> | // Author : go_developer@163.com<白茶清欢> | ||||||
| // | // | ||||||
| // Date : 14:52 2024/9/24 | // Date : 14:52 2024/9/24 | ||||||
| func SuccessWithExtension(ctx *gin.Context, data any, extension map[string]any) { | func SuccessWithExtension(ctx *gin.Context, data any, responseOption *define.ResponseOption) { | ||||||
| 	successException := exception.NewSuccess(data) | 	successException := exception.NewSuccess(data) | ||||||
| 	Send(ctx, successException.GetCode(), successException.GetHttpCode(), successException.GetData(), extension) | 	Send(ctx, successException.GetCode(), successException.GetHttpCode(), successException.GetData(), responseOption) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Send 基础的发送数据 | // Send 基础的发送数据 | ||||||
| @ -61,32 +64,64 @@ func SuccessWithExtension(ctx *gin.Context, data any, extension map[string]any) | |||||||
| // Author : go_developer@163.com<白茶清欢> | // Author : go_developer@163.com<白茶清欢> | ||||||
| // | // | ||||||
| // Date : 22:40 2022/6/25 | // Date : 22:40 2022/6/25 | ||||||
| func Send(ctx *gin.Context, code any, httpCode int, data any, extension map[string]any) { | func Send(ctx *gin.Context, code any, httpCode int, data any, responseOption *define.ResponseOption) { | ||||||
|  | 	if nil == responseOption { | ||||||
|  | 		responseOption = &define.ResponseOption{ | ||||||
|  | 			ContentType: "application/json", | ||||||
|  | 			Extension:   make(map[string]any), | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if len(responseOption.ContentType) == 0 { | ||||||
|  | 		responseOption.ContentType = "application/json" | ||||||
|  | 	} | ||||||
|  | 	if len(responseOption.XmlName) == 0 { | ||||||
|  | 		responseOption.XmlName = "ResponseData" | ||||||
|  | 	} | ||||||
| 	// 设置请求是否成功的标识 | 	// 设置请求是否成功的标识 | ||||||
| 	ctx.Set(define.GetHttpHandleConfig().RequestIsSuccessField, fmt.Sprintf("%v", code) == fmt.Sprintf("%v", successBusinessCode)) | 	ctx.Set(define.GetHttpHandleConfig().RequestIsSuccessField, fmt.Sprintf("%v", code) == fmt.Sprintf("%v", successBusinessCode)) | ||||||
| 	if ctx.GetBool(hasSendResponseFlag) { | 	if ctx.GetBool(hasSendResponseFlag) { | ||||||
| 		// 已经发送过数据, 后面在发送数据, 不执行 | 		// 已经发送过数据, 后面在发送数据, 不执行 | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	finishRequestTime := time.Now().UnixMilli() |  | ||||||
| 	// 设置数据已发送的标识 | 	// 设置数据已发送的标识 | ||||||
| 	defer ctx.Set(hasSendResponseFlag, true) | 	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() | 	responseConfig := define.GetHttpHandleConfig() | ||||||
| 	responseData := map[string]any{ | 	responseData := map[string]any{ | ||||||
| 		responseConfig.ResponseCodeField:      code, | 		responseConfig.ResponseCodeField:      code, | ||||||
| 		responseConfig.ResponseMessageField:   exception.GetMessage(code), | 		responseConfig.ResponseMessageField:   exception.GetMessage(code), | ||||||
| 		responseConfig.ResponseTraceIDField:   ctx.GetString(responseConfig.ResponseTraceIDField), | 		responseConfig.ResponseTraceIDField:   ctx.GetString(responseConfig.ResponseTraceIDField), | ||||||
| 		responseConfig.ResponseDataField:      data, | 		responseConfig.ResponseDataField:      data, | ||||||
| 		responseConfig.HandleRequestCostField: finishRequestTime - ctx.GetInt64(responseConfig.StartRequestTimeField), | 		responseConfig.HandleRequestCostField: finishTime.UnixMilli() - ctx.GetInt64(responseConfig.StartRequestTimeField), | ||||||
| 	} | 	} | ||||||
| 	if responseConfig.EnableExtensionOutput && nil != extension { | 	if responseConfig.EnableExtensionOutput && nil != extension { | ||||||
| 		responseData[responseConfig.ExtensionOutputField] = extension | 		responseData[responseConfig.ExtensionOutputField] = extension | ||||||
| 	} | 	} | ||||||
| 	// 记录完成时间 | 	return responseData | ||||||
| 	ctx.Set(responseConfig.FinishRequestTimeField, finishRequestTime) |  | ||||||
| 	ctx.Set(responseConfig.ResponseDataField, responseData) |  | ||||||
| 	responseException := exception.New(code, httpCode, responseData) |  | ||||||
| 	ctx.JSON(responseException.GetHttpCode(), responseException.GetData()) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // SendWithStatusOK ... | // SendWithStatusOK ... | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user