Browse Source

feat: create Mini Program entertainment mini-drama related interface (#711)

houseme 2 years ago
parent
commit
cc201fcece

+ 2 - 1
miniprogram/README.md

@@ -21,7 +21,7 @@ miniprogram.GetAnalysis().GetAnalysisDailyRetain()
 ```
 
 ### 小程序虚拟支付 
-#### `注意:需要传入 Appkey 的值`
+#### `注意:需要传入 Appkey、OfferID 的值`
 相关文档:[小程序虚拟支付](https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/virtual-payment.html)
 ```go
 wc := wechat.NewWechat()
@@ -29,6 +29,7 @@ miniprogram := wc.GetMiniProgram(&miniConfig.Config{
     AppID:     "xxx",
     AppSecret: "xxx",
     AppKey:    "xxx",
+    OfferID:   "xxx",
     Cache: cache.NewRedis(&redis.Options{
         Addr: "",
     }),

+ 1 - 0
miniprogram/config/config.go

@@ -10,5 +10,6 @@ type Config struct {
 	AppID     string `json:"app_id"`     // appid
 	AppSecret string `json:"app_secret"` // appSecret
 	AppKey    string `json:"app_key"`    // appKey
+	OfferID   string `json:"offer_id"`   // offerId
 	Cache     cache.Cache
 }

+ 100 - 0
miniprogram/minidrama/constant.go

@@ -0,0 +1,100 @@
+/*
+ *   Copyright silenceper/wechat Author(https://silenceper.com/wechat/). All Rights Reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ *    You can obtain one at https://github.com/silenceper/wechat.
+ *
+ */
+
+package minidrama
+
+const (
+	// Success 错误码 0、成功
+	Success ErrCode = 0
+	// SystemError 错误码 -1、系统错误
+	SystemError ErrCode = -1
+	// InitError 错误码 -2 初始化未完成,请稍后再试
+	InitError ErrCode = -2
+	// FormatError 错误码 47001	输入格式错误
+	FormatError ErrCode = 47001
+	// ParamError 错误码 47003	参数不符合要求
+	ParamError ErrCode = 47003
+	// PostError 错误码 44002	POST 内容为空
+	PostError ErrCode = 44002
+	// MethodError 错误码 43002	HTTP 请求必须使用 POST 方法
+	MethodError ErrCode = 43002
+	// VideoTypeError 错误码 10090001	视频类型不支持
+	VideoTypeError ErrCode = 10090001
+	// ImageTypeError 错误码 10090002	图片类型不支持
+	ImageTypeError ErrCode = 10090002
+	// ImageURLError 错误码 10090003	图片 URL 无效
+	ImageURLError ErrCode = 10090003
+	// ResourceType 错误码 10090005	resource_type 无效
+	ResourceType ErrCode = 10090005
+	// OperationError 错误码 10093011	操作失败
+	OperationError ErrCode = 10093011
+	// ParamError2 错误码 10093014	参数错误(包括参数格式、类型等错误)
+	ParamError2 ErrCode = 10093014
+	// OperationFrequentError 错误码 10093023	操作过于频繁
+	OperationFrequentError ErrCode = 10093023
+	// ResourceNotExistError 错误码 10093030	资源不存在
+	ResourceNotExistError ErrCode = 10093030
+)
+
+const (
+	// singleFileUpload 单个文件上传,上传媒体(和封面)文件,上传小文件(小于 10MB)时使用。上传大文件请使用分片上传接口。
+	singleFileUpload = "https://api.weixin.qq.com/wxa/sec/vod/singlefileupload?access_token="
+
+	// pullUpload 拉取上传,该接口用于将一个网络上的视频拉取上传到平台。
+	pullUpload = "https://api.weixin.qq.com/wxa/sec/vod/pullupload?access_token="
+
+	// getTask 查询任务,该接口用于查询拉取上传的任务状态。
+	getTask = "https://api.weixin.qq.com/wxa/sec/vod/gettask?access_token="
+
+	// applyUpload 申请分片上传
+	applyUpload = "https://api.weixin.qq.com/wxa/sec/vod/applyupload?access_token="
+
+	// uploadPart 上传分片
+	uploadPart = "https://api.weixin.qq.com/wxa/sec/vod/uploadpart?access_token="
+
+	// commitUpload 确认上传,该接口用于完成整个分片上传流程,合并所有文件分片,确认媒体文件(和封面图片文件)上传到平台的结果,返回文件的 ID。请求中需要给出每一个分片的 part_number 和 etag,用来校验分片的准确性。
+	commitUpload = "https://api.weixin.qq.com/wxa/sec/vod/commitupload?access_token="
+
+	// listMedia 获取媒体列表
+	listMedia = "https://api.weixin.qq.com/wxa/sec/vod/listmedia?access_token="
+
+	// getMedia 获取媒资详细信息,该接口用于获取已上传到平台的指定媒资信息,用于开发者后台管理使用。用于给用户客户端播放的链接应该使用 getmedialink 接口获取。
+	getMedia = "https://api.weixin.qq.com/wxa/sec/vod/getmedia?access_token="
+
+	// getMediaLink 获取媒资播放链接,该接口用于获取视频临时播放链接,用于给用户的播放使用。只有审核通过的视频才能通过该接口获取播放链接。
+	getMediaLink = "https://api.weixin.qq.com/wxa/sec/vod/getmedialink?access_token="
+
+	// deleteMedia 删除媒体,该接口用于删除指定媒资。
+	deleteMedia = "https://api.weixin.qq.com/wxa/sec/vod/deletemedia?access_token="
+
+	// auditDrama 审核剧本
+	auditDrama = "https://api.weixin.qq.com/wxa/sec/vod/auditdrama?access_token="
+
+	// listDramas 获取剧目列表
+	listDramas = "https://api.weixin.qq.com/wxa/sec/vod/listdramas?access_token="
+
+	// getDrama 获取剧目信息,该接口用于查询已提交的剧目。
+	getDrama = "https://api.weixin.qq.com/wxa/sec/vod/getdrama?access_token="
+
+	// getCdnUsageData 查询 CDN 用量数据,该接口用于查询点播 CDN 的流量数据。
+	getCdnUsageData = "https://api.weixin.qq.com/wxa/sec/vod/getcdnusagedata?access_token="
+
+	// getCdnLogs 查询 CDN 日志,该接口用于查询点播 CDN 的日志。
+	getCdnLogs = "https://api.weixin.qq.com/wxa/sec/vod/getcdnlogs?access_token="
+)

+ 32 - 0
miniprogram/minidrama/doc.go

@@ -0,0 +1,32 @@
+/*
+ *   Copyright silenceper/wechat Author(https://silenceper.com/wechat/). All Rights Reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ *   You can obtain one at https://github.com/silenceper/wechat.
+ *
+ */
+
+// Package minidrama Mini Program entertainment mini-drama related interface
+package minidrama
+
+import (
+	"github.com/silenceper/wechat/v2/miniprogram/context"
+)
+
+// NewMiniDrama 实例化小程序娱乐直播 API
+func NewMiniDrama(ctx *context.Context) *MiniDrama {
+	return &MiniDrama{
+		ctx: ctx,
+	}
+}

File diff suppressed because it is too large
+ 440 - 0
miniprogram/minidrama/domain.go


+ 346 - 0
miniprogram/minidrama/minidrama.go

@@ -0,0 +1,346 @@
+/*
+ *   Copyright silenceper/wechat Author(https://silenceper.com/wechat/). All Rights Reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ *    You can obtain one at https://github.com/silenceper/wechat.
+ *
+ */
+
+package minidrama
+
+import (
+	"context"
+	"strconv"
+
+	"github.com/silenceper/wechat/v2/util"
+)
+
+// SingleFileUpload 单文件上传
+func (s *MiniDrama) SingleFileUpload(ctx context.Context, in *SingleFileUploadRequest) (out *SingleFileUploadResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, singleFileUpload); err != nil {
+		return
+	}
+	var (
+		fields = []util.MultipartFormField{
+			{
+				IsFile:    true,
+				Fieldname: "media_data",
+				Filename:  string(in.MediaData),
+			}, {
+				IsFile:    false,
+				Fieldname: "media_name",
+				Value:     []byte(in.MediaName),
+			}, {
+				IsFile:    false,
+				Fieldname: "media_type",
+				Value:     []byte(in.MediaType),
+			},
+		}
+		response []byte
+	)
+
+	if in.CoverType != "" && in.CoverData != nil {
+		fields = append(fields, util.MultipartFormField{
+			IsFile:    false,
+			Fieldname: "cover_type",
+			Value:     []byte(in.CoverType),
+		})
+		fields = append(fields, util.MultipartFormField{
+			IsFile:    true,
+			Fieldname: "cover_data",
+			Filename:  string(in.CoverData),
+		})
+	}
+
+	if in.SourceContext != "" {
+		fields = append(fields, util.MultipartFormField{
+			IsFile:    false,
+			Fieldname: "source_context",
+			Value:     []byte(in.SourceContext),
+		})
+	}
+
+	if response, err = util.PostMultipartForm(fields, address); err != nil {
+		return
+	}
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "SingleFileUpload")
+	return
+}
+
+// PullUpload 拉取上传
+func (s *MiniDrama) PullUpload(ctx context.Context, in *PullUploadRequest) (out *PullUploadResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, pullUpload); err != nil {
+		return
+	}
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "PullUpload")
+	return
+}
+
+// GetTask 查询任务状态
+func (s *MiniDrama) GetTask(ctx context.Context, in *GetTaskRequest) (out *GetTaskResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, getTask); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "GetTask")
+	return
+}
+
+// ApplyUpload 申请分片上传
+func (s *MiniDrama) ApplyUpload(ctx context.Context, in *ApplyUploadRequest) (out *ApplyUploadResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, applyUpload); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "ApplyUpload")
+	return
+}
+
+// UploadPart 上传分片
+// Content-Type 需要指定为 multipart/form-data; boundary=<delimiter>,<箭头括号>表示必须替换为有效值的变量。
+func (s *MiniDrama) UploadPart(ctx context.Context, in *UploadPartRequest) (out *UploadPartResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, uploadPart); err != nil {
+		return
+	}
+
+	var (
+		fields = []util.MultipartFormField{
+			{
+				IsFile:    true,
+				Fieldname: "data",
+				Filename:  string(in.Data),
+			}, {
+				IsFile:    false,
+				Fieldname: "upload_id",
+				Value:     []byte(in.UploadID),
+			}, {
+				IsFile:    false,
+				Fieldname: "part_number",
+				Value:     []byte(strconv.Itoa(in.PartNumber)),
+			}, {
+				IsFile:    false,
+				Fieldname: "resource_type",
+				Value:     []byte(strconv.Itoa(in.PartNumber)),
+			},
+		}
+		response []byte
+	)
+	if response, err = util.PostMultipartForm(fields, address); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "UploadPart")
+	return
+}
+
+// CommitUpload 确认上传
+func (s *MiniDrama) CommitUpload(ctx context.Context, in *CommitUploadRequest) (out *CommitUploadResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, commitUpload); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "CommitUpload")
+	return
+}
+
+// ListMedia 获取媒体列表
+func (s *MiniDrama) ListMedia(ctx context.Context, in *ListMediaRequest) (out *ListMediaResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, listMedia); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "ListMedia")
+	return
+}
+
+// GetMedia 获取媒资详细信息
+func (s *MiniDrama) GetMedia(ctx context.Context, in *GetMediaRequest) (out *GetMediaResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, getMedia); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "GetMedia")
+	return
+}
+
+// GetMediaLink 获取媒资播放链接
+func (s *MiniDrama) GetMediaLink(ctx context.Context, in *GetMediaLinkRequest) (out *GetMediaLinkResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, getMediaLink); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "GetMediaLink")
+	return
+}
+
+// DeleteMedia 删除媒体
+func (s *MiniDrama) DeleteMedia(ctx context.Context, in *DeleteMediaRequest) (out *DeleteMediaResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, deleteMedia); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "DeleteMedia")
+	return
+}
+
+// AuditDrama 审核剧本
+func (s *MiniDrama) AuditDrama(ctx context.Context, in *AuditDramaRequest) (out *AuditDramaResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, auditDrama); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "AuditDrama")
+	return
+}
+
+// ListDramas 获取剧目列表
+func (s *MiniDrama) ListDramas(ctx context.Context, in *ListDramasRequest) (out *ListDramasResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, listDramas); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "ListDramas")
+	return
+}
+
+// GetDrama 获取剧目信息
+func (s *MiniDrama) GetDrama(ctx context.Context, in *GetDramaRequest) (out *GetDramaResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, getDrama); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "GetDrama")
+	return
+}
+
+// GetCdnUsageData 查询 CDN 用量数据
+func (s *MiniDrama) GetCdnUsageData(ctx context.Context, in *GetCdnUsageDataRequest) (out *GetCdnUsageDataResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, getCdnUsageData); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "GetCdnUsageData")
+	return
+}
+
+// GetCdnLogs 查询 CDN 日志
+func (s *MiniDrama) GetCdnLogs(ctx context.Context, in *GetCdnLogsRequest) (out *GetCdnLogsResponse, err error) {
+	var address string
+	if address, err = s.requestAddress(ctx, getCdnLogs); err != nil {
+		return
+	}
+
+	var response []byte
+	if response, err = util.PostJSONContext(ctx, address, in); err != nil {
+		return
+	}
+	// 使用通用方法返回错误
+	err = util.DecodeWithError(response, out, "GetCdnLogs")
+	return
+}
+
+// requestAddress 请求地址
+func (s *MiniDrama) requestAddress(_ context.Context, url string) (string, error) {
+	accessToken, err := s.ctx.GetAccessToken()
+	if err != nil {
+		return "", err
+	}
+	return url + accessToken, nil
+}

