package logic import ( "fmt" "regexp" "strings" "img_infinite_canvas/internal/domain/design" ) var ( promptReferenceDirectivePattern = regexp.MustCompile(`(?i)(?:参考图|reference image)\s*\d*\s*(?:[((][^))\n]+[))])?\s*[::]\s*(?:https?://[^\s\],。]+|data:image/[^\s\],。]+|/[^\s\],。]+)`) promptImageTokenPattern = regexp.MustCompile(`\[@image:#\d+:[^:\]]+:(?:\[[^\]]+\]\((?:[^)]+)\)|[^\]]+)\]`) ) func validateRequiredPrompt(prompt string, allowEmpty bool) error { if allowEmpty { return nil } if hasRequiredPromptText(prompt) { return nil } return fmt.Errorf("%w: prompt is required", design.ErrInvalidInput) } func hasRequiredPromptText(prompt string) bool { prompt = promptImageTokenPattern.ReplaceAllString(prompt, " ") prompt = promptReferenceDirectivePattern.ReplaceAllString(prompt, " ") for _, line := range strings.Split(prompt, "\n") { line = strings.TrimSpace(strings.ReplaceAll(line, "\u00a0", " ")) if line == "" || isPromptReferenceDirective(line) { continue } return true } return false } func isPromptReferenceDirective(line string) bool { lower := strings.ToLower(line) hasURL := strings.Contains(lower, "http://") || strings.Contains(lower, "https://") if !hasURL { return false } return strings.HasPrefix(line, "参考图") || strings.HasPrefix(lower, "reference image") }