新增正则和扩展模块

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,479 @@
package app
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"strings"
"git.echol.cn/loser/st/server/global"
"git.echol.cn/loser/st/server/middleware"
"git.echol.cn/loser/st/server/model/app"
"git.echol.cn/loser/st/server/model/app/request"
"git.echol.cn/loser/st/server/model/app/response"
sysResponse "git.echol.cn/loser/st/server/model/common/response"
"git.echol.cn/loser/st/server/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type RegexScriptApi struct{}
var regexScriptService = service.ServiceGroupApp.AppServiceGroup.RegexScriptService
// CreateRegexScript 创建正则脚本
// @Summary 创建正则脚本
// @Description 创建一个新的正则表达式脚本
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param data body request.CreateRegexScriptRequest true "脚本信息"
// @Success 200 {object} response.Response{data=app.AIRegexScript}
// @Router /app/regex [post]
func (a *RegexScriptApi) CreateRegexScript(c *gin.Context) {
userID := middleware.GetAppUserID(c)
var req request.CreateRegexScriptRequest
if err := c.ShouldBindJSON(&req); err != nil {
sysResponse.FailWithMessage(err.Error(), c)
return
}
script, err := regexScriptService.CreateRegexScript(userID, &req)
if err != nil {
global.GVA_LOG.Error("创建正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("创建失败: "+err.Error(), c)
return
}
sysResponse.OkWithData(response.ToRegexScriptResponse(script), c)
}
// UpdateRegexScript 更新正则脚本
// @Summary 更新正则脚本
// @Description 更新正则脚本信息
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param id path int true "脚本ID"
// @Param data body request.UpdateRegexScriptRequest true "脚本信息"
// @Success 200 {object} response.Response
// @Router /app/regex/:id [put]
func (a *RegexScriptApi) UpdateRegexScript(c *gin.Context) {
userID := middleware.GetAppUserID(c)
// 从路径参数获取 ID
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
sysResponse.FailWithMessage("无效的脚本ID", c)
return
}
scriptID := uint(id)
var req request.UpdateRegexScriptRequest
if err := c.ShouldBindJSON(&req); err != nil {
sysResponse.FailWithMessage(err.Error(), c)
return
}
if err := regexScriptService.UpdateRegexScript(userID, scriptID, &req); err != nil {
global.GVA_LOG.Error("更新正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("更新失败: "+err.Error(), c)
return
}
sysResponse.OkWithMessage("更新成功", c)
}
// DeleteRegexScript 删除正则脚本
// @Summary 删除正则脚本
// @Description 删除正则脚本
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param id path int true "脚本ID"
// @Success 200 {object} response.Response
// @Router /app/regex/:id [delete]
func (a *RegexScriptApi) DeleteRegexScript(c *gin.Context) {
userID := middleware.GetAppUserID(c)
// 从路径参数获取 ID
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
sysResponse.FailWithMessage("无效的脚本ID", c)
return
}
scriptID := uint(id)
if err := regexScriptService.DeleteRegexScript(userID, scriptID); err != nil {
global.GVA_LOG.Error("删除正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("删除失败: "+err.Error(), c)
return
}
sysResponse.OkWithMessage("删除成功", c)
}
// GetRegexScript 获取正则脚本详情
// @Summary 获取正则脚本详情
// @Description 获取正则脚本详细信息
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param id path int true "脚本ID"
// @Success 200 {object} response.Response{data=response.RegexScriptResponse}
// @Router /app/regex/:id [get]
func (a *RegexScriptApi) GetRegexScript(c *gin.Context) {
userID := middleware.GetAppUserID(c)
// 从路径参数获取 ID
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
sysResponse.FailWithMessage("无效的脚本ID", c)
return
}
scriptID := uint(id)
script, err := regexScriptService.GetRegexScript(userID, scriptID)
if err != nil {
global.GVA_LOG.Error("获取正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("获取失败: "+err.Error(), c)
return
}
sysResponse.OkWithData(response.ToRegexScriptResponse(script), c)
}
// GetRegexScriptList 获取正则脚本列表
// @Summary 获取正则脚本列表
// @Description 获取正则脚本列表
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param scriptName query string false "脚本名称"
// @Param isGlobal query boolean false "是否全局"
// @Param enabled query boolean false "是否启用"
// @Param characterId query int false "关联角色ID"
// @Param page query int false "页码"
// @Param pageSize query int false "每页大小"
// @Success 200 {object} response.Response{data=response.RegexScriptListResponse}
// @Router /app/regex [get]
func (a *RegexScriptApi) GetRegexScriptList(c *gin.Context) {
userID := middleware.GetAppUserID(c)
var req request.RegexScriptListRequest
if err := c.ShouldBindQuery(&req); err != nil {
sysResponse.FailWithMessage(err.Error(), c)
return
}
// 设置默认值
if req.Page <= 0 {
req.Page = 1
}
if req.PageSize <= 0 {
req.PageSize = 20
}
scripts, total, err := regexScriptService.GetRegexScriptList(userID, &req)
if err != nil {
global.GVA_LOG.Error("获取正则脚本列表失败", zap.Error(err))
sysResponse.FailWithMessage("获取失败: "+err.Error(), c)
return
}
// 转换为响应格式
responses := make([]response.RegexScriptResponse, len(scripts))
for i, script := range scripts {
responses[i] = response.ToRegexScriptResponse(&script)
}
sysResponse.OkWithData(response.RegexScriptListResponse{
List: responses,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, c)
}
// LinkCharactersToRegex 关联角色到正则脚本
// @Summary 关联角色到正则脚本
// @Description 将角色关联到指定的正则脚本
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param id path int true "脚本ID"
// @Param data body request.LinkCharacterToRegexRequest true "角色ID列表"
// @Success 200 {object} response.Response
// @Router /app/regex/:id/link [post]
func (a *RegexScriptApi) LinkCharactersToRegex(c *gin.Context) {
userID := middleware.GetAppUserID(c)
// 从路径参数获取 ID
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
sysResponse.FailWithMessage("无效的脚本ID", c)
return
}
scriptID := uint(id)
var req request.LinkCharacterToRegexRequest
if err := c.ShouldBindJSON(&req); err != nil {
sysResponse.FailWithMessage(err.Error(), c)
return
}
if err := regexScriptService.LinkCharactersToRegex(userID, scriptID, req.CharacterIDs); err != nil {
global.GVA_LOG.Error("关联角色失败", zap.Error(err))
sysResponse.FailWithMessage("关联失败: "+err.Error(), c)
return
}
sysResponse.OkWithMessage("关联成功", c)
}
// GetCharacterRegexScripts 获取角色关联的正则脚本
// @Summary 获取角色关联的正则脚本
// @Description 获取特定角色关联的所有正则脚本
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param characterId path int true "角色ID"
// @Success 200 {object} response.Response{data=[]response.RegexScriptResponse}
// @Router /app/regex/character/:characterId [get]
func (a *RegexScriptApi) GetCharacterRegexScripts(c *gin.Context) {
userID := middleware.GetAppUserID(c)
// 从路径参数获取 ID
idStr := c.Param("characterId")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
sysResponse.FailWithMessage("无效的角色ID", c)
return
}
characterID := uint(id)
scripts, err := regexScriptService.GetCharacterRegexScripts(userID, characterID)
if err != nil {
global.GVA_LOG.Error("获取角色正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("获取失败: "+err.Error(), c)
return
}
// 转换为响应格式
responses := make([]response.RegexScriptResponse, len(scripts))
for i, script := range scripts {
responses[i] = response.ToRegexScriptResponse(&script)
}
sysResponse.OkWithData(responses, c)
}
// DuplicateRegexScript 复制正则脚本
// @Summary 复制正则脚本
// @Description 创建正则脚本的副本
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param id path int true "脚本ID"
// @Success 200 {object} response.Response{data=app.AIRegexScript}
// @Router /app/regex/:id/duplicate [post]
func (a *RegexScriptApi) DuplicateRegexScript(c *gin.Context) {
userID := middleware.GetAppUserID(c)
// 从路径参数获取 ID
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
sysResponse.FailWithMessage("无效的脚本ID", c)
return
}
scriptID := uint(id)
newScript, err := regexScriptService.DuplicateRegexScript(userID, scriptID)
if err != nil {
global.GVA_LOG.Error("复制正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("复制失败: "+err.Error(), c)
return
}
sysResponse.OkWithData(response.ToRegexScriptResponse(newScript), c)
}
// TestRegexScript 测试正则脚本
// @Summary 测试正则脚本
// @Description 测试正则表达式的匹配和替换效果
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param data body request.TestRegexScriptRequest true "测试数据"
// @Success 200 {object} response.Response{data=response.TestRegexScriptResponse}
// @Router /app/regex/test [post]
func (a *RegexScriptApi) TestRegexScript(c *gin.Context) {
var req request.TestRegexScriptRequest
if err := c.ShouldBindJSON(&req); err != nil {
sysResponse.FailWithMessage(err.Error(), c)
return
}
result, err := regexScriptService.TestRegexScript(&req)
if err != nil {
global.GVA_LOG.Error("测试正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("测试失败: "+err.Error(), c)
return
}
sysResponse.OkWithData(result, c)
}
// ApplyRegexScripts 应用正则脚本
// @Summary 应用正则脚本
// @Description 对文本应用正则脚本进行处理
// @Tags 正则脚本管理
// @Accept json
// @Produce json
// @Param data body request.ApplyRegexScriptsRequest true "应用参数"
// @Success 200 {object} response.Response{data=response.ApplyRegexScriptsResponse}
// @Router /app/regex/apply [post]
func (a *RegexScriptApi) ApplyRegexScripts(c *gin.Context) {
userID := middleware.GetAppUserID(c)
var req request.ApplyRegexScriptsRequest
if err := c.ShouldBindJSON(&req); err != nil {
sysResponse.FailWithMessage(err.Error(), c)
return
}
result, err := regexScriptService.ApplyRegexScripts(userID, &req)
if err != nil {
global.GVA_LOG.Error("应用正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("应用失败: "+err.Error(), c)
return
}
sysResponse.OkWithData(result, c)
}
// ImportRegexScripts 导入正则脚本
// @Summary 导入正则脚本
// @Description 从 JSON 文件导入正则脚本
// @Tags 正则脚本管理
// @Accept multipart/form-data
// @Produce json
// @Param file formData file true "JSON 文件"
// @Param overwriteMode formData string false "覆盖模式: skip, overwrite, merge"
// @Success 200 {object} response.Response
// @Router /app/regex/import [post]
func (a *RegexScriptApi) ImportRegexScripts(c *gin.Context) {
userID := middleware.GetAppUserID(c)
// 获取文件
file, err := c.FormFile("file")
if err != nil {
sysResponse.FailWithMessage("获取文件失败: "+err.Error(), c)
return
}
// 获取覆盖模式
overwriteMode := c.DefaultPostForm("overwriteMode", "skip")
// 读取文件内容
openedFile, err := file.Open()
if err != nil {
sysResponse.FailWithMessage("打开文件失败: "+err.Error(), c)
return
}
defer openedFile.Close()
content, err := io.ReadAll(openedFile)
if err != nil {
sysResponse.FailWithMessage("读取文件失败: "+err.Error(), c)
return
}
// 解析 JSON
var exportData response.RegexScriptExportData
if err := json.Unmarshal(content, &exportData); err != nil {
sysResponse.FailWithMessage("解析JSON失败: "+err.Error(), c)
return
}
// 转换为 AIRegexScript
scripts := make([]app.AIRegexScript, len(exportData.Scripts))
for i, resp := range exportData.Scripts {
scripts[i] = app.AIRegexScript{
ScriptName: resp.ScriptName,
Description: resp.Description,
FindRegex: resp.FindRegex,
ReplaceString: resp.ReplaceString,
Enabled: resp.Enabled,
IsGlobal: resp.IsGlobal,
TrimStrings: resp.TrimStrings,
OnlyFormat: resp.OnlyFormat,
RunOnEdit: resp.RunOnEdit,
SubstituteRegex: resp.SubstituteRegex,
MinDepth: resp.MinDepth,
MaxDepth: resp.MaxDepth,
Placement: resp.Placement,
AffectMinDepth: resp.AffectMinDepth,
AffectMaxDepth: resp.AffectMaxDepth,
LinkedChars: resp.LinkedChars,
}
}
// 导入
imported, err := regexScriptService.ImportRegexScripts(userID, scripts, overwriteMode)
if err != nil {
global.GVA_LOG.Error("导入正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("导入失败: "+err.Error(), c)
return
}
sysResponse.OkWithMessage(fmt.Sprintf("成功导入 %d 个脚本", imported), c)
}
// ExportRegexScripts 导出正则脚本
// @Summary 导出正则脚本
// @Description 导出正则脚本为 JSON 文件
// @Tags 正则脚本管理
// @Accept json
// @Produce application/json
// @Param scriptIds query string false "脚本ID列表逗号分隔"
// @Success 200 {object} response.RegexScriptExportData
// @Router /app/regex/export [get]
func (a *RegexScriptApi) ExportRegexScripts(c *gin.Context) {
userID := middleware.GetAppUserID(c)
// 获取脚本ID列表
scriptIDsStr := c.Query("scriptIds")
var scriptIDs []uint
if scriptIDsStr != "" {
var ids []uint
for _, idStr := range strings.Split(scriptIDsStr, ",") {
id, err := strconv.ParseUint(idStr, 10, 32)
if err == nil {
ids = append(ids, uint(id))
}
}
scriptIDs = ids
}
exportData, err := regexScriptService.ExportRegexScripts(userID, scriptIDs)
if err != nil {
global.GVA_LOG.Error("导出正则脚本失败", zap.Error(err))
sysResponse.FailWithMessage("导出失败: "+err.Error(), c)
return
}
// 设置下载响应头
c.Header("Content-Type", "application/json")
c.Header("Content-Disposition", "attachment; filename=regex_scripts_export.json")
c.JSON(http.StatusOK, exportData)
}