+ 6 - 0
miniprogram/miniprogram.go

@@ -11,6 +11,7 @@ import (
 	"github.com/silenceper/wechat/v2/miniprogram/context"
 	"github.com/silenceper/wechat/v2/miniprogram/encryptor"
 	"github.com/silenceper/wechat/v2/miniprogram/message"
+	"github.com/silenceper/wechat/v2/miniprogram/minidrama"
 	"github.com/silenceper/wechat/v2/miniprogram/privacy"
 	"github.com/silenceper/wechat/v2/miniprogram/qrcode"
 	"github.com/silenceper/wechat/v2/miniprogram/riskcontrol"
@@ -138,3 +139,8 @@ func (miniProgram *MiniProgram) GetOpenAPI() *openapi.OpenAPI {
 func (miniProgram *MiniProgram) GetVirtualPayment() *virtualpayment.VirtualPayment {
 	return virtualpayment.NewVirtualPayment(miniProgram.ctx)
 }
+
+// GetMiniDrama 小程序娱乐微短剧
+func (miniProgram *MiniProgram) GetMiniDrama() *minidrama.MiniDrama {
+	return minidrama.NewMiniDrama(miniProgram.ctx)
+}

+ 14 - 56
miniprogram/virtualpayment/virtualpayment.go

@@ -60,10 +60,7 @@ func (s *VirtualPayment) QueryUserBalance(ctx context.Context, in *QueryUserBala
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "QueryUserBalance"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "QueryUserBalance")
 	return
 }
 
@@ -91,10 +88,7 @@ func (s *VirtualPayment) CurrencyPay(ctx context.Context, in *CurrencyPayRequest
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "CurrencyPay"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "CurrencyPay")
 	return
 }
 
