326 lines
6.8 KiB
Go
326 lines
6.8 KiB
Go
package service
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
)
|
||
|
||
// ============================================
|
||
// 表单处理
|
||
// ============================================
|
||
|
||
// FormProcessor 表单处理器
|
||
type FormProcessor struct {
|
||
SystemForm map[string]any
|
||
UserForm map[string]any
|
||
}
|
||
|
||
// NewFormProcessor 创建表单处理器
|
||
func NewFormProcessor(systemForm, userForm map[string]any) *FormProcessor {
|
||
return &FormProcessor{
|
||
SystemForm: systemForm,
|
||
UserForm: userForm,
|
||
}
|
||
}
|
||
|
||
// Merge 合并表单,用户表单覆盖系统表单
|
||
func (p *FormProcessor) Merge() map[string]any {
|
||
if len(p.SystemForm) == 0 {
|
||
return p.SystemForm
|
||
}
|
||
|
||
result := make(map[string]any)
|
||
for k, v := range p.SystemForm {
|
||
result[k] = v
|
||
}
|
||
|
||
if len(p.UserForm) == 0 {
|
||
return result
|
||
}
|
||
|
||
// 构建用户表单索引
|
||
userIndex := buildFieldIndex(p.UserForm)
|
||
|
||
// 覆盖匹配的字段
|
||
for key, value := range result {
|
||
item, ok := value.(map[string]any)
|
||
if !ok || len(item) == 0 {
|
||
continue
|
||
}
|
||
|
||
field := getField(item, key)
|
||
|
||
if userItem, exists := findInIndex(userIndex, field, getLabel(item)); exists {
|
||
if userValue := getValue(userItem); !isNilOrEmpty(userValue) {
|
||
result[key] = cloneWithValue(item, userValue)
|
||
}
|
||
}
|
||
}
|
||
|
||
return result
|
||
}
|
||
|
||
// RemoveDuplicates 移除被用户表单覆盖的字段
|
||
func (p *FormProcessor) RemoveDuplicates() map[string]any {
|
||
if len(p.SystemForm) == 0 || len(p.UserForm) == 0 {
|
||
return p.SystemForm
|
||
}
|
||
|
||
userFields := buildFieldSet(p.UserForm)
|
||
result := make(map[string]any)
|
||
|
||
for key, value := range p.SystemForm {
|
||
item, ok := value.(map[string]any)
|
||
if !ok || len(item) == 0 {
|
||
result[key] = value
|
||
continue
|
||
}
|
||
|
||
field := getField(item, key)
|
||
label := getLabel(item)
|
||
|
||
// 跳过重复字段
|
||
if userFields.contains(field) || userFields.containsLabel(label) {
|
||
continue
|
||
}
|
||
|
||
result[key] = value
|
||
}
|
||
|
||
return result
|
||
}
|
||
|
||
// RemoveSemanticDuplicates 语义去重
|
||
func (p *FormProcessor) RemoveSemanticDuplicates() map[string]any {
|
||
if len(p.SystemForm) == 0 || len(p.UserForm) == 0 {
|
||
return p.SystemForm
|
||
}
|
||
|
||
userText := renderUserTextOnly(p.UserForm)
|
||
if userText == "" {
|
||
return p.SystemForm
|
||
}
|
||
|
||
result := make(map[string]any)
|
||
for key, value := range p.SystemForm {
|
||
item, ok := value.(map[string]any)
|
||
if !ok || len(item) == 0 {
|
||
result[key] = value
|
||
continue
|
||
}
|
||
|
||
if isDuplicate(userText, getField(item, key), getLabel(item), getValue(item)) {
|
||
continue
|
||
}
|
||
|
||
result[key] = value
|
||
}
|
||
|
||
return result
|
||
}
|
||
|
||
// RenderSystemText 渲染系统提示词文本
|
||
func (p *FormProcessor) RenderSystemText() string {
|
||
return renderFormText(p.SystemForm, false)
|
||
}
|
||
|
||
// RenderUserText 渲染用户提示词文本
|
||
func (p *FormProcessor) RenderUserText() string {
|
||
return renderUserText(p.UserForm, p.SystemForm)
|
||
}
|
||
|
||
// ============================================
|
||
// 表单处理辅助方法
|
||
// ============================================
|
||
|
||
type fieldSet struct {
|
||
fields map[string]bool
|
||
labels map[string]bool
|
||
}
|
||
|
||
func buildFieldSet(form map[string]any) *fieldSet {
|
||
fs := &fieldSet{
|
||
fields: make(map[string]bool),
|
||
labels: make(map[string]bool),
|
||
}
|
||
|
||
for key, value := range form {
|
||
item, ok := value.(map[string]any)
|
||
if !ok || len(item) == 0 {
|
||
continue
|
||
}
|
||
|
||
field := strings.ToLower(getField(item, key))
|
||
if field != "" {
|
||
fs.fields[field] = true
|
||
}
|
||
|
||
if label := strings.ToLower(getLabel(item)); label != "" {
|
||
fs.labels[label] = true
|
||
}
|
||
}
|
||
|
||
return fs
|
||
}
|
||
|
||
func (fs *fieldSet) contains(field string) bool {
|
||
return fs.fields[strings.ToLower(field)]
|
||
}
|
||
|
||
func (fs *fieldSet) containsLabel(label string) bool {
|
||
return label != "" && fs.labels[strings.ToLower(label)]
|
||
}
|
||
|
||
func buildFieldIndex(form map[string]any) map[string]map[string]any {
|
||
index := make(map[string]map[string]any)
|
||
|
||
for key, value := range form {
|
||
item, ok := value.(map[string]any)
|
||
if !ok || len(item) == 0 {
|
||
continue
|
||
}
|
||
|
||
field := strings.ToLower(getField(item, key))
|
||
if field != "" {
|
||
index[field] = item
|
||
}
|
||
|
||
if label := strings.ToLower(getLabel(item)); label != "" {
|
||
if _, exists := index[label]; !exists {
|
||
index[label] = item
|
||
}
|
||
}
|
||
}
|
||
|
||
return index
|
||
}
|
||
|
||
func findInIndex(index map[string]map[string]any, field, label string) (map[string]any, bool) {
|
||
key := strings.ToLower(field)
|
||
if item, ok := index[key]; ok {
|
||
return item, true
|
||
}
|
||
|
||
if label != "" {
|
||
key = strings.ToLower(label)
|
||
if item, ok := index[key]; ok {
|
||
return item, true
|
||
}
|
||
}
|
||
|
||
return nil, false
|
||
}
|
||
|
||
// ============================================
|
||
// 表单渲染
|
||
// ============================================
|
||
|
||
func renderFormText(form map[string]any, isUserForm bool) string {
|
||
if len(form) == 0 {
|
||
return ""
|
||
}
|
||
|
||
// 用户表单只有一个文本字段时,直接返回值
|
||
if isUserForm && len(form) == 1 {
|
||
for _, value := range form {
|
||
if item, ok := value.(map[string]any); ok {
|
||
return strings.TrimSpace(asString(getValue(item)))
|
||
}
|
||
}
|
||
}
|
||
|
||
// 拼接渲染
|
||
items := extractFormItems(form)
|
||
if isUserForm {
|
||
return renderUserFormItems(items)
|
||
}
|
||
return renderSystemFormItems(items)
|
||
}
|
||
|
||
type formItem struct {
|
||
Key string
|
||
Field string
|
||
Label string
|
||
Value any
|
||
}
|
||
|
||
func extractFormItems(form map[string]any) []formItem {
|
||
var items []formItem
|
||
|
||
keys := sortedKeys(form)
|
||
for _, key := range keys {
|
||
item, ok := form[key].(map[string]any)
|
||
if !ok || len(item) == 0 {
|
||
continue
|
||
}
|
||
|
||
field := getField(item, key)
|
||
value := getValue(item)
|
||
|
||
// 跳过敏感字段和空值
|
||
if isSensitiveField(field) || isNilOrEmpty(value) {
|
||
continue
|
||
}
|
||
|
||
items = append(items, formItem{
|
||
Key: key,
|
||
Field: field,
|
||
Label: getLabel(item),
|
||
Value: value,
|
||
})
|
||
}
|
||
|
||
return items
|
||
}
|
||
|
||
func renderUserFormItems(items []formItem) string {
|
||
// 只有一个文本类型字段时,直接返回值
|
||
if len(items) == 1 && isTextType(items[0].Field, items[0].Label) {
|
||
return formatValue(items[0].Value)
|
||
}
|
||
|
||
// 拼接
|
||
var parts []string
|
||
for _, item := range items {
|
||
if isTextType(item.Field, item.Label) {
|
||
parts = append(parts, formatValue(item.Value))
|
||
} else {
|
||
label := item.Label
|
||
if label == "" {
|
||
label = item.Field
|
||
}
|
||
parts = append(parts, fmt.Sprintf("%s:%s", label, formatValue(item.Value)))
|
||
}
|
||
}
|
||
|
||
return strings.Join(parts, ",")
|
||
}
|
||
|
||
func renderSystemFormItems(items []formItem) string {
|
||
var parts []string
|
||
for _, item := range items {
|
||
label := item.Label
|
||
if label == "" {
|
||
label = item.Field
|
||
}
|
||
parts = append(parts, fmt.Sprintf("%s:%s", label, formatValue(item.Value)))
|
||
}
|
||
|
||
return strings.Join(parts, ",")
|
||
}
|
||
|
||
func renderUserText(userForm, systemForm map[string]any) string {
|
||
if text := renderFormText(userForm, true); text != "" {
|
||
return text
|
||
}
|
||
// 用户表单为空时,使用系统表单生成
|
||
if text := renderFormText(systemForm, false); text != "" {
|
||
return "参考系统字段生成用户提示词:" + text
|
||
}
|
||
return ""
|
||
}
|
||
|
||
func renderUserTextOnly(userForm map[string]any) string {
|
||
return renderFormText(userForm, true)
|
||
}
|