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