Files
prompts-core/service/form_processor.go

326 lines
6.8 KiB
Go
Raw Normal View History

2026-05-12 13:59:15 +08:00
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)
}