jimmyyem 4 ماه پیش
والد
کامیت
9e6c0263c5

+ 40 - 0
desc/wechat/avatar.api

@@ -69,6 +69,38 @@ type (
         Policy *string `json:"policy"`
         Signature *string `json:"signature"`
     }
+
+	// send text | 数字人-发送消息
+	SendTextReq {
+		CardId *uint64 `json:"cardId"`
+		SessionId *string `json:"sessionId"`
+		Text *string `json:"text"`
+		IsStream *bool `json:"isStream,optional"`
+		Index *int32 `json:"index,optional"`
+		Position *string `json:"position,optional"`
+	}
+	SendTextResp {
+		BaseDataInfo
+		Data SendText `json:"data"`
+	}
+	SendText {
+		SessionId *string `json:"sessionId"`
+		UniqueCode *string `json:"uniqueCode"`
+	}
+
+	// stop instance | 数字人-停止实例
+	StopInstanceReq {
+		CardId *uint64 `json:"cardId"`
+		SessionId *string `json:"sessionId"`
+	}
+	StopInstanceResp {
+		BaseDataInfo
+		Data StopInstance `json:"data"`
+	}
+	StopInstance {
+		SessionId *string `json:"sessionId"`
+		RequestId *string `json:"requestId"`
+	}
 )
 
 @server(
@@ -82,6 +114,14 @@ service Wechat {
 	@handler getApiAvatarConfig
 	post /api/avatar/config (AvatarConfigReq) returns (AvatarConfigResp)
 
+	// send text  | 发送消息
+	@handler sendApiAvatarText
+	post /api/avatar/sendText (SendTextReq) returns (SendTextResp)
+
+	// stop avatar instance  | 停止数字人实例
+	@handler stopApiAvatar
+	post /api/avatar/stop (StopInstanceReq) returns (StopInstanceResp)
+
 	// get avatar configuration | 阿里云sts
     @handler getAcsResponse
     post /api/avatar/sts () returns (AvatarStsResp)

+ 65 - 0
hook/aliyun/avatar.go

@@ -8,6 +8,7 @@ import (
 	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
 	util "github.com/alibabacloud-go/tea-utils/v2/service"
 	"github.com/alibabacloud-go/tea/tea"
+	"github.com/suyuan32/simple-admin-common/utils/uuidx"
 	"strconv"
 	"strings"
 	"wechat-api/internal/utils/jwt"
@@ -69,6 +70,70 @@ func StartInstance(userId uint64, jsonData AiTypes) (*avatar20220130.StartInstan
 	return nil, errors.New(*_result.Body.Message)
 }
 
+// SendText 发送消息
+func SendText(sessionId, text string, isStream bool, index int32, position string, jsonData AiTypes) (*avatar20220130.SendTextResponseBodyData, error) {
+	accessKeyId := jsonData.AccessKeyId
+	accessKeySecret := jsonData.AccessKeySecret
+	tenantId := jsonData.TenantId
+
+	client, _err := CreateClient(accessKeyId, accessKeySecret)
+	if _err != nil {
+		return nil, _err
+	}
+
+	unicodeCode := uuidx.NewUUID().String()
+	sendTextRequest := &avatar20220130.SendTextRequest{
+		TenantId:   tea.Int64(int64(tenantId)),
+		SessionId:  &sessionId,
+		UniqueCode: &unicodeCode,
+		Text:       &text,
+	}
+	if isStream == true {
+		sendTextRequest.StreamExtension = &avatar20220130.SendTextRequestStreamExtension{
+			Index:    &index,
+			Position: &position,
+			IsStream: &isStream,
+		}
+	}
+
+	_result, _err := client.SendText(sendTextRequest)
+	if _err != nil {
+		return nil, _err
+	}
+	if *_result.Body.Success {
+		fmt.Println(_result.Body.Data)
+		return _result.Body.Data, nil
+	}
+	return nil, errors.New(*_result.Body.Message)
+}
+
+// StopInstance 停止数字人
+func StopInstance(sessionId string, jsonData AiTypes) (*avatar20220130.StopInstanceResponseBodyData, error) {
+	accessKeyId := jsonData.AccessKeyId
+	accessKeySecret := jsonData.AccessKeySecret
+	tenantId := jsonData.TenantId
+
+	client, _err := CreateClient(accessKeyId, accessKeySecret)
+	if _err != nil {
+		return nil, _err
+	}
+
+	stopInstanceRequest := &avatar20220130.StopInstanceRequest{
+		TenantId:  tea.Int64(int64(tenantId)),
+		SessionId: &sessionId,
+	}
+
+	_result, _err := client.StopInstance(stopInstanceRequest)
+	if _err != nil {
+		return nil, _err
+	}
+	if *_result.Body.Success {
+		fmt.Println(_result.Body.Data)
+		return _result.Body.Data, nil
+	}
+	return nil, errors.New(*_result.Body.Message)
+}
+
 func _main(args []*string) (_err error) {
 	client, _err := CreateClient("", "")
 	if _err != nil {

+ 44 - 0
internal/handler/avatar/send_api_avatar_text_handler.go

@@ -0,0 +1,44 @@
+package avatar
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/avatar"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /api/avatar/sendText avatar SendApiAvatarText
+//
+// send text  | 发送消息
+//
+// send text  | 发送消息
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: SendTextReq
+//
+// Responses:
+//  200: SendTextResp
+
+func SendApiAvatarTextHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.SendTextReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := avatar.NewSendApiAvatarTextLogic(r.Context(), svcCtx)
+		resp, err := l.SendApiAvatarText(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/avatar/stop_api_avatar_handler.go

@@ -0,0 +1,44 @@
+package avatar
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/avatar"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /api/avatar/stop avatar StopApiAvatar
+//
+// stop avatar instance  | 停止数字人实例
+//
+// stop avatar instance  | 停止数字人实例
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: StopInstanceReq
+//
+// Responses:
+//  200: StopInstanceResp
+
+func StopApiAvatarHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.StopInstanceReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := avatar.NewStopApiAvatarLogic(r.Context(), svcCtx)
+		resp, err := l.StopApiAvatar(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 10 - 0
internal/handler/routes.go

@@ -1301,6 +1301,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				},
 				{
 					Method:  http.MethodPost,
+					Path:    "/api/avatar/sendText",
+					Handler: avatar.SendApiAvatarTextHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/api/avatar/stop",
+					Handler: avatar.StopApiAvatarHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
 					Path:    "/api/avatar/sts",
 					Handler: avatar.GetAcsResponseHandler(serverCtx),
 				},

+ 67 - 0
internal/logic/avatar/send_api_avatar_text_logic.go

@@ -0,0 +1,67 @@
+package avatar
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	avatar20220130 "github.com/alibabacloud-go/avatar-20220130/v2/client"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"wechat-api/ent/wxcard"
+	"wechat-api/hook/aliyun"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type SendApiAvatarTextLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewSendApiAvatarTextLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendApiAvatarTextLogic {
+	return &SendApiAvatarTextLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+func (l *SendApiAvatarTextLogic) SendApiAvatarText(req *types.SendTextReq) (*types.SendTextResp, error) {
+	card, err := l.svcCtx.DB.WxCard.Query().Where(wxcard.ID(*req.CardId)).Only(l.ctx)
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	if card.AiInfo == "" {
+		return nil, errorx.NewInvalidArgumentError("AiInfo is empty")
+	}
+
+	var jsonData aliyun.AiTypes
+	err = json.Unmarshal([]byte(card.AiInfo), &jsonData)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError(err.Error())
+	}
+
+	var aiData *avatar20220130.SendTextResponseBodyData
+	aiData, err = aliyun.SendText(*req.SessionId, *req.Text, *req.IsStream, *req.Index, *req.Position, jsonData)
+	fmt.Printf("aliData=%v error=%v \n", aiData, err)
+	if err != nil {
+		return nil, errorx.NewInternalError(err.Error())
+	}
+
+	return &types.SendTextResp{
+		BaseDataInfo: types.BaseDataInfo{
+			Code: 0,
+			Msg:  errormsg.Success,
+		},
+		Data: types.SendText{
+			UniqueCode: aiData.UniqueCode,
+			SessionId:  aiData.SessionId,
+		},
+	}, nil
+}

+ 66 - 0
internal/logic/avatar/stop_api_avatar_logic.go

@@ -0,0 +1,66 @@
+package avatar
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	avatar20220130 "github.com/alibabacloud-go/avatar-20220130/v2/client"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"wechat-api/ent/wxcard"
+	"wechat-api/hook/aliyun"
+	"wechat-api/internal/utils/dberrorhandler"
+
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type StopApiAvatarLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewStopApiAvatarLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StopApiAvatarLogic {
+	return &StopApiAvatarLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *StopApiAvatarLogic) StopApiAvatar(req *types.StopInstanceReq) (*types.StopInstanceResp, error) {
+	card, err := l.svcCtx.DB.WxCard.Query().Where(wxcard.ID(*req.CardId)).Only(l.ctx)
+	if err != nil {
+		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
+	}
+
+	if card.AiInfo == "" {
+		return nil, errorx.NewInvalidArgumentError("AiInfo is empty")
+	}
+
+	var jsonData aliyun.AiTypes
+	err = json.Unmarshal([]byte(card.AiInfo), &jsonData)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError(err.Error())
+	}
+
+	var aiData *avatar20220130.StopInstanceResponseBodyData
+	aiData, err = aliyun.StopInstance(*req.SessionId, jsonData)
+	fmt.Printf("aliData=%v error=%v \n", aiData, err)
+	if err != nil {
+		return nil, errorx.NewInternalError(err.Error())
+	}
+
+	return &types.StopInstanceResp{
+		BaseDataInfo: types.BaseDataInfo{
+			Code: 0,
+			Msg:  errormsg.Success,
+		},
+		Data: types.StopInstance{
+			RequestId: aiData.RequestId,
+			SessionId: aiData.SessionId,
+		},
+	}, nil
+}

+ 40 - 0
internal/types/types.go

@@ -2537,6 +2537,46 @@ type SignatureInfo struct {
 	Signature      *string `json:"signature"`
 }
 
+// send text | 数字人-发送消息
+// swagger:model SendTextReq
+type SendTextReq struct {
+	CardId    *uint64 `json:"cardId"`
+	SessionId *string `json:"sessionId"`
+	Text      *string `json:"text"`
+	IsStream  *bool   `json:"isStream,optional"`
+	Index     *int32  `json:"index,optional"`
+	Position  *string `json:"position,optional"`
+}
+
+// swagger:model SendTextResp
+type SendTextResp struct {
+	BaseDataInfo
+	Data SendText `json:"data"`
+}
+
+type SendText struct {
+	SessionId  *string `json:"sessionId"`
+	UniqueCode *string `json:"uniqueCode"`
+}
+
+// stop instance | 数字人-停止实例
+// swagger:model StopInstanceReq
+type StopInstanceReq struct {
+	CardId    *uint64 `json:"cardId"`
+	SessionId *string `json:"sessionId"`
+}
+
+// swagger:model StopInstanceResp
+type StopInstanceResp struct {
+	BaseDataInfo
+	Data StopInstance `json:"data"`
+}
+
+type StopInstance struct {
+	SessionId *string `json:"sessionId"`
+	RequestId *string `json:"requestId"`
+}
+
 // The data of aliyun avatar information | AliyunAvatar信息
 // swagger:model AliyunAvatarInfo
 type AliyunAvatarInfo struct {