🎉 更新系统版本
This commit is contained in:
@@ -321,3 +321,61 @@ func (s *SystemApiApi) FreshCasbin(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
response.OkWithMessage("刷新成功", c)
|
response.OkWithMessage("刷新成功", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetApiRoles
|
||||||
|
// @Tags SysApi
|
||||||
|
// @Summary 获取拥有指定API权限的角色ID列表
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param path query string true "API路径"
|
||||||
|
// @Param method query string true "请求方法"
|
||||||
|
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取成功"
|
||||||
|
// @Router /api/getApiRoles [get]
|
||||||
|
func (s *SystemApiApi) GetApiRoles(c *gin.Context) {
|
||||||
|
path := c.Query("path")
|
||||||
|
method := c.Query("method")
|
||||||
|
if path == "" || method == "" {
|
||||||
|
response.FailWithMessage("API路径和请求方法不能为空", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
authorityIds, err := casbinService.GetAuthoritiesByApi(path, method)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("获取失败"+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if authorityIds == nil {
|
||||||
|
authorityIds = []uint{}
|
||||||
|
}
|
||||||
|
response.OkWithDetailed(authorityIds, "获取成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetApiRoles
|
||||||
|
// @Tags SysApi
|
||||||
|
// @Summary 全量覆盖某API关联的角色列表
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param data body systemReq.SetApiAuthorities true "API路径、请求方法和角色ID列表"
|
||||||
|
// @Success 200 {object} response.Response{msg=string} "设置成功"
|
||||||
|
// @Router /api/setApiRoles [post]
|
||||||
|
func (s *SystemApiApi) SetApiRoles(c *gin.Context) {
|
||||||
|
var req systemReq.SetApiAuthorities
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
response.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.Path == "" || req.Method == "" {
|
||||||
|
response.FailWithMessage("API路径和请求方法不能为空", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := casbinService.SetApiAuthorities(req.Path, req.Method, req.AuthorityIds); err != nil {
|
||||||
|
global.GVA_LOG.Error("设置失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("设置失败"+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 刷新casbin缓存使策略立即生效
|
||||||
|
_ = casbinService.FreshCasbin()
|
||||||
|
response.OkWithMessage("设置成功", c)
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"git.echol.cn/loser/st/server/global"
|
"git.echol.cn/loser/st/server/global"
|
||||||
"git.echol.cn/loser/st/server/model/common/response"
|
"git.echol.cn/loser/st/server/model/common/response"
|
||||||
"git.echol.cn/loser/st/server/model/system"
|
"git.echol.cn/loser/st/server/model/system"
|
||||||
|
systemReq "git.echol.cn/loser/st/server/model/system/request"
|
||||||
systemRes "git.echol.cn/loser/st/server/model/system/response"
|
systemRes "git.echol.cn/loser/st/server/model/system/response"
|
||||||
"git.echol.cn/loser/st/server/utils"
|
"git.echol.cn/loser/st/server/utils"
|
||||||
|
|
||||||
@@ -200,3 +201,57 @@ func (a *AuthorityApi) SetDataAuthority(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
response.OkWithMessage("设置成功", c)
|
response.OkWithMessage("设置成功", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUsersByAuthority
|
||||||
|
// @Tags Authority
|
||||||
|
// @Summary 获取拥有指定角色的用户ID列表
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param authorityId query uint true "角色ID"
|
||||||
|
// @Success 200 {object} response.Response{data=[]uint,msg=string} "获取成功"
|
||||||
|
// @Router /authority/getUsersByAuthority [get]
|
||||||
|
func (a *AuthorityApi) GetUsersByAuthority(c *gin.Context) {
|
||||||
|
var req systemReq.SetRoleUsers
|
||||||
|
if err := c.ShouldBindQuery(&req); err != nil {
|
||||||
|
response.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
userIds, err := authorityService.GetUserIdsByAuthorityId(req.AuthorityId)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("获取失败"+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if userIds == nil {
|
||||||
|
userIds = []uint{}
|
||||||
|
}
|
||||||
|
response.OkWithDetailed(userIds, "获取成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRoleUsers
|
||||||
|
// @Tags Authority
|
||||||
|
// @Summary 全量覆盖某角色关联的用户列表
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param data body systemReq.SetRoleUsers true "角色ID和用户ID列表"
|
||||||
|
// @Success 200 {object} response.Response{msg=string} "设置成功"
|
||||||
|
// @Router /authority/setRoleUsers [post]
|
||||||
|
func (a *AuthorityApi) SetRoleUsers(c *gin.Context) {
|
||||||
|
var req systemReq.SetRoleUsers
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
response.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.AuthorityId == 0 {
|
||||||
|
response.FailWithMessage("角色ID不能为空", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := authorityService.SetRoleUsers(req.AuthorityId, req.UserIds); err != nil {
|
||||||
|
global.GVA_LOG.Error("设置失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("设置失败"+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithMessage("设置成功", c)
|
||||||
|
}
|
||||||
|
|||||||
@@ -244,6 +244,76 @@ func (a *AuthorityMenuApi) GetBaseMenuById(c *gin.Context) {
|
|||||||
response.OkWithDetailed(systemRes.SysBaseMenuResponse{Menu: menu}, "获取成功", c)
|
response.OkWithDetailed(systemRes.SysBaseMenuResponse{Menu: menu}, "获取成功", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMenuRoles
|
||||||
|
// @Tags AuthorityMenu
|
||||||
|
// @Summary 获取拥有指定菜单的角色ID列表
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param menuId query uint true "菜单ID"
|
||||||
|
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取成功"
|
||||||
|
// @Router /menu/getMenuRoles [get]
|
||||||
|
func (a *AuthorityMenuApi) GetMenuRoles(c *gin.Context) {
|
||||||
|
var req systemReq.SetMenuAuthorities
|
||||||
|
if err := c.ShouldBindQuery(&req); err != nil {
|
||||||
|
response.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.MenuId == 0 {
|
||||||
|
response.FailWithMessage("菜单ID不能为空", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
authorityIds, err := menuService.GetAuthoritiesByMenuId(req.MenuId)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("获取失败"+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if authorityIds == nil {
|
||||||
|
authorityIds = []uint{}
|
||||||
|
}
|
||||||
|
defaultRouterAuthorityIds, err := menuService.GetDefaultRouterAuthorityIds(req.MenuId)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("获取首页角色失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("获取失败"+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if defaultRouterAuthorityIds == nil {
|
||||||
|
defaultRouterAuthorityIds = []uint{}
|
||||||
|
}
|
||||||
|
response.OkWithDetailed(gin.H{
|
||||||
|
"authorityIds": authorityIds,
|
||||||
|
"defaultRouterAuthorityIds": defaultRouterAuthorityIds,
|
||||||
|
}, "获取成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMenuRoles
|
||||||
|
// @Tags AuthorityMenu
|
||||||
|
// @Summary 全量覆盖某菜单关联的角色列表
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param data body systemReq.SetMenuAuthorities true "菜单ID和角色ID列表"
|
||||||
|
// @Success 200 {object} response.Response{msg=string} "设置成功"
|
||||||
|
// @Router /menu/setMenuRoles [post]
|
||||||
|
func (a *AuthorityMenuApi) SetMenuRoles(c *gin.Context) {
|
||||||
|
var req systemReq.SetMenuAuthorities
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
response.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.MenuId == 0 {
|
||||||
|
response.FailWithMessage("菜单ID不能为空", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := menuService.SetMenuAuthorities(req.MenuId, req.AuthorityIds); err != nil {
|
||||||
|
global.GVA_LOG.Error("设置失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("设置失败"+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithMessage("设置成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
// GetMenuList
|
// GetMenuList
|
||||||
// @Tags Menu
|
// @Tags Menu
|
||||||
// @Summary 分页获取基础menu列表
|
// @Summary 分页获取基础menu列表
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"git.echol.cn/loser/st/server/global"
|
"git.echol.cn/loser/st/server/global"
|
||||||
"git.echol.cn/loser/st/server/model/common/response"
|
"git.echol.cn/loser/st/server/model/common/response"
|
||||||
"git.echol.cn/loser/st/server/model/system/request"
|
"git.echol.cn/loser/st/server/model/system/request"
|
||||||
@@ -55,6 +57,17 @@ func (s *SkillsApi) SaveSkill(c *gin.Context) {
|
|||||||
response.OkWithMessage("保存成功", c)
|
response.OkWithMessage("保存成功", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SkillsApi) DeleteSkill(c *gin.Context) {
|
||||||
|
var req request.SkillDeleteRequest
|
||||||
|
_ = c.ShouldBindJSON(&req)
|
||||||
|
if err := skillsService.Delete(c.Request.Context(), req); err != nil {
|
||||||
|
global.GVA_LOG.Error("删除技能失败", zap.Error(err))
|
||||||
|
response.FailWithMessage("删除技能失败: "+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithMessage("删除成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SkillsApi) CreateScript(c *gin.Context) {
|
func (s *SkillsApi) CreateScript(c *gin.Context) {
|
||||||
var req request.SkillScriptCreateRequest
|
var req request.SkillScriptCreateRequest
|
||||||
_ = c.ShouldBindJSON(&req)
|
_ = c.ShouldBindJSON(&req)
|
||||||
@@ -217,3 +230,34 @@ func (s *SkillsApi) SaveGlobalConstraint(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
response.OkWithMessage("保存成功", c)
|
response.OkWithMessage("保存成功", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SkillsApi) PackageSkill(c *gin.Context) {
|
||||||
|
var req request.SkillPackageRequest
|
||||||
|
_ = c.ShouldBindJSON(&req)
|
||||||
|
|
||||||
|
fileName, data, err := skillsService.Package(c.Request.Context(), req)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("打包技能失败", zap.Error(err))
|
||||||
|
response.FailWithMessage("打包技能失败: "+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Header("Content-Type", "application/zip")
|
||||||
|
c.Header("Content-Disposition", "attachment; filename=\""+fileName+"\"")
|
||||||
|
c.Data(http.StatusOK, "application/zip", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SkillsApi) DownloadOnlineSkill(c *gin.Context) {
|
||||||
|
var req request.DownloadOnlineSkillReq
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
response.FailWithMessage("参数错误", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := skillsService.DownloadOnlineSkill(c.Request.Context(), req); err != nil {
|
||||||
|
global.GVA_LOG.Error("下载在线技能失败", zap.Error(err))
|
||||||
|
response.FailWithMessage("下载在线技能失败: "+err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithMessage("下载成功", c)
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,5 +12,4 @@ type System struct {
|
|||||||
UseMongo bool `mapstructure:"use-mongo" json:"use-mongo" yaml:"use-mongo"` // 使用mongo
|
UseMongo bool `mapstructure:"use-mongo" json:"use-mongo" yaml:"use-mongo"` // 使用mongo
|
||||||
UseStrictAuth bool `mapstructure:"use-strict-auth" json:"use-strict-auth" yaml:"use-strict-auth"` // 使用树形角色分配模式
|
UseStrictAuth bool `mapstructure:"use-strict-auth" json:"use-strict-auth" yaml:"use-strict-auth"` // 使用树形角色分配模式
|
||||||
DisableAutoMigrate bool `mapstructure:"disable-auto-migrate" json:"disable-auto-migrate" yaml:"disable-auto-migrate"` // 自动迁移数据库表结构,生产环境建议设为false,手动迁移
|
DisableAutoMigrate bool `mapstructure:"disable-auto-migrate" json:"disable-auto-migrate" yaml:"disable-auto-migrate"` // 自动迁移数据库表结构,生产环境建议设为false,手动迁移
|
||||||
DataDir string `mapstructure:"data-dir" json:"data-dir" yaml:"data-dir"` // 数据目录
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ func RunServer() {
|
|||||||
address := fmt.Sprintf(":%d", global.GVA_CONFIG.System.Addr)
|
address := fmt.Sprintf(":%d", global.GVA_CONFIG.System.Addr)
|
||||||
|
|
||||||
fmt.Printf(`
|
fmt.Printf(`
|
||||||
|
欢迎使用 gin-vue-admin
|
||||||
|
当前版本:%s
|
||||||
|
插件市场:https://plugin.gin-vue-admin.com
|
||||||
默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
|
默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
|
||||||
默认MCP SSE地址:http://127.0.0.1%s%s
|
默认MCP SSE地址:http://127.0.0.1%s%s
|
||||||
默认MCP Message地址:http://127.0.0.1%s%s
|
默认MCP Message地址:http://127.0.0.1%s%s
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ package global
|
|||||||
// 目前只有Version正式使用 其余为预留
|
// 目前只有Version正式使用 其余为预留
|
||||||
const (
|
const (
|
||||||
// Version 当前版本号
|
// Version 当前版本号
|
||||||
Version = "v2.8.9"
|
Version = "v2.9.0"
|
||||||
// AppName 应用名称
|
// AppName 应用名称
|
||||||
AppName = "Gin-Vue-Admin"
|
AppName = "Gin-Vue-Admin"
|
||||||
// Description 应用描述
|
// Description 应用描述
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ toolchain go1.24.2
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
|
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
|
||||||
github.com/aws/aws-sdk-go v1.55.6
|
github.com/aws/aws-sdk-go v1.55.8
|
||||||
github.com/casbin/casbin/v2 v2.103.0
|
github.com/casbin/casbin/v2 v2.103.0
|
||||||
github.com/casbin/gorm-adapter/v3 v3.32.0
|
github.com/casbin/gorm-adapter/v3 v3.32.0
|
||||||
github.com/dzwvip/gorm-oracle v0.1.2
|
github.com/dzwvip/gorm-oracle v0.1.2
|
||||||
@@ -20,13 +20,11 @@ require (
|
|||||||
github.com/gookit/color v1.5.4
|
github.com/gookit/color v1.5.4
|
||||||
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible
|
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
||||||
github.com/lib/pq v1.10.9
|
|
||||||
github.com/mark3labs/mcp-go v0.41.1
|
github.com/mark3labs/mcp-go v0.41.1
|
||||||
github.com/mholt/archives v0.1.1
|
github.com/mholt/archives v0.1.1
|
||||||
github.com/minio/minio-go/v7 v7.0.84
|
github.com/minio/minio-go/v7 v7.0.84
|
||||||
github.com/mojocn/base64Captcha v1.3.8
|
github.com/mojocn/base64Captcha v1.3.8
|
||||||
github.com/otiai10/copy v1.14.1
|
github.com/otiai10/copy v1.14.1
|
||||||
github.com/pgvector/pgvector-go v0.3.0
|
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/qiniu/go-sdk/v7 v7.25.2
|
github.com/qiniu/go-sdk/v7 v7.25.2
|
||||||
github.com/qiniu/qmgo v1.1.9
|
github.com/qiniu/qmgo v1.1.9
|
||||||
@@ -53,6 +51,7 @@ require (
|
|||||||
gorm.io/driver/mysql v1.5.7
|
gorm.io/driver/mysql v1.5.7
|
||||||
gorm.io/driver/postgres v1.5.11
|
gorm.io/driver/postgres v1.5.11
|
||||||
gorm.io/driver/sqlserver v1.5.4
|
gorm.io/driver/sqlserver v1.5.4
|
||||||
|
gorm.io/gen v0.3.26
|
||||||
gorm.io/gorm v1.25.12
|
gorm.io/gorm v1.25.12
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -121,7 +120,6 @@ require (
|
|||||||
github.com/magiconair/properties v1.8.9 // indirect
|
github.com/magiconair/properties v1.8.9 // indirect
|
||||||
github.com/mailru/easyjson v0.9.0 // indirect
|
github.com/mailru/easyjson v0.9.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.16 // indirect
|
|
||||||
github.com/microsoft/go-mssqldb v1.8.0 // indirect
|
github.com/microsoft/go-mssqldb v1.8.0 // indirect
|
||||||
github.com/minio/md5-simd v1.1.2 // indirect
|
github.com/minio/md5-simd v1.1.2 // indirect
|
||||||
github.com/minio/minlz v1.0.0 // indirect
|
github.com/minio/minlz v1.0.0 // indirect
|
||||||
@@ -174,13 +172,14 @@ require (
|
|||||||
golang.org/x/arch v0.13.0 // indirect
|
golang.org/x/arch v0.13.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
|
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
|
||||||
golang.org/x/image v0.23.0 // indirect
|
golang.org/x/image v0.23.0 // indirect
|
||||||
golang.org/x/net v0.37.0 // indirect
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
|
golang.org/x/net v0.35.0 // indirect
|
||||||
golang.org/x/sys v0.32.0 // indirect
|
golang.org/x/sys v0.32.0 // indirect
|
||||||
golang.org/x/time v0.9.0 // indirect
|
golang.org/x/time v0.9.0 // indirect
|
||||||
golang.org/x/tools v0.31.0 // indirect
|
golang.org/x/tools v0.29.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.6 // indirect
|
google.golang.org/protobuf v1.36.6 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gorm.io/driver/sqlite v1.5.0 // indirect
|
gorm.io/hints v1.1.2 // indirect
|
||||||
gorm.io/plugin/dbresolver v1.5.3 // indirect
|
gorm.io/plugin/dbresolver v1.5.3 // indirect
|
||||||
modernc.org/fileutil v1.3.0 // indirect
|
modernc.org/fileutil v1.3.0 // indirect
|
||||||
modernc.org/libc v1.61.9 // indirect
|
modernc.org/libc v1.61.9 // indirect
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+
|
|||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
entgo.io/ent v0.14.3 h1:wokAV/kIlH9TeklJWGGS7AYJdVckr0DloWjIcO9iIIQ=
|
|
||||||
entgo.io/ent v0.14.3/go.mod h1:aDPE/OziPEu8+OWbzy4UlvWmD2/kbRuWfK2A40hcxJM=
|
|
||||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
|
||||||
@@ -56,8 +54,8 @@ github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F
|
|||||||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||||
github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk=
|
github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ=
|
||||||
github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk=
|
||||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||||
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||||
@@ -152,10 +150,6 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z
|
|||||||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||||
github.com/go-pg/pg/v10 v10.11.0 h1:CMKJqLgTrfpE/aOVeLdybezR2om071Vh38OLZjsyMI0=
|
|
||||||
github.com/go-pg/pg/v10 v10.11.0/go.mod h1:4BpHRoxE61y4Onpof3x1a2SQvi9c+q1dJnrNdMjsroA=
|
|
||||||
github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU=
|
|
||||||
github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo=
|
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
@@ -214,9 +208,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
|||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
@@ -284,8 +277,6 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
|||||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||||
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
|
|
||||||
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
|
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
||||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
@@ -322,8 +313,8 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx
|
|||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0=
|
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0=
|
||||||
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
|
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
|
||||||
github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
|
github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
|
||||||
@@ -377,8 +368,6 @@ github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
|||||||
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||||
github.com/pgvector/pgvector-go v0.3.0 h1:Ij+Yt78R//uYqs3Zk35evZFvr+G0blW0OUN+Q2D1RWc=
|
|
||||||
github.com/pgvector/pgvector-go v0.3.0/go.mod h1:duFy+PXWfW7QQd5ibqutBO4GxLsUZ9RVXhFZGIBsWSA=
|
|
||||||
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
|
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
|
||||||
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||||
@@ -481,8 +470,6 @@ github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZ
|
|||||||
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
|
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
|
||||||
github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo=
|
github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo=
|
||||||
github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI=
|
github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI=
|
||||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
|
|
||||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
|
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
@@ -492,24 +479,8 @@ github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
|||||||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||||
github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU=
|
github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU=
|
||||||
github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
||||||
github.com/uptrace/bun v1.1.12 h1:sOjDVHxNTuM6dNGaba0wUuz7KvDE1BmNu9Gqs2gJSXQ=
|
|
||||||
github.com/uptrace/bun v1.1.12/go.mod h1:NPG6JGULBeQ9IU6yHp7YGELRa5Agmd7ATZdz4tGZ6z0=
|
|
||||||
github.com/uptrace/bun/dialect/pgdialect v1.1.12 h1:m/CM1UfOkoBTglGO5CUTKnIKKOApOYxkcP2qn0F9tJk=
|
|
||||||
github.com/uptrace/bun/dialect/pgdialect v1.1.12/go.mod h1:Ij6WIxQILxLlL2frUBxUBOZJtLElD2QQNDcu/PWDHTc=
|
|
||||||
github.com/uptrace/bun/driver/pgdriver v1.1.12 h1:3rRWB1GK0psTJrHwxzNfEij2MLibggiLdTqjTtfHc1w=
|
|
||||||
github.com/uptrace/bun/driver/pgdriver v1.1.12/go.mod h1:ssYUP+qwSEgeDDS1xm2XBip9el1y9Mi5mTAvLoiADLM=
|
|
||||||
github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94=
|
|
||||||
github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ=
|
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
|
||||||
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
|
|
||||||
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
|
||||||
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
||||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||||
@@ -606,8 +577,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -636,8 +607,8 @@ golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
|||||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@@ -761,8 +732,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
|
|||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
|
||||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -827,12 +798,17 @@ gorm.io/driver/sqlite v1.5.0 h1:zKYbzRCpBrT1bNijRnxLDJWPjVfImGEn0lSnUY5gZ+c=
|
|||||||
gorm.io/driver/sqlite v1.5.0/go.mod h1:kDMDfntV9u/vuMmz8APHtHF0b4nyBB7sfCieC6G8k8I=
|
gorm.io/driver/sqlite v1.5.0/go.mod h1:kDMDfntV9u/vuMmz8APHtHF0b4nyBB7sfCieC6G8k8I=
|
||||||
gorm.io/driver/sqlserver v1.5.4 h1:xA+Y1KDNspv79q43bPyjDMUgHoYHLhXYmdFcYPobg8g=
|
gorm.io/driver/sqlserver v1.5.4 h1:xA+Y1KDNspv79q43bPyjDMUgHoYHLhXYmdFcYPobg8g=
|
||||||
gorm.io/driver/sqlserver v1.5.4/go.mod h1:+frZ/qYmuna11zHPlh5oc2O6ZA/lS88Keb0XSH1Zh/g=
|
gorm.io/driver/sqlserver v1.5.4/go.mod h1:+frZ/qYmuna11zHPlh5oc2O6ZA/lS88Keb0XSH1Zh/g=
|
||||||
|
gorm.io/gen v0.3.26 h1:sFf1j7vNStimPRRAtH4zz5NiHM+1dr6eA9aaRdplyhY=
|
||||||
|
gorm.io/gen v0.3.26/go.mod h1:a5lq5y3w4g5LMxBcw0wnO6tYUCdNutWODq5LrIt75LE=
|
||||||
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||||
gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
|
gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||||
|
gorm.io/hints v1.1.2 h1:b5j0kwk5p4+3BtDtYqqfY+ATSxjj+6ptPgVveuynn9o=
|
||||||
|
gorm.io/hints v1.1.2/go.mod h1:/ARdpUHAtyEMCh5NNi3tI7FsGh+Cj/MIUlvNxCNCFWg=
|
||||||
gorm.io/plugin/dbresolver v1.5.3 h1:wFwINGZZmttuu9h7XpvbDHd8Lf9bb8GNzp/NpAMV2wU=
|
gorm.io/plugin/dbresolver v1.5.3 h1:wFwINGZZmttuu9h7XpvbDHd8Lf9bb8GNzp/NpAMV2wU=
|
||||||
gorm.io/plugin/dbresolver v1.5.3/go.mod h1:TSrVhaUg2DZAWP3PrHlDlITEJmNOkL0tFTjvTEsQ4XE=
|
gorm.io/plugin/dbresolver v1.5.3/go.mod h1:TSrVhaUg2DZAWP3PrHlDlITEJmNOkL0tFTjvTEsQ4XE=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
@@ -840,8 +816,6 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo=
|
|
||||||
mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw=
|
|
||||||
modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0=
|
modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0=
|
||||||
modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||||
modernc.org/ccgo/v4 v4.23.13 h1:PFiaemQwE/jdwi8XEHyEV+qYWoIuikLP3T4rvDeJb00=
|
modernc.org/ccgo/v4 v4.23.13 h1:PFiaemQwE/jdwi8XEHyEV+qYWoIuikLP3T4rvDeJb00=
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"git.echol.cn/loser/st/server/model/example"
|
"git.echol.cn/loser/st/server/model/example"
|
||||||
sysModel "git.echol.cn/loser/st/server/model/system"
|
sysModel "git.echol.cn/loser/st/server/model/system"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/model"
|
||||||
"git.echol.cn/loser/st/server/service/system"
|
"git.echol.cn/loser/st/server/service/system"
|
||||||
adapter "github.com/casbin/gorm-adapter/v3"
|
adapter "github.com/casbin/gorm-adapter/v3"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -64,6 +65,8 @@ func (e *ensureTables) MigrateTable(ctx context.Context) (context.Context, error
|
|||||||
example.ExaFileChunk{},
|
example.ExaFileChunk{},
|
||||||
example.ExaFileUploadAndDownload{},
|
example.ExaFileUploadAndDownload{},
|
||||||
example.ExaAttachmentCategory{},
|
example.ExaAttachmentCategory{},
|
||||||
|
|
||||||
|
model.Info{},
|
||||||
}
|
}
|
||||||
for _, t := range tables {
|
for _, t := range tables {
|
||||||
_ = db.AutoMigrate(&t)
|
_ = db.AutoMigrate(&t)
|
||||||
@@ -103,6 +106,8 @@ func (e *ensureTables) TableCreated(ctx context.Context) bool {
|
|||||||
example.ExaFileChunk{},
|
example.ExaFileChunk{},
|
||||||
example.ExaFileUploadAndDownload{},
|
example.ExaFileUploadAndDownload{},
|
||||||
example.ExaAttachmentCategory{},
|
example.ExaAttachmentCategory{},
|
||||||
|
|
||||||
|
model.Info{},
|
||||||
}
|
}
|
||||||
yes := true
|
yes := true
|
||||||
for _, t := range tables {
|
for _, t := range tables {
|
||||||
|
|||||||
@@ -35,21 +35,12 @@ func (fs justFilesFilesystem) Open(name string) (http.File, error) {
|
|||||||
|
|
||||||
func Routers() *gin.Engine {
|
func Routers() *gin.Engine {
|
||||||
Router := gin.New()
|
Router := gin.New()
|
||||||
|
|
||||||
// 设置文件上传大小限制(10MB)
|
|
||||||
Router.MaxMultipartMemory = 10 << 20 // 10 MB
|
|
||||||
|
|
||||||
// 使用自定义的 Recovery 中间件,记录 panic 并入库
|
// 使用自定义的 Recovery 中间件,记录 panic 并入库
|
||||||
Router.Use(middleware.GinRecovery(true))
|
Router.Use(middleware.GinRecovery(true))
|
||||||
if gin.Mode() == gin.DebugMode {
|
if gin.Mode() == gin.DebugMode {
|
||||||
Router.Use(gin.Logger())
|
Router.Use(gin.Logger())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跨域配置(前台应用需要)
|
|
||||||
// 必须在静态文件路由之前注册,否则静态文件跨域会失败
|
|
||||||
Router.Use(middleware.Cors())
|
|
||||||
global.GVA_LOG.Info("use middleware cors")
|
|
||||||
|
|
||||||
if !global.GVA_CONFIG.MCP.Separate {
|
if !global.GVA_CONFIG.MCP.Separate {
|
||||||
|
|
||||||
sseServer := McpRun()
|
sseServer := McpRun()
|
||||||
@@ -66,26 +57,6 @@ func Routers() *gin.Engine {
|
|||||||
|
|
||||||
systemRouter := router.RouterGroupApp.System
|
systemRouter := router.RouterGroupApp.System
|
||||||
exampleRouter := router.RouterGroupApp.Example
|
exampleRouter := router.RouterGroupApp.Example
|
||||||
appRouter := router.RouterGroupApp.App // 前台应用路由
|
|
||||||
|
|
||||||
// SillyTavern 核心脚本静态文件服务
|
|
||||||
// 所有核心文件存储在 data/st-core-scripts/ 下,完全独立于 web-app/ 目录
|
|
||||||
stCorePath := "data/st-core-scripts"
|
|
||||||
if _, err := os.Stat(stCorePath); err == nil {
|
|
||||||
Router.Static("/scripts", stCorePath+"/scripts")
|
|
||||||
Router.Static("/css", stCorePath+"/css")
|
|
||||||
Router.Static("/img", stCorePath+"/img")
|
|
||||||
Router.Static("/webfonts", stCorePath+"/webfonts")
|
|
||||||
Router.Static("/lib", stCorePath+"/lib") // SillyTavern 依赖的第三方库
|
|
||||||
Router.Static("/locales", stCorePath+"/locales") // 国际化文件
|
|
||||||
Router.StaticFile("/script.js", stCorePath+"/script.js") // SillyTavern 主入口
|
|
||||||
Router.StaticFile("/lib.js", stCorePath+"/lib.js") // Webpack 编译后的 lib.js
|
|
||||||
global.GVA_LOG.Info("SillyTavern 核心脚本服务已启动: " + stCorePath)
|
|
||||||
} else {
|
|
||||||
global.GVA_LOG.Warn("SillyTavern 核心脚本目录不存在: " + stCorePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 管理后台前端静态文件(web)
|
|
||||||
// 如果想要不使用nginx代理前端网页,可以修改 web/.env.production 下的
|
// 如果想要不使用nginx代理前端网页,可以修改 web/.env.production 下的
|
||||||
// VUE_APP_BASE_API = /
|
// VUE_APP_BASE_API = /
|
||||||
// VUE_APP_BASE_PATH = http://localhost
|
// VUE_APP_BASE_PATH = http://localhost
|
||||||
@@ -95,7 +66,10 @@ func Routers() *gin.Engine {
|
|||||||
// Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面
|
// Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面
|
||||||
|
|
||||||
Router.StaticFS(global.GVA_CONFIG.Local.StorePath, justFilesFilesystem{http.Dir(global.GVA_CONFIG.Local.StorePath)}) // Router.Use(middleware.LoadTls()) // 如果需要使用https 请打开此中间件 然后前往 core/server.go 将启动模式 更变为 Router.RunTLS("端口","你的cre/pem文件","你的key文件")
|
Router.StaticFS(global.GVA_CONFIG.Local.StorePath, justFilesFilesystem{http.Dir(global.GVA_CONFIG.Local.StorePath)}) // Router.Use(middleware.LoadTls()) // 如果需要使用https 请打开此中间件 然后前往 core/server.go 将启动模式 更变为 Router.RunTLS("端口","你的cre/pem文件","你的key文件")
|
||||||
|
// 跨域,如需跨域可以打开下面的注释
|
||||||
|
// Router.Use(middleware.Cors()) // 直接放行全部跨域请求
|
||||||
|
// Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求
|
||||||
|
// global.GVA_LOG.Info("use middleware cors")
|
||||||
docs.SwaggerInfo.BasePath = global.GVA_CONFIG.System.RouterPrefix
|
docs.SwaggerInfo.BasePath = global.GVA_CONFIG.System.RouterPrefix
|
||||||
Router.GET(global.GVA_CONFIG.System.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
Router.GET(global.GVA_CONFIG.System.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||||
global.GVA_LOG.Info("register swagger handler")
|
global.GVA_LOG.Info("register swagger handler")
|
||||||
@@ -137,26 +111,13 @@ func Routers() *gin.Engine {
|
|||||||
systemRouter.InitSysErrorRouter(PrivateGroup, PublicGroup) // 错误日志
|
systemRouter.InitSysErrorRouter(PrivateGroup, PublicGroup) // 错误日志
|
||||||
systemRouter.InitLoginLogRouter(PrivateGroup) // 登录日志
|
systemRouter.InitLoginLogRouter(PrivateGroup) // 登录日志
|
||||||
systemRouter.InitApiTokenRouter(PrivateGroup) // apiToken签发
|
systemRouter.InitApiTokenRouter(PrivateGroup) // apiToken签发
|
||||||
systemRouter.InitSkillsRouter(PrivateGroup) // Skills 定义器
|
systemRouter.InitSkillsRouter(PrivateGroup, PublicGroup) // Skills 定义器
|
||||||
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
|
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
|
||||||
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
|
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
|
||||||
exampleRouter.InitAttachmentCategoryRouterRouter(PrivateGroup) // 文件上传下载分类
|
exampleRouter.InitAttachmentCategoryRouterRouter(PrivateGroup) // 文件上传下载分类
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 前台应用路由(新增)
|
|
||||||
{
|
|
||||||
appGroup := PublicGroup.Group("app") // 统一使用 /app 前缀
|
|
||||||
appRouter.InitAuthRouter(appGroup) // 认证路由:/app/auth/* 和 /app/user/*
|
|
||||||
appRouter.InitCharacterRouter(appGroup) // 角色卡路由:/app/character/*
|
|
||||||
appRouter.InitConversationRouter(appGroup) // 对话路由:/app/conversation/*
|
|
||||||
appRouter.InitAIConfigRouter(appGroup) // AI配置路由:/app/ai-config/*
|
|
||||||
appRouter.InitPresetRouter(appGroup) // 预设路由:/app/preset/*
|
|
||||||
appRouter.InitUploadRouter(appGroup) // 上传路由:/app/upload/*
|
|
||||||
appRouter.InitWorldbookRouter(appGroup) // 世界书路由:/app/worldbook/*
|
|
||||||
appRouter.InitRegexScriptRouter(appGroup) // 正则脚本路由:/app/regex/*
|
|
||||||
}
|
|
||||||
|
|
||||||
//插件路由安装
|
//插件路由安装
|
||||||
InstallPlugin(PrivateGroup, PublicGroup, Router)
|
InstallPlugin(PrivateGroup, PublicGroup, Router)
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
// PageInfo Paging common input parameter structure
|
// PageInfo Paging common input parameter structure
|
||||||
type PageInfo struct {
|
type PageInfo struct {
|
||||||
Page int `json:"page" form:"page,default=1"` // 页码
|
Page int `json:"page" form:"page"` // 页码
|
||||||
PageSize int `json:"pageSize" form:"pageSize,default=20"` // 每页大小
|
PageSize int `json:"pageSize" form:"pageSize"` // 每页大小
|
||||||
Keyword string `json:"keyword" form:"keyword"` // 关键字
|
Keyword string `json:"keyword" form:"keyword"` // 关键字
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,3 +12,10 @@ type SearchApiParams struct {
|
|||||||
OrderKey string `json:"orderKey"` // 排序
|
OrderKey string `json:"orderKey"` // 排序
|
||||||
Desc bool `json:"desc"` // 排序方式:升序false(默认)|降序true
|
Desc bool `json:"desc"` // 排序方式:升序false(默认)|降序true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetApiAuthorities 通过API路径和方法全量覆盖关联角色列表
|
||||||
|
type SetApiAuthorities struct {
|
||||||
|
Path string `json:"path" form:"path"` // API路径
|
||||||
|
Method string `json:"method" form:"method"` // 请求方法
|
||||||
|
AuthorityIds []uint `json:"authorityIds" form:"authorityIds"` // 角色ID列表
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ type AddMenuAuthorityInfo struct {
|
|||||||
AuthorityId uint `json:"authorityId"` // 角色ID
|
AuthorityId uint `json:"authorityId"` // 角色ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetMenuAuthorities 通过菜单ID全量覆盖关联角色列表
|
||||||
|
type SetMenuAuthorities struct {
|
||||||
|
MenuId uint `json:"menuId" form:"menuId"` // 菜单ID
|
||||||
|
AuthorityIds []uint `json:"authorityIds" form:"authorityIds"` // 角色ID列表
|
||||||
|
}
|
||||||
|
|
||||||
func DefaultMenu() []system.SysBaseMenu {
|
func DefaultMenu() []system.SysBaseMenu {
|
||||||
return []system.SysBaseMenu{{
|
return []system.SysBaseMenu{{
|
||||||
GVA_MODEL: global.GVA_MODEL{ID: 1},
|
GVA_MODEL: global.GVA_MODEL{ID: 1},
|
||||||
|
|||||||
@@ -11,6 +11,16 @@ type SkillDetailRequest struct {
|
|||||||
Skill string `json:"skill"`
|
Skill string `json:"skill"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SkillDeleteRequest struct {
|
||||||
|
Tool string `json:"tool"`
|
||||||
|
Skill string `json:"skill"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SkillPackageRequest struct {
|
||||||
|
Tool string `json:"tool"`
|
||||||
|
Skill string `json:"skill"`
|
||||||
|
}
|
||||||
|
|
||||||
type SkillSaveRequest struct {
|
type SkillSaveRequest struct {
|
||||||
Tool string `json:"tool"`
|
Tool string `json:"tool"`
|
||||||
Skill string `json:"skill"`
|
Skill string `json:"skill"`
|
||||||
@@ -62,3 +72,9 @@ type SkillGlobalConstraintSaveRequest struct {
|
|||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
SyncTools []string `json:"syncTools"`
|
SyncTools []string `json:"syncTools"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DownloadOnlineSkillReq struct {
|
||||||
|
Tool string `json:"tool" binding:"required"`
|
||||||
|
ID uint `json:"id" binding:"required"`
|
||||||
|
Version string `json:"version" binding:"required"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,4 +66,12 @@ type GetUserList struct {
|
|||||||
NickName string `json:"nickName" form:"nickName"`
|
NickName string `json:"nickName" form:"nickName"`
|
||||||
Phone string `json:"phone" form:"phone"`
|
Phone string `json:"phone" form:"phone"`
|
||||||
Email string `json:"email" form:"email"`
|
Email string `json:"email" form:"email"`
|
||||||
|
OrderKey string `json:"orderKey" form:"orderKey"` // 排序
|
||||||
|
Desc bool `json:"desc" form:"desc"` // 排序方式:升序false(默认)|降序true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRoleUsers 通过角色ID全量覆盖关联用户列表
|
||||||
|
type SetRoleUsers struct {
|
||||||
|
AuthorityId uint `json:"authorityId" form:"authorityId"` // 角色ID
|
||||||
|
UserIds []uint `json:"userIds" form:"userIds"` // 用户ID列表
|
||||||
}
|
}
|
||||||
|
|||||||
10
server/plugin/announcement/api/enter.go
Normal file
10
server/plugin/announcement/api/enter.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import "git.echol.cn/loser/st/server/plugin/announcement/service"
|
||||||
|
|
||||||
|
var (
|
||||||
|
Api = new(api)
|
||||||
|
serviceInfo = service.Service.Info
|
||||||
|
)
|
||||||
|
|
||||||
|
type api struct{ Info info }
|
||||||
183
server/plugin/announcement/api/info.go
Normal file
183
server/plugin/announcement/api/info.go
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.echol.cn/loser/st/server/global"
|
||||||
|
"git.echol.cn/loser/st/server/model/common/response"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/model"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/model/request"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Info = new(info)
|
||||||
|
|
||||||
|
type info struct{}
|
||||||
|
|
||||||
|
// CreateInfo 创建公告
|
||||||
|
// @Tags Info
|
||||||
|
// @Summary 创建公告
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param data body model.Info true "创建公告"
|
||||||
|
// @Success 200 {object} response.Response{msg=string} "创建成功"
|
||||||
|
// @Router /info/createInfo [post]
|
||||||
|
func (a *info) CreateInfo(c *gin.Context) {
|
||||||
|
var info model.Info
|
||||||
|
err := c.ShouldBindJSON(&info)
|
||||||
|
if err != nil {
|
||||||
|
response.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = serviceInfo.CreateInfo(&info)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("创建失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("创建失败", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithMessage("创建成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteInfo 删除公告
|
||||||
|
// @Tags Info
|
||||||
|
// @Summary 删除公告
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param data body model.Info true "删除公告"
|
||||||
|
// @Success 200 {object} response.Response{msg=string} "删除成功"
|
||||||
|
// @Router /info/deleteInfo [delete]
|
||||||
|
func (a *info) DeleteInfo(c *gin.Context) {
|
||||||
|
ID := c.Query("ID")
|
||||||
|
err := serviceInfo.DeleteInfo(ID)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("删除失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("删除失败", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithMessage("删除成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteInfoByIds 批量删除公告
|
||||||
|
// @Tags Info
|
||||||
|
// @Summary 批量删除公告
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Success 200 {object} response.Response{msg=string} "批量删除成功"
|
||||||
|
// @Router /info/deleteInfoByIds [delete]
|
||||||
|
func (a *info) DeleteInfoByIds(c *gin.Context) {
|
||||||
|
IDs := c.QueryArray("IDs[]")
|
||||||
|
if err := serviceInfo.DeleteInfoByIds(IDs); err != nil {
|
||||||
|
global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("批量删除失败", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithMessage("批量删除成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateInfo 更新公告
|
||||||
|
// @Tags Info
|
||||||
|
// @Summary 更新公告
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param data body model.Info true "更新公告"
|
||||||
|
// @Success 200 {object} response.Response{msg=string} "更新成功"
|
||||||
|
// @Router /info/updateInfo [put]
|
||||||
|
func (a *info) UpdateInfo(c *gin.Context) {
|
||||||
|
var info model.Info
|
||||||
|
err := c.ShouldBindJSON(&info)
|
||||||
|
if err != nil {
|
||||||
|
response.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = serviceInfo.UpdateInfo(info)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("更新失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("更新失败", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithMessage("更新成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindInfo 用id查询公告
|
||||||
|
// @Tags Info
|
||||||
|
// @Summary 用id查询公告
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param data query model.Info true "用id查询公告"
|
||||||
|
// @Success 200 {object} response.Response{data=model.Info,msg=string} "查询成功"
|
||||||
|
// @Router /info/findInfo [get]
|
||||||
|
func (a *info) FindInfo(c *gin.Context) {
|
||||||
|
ID := c.Query("ID")
|
||||||
|
reinfo, err := serviceInfo.GetInfo(ID)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("查询失败", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithData(reinfo, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInfoList 分页获取公告列表
|
||||||
|
// @Tags Info
|
||||||
|
// @Summary 分页获取公告列表
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param data query request.InfoSearch true "分页获取公告列表"
|
||||||
|
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功"
|
||||||
|
// @Router /info/getInfoList [get]
|
||||||
|
func (a *info) GetInfoList(c *gin.Context) {
|
||||||
|
var pageInfo request.InfoSearch
|
||||||
|
err := c.ShouldBindQuery(&pageInfo)
|
||||||
|
if err != nil {
|
||||||
|
response.FailWithMessage(err.Error(), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
list, total, err := serviceInfo.GetInfoInfoList(pageInfo)
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("获取失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("获取失败", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithDetailed(response.PageResult{
|
||||||
|
List: list,
|
||||||
|
Total: total,
|
||||||
|
Page: pageInfo.Page,
|
||||||
|
PageSize: pageInfo.PageSize,
|
||||||
|
}, "获取成功", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInfoDataSource 获取Info的数据源
|
||||||
|
// @Tags Info
|
||||||
|
// @Summary 获取Info的数据源
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Success 200 {object} response.Response{data=object,msg=string} "查询成功"
|
||||||
|
// @Router /info/getInfoDataSource [get]
|
||||||
|
func (a *info) GetInfoDataSource(c *gin.Context) {
|
||||||
|
// 此接口为获取数据源定义的数据
|
||||||
|
dataSource, err := serviceInfo.GetInfoDataSource()
|
||||||
|
if err != nil {
|
||||||
|
global.GVA_LOG.Error("查询失败!", zap.Error(err))
|
||||||
|
response.FailWithMessage("查询失败", c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.OkWithData(dataSource, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInfoPublic 不需要鉴权的公告接口
|
||||||
|
// @Tags Info
|
||||||
|
// @Summary 不需要鉴权的公告接口
|
||||||
|
// @accept application/json
|
||||||
|
// @Produce application/json
|
||||||
|
// @Param data query request.InfoSearch true "分页获取公告列表"
|
||||||
|
// @Success 200 {object} response.Response{data=object,msg=string} "获取成功"
|
||||||
|
// @Router /info/getInfoPublic [get]
|
||||||
|
func (a *info) GetInfoPublic(c *gin.Context) {
|
||||||
|
// 此接口不需要鉴权 示例为返回了一个固定的消息接口,一般本接口用于C端服务,需要自己实现业务逻辑
|
||||||
|
response.OkWithDetailed(gin.H{"info": "不需要鉴权的公告接口信息"}, "获取成功", c)
|
||||||
|
}
|
||||||
4
server/plugin/announcement/config/config.go
Normal file
4
server/plugin/announcement/config/config.go
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
}
|
||||||
18
server/plugin/announcement/gen/gen.go
Normal file
18
server/plugin/announcement/gen/gen.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath" //go:generate go mod tidy
|
||||||
|
|
||||||
|
"gorm.io/gen"
|
||||||
|
//go:generate go mod download
|
||||||
|
//go:generate go run gen.go
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
g := gen.NewGenerator(gen.Config{OutPath: filepath.Join("..", "..", "..", "announcement", "blender", "model", "dao"), Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface})
|
||||||
|
g.ApplyBasic(
|
||||||
|
new(model.Info),
|
||||||
|
)
|
||||||
|
g.Execute()
|
||||||
|
}
|
||||||
50
server/plugin/announcement/initialize/api.go
Normal file
50
server/plugin/announcement/initialize/api.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
model "git.echol.cn/loser/st/server/model/system"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/plugin-tool/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Api(ctx context.Context) {
|
||||||
|
entities := []model.SysApi{
|
||||||
|
{
|
||||||
|
Path: "/info/createInfo",
|
||||||
|
Description: "新建公告",
|
||||||
|
ApiGroup: "公告",
|
||||||
|
Method: "POST",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/info/deleteInfo",
|
||||||
|
Description: "删除公告",
|
||||||
|
ApiGroup: "公告",
|
||||||
|
Method: "DELETE",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/info/deleteInfoByIds",
|
||||||
|
Description: "批量删除公告",
|
||||||
|
ApiGroup: "公告",
|
||||||
|
Method: "DELETE",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/info/updateInfo",
|
||||||
|
Description: "更新公告",
|
||||||
|
ApiGroup: "公告",
|
||||||
|
Method: "PUT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/info/findInfo",
|
||||||
|
Description: "根据ID获取公告",
|
||||||
|
ApiGroup: "公告",
|
||||||
|
Method: "GET",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Path: "/info/getInfoList",
|
||||||
|
Description: "获取公告列表",
|
||||||
|
ApiGroup: "公告",
|
||||||
|
Method: "GET",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
utils.RegisterApis(entities...)
|
||||||
|
}
|
||||||
13
server/plugin/announcement/initialize/dictionary.go
Normal file
13
server/plugin/announcement/initialize/dictionary.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
model "git.echol.cn/loser/st/server/model/system"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/plugin-tool/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Dictionary(ctx context.Context) {
|
||||||
|
entities := []model.SysDictionary{}
|
||||||
|
utils.RegisterDictionaries(entities...)
|
||||||
|
}
|
||||||
21
server/plugin/announcement/initialize/gorm.go
Normal file
21
server/plugin/announcement/initialize/gorm.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.echol.cn/loser/st/server/global"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/model"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Gorm(ctx context.Context) {
|
||||||
|
err := global.GVA_DB.WithContext(ctx).AutoMigrate(
|
||||||
|
new(model.Info),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "注册表失败!")
|
||||||
|
zap.L().Error(fmt.Sprintf("%+v", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
23
server/plugin/announcement/initialize/menu.go
Normal file
23
server/plugin/announcement/initialize/menu.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
model "git.echol.cn/loser/st/server/model/system"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/plugin-tool/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Menu(ctx context.Context) {
|
||||||
|
entities := []model.SysBaseMenu{
|
||||||
|
{
|
||||||
|
ParentId: 9,
|
||||||
|
Path: "anInfo",
|
||||||
|
Name: "anInfo",
|
||||||
|
Hidden: false,
|
||||||
|
Component: "plugin/announcement/view/info.vue",
|
||||||
|
Sort: 5,
|
||||||
|
Meta: model.Meta{Title: "公告管理", Icon: "box"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
utils.RegisterMenus(entities...)
|
||||||
|
}
|
||||||
15
server/plugin/announcement/initialize/router.go
Normal file
15
server/plugin/announcement/initialize/router.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.echol.cn/loser/st/server/global"
|
||||||
|
"git.echol.cn/loser/st/server/middleware"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/router"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Router(engine *gin.Engine) {
|
||||||
|
public := engine.Group(global.GVA_CONFIG.System.RouterPrefix).Group("")
|
||||||
|
private := engine.Group(global.GVA_CONFIG.System.RouterPrefix).Group("")
|
||||||
|
private.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
|
||||||
|
router.Router.Info.Init(public, private)
|
||||||
|
}
|
||||||
18
server/plugin/announcement/initialize/viper.go
Normal file
18
server/plugin/announcement/initialize/viper.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.echol.cn/loser/st/server/global"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/plugin"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Viper() {
|
||||||
|
err := global.GVA_VP.UnmarshalKey("announcement", &plugin.Config)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "初始化配置文件失败!")
|
||||||
|
zap.L().Error(fmt.Sprintf("%+v", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
20
server/plugin/announcement/model/info.go
Normal file
20
server/plugin/announcement/model/info.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.echol.cn/loser/st/server/global"
|
||||||
|
"gorm.io/datatypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Info 公告 结构体
|
||||||
|
type Info struct {
|
||||||
|
global.GVA_MODEL
|
||||||
|
Title string `json:"title" form:"title" gorm:"column:title;comment:公告标题;"` //标题
|
||||||
|
Content string `json:"content" form:"content" gorm:"column:content;comment:公告内容;type:text;"` //内容
|
||||||
|
UserID *int `json:"userID" form:"userID" gorm:"column:user_id;comment:发布者;"` //作者
|
||||||
|
Attachments datatypes.JSON `json:"attachments" form:"attachments" gorm:"column:attachments;comment:相关附件;" swaggertype:"array,object"` //附件
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName 公告 Info自定义表名 gva_announcements_info
|
||||||
|
func (Info) TableName() string {
|
||||||
|
return "gva_announcements_info"
|
||||||
|
}
|
||||||
13
server/plugin/announcement/model/request/info.go
Normal file
13
server/plugin/announcement/model/request/info.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.echol.cn/loser/st/server/model/common/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InfoSearch struct {
|
||||||
|
StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"`
|
||||||
|
EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"`
|
||||||
|
request.PageInfo
|
||||||
|
}
|
||||||
33
server/plugin/announcement/plugin.go
Normal file
33
server/plugin/announcement/plugin.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package announcement
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/initialize"
|
||||||
|
interfaces "git.echol.cn/loser/st/server/utils/plugin/v2"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ interfaces.Plugin = (*plugin)(nil)
|
||||||
|
|
||||||
|
var Plugin = new(plugin)
|
||||||
|
|
||||||
|
type plugin struct{}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
interfaces.Register(Plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *plugin) Register(group *gin.Engine) {
|
||||||
|
ctx := context.Background()
|
||||||
|
// 如果需要配置文件,请到config.Config中填充配置结构,且到下方发放中填入其在config.yaml中的key
|
||||||
|
// initialize.Viper()
|
||||||
|
// 安装插件时候自动注册的api数据请到下方法.Api方法中实现
|
||||||
|
initialize.Api(ctx)
|
||||||
|
// 安装插件时候自动注册的Menu数据请到下方法.Menu方法中实现
|
||||||
|
initialize.Menu(ctx)
|
||||||
|
// 安装插件时候自动注册的Dictionary数据请到下方法.Dictionary方法中实现
|
||||||
|
initialize.Dictionary(ctx)
|
||||||
|
initialize.Gorm(ctx)
|
||||||
|
initialize.Router(group)
|
||||||
|
}
|
||||||
5
server/plugin/announcement/plugin/plugin.go
Normal file
5
server/plugin/announcement/plugin/plugin.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package plugin
|
||||||
|
|
||||||
|
import "git.echol.cn/loser/st/server/plugin/announcement/config"
|
||||||
|
|
||||||
|
var Config config.Config
|
||||||
10
server/plugin/announcement/router/enter.go
Normal file
10
server/plugin/announcement/router/enter.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import "git.echol.cn/loser/st/server/plugin/announcement/api"
|
||||||
|
|
||||||
|
var (
|
||||||
|
Router = new(router)
|
||||||
|
apiInfo = api.Api.Info
|
||||||
|
)
|
||||||
|
|
||||||
|
type router struct{ Info info }
|
||||||
31
server/plugin/announcement/router/info.go
Normal file
31
server/plugin/announcement/router/info.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.echol.cn/loser/st/server/middleware"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Info = new(info)
|
||||||
|
|
||||||
|
type info struct{}
|
||||||
|
|
||||||
|
// Init 初始化 公告 路由信息
|
||||||
|
func (r *info) Init(public *gin.RouterGroup, private *gin.RouterGroup) {
|
||||||
|
{
|
||||||
|
group := private.Group("info").Use(middleware.OperationRecord())
|
||||||
|
group.POST("createInfo", apiInfo.CreateInfo) // 新建公告
|
||||||
|
group.DELETE("deleteInfo", apiInfo.DeleteInfo) // 删除公告
|
||||||
|
group.DELETE("deleteInfoByIds", apiInfo.DeleteInfoByIds) // 批量删除公告
|
||||||
|
group.PUT("updateInfo", apiInfo.UpdateInfo) // 更新公告
|
||||||
|
}
|
||||||
|
{
|
||||||
|
group := private.Group("info")
|
||||||
|
group.GET("findInfo", apiInfo.FindInfo) // 根据ID获取公告
|
||||||
|
group.GET("getInfoList", apiInfo.GetInfoList) // 获取公告列表
|
||||||
|
}
|
||||||
|
{
|
||||||
|
group := public.Group("info")
|
||||||
|
group.GET("getInfoDataSource", apiInfo.GetInfoDataSource) // 获取公告数据源
|
||||||
|
group.GET("getInfoPublic", apiInfo.GetInfoPublic) // 获取公告列表
|
||||||
|
}
|
||||||
|
}
|
||||||
5
server/plugin/announcement/service/enter.go
Normal file
5
server/plugin/announcement/service/enter.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
var Service = new(service)
|
||||||
|
|
||||||
|
type service struct{ Info info }
|
||||||
78
server/plugin/announcement/service/info.go
Normal file
78
server/plugin/announcement/service/info.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.echol.cn/loser/st/server/global"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/model"
|
||||||
|
"git.echol.cn/loser/st/server/plugin/announcement/model/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Info = new(info)
|
||||||
|
|
||||||
|
type info struct{}
|
||||||
|
|
||||||
|
// CreateInfo 创建公告记录
|
||||||
|
// Author [piexlmax](https://github.com/piexlmax)
|
||||||
|
func (s *info) CreateInfo(info *model.Info) (err error) {
|
||||||
|
err = global.GVA_DB.Create(info).Error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteInfo 删除公告记录
|
||||||
|
// Author [piexlmax](https://github.com/piexlmax)
|
||||||
|
func (s *info) DeleteInfo(ID string) (err error) {
|
||||||
|
err = global.GVA_DB.Delete(&model.Info{}, "id = ?", ID).Error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteInfoByIds 批量删除公告记录
|
||||||
|
// Author [piexlmax](https://github.com/piexlmax)
|
||||||
|
func (s *info) DeleteInfoByIds(IDs []string) (err error) {
|
||||||
|
err = global.GVA_DB.Delete(&[]model.Info{}, "id in ?", IDs).Error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateInfo 更新公告记录
|
||||||
|
// Author [piexlmax](https://github.com/piexlmax)
|
||||||
|
func (s *info) UpdateInfo(info model.Info) (err error) {
|
||||||
|
err = global.GVA_DB.Model(&model.Info{}).Where("id = ?", info.ID).Updates(&info).Error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInfo 根据ID获取公告记录
|
||||||
|
// Author [piexlmax](https://github.com/piexlmax)
|
||||||
|
func (s *info) GetInfo(ID string) (info model.Info, err error) {
|
||||||
|
err = global.GVA_DB.Where("id = ?", ID).First(&info).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInfoInfoList 分页获取公告记录
|
||||||
|
// Author [piexlmax](https://github.com/piexlmax)
|
||||||
|
func (s *info) GetInfoInfoList(info request.InfoSearch) (list []model.Info, total int64, err error) {
|
||||||
|
limit := info.PageSize
|
||||||
|
offset := info.PageSize * (info.Page - 1)
|
||||||
|
// 创建db
|
||||||
|
db := global.GVA_DB.Model(&model.Info{})
|
||||||
|
var infos []model.Info
|
||||||
|
// 如果有条件搜索 下方会自动创建搜索语句
|
||||||
|
if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
|
||||||
|
db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
|
||||||
|
}
|
||||||
|
err = db.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if limit != 0 {
|
||||||
|
db = db.Limit(limit).Offset(offset)
|
||||||
|
}
|
||||||
|
err = db.Find(&infos).Error
|
||||||
|
return infos, total, err
|
||||||
|
}
|
||||||
|
func (s *info) GetInfoDataSource() (res map[string][]map[string]any, err error) {
|
||||||
|
res = make(map[string][]map[string]any)
|
||||||
|
|
||||||
|
userID := make([]map[string]any, 0)
|
||||||
|
global.GVA_DB.Table("sys_users").Select("nick_name as label,id as value").Scan(&userID)
|
||||||
|
res["userID"] = userID
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -1 +1,5 @@
|
|||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "git.echol.cn/loser/st/server/plugin/announcement"
|
||||||
|
)
|
||||||
|
|||||||
@@ -22,10 +22,12 @@ func (s *ApiRouter) InitApiRouter(Router *gin.RouterGroup, RouterPub *gin.Router
|
|||||||
apiRouter.POST("getApiById", apiRouterApi.GetApiById) // 获取单条Api消息
|
apiRouter.POST("getApiById", apiRouterApi.GetApiById) // 获取单条Api消息
|
||||||
apiRouter.POST("updateApi", apiRouterApi.UpdateApi) // 更新api
|
apiRouter.POST("updateApi", apiRouterApi.UpdateApi) // 更新api
|
||||||
apiRouter.DELETE("deleteApisByIds", apiRouterApi.DeleteApisByIds) // 删除选中api
|
apiRouter.DELETE("deleteApisByIds", apiRouterApi.DeleteApisByIds) // 删除选中api
|
||||||
|
apiRouter.POST("setApiRoles", apiRouterApi.SetApiRoles) // 全量覆盖API关联角色
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
apiRouterWithoutRecord.POST("getAllApis", apiRouterApi.GetAllApis) // 获取所有api
|
apiRouterWithoutRecord.POST("getAllApis", apiRouterApi.GetAllApis) // 获取所有api
|
||||||
apiRouterWithoutRecord.POST("getApiList", apiRouterApi.GetApiList) // 获取Api列表
|
apiRouterWithoutRecord.POST("getApiList", apiRouterApi.GetApiList) // 获取Api列表
|
||||||
|
apiRouterWithoutRecord.GET("getApiRoles", apiRouterApi.GetApiRoles) // 获取API关联角色ID列表
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
apiPublicRouterWithoutRecord.GET("freshCasbin", apiRouterApi.FreshCasbin) // 刷新casbin权限
|
apiPublicRouterWithoutRecord.GET("freshCasbin", apiRouterApi.FreshCasbin) // 刷新casbin权限
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ func (s *AuthorityRouter) InitAuthorityRouter(Router *gin.RouterGroup) {
|
|||||||
authorityRouter.PUT("updateAuthority", authorityApi.UpdateAuthority) // 更新角色
|
authorityRouter.PUT("updateAuthority", authorityApi.UpdateAuthority) // 更新角色
|
||||||
authorityRouter.POST("copyAuthority", authorityApi.CopyAuthority) // 拷贝角色
|
authorityRouter.POST("copyAuthority", authorityApi.CopyAuthority) // 拷贝角色
|
||||||
authorityRouter.POST("setDataAuthority", authorityApi.SetDataAuthority) // 设置角色资源权限
|
authorityRouter.POST("setDataAuthority", authorityApi.SetDataAuthority) // 设置角色资源权限
|
||||||
|
authorityRouter.POST("setRoleUsers", authorityApi.SetRoleUsers) // 全量覆盖角色关联用户
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
authorityRouterWithoutRecord.POST("getAuthorityList", authorityApi.GetAuthorityList) // 获取角色列表
|
authorityRouterWithoutRecord.POST("getAuthorityList", authorityApi.GetAuthorityList) // 获取角色列表
|
||||||
|
authorityRouterWithoutRecord.GET("getUsersByAuthority", authorityApi.GetUsersByAuthority) // 获取角色关联用户ID列表
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func (s *MenuRouter) InitMenuRouter(Router *gin.RouterGroup) (R gin.IRoutes) {
|
|||||||
menuRouter.POST("addMenuAuthority", authorityMenuApi.AddMenuAuthority) // 增加menu和角色关联关系
|
menuRouter.POST("addMenuAuthority", authorityMenuApi.AddMenuAuthority) // 增加menu和角色关联关系
|
||||||
menuRouter.POST("deleteBaseMenu", authorityMenuApi.DeleteBaseMenu) // 删除菜单
|
menuRouter.POST("deleteBaseMenu", authorityMenuApi.DeleteBaseMenu) // 删除菜单
|
||||||
menuRouter.POST("updateBaseMenu", authorityMenuApi.UpdateBaseMenu) // 更新菜单
|
menuRouter.POST("updateBaseMenu", authorityMenuApi.UpdateBaseMenu) // 更新菜单
|
||||||
|
menuRouter.POST("setMenuRoles", authorityMenuApi.SetMenuRoles) // 全量覆盖菜单关联角色
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
menuRouterWithoutRecord.POST("getMenu", authorityMenuApi.GetMenu) // 获取菜单树
|
menuRouterWithoutRecord.POST("getMenu", authorityMenuApi.GetMenu) // 获取菜单树
|
||||||
@@ -22,6 +23,7 @@ func (s *MenuRouter) InitMenuRouter(Router *gin.RouterGroup) (R gin.IRoutes) {
|
|||||||
menuRouterWithoutRecord.POST("getBaseMenuTree", authorityMenuApi.GetBaseMenuTree) // 获取用户动态路由
|
menuRouterWithoutRecord.POST("getBaseMenuTree", authorityMenuApi.GetBaseMenuTree) // 获取用户动态路由
|
||||||
menuRouterWithoutRecord.POST("getMenuAuthority", authorityMenuApi.GetMenuAuthority) // 获取指定角色menu
|
menuRouterWithoutRecord.POST("getMenuAuthority", authorityMenuApi.GetMenuAuthority) // 获取指定角色menu
|
||||||
menuRouterWithoutRecord.POST("getBaseMenuById", authorityMenuApi.GetBaseMenuById) // 根据id获取菜单
|
menuRouterWithoutRecord.POST("getBaseMenuById", authorityMenuApi.GetBaseMenuById) // 根据id获取菜单
|
||||||
|
menuRouterWithoutRecord.GET("getMenuRoles", authorityMenuApi.GetMenuRoles) // 获取菜单关联角色ID列表
|
||||||
}
|
}
|
||||||
return menuRouter
|
return menuRouter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ import "github.com/gin-gonic/gin"
|
|||||||
|
|
||||||
type SkillsRouter struct{}
|
type SkillsRouter struct{}
|
||||||
|
|
||||||
func (s *SkillsRouter) InitSkillsRouter(Router *gin.RouterGroup) {
|
func (s *SkillsRouter) InitSkillsRouter(Router *gin.RouterGroup, pubRouter *gin.RouterGroup) {
|
||||||
skillsRouter := Router.Group("skills")
|
skillsRouter := Router.Group("skills")
|
||||||
|
skillsRouterPub := pubRouter.Group("skills")
|
||||||
{
|
{
|
||||||
skillsRouter.GET("getTools", skillsApi.GetTools)
|
skillsRouter.GET("getTools", skillsApi.GetTools)
|
||||||
skillsRouter.POST("getSkillList", skillsApi.GetSkillList)
|
skillsRouter.POST("getSkillList", skillsApi.GetSkillList)
|
||||||
skillsRouter.POST("getSkillDetail", skillsApi.GetSkillDetail)
|
skillsRouter.POST("getSkillDetail", skillsApi.GetSkillDetail)
|
||||||
skillsRouter.POST("saveSkill", skillsApi.SaveSkill)
|
skillsRouter.POST("saveSkill", skillsApi.SaveSkill)
|
||||||
|
skillsRouter.POST("deleteSkill", skillsApi.DeleteSkill)
|
||||||
skillsRouter.POST("createScript", skillsApi.CreateScript)
|
skillsRouter.POST("createScript", skillsApi.CreateScript)
|
||||||
skillsRouter.POST("getScript", skillsApi.GetScript)
|
skillsRouter.POST("getScript", skillsApi.GetScript)
|
||||||
skillsRouter.POST("saveScript", skillsApi.SaveScript)
|
skillsRouter.POST("saveScript", skillsApi.SaveScript)
|
||||||
@@ -25,5 +27,9 @@ func (s *SkillsRouter) InitSkillsRouter(Router *gin.RouterGroup) {
|
|||||||
skillsRouter.POST("saveTemplate", skillsApi.SaveTemplate)
|
skillsRouter.POST("saveTemplate", skillsApi.SaveTemplate)
|
||||||
skillsRouter.POST("getGlobalConstraint", skillsApi.GetGlobalConstraint)
|
skillsRouter.POST("getGlobalConstraint", skillsApi.GetGlobalConstraint)
|
||||||
skillsRouter.POST("saveGlobalConstraint", skillsApi.SaveGlobalConstraint)
|
skillsRouter.POST("saveGlobalConstraint", skillsApi.SaveGlobalConstraint)
|
||||||
|
skillsRouter.POST("packageSkill", skillsApi.PackageSkill)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
skillsRouterPub.POST("downloadOnlineSkill", skillsApi.DownloadOnlineSkill)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,3 +331,82 @@ func (authorityService *AuthorityService) GetParentAuthorityID(authorityID uint)
|
|||||||
}
|
}
|
||||||
return *authority.ParentId, nil
|
return *authority.ParentId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUserIdsByAuthorityId 获取拥有指定角色的所有用户ID
|
||||||
|
func (authorityService *AuthorityService) GetUserIdsByAuthorityId(authorityId uint) (userIds []uint, err error) {
|
||||||
|
var records []system.SysUserAuthority
|
||||||
|
err = global.GVA_DB.Where("sys_authority_authority_id = ?", authorityId).Find(&records).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, r := range records {
|
||||||
|
userIds = append(userIds, r.SysUserId)
|
||||||
|
}
|
||||||
|
return userIds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRoleUsers 全量覆盖某角色关联的用户列表
|
||||||
|
// 入参:角色ID + 目标用户ID列表,保存时将该角色的关联关系完全替换为传入列表
|
||||||
|
func (authorityService *AuthorityService) SetRoleUsers(authorityId uint, userIds []uint) error {
|
||||||
|
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
// 1. 查出当前拥有该角色的所有用户ID
|
||||||
|
var existingRecords []system.SysUserAuthority
|
||||||
|
if err := tx.Where("sys_authority_authority_id = ?", authorityId).Find(&existingRecords).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
currentSet := make(map[uint]struct{})
|
||||||
|
for _, r := range existingRecords {
|
||||||
|
currentSet[r.SysUserId] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
targetSet := make(map[uint]struct{})
|
||||||
|
for _, id := range userIds {
|
||||||
|
targetSet[id] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 删除该角色所有已有的用户关联
|
||||||
|
if err := tx.Delete(&system.SysUserAuthority{}, "sys_authority_authority_id = ?", authorityId).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 对被移除的用户:若该角色是其主角色,则将主角色切换为其剩余的其他角色
|
||||||
|
for userId := range currentSet {
|
||||||
|
if _, ok := targetSet[userId]; ok {
|
||||||
|
continue // 仍在目标列表中,不处理
|
||||||
|
}
|
||||||
|
var user system.SysUser
|
||||||
|
if err := tx.First(&user, "id = ?", userId).Error; err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if user.AuthorityId == authorityId {
|
||||||
|
// 从剩余关联(已删除当前角色后)中找另一个角色作为主角色
|
||||||
|
var another system.SysUserAuthority
|
||||||
|
if err := tx.Where("sys_user_id = ?", userId).First(&another).Error; err != nil {
|
||||||
|
// 没有其他角色,主角色保持不变,不做处理
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := tx.Model(&system.SysUser{}).Where("id = ?", userId).
|
||||||
|
Update("authority_id", another.SysAuthorityAuthorityId).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 批量插入新的关联记录
|
||||||
|
if len(userIds) > 0 {
|
||||||
|
newRecords := make([]system.SysUserAuthority, 0, len(userIds))
|
||||||
|
for _, userId := range userIds {
|
||||||
|
newRecords = append(newRecords, system.SysUserAuthority{
|
||||||
|
SysUserId: userId,
|
||||||
|
SysAuthorityAuthorityId: authorityId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := tx.Create(&newRecords).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -171,3 +171,45 @@ func (casbinService *CasbinService) FreshCasbin() (err error) {
|
|||||||
err = e.LoadPolicy()
|
err = e.LoadPolicy()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAuthoritiesByApi 获取拥有指定API权限的所有角色ID
|
||||||
|
func (casbinService *CasbinService) GetAuthoritiesByApi(path, method string) (authorityIds []uint, err error) {
|
||||||
|
var rules []gormadapter.CasbinRule
|
||||||
|
err = global.GVA_DB.Where("ptype = 'p' AND v1 = ? AND v2 = ?", path, method).Find(&rules).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, r := range rules {
|
||||||
|
id, e := strconv.Atoi(r.V0)
|
||||||
|
if e == nil {
|
||||||
|
authorityIds = append(authorityIds, uint(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return authorityIds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetApiAuthorities 全量覆盖某API关联的角色列表
|
||||||
|
func (casbinService *CasbinService) SetApiAuthorities(path, method string, authorityIds []uint) error {
|
||||||
|
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
// 1. 删除该API所有已有的角色关联
|
||||||
|
if err := tx.Where("ptype = 'p' AND v1 = ? AND v2 = ?", path, method).Delete(&gormadapter.CasbinRule{}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 2. 批量插入新的关联记录
|
||||||
|
if len(authorityIds) > 0 {
|
||||||
|
newRules := make([]gormadapter.CasbinRule, 0, len(authorityIds))
|
||||||
|
for _, authorityId := range authorityIds {
|
||||||
|
newRules = append(newRules, gormadapter.CasbinRule{
|
||||||
|
Ptype: "p",
|
||||||
|
V0: strconv.Itoa(int(authorityId)),
|
||||||
|
V1: path,
|
||||||
|
V2: method,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := tx.Create(&newRules).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -315,6 +315,65 @@ func (menuService *MenuService) GetMenuAuthority(info *request.GetAuthorityId) (
|
|||||||
return menus, err
|
return menus, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAuthoritiesByMenuId 获取拥有指定菜单的所有角色ID
|
||||||
|
func (menuService *MenuService) GetAuthoritiesByMenuId(menuId uint) (authorityIds []uint, err error) {
|
||||||
|
var records []system.SysAuthorityMenu
|
||||||
|
err = global.GVA_DB.Where("sys_base_menu_id = ?", menuId).Find(&records).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, r := range records {
|
||||||
|
id, e := strconv.Atoi(r.AuthorityId)
|
||||||
|
if e == nil {
|
||||||
|
authorityIds = append(authorityIds, uint(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return authorityIds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDefaultRouterAuthorityIds 获取将指定菜单设为首页的角色ID列表
|
||||||
|
func (menuService *MenuService) GetDefaultRouterAuthorityIds(menuId uint) (authorityIds []uint, err error) {
|
||||||
|
var menu system.SysBaseMenu
|
||||||
|
err = global.GVA_DB.First(&menu, menuId).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var authorities []system.SysAuthority
|
||||||
|
err = global.GVA_DB.Where("default_router = ?", menu.Name).Find(&authorities).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, auth := range authorities {
|
||||||
|
authorityIds = append(authorityIds, auth.AuthorityId)
|
||||||
|
}
|
||||||
|
return authorityIds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMenuAuthorities 全量覆盖某菜单关联的角色列表
|
||||||
|
func (menuService *MenuService) SetMenuAuthorities(menuId uint, authorityIds []uint) error {
|
||||||
|
return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
// 1. 删除该菜单所有已有的角色关联
|
||||||
|
if err := tx.Where("sys_base_menu_id = ?", menuId).Delete(&system.SysAuthorityMenu{}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 2. 批量插入新的关联记录
|
||||||
|
if len(authorityIds) > 0 {
|
||||||
|
menuIdStr := strconv.Itoa(int(menuId))
|
||||||
|
newRecords := make([]system.SysAuthorityMenu, 0, len(authorityIds))
|
||||||
|
for _, authorityId := range authorityIds {
|
||||||
|
newRecords = append(newRecords, system.SysAuthorityMenu{
|
||||||
|
MenuId: menuIdStr,
|
||||||
|
AuthorityId: strconv.Itoa(int(authorityId)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := tx.Create(&newRecords).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// UserAuthorityDefaultRouter 用户角色默认路由检查
|
// UserAuthorityDefaultRouter 用户角色默认路由检查
|
||||||
//
|
//
|
||||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -158,6 +163,107 @@ func (s *SkillsService) Save(_ context.Context, req request.SkillSaveRequest) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SkillsService) Delete(_ context.Context, req request.SkillDeleteRequest) error {
|
||||||
|
if strings.TrimSpace(req.Tool) == "" {
|
||||||
|
return errors.New("工具类型不能为空")
|
||||||
|
}
|
||||||
|
if !isSafeName(req.Skill) {
|
||||||
|
return errors.New("技能名称不合法")
|
||||||
|
}
|
||||||
|
skillDir, err := s.skillDir(req.Tool, req.Skill)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info, err := os.Stat(skillDir)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return errors.New("技能不存在")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
return errors.New("技能目录异常")
|
||||||
|
}
|
||||||
|
return os.RemoveAll(skillDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SkillsService) Package(_ context.Context, req request.SkillPackageRequest) (string, []byte, error) {
|
||||||
|
if strings.TrimSpace(req.Tool) == "" {
|
||||||
|
return "", nil, errors.New("工具类型不能为空")
|
||||||
|
}
|
||||||
|
if !isSafeName(req.Skill) {
|
||||||
|
return "", nil, errors.New("技能名称不合法")
|
||||||
|
}
|
||||||
|
|
||||||
|
skillDir, err := s.skillDir(req.Tool, req.Skill)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
info, err := os.Stat(skillDir)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return "", nil, errors.New("技能不存在")
|
||||||
|
}
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
return "", nil, errors.New("技能目录异常")
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
zw := zip.NewWriter(buf)
|
||||||
|
|
||||||
|
walkErr := filepath.WalkDir(skillDir, func(path string, d fs.DirEntry, walkErr error) error {
|
||||||
|
if walkErr != nil {
|
||||||
|
return walkErr
|
||||||
|
}
|
||||||
|
rel, err := filepath.Rel(skillDir, path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rel == "." {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
zipName := filepath.ToSlash(rel)
|
||||||
|
if d.IsDir() {
|
||||||
|
_, err = zw.Create(strings.TrimSuffix(zipName, "/") + "/")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fileInfo, err := d.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
header, err := zip.FileInfoHeader(fileInfo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
header.Name = zipName
|
||||||
|
header.Method = zip.Deflate
|
||||||
|
|
||||||
|
writer, err := zw.CreateHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
content, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = writer.Write(content)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
if walkErr != nil {
|
||||||
|
_ = zw.Close()
|
||||||
|
return "", nil, walkErr
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = zw.Close(); err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return req.Skill + ".zip", buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SkillsService) CreateScript(_ context.Context, req request.SkillScriptCreateRequest) (string, string, error) {
|
func (s *SkillsService) CreateScript(_ context.Context, req request.SkillScriptCreateRequest) (string, string, error) {
|
||||||
if !isSafeName(req.Skill) {
|
if !isSafeName(req.Skill) {
|
||||||
return "", "", errors.New("技能名称不合法")
|
return "", "", errors.New("技能名称不合法")
|
||||||
@@ -279,6 +385,136 @@ func (s *SkillsService) SaveGlobalConstraint(_ context.Context, req request.Skil
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SkillsService) DownloadOnlineSkill(_ context.Context, req request.DownloadOnlineSkillReq) error {
|
||||||
|
skillsDir, err := s.toolSkillsDir(req.Tool)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(map[string]interface{}{
|
||||||
|
"plugin_id": req.ID,
|
||||||
|
"version": req.Version,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("构建下载请求失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadReq, err := http.NewRequest(http.MethodPost, "https://plugin.gin-vue-admin.com/api/shopPlugin/downloadSkill", bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("构建下载请求失败: %w", err)
|
||||||
|
}
|
||||||
|
downloadReq.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
downloadResp, err := http.DefaultClient.Do(downloadReq)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("下载技能失败: %w", err)
|
||||||
|
}
|
||||||
|
defer downloadResp.Body.Close()
|
||||||
|
|
||||||
|
if downloadResp.StatusCode != http.StatusOK {
|
||||||
|
return fmt.Errorf("下载技能失败, HTTP状态码: %d", downloadResp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
metaBody, err := io.ReadAll(downloadResp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("读取下载结果失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var meta struct {
|
||||||
|
Data struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(metaBody, &meta); err != nil {
|
||||||
|
return fmt.Errorf("解析下载结果失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
realDownloadURL := strings.TrimSpace(meta.Data.URL)
|
||||||
|
if realDownloadURL == "" {
|
||||||
|
return errors.New("下载结果缺少 url")
|
||||||
|
}
|
||||||
|
|
||||||
|
zipResp, err := http.Get(realDownloadURL)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("下载压缩包失败: %w", err)
|
||||||
|
}
|
||||||
|
defer zipResp.Body.Close()
|
||||||
|
|
||||||
|
if zipResp.StatusCode != http.StatusOK {
|
||||||
|
return fmt.Errorf("下载压缩包失败, HTTP状态码: %d", zipResp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpFile, err := os.CreateTemp("", "gva-skill-*.zip")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("创建临时文件失败: %w", err)
|
||||||
|
}
|
||||||
|
tmpPath := tmpFile.Name()
|
||||||
|
defer os.Remove(tmpPath)
|
||||||
|
|
||||||
|
if _, err = io.Copy(tmpFile, zipResp.Body); err != nil {
|
||||||
|
tmpFile.Close()
|
||||||
|
return fmt.Errorf("保存技能包失败: %w", err)
|
||||||
|
}
|
||||||
|
tmpFile.Close()
|
||||||
|
|
||||||
|
if err = extractZipToDir(tmpPath, skillsDir); err != nil {
|
||||||
|
return fmt.Errorf("解压技能包失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractZipToDir(zipPath, destDir string) error {
|
||||||
|
r, err := zip.OpenReader(zipPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
for _, f := range r.File {
|
||||||
|
name := filepath.FromSlash(f.Name)
|
||||||
|
if strings.Contains(name, "..") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
target := filepath.Join(destDir, name)
|
||||||
|
if !strings.HasPrefix(filepath.Clean(target), filepath.Clean(destDir)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.FileInfo().IsDir() {
|
||||||
|
if err := os.MkdirAll(target, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(filepath.Dir(target), os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rc, err := f.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := os.OpenFile(target, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
||||||
|
if err != nil {
|
||||||
|
rc.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(out, rc)
|
||||||
|
rc.Close()
|
||||||
|
out.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SkillsService) toolSkillsDir(tool string) (string, error) {
|
func (s *SkillsService) toolSkillsDir(tool string) (string, error) {
|
||||||
toolDir, ok := skillToolDirs[tool]
|
toolDir, ok := skillToolDirs[tool]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
@@ -109,7 +109,25 @@ func (userService *UserService) GetUserInfoList(info systemReq.GetUserList) (lis
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = db.Limit(limit).Offset(offset).Preload("Authorities").Preload("Authority").Find(&userList).Error
|
|
||||||
|
orderStr := "id desc"
|
||||||
|
if info.OrderKey != "" {
|
||||||
|
allowedOrders := map[string]bool{
|
||||||
|
"id": true,
|
||||||
|
"username": true,
|
||||||
|
"nick_name": true,
|
||||||
|
"phone": true,
|
||||||
|
"email": true,
|
||||||
|
}
|
||||||
|
if allowedOrders[info.OrderKey] {
|
||||||
|
orderStr = info.OrderKey
|
||||||
|
if info.Desc {
|
||||||
|
orderStr = info.OrderKey + " desc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Limit(limit).Offset(offset).Order(orderStr).Preload("Authorities").Preload("Authority").Find(&userList).Error
|
||||||
return userList, total, err
|
return userList, total, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 5174,
|
||||||
// 开发服务器禁用缓存
|
// 开发服务器禁用缓存
|
||||||
headers: {
|
headers: {
|
||||||
'Cache-Control': 'no-store',
|
'Cache-Control': 'no-store',
|
||||||
|
|||||||
Reference in New Issue
Block a user