新增正则和扩展模块

This commit is contained in:
2026-02-11 23:44:09 +08:00
parent 2bca8e2788
commit 4e611d3a5e
47 changed files with 10058 additions and 49 deletions

View File

@@ -0,0 +1,108 @@
package app
import (
"git.echol.cn/loser/st/server/global"
"gorm.io/datatypes"
"time"
)
// AIExtension 扩展表 (兼容 SillyTavern Extension 规范)
type AIExtension struct {
global.GVA_MODEL
UserID uint `json:"userId" gorm:"not null;index;comment:所属用户ID"`
User *AppUser `json:"user" gorm:"foreignKey:UserID"`
Name string `json:"name" gorm:"type:varchar(500);not null;index;comment:扩展名称"`
DisplayName string `json:"displayName" gorm:"type:varchar(500);comment:显示名称"`
Version string `json:"version" gorm:"type:varchar(50);comment:版本号"`
Author string `json:"author" gorm:"type:varchar(200);comment:作者"`
Description string `json:"description" gorm:"type:text;comment:扩展描述"`
Homepage string `json:"homepage" gorm:"type:varchar(1024);comment:主页地址"`
Repository string `json:"repository" gorm:"type:varchar(1024);comment:仓库地址"`
License string `json:"license" gorm:"type:varchar(100);comment:许可证"`
Tags datatypes.JSON `json:"tags" gorm:"type:jsonb;comment:标签列表"`
// 扩展类型和功能
ExtensionType string `json:"extensionType" gorm:"type:varchar(50);default:'ui';comment:扩展类型(ui/server/hybrid)"` // ui, server, hybrid
Category string `json:"category" gorm:"type:varchar(100);comment:分类(utilities/themes/integrations/tools)"`
// 依赖关系
Dependencies datatypes.JSON `json:"dependencies" gorm:"type:jsonb;comment:依赖的其他扩展"`
Conflicts datatypes.JSON `json:"conflicts" gorm:"type:jsonb;comment:冲突的扩展列表"`
// 扩展文件
ManifestData datatypes.JSON `json:"manifestData" gorm:"type:jsonb;not null;comment:manifest.json 完整内容"`
ScriptPath string `json:"scriptPath" gorm:"type:varchar(1024);comment:主脚本文件路径"`
StylePath string `json:"stylePath" gorm:"type:varchar(1024);comment:样式文件路径"`
AssetsPaths datatypes.JSON `json:"assetsPaths" gorm:"type:jsonb;comment:资源文件路径列表"`
// 扩展配置
Settings datatypes.JSON `json:"settings" gorm:"type:jsonb;comment:扩展配置项"`
Options datatypes.JSON `json:"options" gorm:"type:jsonb;comment:扩展选项"`
// 状态
IsEnabled bool `json:"isEnabled" gorm:"default:false;index;comment:是否启用"`
IsInstalled bool `json:"isInstalled" gorm:"default:true;index;comment:是否已安装"`
IsSystemExt bool `json:"isSystemExt" gorm:"default:false;comment:是否系统内置扩展"`
InstallSource string `json:"installSource" gorm:"type:varchar(500);comment:安装来源(url/git/file/marketplace)"`
SourceURL string `json:"sourceUrl" gorm:"type:varchar(1000);comment:原始安装 URL用于更新"`
Branch string `json:"branch" gorm:"type:varchar(100);comment:Git 分支名称"`
InstallDate time.Time `json:"installDate" gorm:"comment:安装日期"`
LastEnabled time.Time `json:"lastEnabled" gorm:"comment:最后启用时间"`
// 更新相关
AutoUpdate bool `json:"autoUpdate" gorm:"default:false;comment:是否自动更新"`
LastUpdateCheck *time.Time `json:"lastUpdateCheck" gorm:"comment:最后检查更新时间"`
AvailableVersion string `json:"availableVersion" gorm:"type:varchar(50);comment:可用的新版本"`
// 统计
UsageCount int `json:"usageCount" gorm:"default:0;comment:使用次数"`
ErrorCount int `json:"errorCount" gorm:"default:0;comment:错误次数"`
LoadTime int `json:"loadTime" gorm:"default:0;comment:平均加载时间(ms)"`
// 元数据
Metadata datatypes.JSON `json:"metadata" gorm:"type:jsonb;comment:扩展元数据"`
}
func (AIExtension) TableName() string {
return "ai_extensions"
}
// AIExtensionManifest 扩展清单结构 (对应 manifest.json)
type AIExtensionManifest struct {
Name string `json:"name"`
DisplayName string `json:"display_name,omitempty"`
Version string `json:"version"`
Description string `json:"description"`
Author string `json:"author"`
Homepage string `json:"homepage,omitempty"`
Repository string `json:"repository,omitempty"`
License string `json:"license,omitempty"`
Tags []string `json:"tags,omitempty"`
Type string `json:"type,omitempty"` // ui, server, hybrid
Category string `json:"category,omitempty"` // utilities, themes, integrations, tools
Dependencies map[string]string `json:"dependencies,omitempty"` // {"extension-name": ">=1.0.0"}
Conflicts []string `json:"conflicts,omitempty"`
Entry string `json:"entry,omitempty"` // 主入口文件
Style string `json:"style,omitempty"` // 样式文件
Assets []string `json:"assets,omitempty"` // 资源文件列表
Settings map[string]interface{} `json:"settings,omitempty"` // 默认设置
Options map[string]interface{} `json:"options,omitempty"` // 扩展选项
Metadata map[string]interface{} `json:"metadata,omitempty"` // 扩展元数据
AutoUpdate bool `json:"auto_update,omitempty"` // 是否自动更新SillyTavern 兼容)
InlineScript string `json:"inline_script,omitempty"` // 内联脚本SillyTavern 兼容)
}
// AIExtensionSettings 用户的扩展配置(已废弃,配置现在直接存储在 AIExtension.Settings 中)
// type AIExtensionSettings struct {
// global.GVA_MODEL
// UserID uint `json:"userId" gorm:"not null;index:idx_user_ext,unique;comment:用户ID"`
// User *AppUser `json:"user" gorm:"foreignKey:UserID"`
// ExtensionID uint `json:"extensionId" gorm:"not null;index:idx_user_ext,unique;comment:扩展ID"`
// Extension *AIExtension `json:"extension" gorm:"foreignKey:ExtensionID"`
// Settings datatypes.JSON `json:"settings" gorm:"type:jsonb;not null;comment:用户配置"`
// IsEnabled bool `json:"isEnabled" gorm:"default:true;comment:用户是否启用"`
// }
//
// func (AIExtensionSettings) TableName() string {
// return "ai_extension_settings"
// }