@@ -122,10 +116,7 @@ func (s *VirtualPayment) QueryOrder(ctx context.Context, in *QueryOrderRequest)
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "QueryOrder"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "QueryOrder")
 	return
 }
 
@@ -153,10 +144,7 @@ func (s *VirtualPayment) CancelCurrencyPay(ctx context.Context, in *CancelCurren
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "CancelCurrencyPay"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "CancelCurrencyPay")
 	return
 }
 
@@ -186,10 +174,7 @@ func (s *VirtualPayment) NotifyProvideGoods(ctx context.Context, in *NotifyProvi
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "NotifyProvideGoods"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "NotifyProvideGoods")
 	return
 }
 
@@ -218,10 +203,7 @@ func (s *VirtualPayment) PresentCurrency(ctx context.Context, in *PresentCurrenc
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "PresentCurrency"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "PresentCurrency")
 	return
 }
 
@@ -250,10 +232,7 @@ func (s *VirtualPayment) DownloadBill(ctx context.Context, in *DownloadBillReque
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "DownloadBill"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "DownloadBill")
 	return
 }
 
@@ -282,10 +261,7 @@ func (s *VirtualPayment) RefundOrder(ctx context.Context, in *RefundOrderRequest
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "RefundOrder"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "RefundOrder")
 	return
 }
 
