Files
st/server/api/v1/app/regex_script.go
2026-02-11 23:44:09 +08:00

480 lines
14 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 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)
}