View File

@@ -0,0 +1,65 @@
package app
import (
"git.echol.cn/loser/st/server/global"
"github.com/lib/pq"
"gorm.io/datatypes"
)
// AIRegexScript 正则表达式脚本
type AIRegexScript struct {
global.GVA_MODEL
UserID uint `json:"userId" gorm:"not null;index;comment:用户ID"`
User *AppUser `json:"user" gorm:"foreignKey:UserID"`
// 基础信息
ScriptName string `json:"scriptName" gorm:"type:varchar(500);not null;comment:脚本名称"`
Description string `json:"description" gorm:"type:text;comment:脚本描述"`
// 脚本内容
FindRegex string `json:"findRegex" gorm:"type:text;not null;comment:查找正则表达式"`
ReplaceString string `json:"replaceString" gorm:"type:text;comment:替换字符串"`
// 脚本配置
Enabled bool `json:"enabled" gorm:"default:true;comment:是否启用"`
IsGlobal bool `json:"isGlobal" gorm:"default:false;index;comment:是否全局脚本"`
TrimStrings bool `json:"trimStrings" gorm:"default:false;comment:是否去除首尾空格"`
OnlyFormat bool `json:"onlyFormat" gorm:"default:false;comment:仅格式化消息"`
RunOnEdit bool `json:"runOnEdit" gorm:"default:false;comment:编辑时运行"`
SubstituteRegex bool `json:"substituteRegex" gorm:"default:false;comment:替换正则"`
MinDepth *int `json:"minDepth" gorm:"comment:最小深度"`
MaxDepth *int `json:"maxDepth" gorm:"comment:最大深度"`
// 应用范围
Placement string `json:"placement" gorm:"type:varchar(50);comment:应用位置:user,ai,sys,slash"` // user, ai, sys, slash
AffectMinDepth *int `json:"affectMinDepth" gorm:"comment:影响最小深度"`
AffectMaxDepth *int `json:"affectMaxDepth" gorm:"comment:影响最大深度"`
// 关联数据
LinkedChars pq.StringArray `json:"linkedChars" gorm:"type:text[];comment:关联的角色ID列表"`
// 扩展数据(用于存储额外配置)
ScriptData datatypes.JSON `json:"scriptData" gorm:"type:jsonb;comment:脚本附加数据"`
// 统计信息
UsageCount int `json:"usageCount" gorm:"default:0;comment:使用次数"`
LastUsedAt *int64 `json:"lastUsedAt" gorm:"comment:最后使用时间戳"`
}
func (AIRegexScript) TableName() string {
return "ai_regex_scripts"
}
// AICharacterRegexScript 角色与正则脚本关联表
type AICharacterRegexScript struct {
global.GVA_MODEL
CharacterID uint `json:"characterId" gorm:"not null;index:idx_char_regex,unique;comment:角色ID"`
Character *AICharacter `json:"character" gorm:"foreignKey:CharacterID"`
RegexID uint `json:"regexId" gorm:"not null;index:idx_char_regex,unique;comment:正则脚本ID"`
Regex *AIRegexScript `json:"regex" gorm:"foreignKey:RegexID"`
Order int `json:"order" gorm:"default:0;comment:执行顺序"`
}
func (AICharacterRegexScript) TableName() string {
return "ai_character_regex_scripts"
}

