This commit is contained in:
2025-03-07 17:23:50 +08:00
commit 4605e853c0
181 changed files with 17685 additions and 0 deletions
+174
View File
@@ -0,0 +1,174 @@
package superKangaroo
import (
"bytes"
"case-admin-api/api/model"
"case-admin-api/config"
"case-admin-api/utils"
"encoding/json"
"errors"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"strconv"
"time"
)
// ReportUserAnswerRequest 上报用户答题数据
type ReportUserAnswerRequest struct {
SrId string `json:"srid"` // 数据记录id,用于判断是否重复推送
Sid string `json:"sid"` // 互动病例ID
TslUid string `json:"tsl_uid"` // 进入h5携带用户标识(唯一性)
Items string `json:"items"` // 答题条目数据
ShareUserId string `json:"share_user_id"` // 分享人用户id
}
type ReportUserAnswerItemsRequest struct {
Question string `json:"question"` // 问题
Answer string `json:"answer"` // 答案
Correct bool `json:"correct"` // 是否正确,true:正确;false:错误
Order int `json:"order"` // 题目顺序
}
// ReportUserAnswerResponse 上报用户答题数据-返回数据
type ReportUserAnswerResponse struct {
Code interface{} `json:"code"` // 接口调用状态。200:正常;其它值:调用出错
Msg string `json:"msg"` // 结果说明。如果接口调用出错,那么返回错误描述。成功则返回 ok
Data string `json:"data"` // 接口返回结果,各个接口自定义,数据结构参考具体文档说明
}
// ReportUserAnswerScore 上报用户答题数据
func ReportUserAnswerScore(caseId int64, appIden string, caseUserAnswers []*model.CaseUserAnswer, caseUser *model.CaseUser) (g *ReportUserAnswerResponse, err error) {
items := make([]*ReportUserAnswerItemsRequest, len(caseUserAnswers))
for i, answer := range caseUserAnswers {
item := &ReportUserAnswerItemsRequest{
Question: answer.CaseItemQuestion.QuestionName,
Answer: answer.CaseItemQuestion.QuestionAnswer,
Correct: utils.IntToBool(answer.IsTrue),
Order: i + 1,
}
items[i] = item
}
itemJsonStr, err := StructToJSONString(items)
if err != nil {
return g, err
}
// 准备要发送的 JSON 数据
requestData := ReportUserAnswerRequest{
SrId: fmt.Sprintf("%d", caseId) + appIden,
Sid: fmt.Sprintf("%d", caseId),
TslUid: appIden,
Items: itemJsonStr,
ShareUserId: caseUser.ShareUserIden,
}
// 创建 form-data 的请求体
var bodyBuffer bytes.Buffer
writer := multipart.NewWriter(&bodyBuffer)
// 写入字段数据
err = writer.WriteField("srid", requestData.SrId)
if err != nil {
return g, err
}
err = writer.WriteField("sid", requestData.Sid)
if err != nil {
return g, err
}
err = writer.WriteField("tsl_uid", requestData.TslUid)
if err != nil {
return g, err
}
err = writer.WriteField("items", itemJsonStr)
if err != nil {
return g, err
}
err = writer.WriteField("share_user_id", caseUser.ShareUserIden)
if err != nil {
return g, err
}
// 关闭 writer(写入结束标记)
err = writer.Close()
if err != nil {
return g, err
}
// 随机6位数
nonce := generateRandom6Digit()
// 当前毫秒时间戳
curTime := strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
// 获取请求签名
sign, err := GenSignature("", strconv.Itoa(nonce), curTime)
if err != nil {
return g, err
}
// 设置请求 URL
u, err := url.Parse(config.C.SuperKangaroo.ApiUrl + "newindex/receivingCase")
if err != nil {
return g, err
}
query := u.Query()
query.Set("secret", config.C.SuperKangaroo.SecretKey)
query.Set("nonce", strconv.Itoa(nonce))
query.Set("curTime", curTime)
query.Set("checkSum", sign)
u.RawQuery = query.Encode()
// 创建 POST 请求
req, err := http.NewRequest("POST", u.String(), &bodyBuffer)
if err != nil {
return g, err
}
// 设置请求头
req.Header.Set("Content-Type", writer.FormDataContentType())
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return g, err
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return g, err
}
// 检查响应状态码
if resp.StatusCode != 200 {
return g, errors.New("失败")
}
err = json.Unmarshal(body, &g)
if err != nil {
// json解析失败
return g, err
}
utils.LogJsonInfo("获取超级袋鼠数据返回", g)
if g.Code != 1 && g.Code != "1" && g.Code != float64(1) {
if g.Msg != "" {
return g, errors.New(g.Msg)
} else {
return g, errors.New("失败")
}
}
return g, nil
}
+164
View File
@@ -0,0 +1,164 @@
package superKangaroo
import (
"bytes"
"case-admin-api/api/model"
"case-admin-api/config"
"case-admin-api/utils"
"encoding/json"
"errors"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"strconv"
"time"
)
// ReportUserScoreRequest 上报积分
type ReportUserScoreRequest struct {
Id string `json:"id"` //积分记录id,用于判断是否重复推送
Sid string `json:"sid"` // 互动病例ID
TslUid string `json:"tsl_uid"` // 进入h5携带用户标识(唯一性)
Title string `json:"title"` // 积分类型
Credit string `json:"credit"` // 积分
AddTime string `json:"addtime"` // 获得时间
Remark string `json:"remark"` // 病例名称
}
// ReportUserScoreResponse 上报用户积分-返回数据
type ReportUserScoreResponse struct {
Code interface{} `json:"code"` // 接口调用状态。200:正常;其它值:调用出错
Msg string `json:"msg"` // 结果说明。如果接口调用出错,那么返回错误描述。成功则返回 ok
Data string `json:"data"` // 接口返回结果,各个接口自定义,数据结构参考具体文档说明
}
// ReportUserScore 上报用户积分
func ReportUserScore(caseId int64, appIden, title string, recordScore *model.RecordScore, c *model.Case) (g *ReportUserScoreResponse, err error) {
// 准备要发送的 JSON 数据
requestData := ReportUserScoreRequest{
Id: fmt.Sprintf("%d", recordScore.ScoreId), // 获取积分记录的唯一id
Sid: fmt.Sprintf("%d", caseId),
TslUid: appIden,
Title: title,
Credit: fmt.Sprintf("%d", recordScore.Score),
AddTime: time.Time(recordScore.CreatedAt).Format("2006-01-02 15:04:05"),
Remark: c.CaseName,
}
// 创建 form-data 的请求体
var bodyBuffer bytes.Buffer
writer := multipart.NewWriter(&bodyBuffer)
// 写入字段数据
err = writer.WriteField("id", requestData.Id)
if err != nil {
return g, err
}
err = writer.WriteField("sid", requestData.Sid)
if err != nil {
return g, err
}
err = writer.WriteField("tsl_uid", requestData.TslUid)
if err != nil {
return g, err
}
err = writer.WriteField("title", requestData.Title)
if err != nil {
return g, err
}
err = writer.WriteField("credit", requestData.Credit)
if err != nil {
return g, err
}
err = writer.WriteField("addtime", requestData.AddTime)
if err != nil {
return g, err
}
err = writer.WriteField("remark", c.CaseName)
if err != nil {
return g, err
}
// 关闭 writer(写入结束标记)
err = writer.Close()
if err != nil {
return g, err
}
// 随机6位数
nonce := generateRandom6Digit()
// 当前毫秒时间戳
curTime := strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
// 获取请求签名
sign, err := GenSignature("", strconv.Itoa(nonce), curTime)
if err != nil {
return g, err
}
// 设置请求 URL
u, err := url.Parse(config.C.SuperKangaroo.ApiUrl + "newindex/receivingSorce")
if err != nil {
return g, err
}
query := u.Query()
query.Set("secret", config.C.SuperKangaroo.SecretKey)
query.Set("nonce", strconv.Itoa(nonce))
query.Set("curTime", curTime)
query.Set("checkSum", sign)
u.RawQuery = query.Encode()
utils.LogJsonInfo("请求超级袋鼠数据参数", requestData)
// 创建 POST 请求
req, err := http.NewRequest("POST", u.String(), &bodyBuffer)
if err != nil {
return g, err
}
// 设置请求头
req.Header.Set("Content-Type", writer.FormDataContentType())
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return g, err
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return g, err
}
// 检查响应状态码
if resp.StatusCode != 200 {
return g, errors.New("失败")
}
err = json.Unmarshal(body, &g)
if err != nil {
// json解析失败
return g, err
}
utils.LogJsonInfo("获取超级袋鼠数据返回", g)
if g.Code != 1 && g.Code != "1" && g.Code != float64(1) {
if g.Msg != "" {
return g, errors.New(g.Msg)
} else {
return g, errors.New("失败")
}
}
return g, nil
}
+48
View File
@@ -0,0 +1,48 @@
package superKangaroo
import (
"bytes"
"case-admin-api/config"
"case-admin-api/utils"
"encoding/json"
"math/rand"
"time"
)
// GenSignature 生成签名信息
func GenSignature(body, nonce, curTime string) (string, error) {
sing := utils.GenerateSHA1(config.C.SuperKangaroo.SecretKey, nonce, curTime, body)
return sing, nil
}
// GenerateRandom6Digit 生成一个随机的6位数
func generateRandom6Digit() int {
// 设置随机种子
rand.Seed(time.Now().UnixNano())
// 生成6位数范围 [100000, 999999]
return rand.Intn(900000) + 100000
}
// StructToJSONString 将结构体转换为 JSON 字符串,并支持 JSON_UNESCAPED_UNICODE
func StructToJSONString(data interface{}) (string, error) {
// 创建 buffer 以支持定制化的编码
var buffer bytes.Buffer
// 创建一个 JSON 编码器
encoder := json.NewEncoder(&buffer)
// 设置 JSON_UNESCAPED_UNICODE
encoder.SetEscapeHTML(false)
// 执行编码
if err := encoder.Encode(data); err != nil {
return "", err
}
// 移除末尾换行符
jsonString := buffer.String()
jsonString = jsonString[:len(jsonString)-1]
return jsonString, nil
}