@@ -314,10 +290,7 @@ func (s *VirtualPayment) CreateWithdrawOrder(ctx context.Context, in *CreateWith
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "CreateWithdrawOrder"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "CreateWithdrawOrder")
 	return
 }
 
@@ -346,10 +319,7 @@ func (s *VirtualPayment) QueryWithdrawOrder(ctx context.Context, in *QueryWithdr
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "QueryWithdrawOrder"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "QueryWithdrawOrder")
 	return
 }
 
@@ -378,10 +348,7 @@ func (s *VirtualPayment) StartUploadGoods(ctx context.Context, in *StartUploadGo
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "StartUploadGoods"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "StartUploadGoods")
 	return
 }
 
@@ -410,10 +377,7 @@ func (s *VirtualPayment) QueryUploadGoods(ctx context.Context, in *QueryUploadGo
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "QueryUploadGoods"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "QueryUploadGoods")
 	return
 }
 
@@ -442,10 +406,7 @@ func (s *VirtualPayment) StartPublishGoods(ctx context.Context, in *StartPublish
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "StartPublishGoods"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "StartPublishGoods")
 	return
 }
 
@@ -474,10 +435,7 @@ func (s *VirtualPayment) QueryPublishGoods(ctx context.Context, in *QueryPublish
 	}
 
 	// 使用通用方法返回错误
-	if err = util.DecodeWithError(response, out, "QueryPublishGoods"); err != nil {
-		return
-	}
-
+	err = util.DecodeWithError(response, out, "QueryPublishGoods")
 	return
 }