View File

@@ -0,0 +1,107 @@
package request
import (
common "git.echol.cn/loser/st/server/model/common/request"
)
// CreateExtensionRequest 创建/安装扩展请求
type CreateExtensionRequest struct {
Name string `json:"name" binding:"required,min=1,max=500"`
DisplayName string `json:"displayName"`
Version string `json:"version"`
Author string `json:"author"`
Description string `json:"description"`
Homepage string `json:"homepage"`
Repository string `json:"repository"`
License string `json:"license"`
Tags []string `json:"tags"`
ExtensionType string `json:"extensionType" binding:"required,oneof=ui server hybrid"`
Category string `json:"category"`
Dependencies map[string]string `json:"dependencies"`
Conflicts []string `json:"conflicts"`
ManifestData map[string]interface{} `json:"manifestData" binding:"required"`
ScriptPath string `json:"scriptPath"`
StylePath string `json:"stylePath"`
AssetsPaths []string `json:"assetsPaths"`
Settings map[string]interface{} `json:"settings"`
Options map[string]interface{} `json:"options"`
InstallSource string `json:"installSource"`
SourceURL string `json:"sourceUrl"` // 原始安装 URL用于更新
Branch string `json:"branch"` // Git 分支
AutoUpdate bool `json:"autoUpdate"` // 是否自动更新
Metadata map[string]interface{} `json:"metadata"`
}
// ExtensionListRequest 扩展列表查询请求
type ExtensionListRequest struct {
common.PageInfo
Name string `json:"name" form:"name"` // 扩展名称(模糊搜索)
ExtensionType string `json:"extensionType" form:"extensionType"` // 扩展类型
Category string `json:"category" form:"category"` // 分类
IsEnabled *bool `json:"isEnabled" form:"isEnabled"` // 是否启用
IsInstalled *bool `json:"isInstalled" form:"isInstalled"` // 是否已安装
Tag string `json:"tag" form:"tag"` // 标签过滤
}
// InstallExtensionRequest 安装扩展请求
type InstallExtensionRequest struct {
Source string `json:"source" binding:"required,oneof=url file marketplace"` // 安装来源
URL string `json:"url"` // URL 安装
ManifestData []byte `json:"manifestData"` // 文件安装
MarketplaceID string `json:"marketplaceId"` // 市场安装
}
// UninstallExtensionRequest 卸载扩展请求
type UninstallExtensionRequest struct {
DeleteFiles bool `json:"deleteFiles"` // 是否删除文件
}
// ToggleExtensionRequest 启用/禁用扩展请求
type ToggleExtensionRequest struct {
IsEnabled *bool `json:"isEnabled"` // 使用指针类型,允许 false 值
}
// UpdateExtensionSettingsRequest 更新扩展配置请求
type UpdateExtensionSettingsRequest struct {
Settings map[string]interface{} `json:"settings" binding:"required"`
}
// ImportExtensionRequest 导入扩展请求
type ImportExtensionRequest struct {
Format string `json:"format" binding:"required,oneof=zip folder"`
}
// ExportExtensionRequest 导出扩展请求
type ExportExtensionRequest struct {
Format string `json:"format" binding:"required,oneof=zip folder"`
IncludeAssets bool `json:"includeAssets"` // 是否包含资源文件
}
// ExtensionStatsRequest 扩展统计请求
type ExtensionStatsRequest struct {
ExtensionID uint `json:"extensionId" binding:"required"`
Action string `json:"action" binding:"required,oneof=usage error load"` // 统计类型
Value int `json:"value"`
}
// InstallExtensionFromGitRequest 从 Git URL 安装扩展请求
type InstallExtensionFromGitRequest struct {
GitUrl string `json:"gitUrl" binding:"required"` // Git 仓库 URL
Branch string `json:"branch" binding:"omitempty,max=100"` // 分支名称(可选,默认 main
}
// InstallExtensionFromURLRequest 从 URL 安装扩展请求(智能识别 Git URL 或 Manifest URL
type InstallExtensionFromURLRequest struct {
URL string `json:"url" binding:"required"` // Git 仓库 URL 或 Manifest.json URL
Branch string `json:"branch"` // Git 分支名称(可选,默认 main
}
// UpdateExtensionRequest 更新扩展请求
type UpdateExtensionRequest struct {
Force bool `json:"force"` // 是否强制更新(忽略本地修改)
DisplayName string `json:"displayName"`
Description string `json:"description"`
Settings map[string]interface{} `json:"settings"`
Options map[string]interface{} `json:"options"`
Metadata map[string]interface{} `json:"metadata"`
}

