添加spark制作ppt的请求spark部分的代码

This commit is contained in:
junleea 2025-04-03 13:33:56 +08:00
parent b6d3d35b53
commit 7c984a6012
8 changed files with 757 additions and 2 deletions

View File

@ -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
}
}

157
proto/spark.go Normal file
View File

@ -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"`
}

View File

@ -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]

View File

@ -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)
}

View File

@ -0,0 +1 @@
package spark

View File

@ -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"`
}

193
service/spark/spark-ppt.go Normal file
View File

@ -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
}

View File

@ -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
}