Files
prompts-core/service/form_processor.go
2026-05-12 13:59:15 +08:00

326 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
}