feat: 重构异步模型字段并更新依赖
This commit is contained in:
@@ -2,13 +2,11 @@ package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
gfgjson "github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
tGjson "github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
)
|
||||
|
||||
// ConvertToMessages 将原始数据转换为消息列表
|
||||
@@ -17,7 +15,7 @@ func ConvertToMessages(raw any) []map[string]any {
|
||||
return nil
|
||||
}
|
||||
|
||||
j := gfgjson.New(raw)
|
||||
j := gjson.New(raw)
|
||||
messages := j.Get("messages")
|
||||
if !messages.IsNil() {
|
||||
return gconv.Maps(messages.Val())
|
||||
@@ -66,7 +64,7 @@ func JSONPretty(v any) string {
|
||||
return gconv.String(v)
|
||||
}
|
||||
|
||||
b, _ := json.MarshalIndent(tmp, "", " ")
|
||||
b, _ := json.Marshal(tmp)
|
||||
return string(b)
|
||||
}
|
||||
|
||||
@@ -102,132 +100,98 @@ func ParseJSONFieldFromGvar(source any, target any) {
|
||||
}
|
||||
}
|
||||
|
||||
// MergeConsult 将 consult 附件合并到模型生成的 messages 结构中。
|
||||
//
|
||||
// 参数说明:
|
||||
// - req: 请求参数 map,需包含 "consult" 字段,值为 []any,每个元素是 {"type":"xxx","url":"..."}
|
||||
// - messages: 模型生成的返回结构(如 rounds[...].messages[...].content 数组)
|
||||
// - extendMapping: 附加映射配置,格式:
|
||||
// {"attachments": {"image": {"template": {...}, "target_path": "...", "field_mapping": {...}}, ...}}
|
||||
//
|
||||
// 返回值:合并后的完整 map。
|
||||
// MergeConsult 将 consult 附件合并到模型生成的 messages 结构中
|
||||
func MergeConsult(req map[string]any, messages map[string]any, extendMapping map[string]any) map[string]any {
|
||||
if len(req) == 0 || len(messages) == 0 || len(extendMapping) == 0 {
|
||||
return messages
|
||||
}
|
||||
|
||||
reqJSON, _ := json.Marshal(req)
|
||||
msgJSON, _ := json.Marshal(messages)
|
||||
extJSON, _ := json.Marshal(extendMapping)
|
||||
|
||||
reqStr := string(reqJSON)
|
||||
msgStr := string(msgJSON)
|
||||
extStr := string(extJSON)
|
||||
|
||||
// 获取 consult 数组
|
||||
consultResult := tGjson.Get(reqStr, "consult")
|
||||
if !consultResult.Exists() || !consultResult.IsArray() {
|
||||
// 1) 获取 consult 数组
|
||||
consult := gconv.Interfaces(req["consult"])
|
||||
if len(consult) == 0 {
|
||||
return messages
|
||||
}
|
||||
|
||||
// 获取 attachments 配置
|
||||
attachmentsResult := tGjson.Get(extStr, "attachments")
|
||||
if !attachmentsResult.Exists() || !attachmentsResult.IsObject() {
|
||||
// 2) 获取配置
|
||||
targetPath := gconv.String(extendMapping["target_content_path"])
|
||||
if targetPath == "" {
|
||||
return messages
|
||||
}
|
||||
|
||||
consultArr := consultResult.Array()
|
||||
attachmentsMap := attachmentsResult.Map()
|
||||
templates := gconv.Map(extendMapping["attachment_templates"])
|
||||
if len(templates) == 0 {
|
||||
return messages
|
||||
}
|
||||
|
||||
for _, consultItem := range consultArr {
|
||||
if !consultItem.IsObject() {
|
||||
continue
|
||||
}
|
||||
// 3) 转为 gjson 操作
|
||||
msgJson := gjson.New(messages)
|
||||
|
||||
itemType := consultItem.Get("type").String()
|
||||
// 固定:如果有 rounds 结构,路径替换为 rounds.0.{targetPath}
|
||||
if arr := msgJson.Get("rounds.0").Array(); arr != nil {
|
||||
targetPath = "rounds.0." + targetPath
|
||||
}
|
||||
|
||||
// 4) 遍历 consult,按类型生成附件并追加
|
||||
for _, item := range consult {
|
||||
itemJson := gjson.New(item)
|
||||
|
||||
itemType := itemJson.Get("type").String()
|
||||
if itemType == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// 查找对应类型的附件配置
|
||||
attachResult, ok := attachmentsMap[itemType]
|
||||
if !ok || !attachResult.IsObject() {
|
||||
// 查找对应模板
|
||||
tmpl := gconv.Map(templates[itemType])
|
||||
if len(tmpl) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 获取模板
|
||||
templateResult := attachResult.Get("template")
|
||||
if !templateResult.Exists() || !templateResult.IsObject() {
|
||||
// 生成附件对象
|
||||
attachment := buildAttachment(tmpl, itemJson.Get("url").String())
|
||||
if attachment == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// 深拷贝模板
|
||||
filledTemplateStr := templateResult.Raw
|
||||
// 获取当前数组长度,用索引追加
|
||||
arr := msgJson.Get(targetPath).Array()
|
||||
idx := len(arr)
|
||||
indexPath := fmt.Sprintf("%s.%d", targetPath, idx)
|
||||
_ = msgJson.Set(indexPath, attachment)
|
||||
}
|
||||
|
||||
// 应用字段映射
|
||||
fieldMappingResult := attachResult.Get("field_mapping")
|
||||
if fieldMappingResult.Exists() && fieldMappingResult.IsObject() {
|
||||
fieldMapping := fieldMappingResult.Map()
|
||||
for fieldPath, valueSource := range fieldMapping {
|
||||
sourceKey := valueSource.String()
|
||||
valueResult := consultItem.Get(sourceKey)
|
||||
if valueResult.Exists() {
|
||||
var err error
|
||||
filledTemplateStr, err = sjson.SetRaw(filledTemplateStr, fieldPath, valueResult.Raw)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return msgJson.Map()
|
||||
}
|
||||
|
||||
// buildAttachment 根据模板和用户数据生成附件对象
|
||||
func buildAttachment(tmpl map[string]any, url string) map[string]any {
|
||||
typ := gconv.String(tmpl["type"])
|
||||
if typ == "" || url == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 深拷贝 body 并填充 url
|
||||
body := gconv.Map(tmpl["body"])
|
||||
bodyJson := gjson.New(body)
|
||||
bodyJson = fillEmpty(bodyJson, url)
|
||||
|
||||
return map[string]any{
|
||||
"type": typ,
|
||||
typ: bodyJson.Map(),
|
||||
}
|
||||
}
|
||||
|
||||
// fillEmpty 递归查找空字符串并替换
|
||||
func fillEmpty(j *gjson.Json, value string) *gjson.Json {
|
||||
m := j.Map()
|
||||
for k, v := range m {
|
||||
switch vv := v.(type) {
|
||||
case string:
|
||||
if vv == "" {
|
||||
_ = j.Set(k, value)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取目标路径
|
||||
targetPath := attachResult.Get("target_path").String()
|
||||
if targetPath == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查目标路径是否存在且为数组
|
||||
targetResult := tGjson.Get(msgStr, targetPath)
|
||||
if !targetResult.Exists() || !targetResult.IsArray() {
|
||||
continue
|
||||
}
|
||||
|
||||
// 追加到数组末尾
|
||||
arrLen := len(targetResult.Array())
|
||||
appendPath := targetPath + "." + strconv.Itoa(arrLen)
|
||||
var err error
|
||||
msgStr, err = sjson.SetRaw(msgStr, appendPath, filledTemplateStr)
|
||||
if err != nil {
|
||||
continue
|
||||
case map[string]any:
|
||||
_ = j.Set(k, fillEmpty(gjson.New(vv), value).Map())
|
||||
}
|
||||
}
|
||||
|
||||
// 转回 map[string]any
|
||||
var result map[string]any
|
||||
if err := json.Unmarshal([]byte(msgStr), &result); err != nil {
|
||||
return messages
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// GetUserMessage 获取用户消息
|
||||
func GetUserMessage(taskReq map[string]any) map[string]any {
|
||||
// 先取 requestPayload
|
||||
rp, ok := taskReq["requestPayload"].(map[string]any)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
// 再取 messages
|
||||
messages, ok := rp["messages"].([]any)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
for _, msg := range messages {
|
||||
m, ok := msg.(map[string]any)
|
||||
if ok && m["role"] == "user" {
|
||||
return m
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return j
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user