View File

@@ -0,0 +1,88 @@
package request
import (
"git.echol.cn/loser/st/server/model/app"
common "git.echol.cn/loser/st/server/model/common/request"
)
// CreateRegexScriptRequest 创建正则脚本请求
type CreateRegexScriptRequest struct {
ScriptName string `json:"scriptName" binding:"required"`
Description string `json:"description"`
FindRegex string `json:"findRegex" binding:"required"`
ReplaceString string `json:"replaceString"`
Enabled bool `json:"enabled"`
IsGlobal bool `json:"isGlobal"`
TrimStrings bool `json:"trimStrings"`
OnlyFormat bool `json:"onlyFormat"`
RunOnEdit bool `json:"runOnEdit"`
SubstituteRegex bool `json:"substituteRegex"`
MinDepth *int `json:"minDepth"`
MaxDepth *int `json:"maxDepth"`
Placement string `json:"placement"`
AffectMinDepth *int `json:"affectMinDepth"`
AffectMaxDepth *int `json:"affectMaxDepth"`
LinkedChars []string `json:"linkedChars"`
ScriptData map[string]interface{} `json:"scriptData"`
}
// UpdateRegexScriptRequest 更新正则脚本请求
type UpdateRegexScriptRequest struct {
ScriptName string `json:"scriptName"`
Description string `json:"description"`
FindRegex string `json:"findRegex"`
ReplaceString string `json:"replaceString"`
Enabled *bool `json:"enabled"`
IsGlobal *bool `json:"isGlobal"`
TrimStrings *bool `json:"trimStrings"`
OnlyFormat *bool `json:"onlyFormat"`
RunOnEdit *bool `json:"runOnEdit"`
SubstituteRegex *bool `json:"substituteRegex"`
MinDepth *int `json:"minDepth"`
MaxDepth *int `json:"maxDepth"`
Placement string `json:"placement"`
AffectMinDepth *int `json:"affectMinDepth"`
AffectMaxDepth *int `json:"affectMaxDepth"`
LinkedChars []string `json:"linkedChars"`
ScriptData map[string]interface{} `json:"scriptData"`
}
// RegexScriptListRequest 正则脚本列表查询请求
type RegexScriptListRequest struct {
common.PageInfo
ScriptName string `json:"scriptName" form:"scriptName"` // 脚本名称(模糊搜索)
IsGlobal *bool `json:"isGlobal" form:"isGlobal"` // 是否全局
Enabled *bool `json:"enabled" form:"enabled"` // 是否启用
CharacterID *uint `json:"characterId" form:"characterId"` // 关联角色ID
}
// LinkCharacterToRegexRequest 关联角色到正则脚本请求
type LinkCharacterToRegexRequest struct {
CharacterIDs []uint `json:"characterIds" binding:"required"`
}
// TestRegexScriptRequest 测试正则脚本请求
type TestRegexScriptRequest struct {
FindRegex string `json:"findRegex" binding:"required"`
ReplaceString string `json:"replaceString"`
TestInput string `json:"testInput" binding:"required"`
TrimStrings bool `json:"trimStrings"`
SubstituteRegex bool `json:"substituteRegex"`
}
// ApplyRegexScriptsRequest 应用正则脚本请求
type ApplyRegexScriptsRequest struct {
Text string `json:"text" binding:"required"`
RegexIDs []uint `json:"regexIds"` // 指定要应用的脚本ID列表
CharacterID *uint `json:"characterId"` // 角色ID自动应用关联的脚本
Placement string `json:"placement"` // 应用位置
MinDepth *int `json:"minDepth"` // 最小深度
MaxDepth *int `json:"maxDepth"` // 最大深度
UseGlobal bool `json:"useGlobal"` // 是否应用全局脚本
}
// ImportRegexScriptsRequest 导入正则脚本请求
type ImportRegexScriptsRequest struct {
Scripts []app.AIRegexScript `json:"scripts" binding:"required"`
OverwriteMode string `json:"overwriteMode"` // skip, overwrite, merge
}

