添加spark制作ppt的请求spark部分的代码
This commit is contained in:
parent
b6d3d35b53
commit
7c984a6012
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"StuAcaWorksAI/proto"
|
"StuAcaWorksAI/proto"
|
||||||
"StuAcaWorksAI/service"
|
"StuAcaWorksAI/service"
|
||||||
"StuAcaWorksAI/worker"
|
"StuAcaWorksAI/worker"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"io"
|
"io"
|
||||||
|
|
@ -54,6 +55,7 @@ func SetUpToolGroup(router *gin.Engine) {
|
||||||
//发送邮件
|
//发送邮件
|
||||||
toolGroup.POST("/send_mail", SendMailTool)
|
toolGroup.POST("/send_mail", SendMailTool)
|
||||||
toolGroup.POST("/dashboard", DashBoardStatistics)
|
toolGroup.POST("/dashboard", DashBoardStatistics)
|
||||||
|
toolGroup.POST("/spark_ppt_theme_list", GetSparkPPTThemeList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetDeviceStatusV2(c *gin.Context) {
|
func SetDeviceStatusV2(c *gin.Context) {
|
||||||
|
|
@ -413,3 +415,39 @@ func DashBoardStatistics(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, gin.H{"code": proto.SuccessCode, "message": "success", "data": resp})
|
c.JSON(http.StatusOK, gin.H{"code": proto.SuccessCode, "message": "success", "data": resp})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSparkPPTThemeList(c *gin.Context) {
|
||||||
|
var req proto.GetSparkPPTThemeReq
|
||||||
|
if err := c.ShouldBind(&req); err == nil {
|
||||||
|
if req.Style == "" || req.Color == "" || req.Industry == "" {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"error": "parameter error,request parameter is null", "code": proto.ParameterError, "message": "failed"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var modelParam proto.ModelParam
|
||||||
|
//获取模型
|
||||||
|
models, funcs, mferr := service.FindFuncModelListByFunctionV2(req.Function)
|
||||||
|
if mferr != nil {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"error": "function not exist", "code": proto.ParameterError, "message": "failed"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(funcs) == 0 || len(models) == 0 {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"error": "function or model not exist", "code": proto.ParameterError, "message": "failed"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
model := models[0]
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(model.Parameter), &modelParam)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"error": "model parameter decode error", "code": proto.ParameterError, "message": "failed"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
modelParam.Url = model.Url
|
||||||
|
modelParam.System = funcs[0].Info //系统功能
|
||||||
|
//获取主题列表
|
||||||
|
themeList, err := service.SparkPPTThemeList(&modelParam, req)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"error": "parameter error", "code": proto.ParameterError, "message": "failed"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
package proto
|
||||||
|
|
||||||
|
type PPTThemeRequest struct {
|
||||||
|
Style string `json:"style"`
|
||||||
|
Color string `json:"color"`
|
||||||
|
Industry string `json:"industry"`
|
||||||
|
PageNum int `json:"pageNum"`
|
||||||
|
PageSize int `json:"pageSize"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response 定义响应结构体
|
||||||
|
type PPTThemeResponse struct {
|
||||||
|
Flag bool `json:"flag"`
|
||||||
|
Code int `json:"code"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
Count interface{} `json:"count"`
|
||||||
|
Data PPTThemeData `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data 定义数据结构体
|
||||||
|
type PPTThemeData struct {
|
||||||
|
Total int `json:"total"`
|
||||||
|
Records []PPTThemeRecord `json:"records"`
|
||||||
|
PageNum int `json:"pageNum"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record 定义记录结构体
|
||||||
|
type PPTThemeRecord struct {
|
||||||
|
TemplateIndexId string `json:"templateIndexId"`
|
||||||
|
PageCount int `json:"pageCount"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Color string `json:"color"`
|
||||||
|
Industry string `json:"industry"`
|
||||||
|
Style string `json:"style"`
|
||||||
|
DetailImage PPTThemeDetailImage `json:"detailImage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DetailImage 定义详细图片结构体
|
||||||
|
type PPTThemeDetailImage struct {
|
||||||
|
TitleCoverImageLarge string `json:"titleCoverImageLarge"`
|
||||||
|
TitleCoverImage string `json:"titleCoverImage"`
|
||||||
|
CatalogueCoverImage string `json:"catalogueCoverImage"`
|
||||||
|
ChapterCoverImage string `json:"chapterCoverImage"`
|
||||||
|
ContentCoverImage string `json:"contentCoverImage"`
|
||||||
|
EndCoverImage string `json:"endCoverImage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetSparkPPTThemeReq struct {
|
||||||
|
Function string `json:"function" form:"function"` // 功能
|
||||||
|
Style string `json:"style" form:"style"` // 风格
|
||||||
|
Color string `json:"color" form:"color"` // 颜色
|
||||||
|
Industry string `json:"industry" form:"industry"` // 行业
|
||||||
|
PageNum int `json:"pageNum" form:"pageNum"` // 页码
|
||||||
|
PageSize int `json:"pageSize" form:"pageSize"` // 每页数量
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileParamContext struct {
|
||||||
|
UserID int `json:"user_id"` //用户id
|
||||||
|
SessionID int `json:"session_id"` //会话id
|
||||||
|
FunctionID int `json:"function_id"` //功能id
|
||||||
|
ModelID int `json:"model_id"` //模型id
|
||||||
|
Channel string `json:"channel"` //消息队列
|
||||||
|
FileID int `json:"file_id"` //文件id
|
||||||
|
FileName string `json:"file_name"` //文件名
|
||||||
|
FileUrl string `json:"file_url"` //文件url
|
||||||
|
}
|
||||||
|
|
||||||
|
type SparkCreateOutlineByDocRequest struct {
|
||||||
|
Query string `json:"query" form:"query" binding:"required,min=1,max=8000,nefield= "` // 查询内容
|
||||||
|
FileUrl string `json:"fileUrl" form:"fileUrl"`
|
||||||
|
FileName string `json:"fileName" form:"fileName"`
|
||||||
|
BusinessId string `json:"businessId,omitempty" form:"businessId,omitempty"`
|
||||||
|
Language string `json:"language,omitempty" form:"language,omitempty" default:"cn"`
|
||||||
|
Search bool `json:"search,omitempty" form:"search,omitempty" default:"false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建大纲响应内容
|
||||||
|
type SparkCreateOutlineResponse struct {
|
||||||
|
Flag bool `json:"flag"`
|
||||||
|
Code int `json:"code"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
Count int `json:"count"`
|
||||||
|
Data SparkCreateOutlineResponseData `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data 定义响应中 data 字段的结构体
|
||||||
|
type SparkCreateOutlineResponseData struct {
|
||||||
|
Sid string `json:"sid"`
|
||||||
|
Outline SparkCreateOutlineResponseOutline `json:"outline"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outline 定义大纲数据的结构体
|
||||||
|
type SparkCreateOutlineResponseOutline struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
SubTitle string `json:"subTitle"`
|
||||||
|
Chapters []SparkCreateOutlineResponseChapter `json:"chapters"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chapter 定义章节数据的结构体
|
||||||
|
type SparkCreateOutlineResponseChapter struct {
|
||||||
|
ChapterTitle string `json:"chapterTitle"`
|
||||||
|
ChapterContents []SparkCreateOutlineResponseChapterContent `json:"chapterContents"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SparkCreateOutlineResponseChapterContent struct {
|
||||||
|
ChapterTitle string `json:"chapterTitle"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SparkCreateOutlineRequest struct {
|
||||||
|
Function string `json:"function" form:"function"` // 功能
|
||||||
|
Query string `json:"query" form:"query"` // 查询内容
|
||||||
|
FileUrl string `json:"fileUrl" form:"fileUrl"` // 文件url
|
||||||
|
FileName string `json:"fileName" form:"fileName"` // 文件名
|
||||||
|
}
|
||||||
|
|
||||||
|
type SparkCreatePPTByOutlineUserRequest struct {
|
||||||
|
Function string `json:"function" form:"function"` // 功能
|
||||||
|
Sid string `json:"sid" form:"sid"` // 会话id,spark提供
|
||||||
|
Query string `json:"query" form:"query"` // 查询内容
|
||||||
|
FileUrl string `json:"fileUrl" form:"fileUrl"` // 文件url
|
||||||
|
FileName string `json:"fileName" form:"fileName"` // 文件名
|
||||||
|
Outline SparkCreateOutlineResponseOutline `json:"outline" form:"outline"` // 大纲
|
||||||
|
}
|
||||||
|
|
||||||
|
type SparkCreatePptByOutlineRequest struct {
|
||||||
|
Query string `json:"query" form:"query" binding:"required,min=1,max=8000,nefield= "`
|
||||||
|
OutlineSid string `json:"outlineSid" form:"outlineSid"`
|
||||||
|
Outline SparkCreateOutlineResponseOutline `json:"outline" form:"outline" binding:"required"`
|
||||||
|
TemplateId string `json:"templateId" form:"templateId"`
|
||||||
|
BusinessId string `json:"businessId" form:"businessId"`
|
||||||
|
Author string `json:"author" form:"author" default:"讯飞智文"`
|
||||||
|
IsCardNote bool `json:"isCardNote" form:"isCardNote" default:"false"`
|
||||||
|
Search bool `json:"search" form:"search" default:"false"`
|
||||||
|
Language string `json:"language" form:"language" default:"cn"`
|
||||||
|
FileUrl string `json:"fileUrl" form:"fileUrl"`
|
||||||
|
FileName string `json:"fileName" form:"fileName" binding:"required_with=FileUrl"`
|
||||||
|
IsFigure bool `json:"isFigure" form:"isFigure" default:"false"`
|
||||||
|
AiImage string `json:"aiImage" form:"aiImage" binding:"omitempty,oneof=normal advanced"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SparkCreatePPTByOutlineResponse struct {
|
||||||
|
Flag bool `json:"flag"`
|
||||||
|
Code int `json:"code"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
Count interface{} `json:"count"`
|
||||||
|
Data SparkCreatePPTByOutlineData `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SparkCreatePPTByOutlineData struct {
|
||||||
|
PptStatus string `json:"pptStatus"`
|
||||||
|
AiImageStatus string `json:"aiImageStatus"`
|
||||||
|
CardNoteStatus string `json:"cardNoteStatus"`
|
||||||
|
PptUrl string `json:"pptUrl"`
|
||||||
|
ErrMsg interface{} `json:"errMsg"`
|
||||||
|
TotalPages int `json:"totalPages"`
|
||||||
|
DonePages int `json:"donePages"`
|
||||||
|
}
|
||||||
|
|
@ -125,13 +125,13 @@ func DouBaoV2(modelParam proto.ModelParam, imCtx *proto.IMParamContext) {
|
||||||
fmt.Printf("doubao Stream chat error: %v\n", err)
|
fmt.Printf("doubao Stream chat error: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
aiStream_id, err3 := CreateAIStreamMsg(imCtx.UserID, imCtx.ModelID, imCtx.SessionID, recv, modelParam.Model)
|
aistreamId, err3 := CreateAIStreamMsg(imCtx.UserID, imCtx.ModelID, imCtx.SessionID, recv, modelParam.Model)
|
||||||
if err3 != nil {
|
if err3 != nil {
|
||||||
log.Println("create ai stream message error:", err3)
|
log.Println("create ai stream message error:", err3)
|
||||||
}
|
}
|
||||||
doubaoToGeneralMassageAndSendMsgQueue(&recv, imCtx.Channel, imCtx.SessionID, imCtx.UserID)
|
doubaoToGeneralMassageAndSendMsgQueue(&recv, imCtx.Channel, imCtx.SessionID, imCtx.UserID)
|
||||||
if recv.Choices == nil {
|
if recv.Choices == nil {
|
||||||
log.Println("doubao stream recv choices is nil:", recv, "\t aiStream_id:", aiStream_id)
|
log.Println("doubao stream recv choices is nil:", recv, "\t aiStream_id:", aistreamId)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
choices := recv.Choices[0]
|
choices := recv.Choices[0]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package spark
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/base64"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// spark 接口签名计算
|
||||||
|
// MD5_TABLE 定义 MD5 转换表
|
||||||
|
var MD5_TABLE = []rune{
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApiAuthAlgorithm 定义 API 认证算法结构体
|
||||||
|
type ApiAuthAlgorithm struct{}
|
||||||
|
|
||||||
|
// GetSignature 获取签名
|
||||||
|
func (a *ApiAuthAlgorithm) GetSignature(appId, secret string, ts int64) string {
|
||||||
|
auth := a.md5(appId + strconv.FormatInt(ts, 10))
|
||||||
|
if auth == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return a.hmacSHA1Encrypt(auth, secret)
|
||||||
|
}
|
||||||
|
|
||||||
|
// hmacSHA1Encrypt sha1 加密
|
||||||
|
func (a *ApiAuthAlgorithm) hmacSHA1Encrypt(encryptText, encryptKey string) string {
|
||||||
|
h := hmac.New(sha1.New, []byte(encryptKey))
|
||||||
|
h.Write([]byte(encryptText))
|
||||||
|
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
// md5 MD5 加密
|
||||||
|
func (a *ApiAuthAlgorithm) md5(cipherText string) string {
|
||||||
|
hash := md5.Sum([]byte(cipherText))
|
||||||
|
result := make([]rune, 32)
|
||||||
|
for i, v := range hash {
|
||||||
|
result[i*2] = MD5_TABLE[v>>4&0xf]
|
||||||
|
result[i*2+1] = MD5_TABLE[v&0xf]
|
||||||
|
}
|
||||||
|
return string(result)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
package spark
|
||||||
|
|
@ -0,0 +1,171 @@
|
||||||
|
package spark
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
hostUrl = "wss://spark-api.cn-huabei-1.xf-yun.com/v2.1/image"
|
||||||
|
appid = "XXXXXXXX"
|
||||||
|
apiKey = "XXXXXXXXXXXXXXXXXXXXXXXX"
|
||||||
|
apiSecret = "XXXXXXXXXXXXXXXXXXXXXXXX"
|
||||||
|
)
|
||||||
|
|
||||||
|
func sparkImage() {
|
||||||
|
|
||||||
|
d := websocket.Dialer{
|
||||||
|
HandshakeTimeout: 5 * time.Second,
|
||||||
|
}
|
||||||
|
//鎻℃墜骞跺缓绔媤ebsocket 杩炴帴
|
||||||
|
conn, resp, err := d.Dial(assembleAuthUrl(hostUrl, apiKey, apiSecret), nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(readResp(resp) + err.Error())
|
||||||
|
return
|
||||||
|
} else if resp.StatusCode != 101 {
|
||||||
|
panic(readResp(resp) + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
//璇诲彇鍥剧墖
|
||||||
|
image, err := os.ReadFile("./1.png")
|
||||||
|
|
||||||
|
messages := []Message{
|
||||||
|
{Role: "user", Content: base64.StdEncoding.EncodeToString(image), ContentType: "image"}, // 棣栨潯蹇呴』鏄浘鐗<E6B598>
|
||||||
|
{Role: "user", Content: "鍥剧墖鏈夊嚑涓汉", ContentType: "text"},
|
||||||
|
{Role: "assistant", Content: "鍥剧墖閲岄潰鏈変竴涓汉", ContentType: "text"},
|
||||||
|
{Role: "user", Content: "杩欎釜浜虹┛浠€涔堣。鏈<E38082>", ContentType: "text"},
|
||||||
|
}
|
||||||
|
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"header": map[string]interface{}{
|
||||||
|
"app_id": appid,
|
||||||
|
},
|
||||||
|
"parameter": map[string]interface{}{
|
||||||
|
"chat": map[string]interface{}{
|
||||||
|
"domain": "imagev3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"payload": map[string]interface{}{ // 鏍规嵁瀹為檯鎯呭喌淇敼杩斿洖鐨勬暟鎹粨鏋勫拰瀛楁鍚<EE868C>
|
||||||
|
"message": map[string]interface{}{ // 鏍规嵁瀹為檯鎯呭喌淇敼杩斿洖鐨勬暟鎹粨鏋勫拰瀛楁鍚<EE868C>
|
||||||
|
"text": messages, // 鏍规嵁瀹為檯鎯呭喌淇敼杩斿洖鐨勬暟鎹粨鏋勫拰瀛楁鍚<EE868C>
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
conn.WriteJSON(data)
|
||||||
|
|
||||||
|
var answer = ""
|
||||||
|
//鑾峰彇杩斿洖鐨勬暟鎹<E69A9F>
|
||||||
|
for {
|
||||||
|
_, msg, err := conn.ReadMessage()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("read message error:", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
var data map[string]interface{}
|
||||||
|
err1 := json.Unmarshal(msg, &data)
|
||||||
|
if err1 != nil {
|
||||||
|
fmt.Println("Error parsing JSON:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(string(msg))
|
||||||
|
//瑙f瀽鏁版嵁
|
||||||
|
payload := data["payload"].(map[string]interface{})
|
||||||
|
choices := payload["choices"].(map[string]interface{})
|
||||||
|
header := data["header"].(map[string]interface{})
|
||||||
|
code := header["code"].(float64)
|
||||||
|
|
||||||
|
if code != 0 {
|
||||||
|
fmt.Println(data["payload"])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status := choices["status"].(float64)
|
||||||
|
fmt.Println(status)
|
||||||
|
text := choices["text"].([]interface{})
|
||||||
|
content := text[0].(map[string]interface{})["content"].(string)
|
||||||
|
if status != 2 {
|
||||||
|
answer += content
|
||||||
|
} else {
|
||||||
|
fmt.Println("鏀跺埌鏈€缁堢粨鏋<E7B2A8>")
|
||||||
|
answer += content
|
||||||
|
usage := payload["usage"].(map[string]interface{})
|
||||||
|
temp := usage["text"].(map[string]interface{})
|
||||||
|
totalTokens := temp["total_tokens"].(float64)
|
||||||
|
fmt.Println("total_tokens:", totalTokens)
|
||||||
|
conn.Close()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//杈撳嚭杩斿洖缁撴灉
|
||||||
|
fmt.Println(answer)
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 鍒涘缓閴存潈url apikey 鍗<> hmac username
|
||||||
|
func assembleAuthUrl(hosturl string, apiKey, apiSecret string) string {
|
||||||
|
ul, err := url.Parse(hosturl)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
//绛惧悕鏃堕棿
|
||||||
|
date := time.Now().UTC().Format(time.RFC1123)
|
||||||
|
//date = "Tue, 28 May 2019 09:10:42 MST"
|
||||||
|
//鍙備笌绛惧悕鐨勫瓧娈<E793A7> host ,date, request-line
|
||||||
|
signString := []string{"host: " + ul.Host, "date: " + date, "GET " + ul.Path + " HTTP/1.1"}
|
||||||
|
//鎷兼帴绛惧悕瀛楃涓<EE8381>
|
||||||
|
sgin := strings.Join(signString, "\n")
|
||||||
|
// fmt.Println(sgin)
|
||||||
|
//绛惧悕缁撴灉
|
||||||
|
sha := HmacWithShaTobase64("hmac-sha256", sgin, apiSecret)
|
||||||
|
// fmt.Println(sha)
|
||||||
|
//鏋勫缓璇锋眰鍙傛暟 姝ゆ椂涓嶉渶瑕乽rlencoding
|
||||||
|
authUrl := fmt.Sprintf("hmac username=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey,
|
||||||
|
"hmac-sha256", "host date request-line", sha)
|
||||||
|
//灏嗚姹傚弬鏁颁娇鐢╞ase64缂栫爜
|
||||||
|
authorization := base64.StdEncoding.EncodeToString([]byte(authUrl))
|
||||||
|
|
||||||
|
v := url.Values{}
|
||||||
|
v.Add("host", ul.Host)
|
||||||
|
v.Add("date", date)
|
||||||
|
v.Add("authorization", authorization)
|
||||||
|
//灏嗙紪鐮佸悗鐨勫瓧绗︿覆url encode鍚庢坊鍔犲埌url鍚庨潰
|
||||||
|
callurl := hosturl + "?" + v.Encode()
|
||||||
|
return callurl
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacWithShaTobase64(algorithm, data, key string) string {
|
||||||
|
mac := hmac.New(sha256.New, []byte(key))
|
||||||
|
mac.Write([]byte(data))
|
||||||
|
encodeData := mac.Sum(nil)
|
||||||
|
return base64.StdEncoding.EncodeToString(encodeData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readResp(resp *http.Response) string {
|
||||||
|
if resp == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
b, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("code=%d,body=%s", resp.StatusCode, string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Role string `json:"role"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
ContentType string `json:"content_type"`
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,193 @@
|
||||||
|
package spark
|
||||||
|
|
||||||
|
import (
|
||||||
|
"StuAcaWorksAI/proto"
|
||||||
|
"StuAcaWorksAI/worker"
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SparkPPTThemeList(model *proto.ModelParam, req proto.GetSparkPPTThemeReq) (proto.PPTThemeResponse, error) {
|
||||||
|
url := "https://zwapi.xfyun.cn/api/ppt/v2/template/list"
|
||||||
|
headers, err := getSparkRequestHeaders(model.APPID, model.APISecret)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark PPT Theme Error getting headers:", err)
|
||||||
|
return proto.PPTThemeResponse{}, err
|
||||||
|
}
|
||||||
|
//log.Println("Spark PPT Theme headers:", headers)
|
||||||
|
|
||||||
|
req_ := proto.PPTThemeRequest{
|
||||||
|
Style: req.Style,
|
||||||
|
Color: req.Color,
|
||||||
|
Industry: req.Industry,
|
||||||
|
PageNum: 1,
|
||||||
|
PageSize: 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
reqStr, err := json.Marshal(req_)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark PPT Theme Error encoding request:", err)
|
||||||
|
return proto.PPTThemeResponse{}, err
|
||||||
|
}
|
||||||
|
log.Println("Spark PPT Theme req:", string(reqStr))
|
||||||
|
|
||||||
|
err, resp := worker.DoPostRequestJSON(url, reqStr, headers)
|
||||||
|
var response proto.PPTThemeResponse
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark PPT Theme Error:", err)
|
||||||
|
} else {
|
||||||
|
err = json.Unmarshal(resp, &response)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark PPT Theme Error decoding response:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println("Spark PPT Theme Response:", string(resp))
|
||||||
|
//log.Println("Spark PPT Theme Response:", response)
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSparkRequestHeaders(appId, apiSecret string) (map[string]string, error) {
|
||||||
|
headers := map[string]string{
|
||||||
|
"appId": "d3a4647c",
|
||||||
|
"timestamp": strconv.FormatInt(time.Now().Unix(), 10),
|
||||||
|
}
|
||||||
|
algorithm := ApiAuthAlgorithm{}
|
||||||
|
signature := algorithm.GetSignature(appId, apiSecret, time.Now().Unix())
|
||||||
|
headers["signature"] = signature
|
||||||
|
return headers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据用户输入及文档生成大纲,文档可以是docx、doc、txt、pdf格式
|
||||||
|
func SparkCreateOutlineByDoc(model *proto.ModelParam, userReq *proto.SparkCreateOutlineRequest) (proto.SparkCreateOutlineResponse, error) {
|
||||||
|
url := "https://zwapi.xfyun.cn/api/ppt/v2/createOutlineByDoc"
|
||||||
|
headers, err := getSparkRequestHeaders(model.APPID, model.APISecret)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark PPT Theme Error getting headers:", err)
|
||||||
|
return proto.SparkCreateOutlineResponse{}, err
|
||||||
|
}
|
||||||
|
log.Println("Spark create outline by doc headers:", headers)
|
||||||
|
|
||||||
|
req := proto.SparkCreateOutlineByDocRequest{
|
||||||
|
Query: userReq.Query,
|
||||||
|
FileUrl: userReq.FileUrl,
|
||||||
|
FileName: userReq.FileName,
|
||||||
|
}
|
||||||
|
|
||||||
|
reqStr, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create outline by doc Error encoding request:", err)
|
||||||
|
}
|
||||||
|
log.Println("Spark create outline by doc req:", string(reqStr))
|
||||||
|
|
||||||
|
err, resp := worker.DoPostRequestForm(url, reqStr, headers)
|
||||||
|
//log.Println("Spark create outline by doc Response:", string(resp))
|
||||||
|
var response proto.SparkCreateOutlineResponse
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create outline by doc Error:", err)
|
||||||
|
} else {
|
||||||
|
err = json.Unmarshal(resp, &response)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create outline by doc Error decoding response:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println("Spark create outline by doc Response struct:", response)
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据query生成大纲
|
||||||
|
func SparkCreateOutline(model *proto.ModelParam, userReq *proto.SparkCreateOutlineRequest) (proto.SparkCreateOutlineResponse, error) {
|
||||||
|
url := "https://zwapi.xfyun.cn/api/ppt/v2/createOutline"
|
||||||
|
headers, err := getSparkRequestHeaders(model.APPID, model.APISecret)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark PPT Theme Error getting headers:", err)
|
||||||
|
return proto.SparkCreateOutlineResponse{}, err
|
||||||
|
}
|
||||||
|
log.Println("Spark create outline by doc headers:", headers)
|
||||||
|
|
||||||
|
//自定义内容
|
||||||
|
req := proto.SparkCreateOutlineByDocRequest{
|
||||||
|
Query: userReq.Query,
|
||||||
|
}
|
||||||
|
reqStr, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create PPT Error encoding request:", err)
|
||||||
|
}
|
||||||
|
log.Println("Spark create PPT req:", string(reqStr))
|
||||||
|
|
||||||
|
err, resp := worker.DoPostRequestForm(url, reqStr, headers)
|
||||||
|
log.Println("Spark create PPT Response:", string(resp))
|
||||||
|
var response proto.SparkCreateOutlineResponse
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create PPT Error:", err)
|
||||||
|
} else {
|
||||||
|
err = json.Unmarshal(resp, &response)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create PPT Error decoding response:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println("Spark create PPT Response struct:", response)
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SparkCreatePPTByOutline(model *proto.ModelParam, userReq *proto.SparkCreatePPTByOutlineUserRequest) (proto.SparkCreatePPTByOutlineResponse, error) {
|
||||||
|
url := "https://zwapi.xfyun.cn/api/ppt/v2/createPptByOutline"
|
||||||
|
headers, err := getSparkRequestHeaders(model.APPID, model.APISecret)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create ppt by outline Error encoding request:", err)
|
||||||
|
return proto.SparkCreatePPTByOutlineResponse{}, err
|
||||||
|
}
|
||||||
|
log.Println("Spark create ppt by outline headers:", headers)
|
||||||
|
|
||||||
|
req := proto.SparkCreatePptByOutlineRequest{
|
||||||
|
Query: userReq.Query,
|
||||||
|
FileUrl: userReq.FileUrl,
|
||||||
|
FileName: userReq.FileName,
|
||||||
|
Outline: userReq.Outline,
|
||||||
|
}
|
||||||
|
|
||||||
|
reqStr, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create ppt by outline Error encoding request:", err)
|
||||||
|
}
|
||||||
|
log.Println("Spark create ppt by outline req:", string(reqStr))
|
||||||
|
|
||||||
|
err, resp := worker.DoPostRequestJSON(url, reqStr, headers)
|
||||||
|
log.Println("Spark create ppt by outline Response:", string(resp))
|
||||||
|
var response proto.SparkCreatePPTByOutlineResponse
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create ppt by outline Error:", err)
|
||||||
|
} else {
|
||||||
|
err = json.Unmarshal(resp, &response)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create ppt by outline Error decoding response:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println("Spark create ppt by outline Response struct:", response)
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SparkGetPPTInfoBySID(model *proto.ModelParam, userReq *proto.SparkCreatePPTByOutlineUserRequest) (proto.SparkCreatePPTByOutlineResponse, error) {
|
||||||
|
url := "https://zwapi.xfyun.cn/api/ppt/v2/progress?sid=" + userReq.Sid
|
||||||
|
headers, err := getSparkRequestHeaders(model.APPID, model.APISecret)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create ppt by outline Error encoding request:", err)
|
||||||
|
return proto.SparkCreatePPTByOutlineResponse{}, err
|
||||||
|
}
|
||||||
|
log.Println("Spark create ppt by outline headers:", headers)
|
||||||
|
|
||||||
|
err, resp := worker.DoGetRequest(url, headers)
|
||||||
|
log.Println("Spark create ppt by outline Response:", string(resp))
|
||||||
|
var response proto.SparkCreatePPTByOutlineResponse
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create ppt by outline Error:", err)
|
||||||
|
} else {
|
||||||
|
err = json.Unmarshal(resp, &response)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Spark create ppt by outline Error decoding response:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println("Spark create ppt by outline Response struct:", response)
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
149
worker/req.go
149
worker/req.go
|
|
@ -7,7 +7,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -178,3 +181,149 @@ func SyncDataFromMasterReq2(url string, data proto.SyncUserReq) (proto.UserSync,
|
||||||
fmt.Println("SyncDataFromMasterReq2 result add data:", len(res.Add), "update data:", len(res.Update), "delete data:", len(res.Delete))
|
fmt.Println("SyncDataFromMasterReq2 result add data:", len(res.Add), "update data:", len(res.Update), "delete data:", len(res.Delete))
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DoPostRequestJSON(url string, jsonData []byte, headers map[string]string) (error, []byte) {
|
||||||
|
httpClient := &http.Client{}
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
fmt.Println("SyncDataFromMasterReq2 error:", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
//从接口获取数据
|
||||||
|
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
//设置header
|
||||||
|
for k, v := range headers {
|
||||||
|
req.Header.Set(k, v)
|
||||||
|
}
|
||||||
|
//传输数据
|
||||||
|
if httpClient == nil {
|
||||||
|
httpClient = &http.Client{}
|
||||||
|
}
|
||||||
|
//获取数据
|
||||||
|
resp, err := httpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
//解析数据
|
||||||
|
responseBod, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
return err, responseBod
|
||||||
|
}
|
||||||
|
|
||||||
|
func DoPostRequestForm(url string, jsonData []byte, headers map[string]string) (error, []byte) {
|
||||||
|
httpClient := &http.Client{}
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
fmt.Println("SyncDataFromMasterReq2 error:", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// 创建一个新的 buffer 用于存储 multipart/form-data 请求体
|
||||||
|
body := &bytes.Buffer{}
|
||||||
|
writer := multipart.NewWriter(body)
|
||||||
|
// 修改 data 类型为 map[string]interface{} 以支持不同类型的值
|
||||||
|
var data map[string]interface{}
|
||||||
|
err2 := json.Unmarshal(jsonData, &data)
|
||||||
|
if err2 != nil {
|
||||||
|
log.Println("do post json unmarshal error:", err2)
|
||||||
|
return err2, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
for k, v := range data {
|
||||||
|
switch val := v.(type) {
|
||||||
|
case bool:
|
||||||
|
// 处理布尔类型的值
|
||||||
|
err = writer.WriteField(k, strconv.FormatBool(val))
|
||||||
|
case string:
|
||||||
|
// 处理字符串类型的值
|
||||||
|
err = writer.WriteField(k, val)
|
||||||
|
default:
|
||||||
|
// 其他类型可以根据需要扩展处理逻辑
|
||||||
|
log.Printf("Unsupported type for field %s: %T\n", k, v)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Println("write field error:", err)
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭 writer 以完成请求体的构建
|
||||||
|
err = writer.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 POST 请求
|
||||||
|
req, err := http.NewRequest("POST", url, body)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置 Content-Type 为 multipart/form-data,并带上 boundary
|
||||||
|
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||||
|
|
||||||
|
// 设置其他自定义请求头
|
||||||
|
for k, v := range headers {
|
||||||
|
req.Header.Set(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
resp, err := httpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// 读取响应体
|
||||||
|
responseBod, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, responseBod
|
||||||
|
}
|
||||||
|
|
||||||
|
func DoGetRequest(url string, headers map[string]string) (error, []byte) {
|
||||||
|
httpClient := &http.Client{}
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
fmt.Println("SyncDataFromMasterReq2 error:", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
//从接口获取数据
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
//设置header
|
||||||
|
for k, v := range headers {
|
||||||
|
req.Header.Set(k, v)
|
||||||
|
}
|
||||||
|
//传输数据
|
||||||
|
if httpClient == nil {
|
||||||
|
httpClient = &http.Client{}
|
||||||
|
}
|
||||||
|
//获取数据
|
||||||
|
resp, err := httpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
//解析数据
|
||||||
|
responseBod, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
return err, responseBod
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue