Files
dypid/internal/controller/tokenController.go
T

344 lines
8.3 KiB
Go

package controller
import (
"dypid/internal/db"
"dypid/internal/global"
"dypid/internal/model"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/redis/go-redis/v9"
)
func ListTokenHandler(c *gin.Context) {
c.JSON(http.StatusOK, model.APIResponse{
Code: 200,
Message: "获取所有token成功",
Data: db.ListToken(),
})
}
func CreateTokenHandler(c *gin.Context) {
//解析输入数据
input := struct {
Token string `form:"token" binding:"required"`
DedupObject string `form:"dedup_object" binding:"required"`
DataFormat string `form:"data_format" binding:"required"`
Notes string `form:"notes"`
}{}
if err := c.ShouldBindQuery(&input); err != nil {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "参数不能为空 " + err.Error(),
})
return
}
//检查Token是否存在
if db.CheckToken(input.Token) {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "创建Token失败,Token已经存在,请勿重复创建",
})
return
}
//创建Token
err := db.CreateToken(input.Token, input.DedupObject, input.DataFormat, input.Notes)
if err != nil {
c.JSON(http.StatusInternalServerError, model.APIResponse{
Code: 500,
Message: err.Error(),
})
return
}
//返回
c.JSON(http.StatusOK, model.APIResponse{
Code: 200,
Message: "创建Token成功",
})
}
func UpdateTokenHandler(c *gin.Context) {
input := struct {
Token string `form:"token" binding:"required"`
DedupObject string `form:"dedup_object" binding:"required"`
DataFormat string `form:"data_format" binding:"required"`
Notes string `form:"notes"`
}{}
if err := c.ShouldBindQuery(&input); err != nil {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "参数不能为空 " + err.Error(),
})
return
}
//检查Token是否存在
if !db.CheckToken(input.Token) {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "更改失败,Token不存在",
})
return
}
err := db.UpdateToken(input.Token, input.DedupObject, input.DataFormat, input.Notes)
if err != nil {
c.JSON(http.StatusInternalServerError, model.APIResponse{
Code: 500,
Message: err.Error(),
})
return
}
c.JSON(http.StatusOK, model.APIResponse{
Code: 200,
Message: "更改Token成功",
})
}
func DeleteTokenHandler(c *gin.Context) {
input := struct {
Token string `form:"token" binding:"required"`
}{}
if err := c.ShouldBindQuery(&input); err != nil {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "参数不能为空 " + err.Error(),
})
return
}
//检查Token是否存在
if !db.CheckToken(input.Token) {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "删除Token失败,Token不存在",
})
return
}
err := db.DeleteToken(input.Token)
if err != nil {
c.JSON(http.StatusInternalServerError, model.APIResponse{
Code: 500,
Message: err.Error(),
})
return
}
c.JSON(http.StatusOK, model.APIResponse{
Code: 200,
Message: "删除Token成功",
})
}
func GetTokenInfoHandler(c *gin.Context) {
input := struct {
Token string `form:"token" binding:"required"`
}{}
if err := c.ShouldBindQuery(&input); err != nil {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "参数不能为空 " + err.Error(),
})
return
}
//检查Token是否存在
if !db.CheckToken(input.Token) {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "获取信息失败,Token不存在",
})
return
}
dedupObject, err := db.GetDedupObject(input.Token)
if err != nil {
c.JSON(http.StatusInternalServerError, model.APIResponse{
Code: 500,
Message: "获取去重对象失败 " + err.Error(),
})
return
}
dataFormat, err := db.GetDataFormat(input.Token)
if err != nil {
c.JSON(http.StatusInternalServerError, model.APIResponse{
Code: 500,
Message: "获取数据格式失败 " + err.Error(),
})
return
}
output := struct {
Token string `json:"token"`
DedupObject string `json:"dedup_object"`
DataFormat string `json:"data_format"`
DedupItemsNumber int64 `json:"dedup_items_number"`
CacheListNumber int64 `json:"cache_list_number"`
}{}
output.Token = input.Token
output.DedupObject = dedupObject
output.DataFormat = dataFormat
output.DedupItemsNumber = global.RDB.CFInfo(global.RCtx, "dedup:"+input.Token+":"+dedupObject).Val().NumItemsInserted
output.CacheListNumber = global.RDB.LLen(global.RCtx, "list:"+input.Token).Val()
c.JSON(http.StatusOK, model.APIResponse{
Code: 200,
Message: "获取Token信息成功",
Data: output,
})
}
func DeleteTokenInfoHandler(c *gin.Context) {
//解析输入数据
input := struct {
Token string `form:"token" binding:"required"`
DedupBF string `form:"dedup_bf"`
CacheList string `form:"cache_list"`
BothNumber string `form:"both_number"`
}{}
if err := c.ShouldBindQuery(&input); err != nil {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "参数不能为空 " + err.Error(),
})
return
}
//检查Token是否存在
if !db.CheckToken(input.Token) {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "删除Token信息失败,Token不存在",
})
return
}
//获取去重对象
dedupObject, err := db.GetDedupObject(input.Token)
if err != nil {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "获取去重对象失败 " + err.Error(),
})
return
}
//删除去重对象
switch input.DedupBF {
case "":
case "all":
keys := global.RDB.Keys(global.RCtx, "dedup:"+input.Token+":*").Val()
global.RDB.Del(global.RCtx, keys...)
global.RDB.Del(global.RCtx, "delete-list:"+input.Token)
default:
num, err := strconv.Atoi(input.DedupBF)
if err != nil {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "dedup_bf数量设置错误 " + err.Error(),
})
return
}
for i := num; i > 0; i -= 20_0000 {
a := 0
if i > 20_0000 {
a = 20_0000
} else {
a = i
}
//获得要删的值(列表)
result := global.RDB.LRange(global.RCtx, "delete-list:"+input.Token, int64(-a), -1).Val()
//用事件批量删除布隆过滤器中值
_, err = global.RDB.TxPipelined(global.RCtx, func(pipe redis.Pipeliner) error {
for _, s := range result {
pipe.CFDel(global.RCtx, "dedup:"+input.Token+":"+dedupObject, s)
}
return nil
})
if err != nil {
c.JSON(http.StatusInternalServerError, model.APIResponse{
Code: 500,
Message: "删除去重对象失败 " + err.Error(),
})
return
}
//清除列表中要删的值
global.RDB.LTrim(global.RCtx, "delete-list:"+input.Token, 0, int64(-a-1))
}
}
//删除原始数据
switch input.CacheList {
case "":
case "all":
global.RDB.Del(global.RCtx, "list:"+input.Token)
default:
num, err := strconv.Atoi(input.CacheList)
if err != nil {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 400,
Message: "cache_list数量设置错误 " + err.Error(),
})
return
}
global.RDB.LTrim(global.RCtx, "list:"+input.Token, 0, int64(-num-1))
}
//删除去重参考值和原始数据
switch input.BothNumber {
case "":
default:
num, err := strconv.Atoi(input.BothNumber)
if err != nil {
c.JSON(http.StatusBadRequest, model.APIResponse{
Code: 500,
Message: "both_number数量设置错误 " + err.Error(),
})
return
}
for i := num; i > 0; i -= 20_0000 {
a := 0
if i > 20_0000 {
a = 20_0000
} else {
a = i
}
result := global.RDB.LRange(global.RCtx, "delete-list:"+input.Token, int64(-a), -1).Val()
_, err = global.RDB.TxPipelined(global.RCtx, func(pipe redis.Pipeliner) error {
for _, s := range result {
pipe.CFDel(global.RCtx, "dedup:"+input.Token+":"+dedupObject, s)
}
pipe.LTrim(global.RCtx, "delete-list:"+input.Token, 0, int64(-a-1))
pipe.LTrim(global.RCtx, "list:"+input.Token, 0, int64(-a-1))
return nil
})
if err != nil {
c.JSON(http.StatusInternalServerError, model.APIResponse{
Code: 500,
Message: "删除Token信息失败 " + err.Error(),
})
return
}
}
}
//输出信息
c.JSON(http.StatusOK, model.APIResponse{
Code: 200,
Message: "删除Token信息成功",
})
}