添加spark制作ppt的请求spark部分的代码
This commit is contained in:
parent
b6d3d35b53
commit
7c984a6012
|
|
@ -5,6 +5,7 @@ import (
|
|||
"StuAcaWorksAI/proto"
|
||||
"StuAcaWorksAI/service"
|
||||
"StuAcaWorksAI/worker"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io"
|
||||
|
|
@ -54,6 +55,7 @@ func SetUpToolGroup(router *gin.Engine) {
|
|||
//发送邮件
|
||||
toolGroup.POST("/send_mail", SendMailTool)
|
||||
toolGroup.POST("/dashboard", DashBoardStatistics)
|
||||
toolGroup.POST("/spark_ppt_theme_list", GetSparkPPTThemeList)
|
||||
}
|
||||
|
||||
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})
|
||||
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)
|
||||
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 {
|
||||
log.Println("create ai stream message error:", err3)
|
||||
}
|
||||
doubaoToGeneralMassageAndSendMsgQueue(&recv, imCtx.Channel, imCtx.SessionID, imCtx.UserID)
|
||||
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
|
||||
}
|
||||
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"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"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))
|
||||
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