View File

@@ -1,6 +1,9 @@
package request
import "git.echol.cn/loser/st/server/model/app"
import (
"git.echol.cn/loser/st/server/model/app"
common "git.echol.cn/loser/st/server/model/common/request"
)
// CreateWorldBookRequest 创建世界书请求
type CreateWorldBookRequest struct {
@@ -20,7 +23,7 @@ type UpdateWorldBookRequest struct {
// WorldBookListRequest 世界书列表查询请求
type WorldBookListRequest struct {
PageInfo
common.PageInfo
BookName string `json:"bookName" form:"bookName"` // 世界书名称(模糊搜索)
IsGlobal *bool `json:"isGlobal" form:"isGlobal"` // 是否全局
CharacterID *uint `json:"characterId" form:"characterId"` // 关联角色ID

View File

@@ -0,0 +1,188 @@
package response
import (
"encoding/json"
"git.echol.cn/loser/st/server/model/app"
"time"
)
// ExtensionResponse 扩展响应
type ExtensionResponse struct {
ID uint `json:"id"`
UserID uint `json:"userId"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
Version string `json:"version"`
Author string `json:"author"`
Description string `json:"description"`
Homepage string `json:"homepage"`
Repository string `json:"repository"`
License string `json:"license"`
Tags []string `json:"tags"`
ExtensionType string `json:"extensionType"`
Category string `json:"category"`
Dependencies map[string]string `json:"dependencies"`
Conflicts []string `json:"conflicts"`
ManifestData map[string]interface{} `json:"manifestData"`
ScriptPath string `json:"scriptPath"`
StylePath string `json:"stylePath"`
AssetsPaths []string `json:"assetsPaths"`
Settings map[string]interface{} `json:"settings"`
Options map[string]interface{} `json:"options"`
IsEnabled bool `json:"isEnabled"`
IsInstalled bool `json:"isInstalled"`
IsSystemExt bool `json:"isSystemExt"`
InstallSource string `json:"installSource"`
InstallDate time.Time `json:"installDate"`
LastEnabled time.Time `json:"lastEnabled"`
UsageCount int `json:"usageCount"`
ErrorCount int `json:"errorCount"`
LoadTime int `json:"loadTime"`
Metadata map[string]interface{} `json:"metadata"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// ExtensionListResponse 扩展列表响应
type ExtensionListResponse struct {
List []ExtensionResponse `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
// ExtensionManifestResponse manifest.json 响应
type ExtensionManifestResponse struct {
Name string `json:"name"`
DisplayName string `json:"display_name,omitempty"`
Version string `json:"version"`
Description string `json:"description"`
Author string `json:"author"`
Homepage string `json:"homepage,omitempty"`
Repository string `json:"repository,omitempty"`
License string `json:"license,omitempty"`
Tags []string `json:"tags,omitempty"`
Type string `json:"type,omitempty"`
Category string `json:"category,omitempty"`
Dependencies map[string]string `json:"dependencies,omitempty"`
Conflicts []string `json:"conflicts,omitempty"`
Entry string `json:"entry,omitempty"`
Style string `json:"style,omitempty"`
Assets []string `json:"assets,omitempty"`
Settings map[string]interface{} `json:"settings,omitempty"`
Options map[string]interface{} `json:"options,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
// ExtensionStatsResponse 扩展统计响应
type ExtensionStatsResponse struct {
ExtensionID uint `json:"extensionId"`
ExtensionName string `json:"extensionName"`
UsageCount int `json:"usageCount"`
ErrorCount int `json:"errorCount"`
LoadTime int `json:"loadTime"`
LastUsed time.Time `json:"lastUsed"`
}
// ToExtensionResponse 转换为扩展响应
func ToExtensionResponse(ext *app.AIExtension) ExtensionResponse {
var tags []string
if ext.Tags != nil {
_ = json.Unmarshal([]byte(ext.Tags), &tags)
}
if tags == nil {
tags = []string{}
}
var dependencies map[string]string
if ext.Dependencies != nil {
_ = json.Unmarshal([]byte(ext.Dependencies), &dependencies)
}
if dependencies == nil {
dependencies = map[string]string{}
}
var conflicts []string
if ext.Conflicts != nil {
_ = json.Unmarshal([]byte(ext.Conflicts), &conflicts)
}
if conflicts == nil {
conflicts = []string{}
}
var manifestData map[string]interface{}
if ext.ManifestData != nil {
_ = json.Unmarshal([]byte(ext.ManifestData), &manifestData)
}
if manifestData == nil {
manifestData = map[string]interface{}{}
}
var assetsPaths []string
if ext.AssetsPaths != nil {
_ = json.Unmarshal([]byte(ext.AssetsPaths), &assetsPaths)
}
if assetsPaths == nil {
assetsPaths = []string{}
}
var settings map[string]interface{}
if ext.Settings != nil {
_ = json.Unmarshal([]byte(ext.Settings), &settings)
}
if settings == nil {
settings = map[string]interface{}{}
}
var options map[string]interface{}
if ext.Options != nil {
_ = json.Unmarshal([]byte(ext.Options), &options)
}
if options == nil {
options = map[string]interface{}{}
}
var metadata map[string]interface{}
if ext.Metadata != nil {
_ = json.Unmarshal([]byte(ext.Metadata), &metadata)
}
if metadata == nil {
metadata = map[string]interface{}{}
}
return ExtensionResponse{
ID: ext.ID,
UserID: ext.UserID,
Name: ext.Name,
DisplayName: ext.DisplayName,
Version: ext.Version,
Author: ext.Author,
Description: ext.Description,
Homepage: ext.Homepage,
Repository: ext.Repository,
License: ext.License,
Tags: tags,
ExtensionType: ext.ExtensionType,
Category: ext.Category,
Dependencies: dependencies,
Conflicts: conflicts,
ManifestData: manifestData,
ScriptPath: ext.ScriptPath,
StylePath: ext.StylePath,
AssetsPaths: assetsPaths,
Settings: settings,
Options: options,
IsEnabled: ext.IsEnabled,
IsInstalled: ext.IsInstalled,
IsSystemExt: ext.IsSystemExt,
InstallSource: ext.InstallSource,
InstallDate: ext.InstallDate,
LastEnabled: ext.LastEnabled,
UsageCount: ext.UsageCount,
ErrorCount: ext.ErrorCount,
LoadTime: ext.LoadTime,
Metadata: metadata,
CreatedAt: ext.CreatedAt,
UpdatedAt: ext.UpdatedAt,
}
}

View File

@@ -0,0 +1,106 @@
package response
import (
"encoding/json"
"git.echol.cn/loser/st/server/model/app"
)
// RegexScriptResponse 正则脚本响应
type RegexScriptResponse struct {
ID uint `json:"id"`
UserID uint `json:"userId"`
ScriptName string `json:"scriptName"`
Description string `json:"description"`
FindRegex string `json:"findRegex"`
ReplaceString string `json:"replaceString"`
Enabled bool `json:"enabled"`
IsGlobal bool `json:"isGlobal"`
TrimStrings bool `json:"trimStrings"`
OnlyFormat bool `json:"onlyFormat"`
RunOnEdit bool `json:"runOnEdit"`
SubstituteRegex bool `json:"substituteRegex"`
MinDepth *int `json:"minDepth"`
MaxDepth *int `json:"maxDepth"`
Placement string `json:"placement"`
AffectMinDepth *int `json:"affectMinDepth"`
AffectMaxDepth *int `json:"affectMaxDepth"`
LinkedChars []string `json:"linkedChars"`
ScriptData map[string]interface{} `json:"scriptData"`
UsageCount int `json:"usageCount"`
LastUsedAt *int64 `json:"lastUsedAt"`
CreatedAt int64 `json:"createdAt"`
UpdatedAt int64 `json:"updatedAt"`
}
// RegexScriptListResponse 正则脚本列表响应
type RegexScriptListResponse struct {
List []RegexScriptResponse `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
// TestRegexScriptResponse 测试正则脚本响应
type TestRegexScriptResponse struct {
Success bool `json:"success"`
Input string `json:"input"`
Output string `json:"output"`
MatchedCount int `json:"matchedCount"`
Matches []string `json:"matches"`
Error string `json:"error,omitempty"`
}
// ApplyRegexScriptsResponse 应用正则脚本响应
type ApplyRegexScriptsResponse struct {
OriginalText string `json:"originalText"`
ProcessedText string `json:"processedText"`
AppliedCount int `json:"appliedCount"`
AppliedScripts []uint `json:"appliedScripts"` // 应用的脚本ID列表
}
// RegexScriptExportData 正则脚本导出数据
type RegexScriptExportData struct {
Version string `json:"version"` // 导出格式版本
Scripts []RegexScriptResponse `json:"scripts"`
ExportedAt int64 `json:"exportedAt"`
}
// ToRegexScriptResponse 将 AIRegexScript 转换为 RegexScriptResponse
func ToRegexScriptResponse(script *app.AIRegexScript) RegexScriptResponse {
var scriptData map[string]interface{}
if len(script.ScriptData) > 0 {
_ = json.Unmarshal(script.ScriptData, &scriptData)
}
linkedChars := []string{}
if script.LinkedChars != nil {
linkedChars = script.LinkedChars
}
return RegexScriptResponse{
ID: script.ID,
UserID: script.UserID,
ScriptName: script.ScriptName,
Description: script.Description,
FindRegex: script.FindRegex,
ReplaceString: script.ReplaceString,
Enabled: script.Enabled,
IsGlobal: script.IsGlobal,
TrimStrings: script.TrimStrings,
OnlyFormat: script.OnlyFormat,
RunOnEdit: script.RunOnEdit,
SubstituteRegex: script.SubstituteRegex,
MinDepth: script.MinDepth,
MaxDepth: script.MaxDepth,
Placement: script.Placement,
AffectMinDepth: script.AffectMinDepth,
AffectMaxDepth: script.AffectMaxDepth,
LinkedChars: linkedChars,
ScriptData: scriptData,
UsageCount: script.UsageCount,
LastUsedAt: script.LastUsedAt,
CreatedAt: script.CreatedAt.Unix(),
UpdatedAt: script.UpdatedAt.Unix(),
}
}