后端重构
This commit is contained in:
@@ -26,8 +26,10 @@ var ProviderSet = wire.NewSet(
|
||||
system.NewExportTemplateUsecase,
|
||||
system.NewAutoCodeUsecase,
|
||||
system.NewAutoCodeHistoryUsecase,
|
||||
system.NewAutoCodePackageUsecase,
|
||||
// Example
|
||||
example.NewFileUploadUsecase,
|
||||
example.NewCustomerUsecase,
|
||||
example.NewAttachmentCategoryUsecase,
|
||||
example.NewBreakpointContinueUsecase,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// ExaFile 文件实体
|
||||
type ExaFile struct {
|
||||
ID uint
|
||||
FileName string
|
||||
FileMd5 string
|
||||
FilePath string
|
||||
ChunkTotal int
|
||||
IsFinish bool
|
||||
ExaFileChunk []ExaFileChunk
|
||||
}
|
||||
|
||||
// ExaFileChunk 文件切片实体
|
||||
type ExaFileChunk struct {
|
||||
ID uint
|
||||
ExaFileID uint
|
||||
FileChunkNumber int
|
||||
FileChunkPath string
|
||||
}
|
||||
|
||||
// BreakpointContinueRepo 断点续传仓储接口
|
||||
type BreakpointContinueRepo interface {
|
||||
FindOrCreateFile(ctx context.Context, fileMd5, fileName string, chunkTotal int) (*ExaFile, error)
|
||||
CreateFileChunk(ctx context.Context, fileID uint, fileChunkPath string, fileChunkNumber int) error
|
||||
DeleteFileChunk(ctx context.Context, fileMd5, filePath string) error
|
||||
}
|
||||
|
||||
// BreakpointContinueUsecase 断点续传用例
|
||||
type BreakpointContinueUsecase struct {
|
||||
repo BreakpointContinueRepo
|
||||
}
|
||||
|
||||
// NewBreakpointContinueUsecase 创建断点续传用例
|
||||
func NewBreakpointContinueUsecase(repo BreakpointContinueRepo) *BreakpointContinueUsecase {
|
||||
return &BreakpointContinueUsecase{repo: repo}
|
||||
}
|
||||
|
||||
// FindOrCreateFile 查找或创建文件记录
|
||||
func (uc *BreakpointContinueUsecase) FindOrCreateFile(ctx context.Context, fileMd5, fileName string, chunkTotal int) (*ExaFile, error) {
|
||||
return uc.repo.FindOrCreateFile(ctx, fileMd5, fileName, chunkTotal)
|
||||
}
|
||||
|
||||
// CreateFileChunk 创建文件切片记录
|
||||
func (uc *BreakpointContinueUsecase) CreateFileChunk(ctx context.Context, fileID uint, fileChunkPath string, fileChunkNumber int) error {
|
||||
return uc.repo.CreateFileChunk(ctx, fileID, fileChunkPath, fileChunkNumber)
|
||||
}
|
||||
|
||||
// DeleteFileChunk 删除文件切片记录
|
||||
func (uc *BreakpointContinueUsecase) DeleteFileChunk(ctx context.Context, fileMd5, filePath string) error {
|
||||
return uc.repo.DeleteFileChunk(ctx, fileMd5, filePath)
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// SysAutoCodePackage 代码包实体
|
||||
type SysAutoCodePackage struct {
|
||||
ID uint
|
||||
Desc string
|
||||
Label string
|
||||
Template string
|
||||
PackageName string
|
||||
Module string
|
||||
}
|
||||
|
||||
// AutoCodePackageRepo 代码包仓储接口
|
||||
type AutoCodePackageRepo interface {
|
||||
Create(ctx context.Context, pkg *SysAutoCodePackage) error
|
||||
Delete(ctx context.Context, id uint) error
|
||||
DeleteByNames(ctx context.Context, names []string) error
|
||||
All(ctx context.Context) ([]SysAutoCodePackage, error)
|
||||
First(ctx context.Context, packageName, template string) (*SysAutoCodePackage, error)
|
||||
FindByPackageName(ctx context.Context, packageName string) (*SysAutoCodePackage, error)
|
||||
BatchCreate(ctx context.Context, pkgs []SysAutoCodePackage) error
|
||||
DeleteByIDs(ctx context.Context, ids []uint) error
|
||||
}
|
||||
|
||||
// AutoCodePackageUsecase 代码包用例
|
||||
type AutoCodePackageUsecase struct {
|
||||
repo AutoCodePackageRepo
|
||||
}
|
||||
|
||||
// NewAutoCodePackageUsecase 创建代码包用例
|
||||
func NewAutoCodePackageUsecase(repo AutoCodePackageRepo) *AutoCodePackageUsecase {
|
||||
return &AutoCodePackageUsecase{repo: repo}
|
||||
}
|
||||
|
||||
// Create 创建包
|
||||
func (uc *AutoCodePackageUsecase) Create(ctx context.Context, pkg *SysAutoCodePackage) error {
|
||||
return uc.repo.Create(ctx, pkg)
|
||||
}
|
||||
|
||||
// Delete 删除包
|
||||
func (uc *AutoCodePackageUsecase) Delete(ctx context.Context, id uint) error {
|
||||
return uc.repo.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// DeleteByNames 根据名称删除包
|
||||
func (uc *AutoCodePackageUsecase) DeleteByNames(ctx context.Context, names []string) error {
|
||||
return uc.repo.DeleteByNames(ctx, names)
|
||||
}
|
||||
|
||||
// All 获取所有包
|
||||
func (uc *AutoCodePackageUsecase) All(ctx context.Context) ([]SysAutoCodePackage, error) {
|
||||
return uc.repo.All(ctx)
|
||||
}
|
||||
|
||||
// First 查询包
|
||||
func (uc *AutoCodePackageUsecase) First(ctx context.Context, packageName, template string) (*SysAutoCodePackage, error) {
|
||||
return uc.repo.First(ctx, packageName, template)
|
||||
}
|
||||
|
||||
// FindByPackageName 根据包名查询
|
||||
func (uc *AutoCodePackageUsecase) FindByPackageName(ctx context.Context, packageName string) (*SysAutoCodePackage, error) {
|
||||
return uc.repo.FindByPackageName(ctx, packageName)
|
||||
}
|
||||
|
||||
// BatchCreate 批量创建
|
||||
func (uc *AutoCodePackageUsecase) BatchCreate(ctx context.Context, pkgs []SysAutoCodePackage) error {
|
||||
return uc.repo.BatchCreate(ctx, pkgs)
|
||||
}
|
||||
|
||||
// DeleteByIDs 根据ID批量删除
|
||||
func (uc *AutoCodePackageUsecase) DeleteByIDs(ctx context.Context, ids []uint) error {
|
||||
return uc.repo.DeleteByIDs(ctx, ids)
|
||||
}
|
||||
@@ -40,10 +40,12 @@ var ProviderSet = wire.NewSet(
|
||||
datasystem.NewExportTemplateRepo,
|
||||
datasystem.NewAutoCodeRepo,
|
||||
datasystem.NewAutoCodeHistoryRepo,
|
||||
datasystem.NewAutoCodePackageRepo,
|
||||
// Example
|
||||
dataexample.NewFileUploadRepo,
|
||||
dataexample.NewCustomerRepo,
|
||||
dataexample.NewAttachmentCategoryRepo,
|
||||
dataexample.NewBreakpointContinueRepo,
|
||||
)
|
||||
|
||||
// Data 数据层包装器
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"kra/internal/biz/example"
|
||||
"kra/internal/data/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type breakpointContinueRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewBreakpointContinueRepo 创建断点续传仓储
|
||||
func NewBreakpointContinueRepo(db *gorm.DB) example.BreakpointContinueRepo {
|
||||
return &breakpointContinueRepo{db: db}
|
||||
}
|
||||
|
||||
// FindOrCreateFile 查找或创建文件记录
|
||||
func (r *breakpointContinueRepo) FindOrCreateFile(ctx context.Context, fileMd5, fileName string, chunkTotal int) (*example.ExaFile, error) {
|
||||
var file model.ExaFile
|
||||
cfile := model.ExaFile{
|
||||
FileMd5: fileMd5,
|
||||
FileName: fileName,
|
||||
ChunkTotal: int64(chunkTotal),
|
||||
}
|
||||
|
||||
// 检查是否已有完成的文件
|
||||
if errors.Is(r.db.WithContext(ctx).Where("file_md5 = ? AND is_finish = ?", fileMd5, true).First(&file).Error, gorm.ErrRecordNotFound) {
|
||||
// 没有完成的文件,查找或创建
|
||||
err := r.db.WithContext(ctx).Where("file_md5 = ? AND file_name = ?", fileMd5, fileName).
|
||||
FirstOrCreate(&file, cfile).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 加载切片
|
||||
var chunks []model.ExaFileChunk
|
||||
r.db.WithContext(ctx).Where("exa_file_id = ?", file.ID).Find(&chunks)
|
||||
return toBizExaFileWithChunks(&file, chunks), nil
|
||||
}
|
||||
|
||||
// 已有完成的文件,创建新记录
|
||||
cfile.IsFinish = true
|
||||
cfile.FilePath = file.FilePath
|
||||
if err := r.db.WithContext(ctx).Create(&cfile).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toBizExaFileWithChunks(&cfile, nil), nil
|
||||
}
|
||||
|
||||
// CreateFileChunk 创建文件切片记录
|
||||
func (r *breakpointContinueRepo) CreateFileChunk(ctx context.Context, fileID uint, fileChunkPath string, fileChunkNumber int) error {
|
||||
chunk := model.ExaFileChunk{
|
||||
ExaFileID: int64(fileID),
|
||||
FileChunkPath: fileChunkPath,
|
||||
FileChunkNumber: int64(fileChunkNumber),
|
||||
}
|
||||
return r.db.WithContext(ctx).Create(&chunk).Error
|
||||
}
|
||||
|
||||
// DeleteFileChunk 删除文件切片记录
|
||||
func (r *breakpointContinueRepo) DeleteFileChunk(ctx context.Context, fileMd5, filePath string) error {
|
||||
var file model.ExaFile
|
||||
err := r.db.WithContext(ctx).Where("file_md5 = ?", fileMd5).First(&file).
|
||||
Updates(map[string]interface{}{
|
||||
"is_finish": true,
|
||||
"file_path": filePath,
|
||||
}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return r.db.WithContext(ctx).Where("exa_file_id = ?", file.ID).Delete(&model.ExaFileChunk{}).Unscoped().Error
|
||||
}
|
||||
|
||||
// 转换函数
|
||||
func toBizExaFileWithChunks(m *model.ExaFile, chunks []model.ExaFileChunk) *example.ExaFile {
|
||||
file := &example.ExaFile{
|
||||
ID: uint(m.ID),
|
||||
FileName: m.FileName,
|
||||
FileMd5: m.FileMd5,
|
||||
FilePath: m.FilePath,
|
||||
ChunkTotal: int(m.ChunkTotal),
|
||||
IsFinish: m.IsFinish,
|
||||
}
|
||||
if len(chunks) > 0 {
|
||||
file.ExaFileChunk = make([]example.ExaFileChunk, len(chunks))
|
||||
for i, chunk := range chunks {
|
||||
file.ExaFileChunk[i] = example.ExaFileChunk{
|
||||
ID: uint(chunk.ID),
|
||||
ExaFileID: uint(chunk.ExaFileID),
|
||||
FileChunkNumber: int(chunk.FileChunkNumber),
|
||||
FileChunkPath: chunk.FileChunkPath,
|
||||
}
|
||||
}
|
||||
}
|
||||
return file
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"kra/internal/biz/system"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// SysAutoCodePackage 代码包数据模型
|
||||
type SysAutoCodePackage struct {
|
||||
gorm.Model
|
||||
Desc string `json:"desc" gorm:"comment:描述"`
|
||||
Label string `json:"label" gorm:"comment:展示名"`
|
||||
Template string `json:"template" gorm:"comment:模版"`
|
||||
PackageName string `json:"packageName" gorm:"comment:包名"`
|
||||
Module string `json:"-" gorm:"comment:模块"`
|
||||
}
|
||||
|
||||
func (SysAutoCodePackage) TableName() string {
|
||||
return "sys_auto_code_packages"
|
||||
}
|
||||
|
||||
type autoCodePackageRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewAutoCodePackageRepo 创建代码包仓储
|
||||
func NewAutoCodePackageRepo(db *gorm.DB) system.AutoCodePackageRepo {
|
||||
return &autoCodePackageRepo{db: db}
|
||||
}
|
||||
|
||||
// Create 创建包
|
||||
func (r *autoCodePackageRepo) Create(ctx context.Context, pkg *system.SysAutoCodePackage) error {
|
||||
entity := toDataAutoCodePackage(pkg)
|
||||
if err := r.db.WithContext(ctx).Create(entity).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
pkg.ID = entity.ID
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete 删除包
|
||||
func (r *autoCodePackageRepo) Delete(ctx context.Context, id uint) error {
|
||||
return r.db.WithContext(ctx).Delete(&SysAutoCodePackage{}, id).Error
|
||||
}
|
||||
|
||||
// DeleteByNames 根据名称删除包
|
||||
func (r *autoCodePackageRepo) DeleteByNames(ctx context.Context, names []string) error {
|
||||
if len(names) == 0 {
|
||||
return nil
|
||||
}
|
||||
return r.db.WithContext(ctx).Where("package_name IN ?", names).Delete(&SysAutoCodePackage{}).Error
|
||||
}
|
||||
|
||||
// All 获取所有包
|
||||
func (r *autoCodePackageRepo) All(ctx context.Context) ([]system.SysAutoCodePackage, error) {
|
||||
var entities []SysAutoCodePackage
|
||||
err := r.db.WithContext(ctx).Find(&entities).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toBizAutoCodePackages(entities), nil
|
||||
}
|
||||
|
||||
// First 查询包
|
||||
func (r *autoCodePackageRepo) First(ctx context.Context, packageName, template string) (*system.SysAutoCodePackage, error) {
|
||||
var entity SysAutoCodePackage
|
||||
err := r.db.WithContext(ctx).Where("package_name = ? AND template = ?", packageName, template).First(&entity).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return toBizAutoCodePackage(&entity), nil
|
||||
}
|
||||
|
||||
// FindByPackageName 根据包名查询
|
||||
func (r *autoCodePackageRepo) FindByPackageName(ctx context.Context, packageName string) (*system.SysAutoCodePackage, error) {
|
||||
var entity SysAutoCodePackage
|
||||
err := r.db.WithContext(ctx).Where("package_name = ?", packageName).First(&entity).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return toBizAutoCodePackage(&entity), nil
|
||||
}
|
||||
|
||||
// BatchCreate 批量创建
|
||||
func (r *autoCodePackageRepo) BatchCreate(ctx context.Context, pkgs []system.SysAutoCodePackage) error {
|
||||
if len(pkgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
entities := make([]SysAutoCodePackage, len(pkgs))
|
||||
for i, pkg := range pkgs {
|
||||
entities[i] = *toDataAutoCodePackage(&pkg)
|
||||
}
|
||||
return r.db.WithContext(ctx).Create(&entities).Error
|
||||
}
|
||||
|
||||
// DeleteByIDs 根据ID批量删除
|
||||
func (r *autoCodePackageRepo) DeleteByIDs(ctx context.Context, ids []uint) error {
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
return r.db.WithContext(ctx).Delete(&SysAutoCodePackage{}, ids).Error
|
||||
}
|
||||
|
||||
// 转换函数
|
||||
func toBizAutoCodePackage(m *SysAutoCodePackage) *system.SysAutoCodePackage {
|
||||
return &system.SysAutoCodePackage{
|
||||
ID: m.ID,
|
||||
Desc: m.Desc,
|
||||
Label: m.Label,
|
||||
Template: m.Template,
|
||||
PackageName: m.PackageName,
|
||||
Module: m.Module,
|
||||
}
|
||||
}
|
||||
|
||||
func toBizAutoCodePackages(models []SysAutoCodePackage) []system.SysAutoCodePackage {
|
||||
result := make([]system.SysAutoCodePackage, len(models))
|
||||
for i, m := range models {
|
||||
result[i] = *toBizAutoCodePackage(&m)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func toDataAutoCodePackage(pkg *system.SysAutoCodePackage) *SysAutoCodePackage {
|
||||
return &SysAutoCodePackage{
|
||||
Model: gorm.Model{ID: pkg.ID},
|
||||
Desc: pkg.Desc,
|
||||
Label: pkg.Label,
|
||||
Template: pkg.Template,
|
||||
PackageName: pkg.PackageName,
|
||||
Module: pkg.Module,
|
||||
}
|
||||
}
|
||||
@@ -41,10 +41,12 @@ func NewGinRouter(
|
||||
exportTemplateUsecase *system.ExportTemplateUsecase,
|
||||
autoCodeUsecase *system.AutoCodeUsecase,
|
||||
autoCodeHistoryUsecase *system.AutoCodeHistoryUsecase,
|
||||
autoCodePackageUsecase *system.AutoCodePackageUsecase,
|
||||
// Example usecases
|
||||
fileUploadUsecase *example.FileUploadUsecase,
|
||||
customerUsecase *example.CustomerUsecase,
|
||||
attachmentCategoryUsecase *example.AttachmentCategoryUsecase,
|
||||
breakpointContinueUsecase *example.BreakpointContinueUsecase,
|
||||
) *gin.Engine {
|
||||
gin.SetMode(gin.DebugMode)
|
||||
|
||||
@@ -91,6 +93,7 @@ func NewGinRouter(
|
||||
exportTemplateUsecase,
|
||||
autoCodeUsecase,
|
||||
autoCodeHistoryUsecase,
|
||||
autoCodePackageUsecase,
|
||||
)
|
||||
handler.SetJWTInstance(jwtPkg)
|
||||
|
||||
@@ -99,6 +102,7 @@ func NewGinRouter(
|
||||
fileUploadUsecase,
|
||||
customerUsecase,
|
||||
attachmentCategoryUsecase,
|
||||
breakpointContinueUsecase,
|
||||
)
|
||||
|
||||
// 创建路由组
|
||||
|
||||
@@ -14,6 +14,7 @@ var (
|
||||
fileUploadUsecase *example.FileUploadUsecase
|
||||
customerUsecase *example.CustomerUsecase
|
||||
attachmentCategoryUsecase *example.AttachmentCategoryUsecase
|
||||
breakpointContinueUsecase *example.BreakpointContinueUsecase
|
||||
)
|
||||
|
||||
// InitUsecases 初始化业务层依赖
|
||||
@@ -21,8 +22,10 @@ func InitUsecases(
|
||||
fileUpload *example.FileUploadUsecase,
|
||||
customer *example.CustomerUsecase,
|
||||
attachmentCategory *example.AttachmentCategoryUsecase,
|
||||
breakpointContinue *example.BreakpointContinueUsecase,
|
||||
) {
|
||||
fileUploadUsecase = fileUpload
|
||||
customerUsecase = customer
|
||||
attachmentCategoryUsecase = attachmentCategory
|
||||
breakpointContinueUsecase = breakpointContinue
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package example
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"kra/internal/biz/example"
|
||||
"kra/pkg/response"
|
||||
"kra/pkg/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// BreakpointContinue 断点续传到服务器
|
||||
func (f *FileUploadApi) BreakpointContinue(c *gin.Context) {
|
||||
fileMd5 := c.Request.FormValue("fileMd5")
|
||||
fileName := c.Request.FormValue("fileName")
|
||||
chunkMd5 := c.Request.FormValue("chunkMd5")
|
||||
chunkNumber, _ := strconv.Atoi(c.Request.FormValue("chunkNumber"))
|
||||
chunkTotal, _ := strconv.Atoi(c.Request.FormValue("chunkTotal"))
|
||||
|
||||
_, FileHeader, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
response.FailWithMessage("接收文件失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
file, err := FileHeader.Open()
|
||||
if err != nil {
|
||||
response.FailWithMessage("文件读取失败", c)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
content, _ := io.ReadAll(file)
|
||||
if !utils.CheckMd5(content, chunkMd5) {
|
||||
response.FailWithMessage("检查md5失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
exaFile, err := breakpointContinueUsecase.FindOrCreateFile(c.Request.Context(), fileMd5, fileName, chunkTotal)
|
||||
if err != nil {
|
||||
response.FailWithMessage("查找或创建记录失败: "+err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
pathC, err := utils.BreakPointContinue(content, fileName, chunkNumber, chunkTotal, fileMd5)
|
||||
if err != nil {
|
||||
response.FailWithMessage("断点续传失败: "+err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
if err = breakpointContinueUsecase.CreateFileChunk(c.Request.Context(), exaFile.ID, pathC, chunkNumber); err != nil {
|
||||
response.FailWithMessage("创建文件记录失败: "+err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
response.OkWithMessage("切片创建成功", c)
|
||||
}
|
||||
|
||||
// FindFile 查找文件
|
||||
func (f *FileUploadApi) FindFile(c *gin.Context) {
|
||||
fileMd5 := c.Query("fileMd5")
|
||||
fileName := c.Query("fileName")
|
||||
chunkTotal, _ := strconv.Atoi(c.Query("chunkTotal"))
|
||||
|
||||
file, err := breakpointContinueUsecase.FindOrCreateFile(c.Request.Context(), fileMd5, fileName, chunkTotal)
|
||||
if err != nil {
|
||||
response.FailWithMessage("查找失败: "+err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
response.OkWithDetailed(gin.H{"file": toFileResponse(file)}, "查找成功", c)
|
||||
}
|
||||
|
||||
// BreakpointContinueFinish 创建文件(合并切片)
|
||||
func (f *FileUploadApi) BreakpointContinueFinish(c *gin.Context) {
|
||||
fileMd5 := c.Query("fileMd5")
|
||||
fileName := c.Query("fileName")
|
||||
|
||||
filePath, err := utils.MakeFile(fileName, fileMd5)
|
||||
if err != nil {
|
||||
response.FailWithDetailed(gin.H{"filePath": filePath}, "文件创建失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
response.OkWithDetailed(gin.H{"filePath": filePath}, "文件创建成功", c)
|
||||
}
|
||||
|
||||
// RemoveChunk 删除切片
|
||||
func (f *FileUploadApi) RemoveChunk(c *gin.Context) {
|
||||
var req struct {
|
||||
FileMd5 string `json:"fileMd5"`
|
||||
FilePath string `json:"filePath"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 路径穿越拦截
|
||||
if strings.Contains(req.FilePath, "..") || strings.Contains(req.FilePath, "../") ||
|
||||
strings.Contains(req.FilePath, "./") || strings.Contains(req.FilePath, ".\\") {
|
||||
response.FailWithMessage("非法路径,禁止删除", c)
|
||||
return
|
||||
}
|
||||
|
||||
if err := utils.RemoveChunk(req.FileMd5); err != nil {
|
||||
response.FailWithMessage("缓存切片删除失败: "+err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
if err := breakpointContinueUsecase.DeleteFileChunk(c.Request.Context(), req.FileMd5, req.FilePath); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
response.OkWithMessage("缓存切片删除成功", c)
|
||||
}
|
||||
|
||||
func toFileResponse(file *example.ExaFile) map[string]interface{} {
|
||||
chunks := make([]map[string]interface{}, len(file.ExaFileChunk))
|
||||
for i, chunk := range file.ExaFileChunk {
|
||||
chunks[i] = map[string]interface{}{
|
||||
"ID": chunk.ID,
|
||||
"exaFileID": chunk.ExaFileID,
|
||||
"fileChunkNumber": chunk.FileChunkNumber,
|
||||
"fileChunkPath": chunk.FileChunkPath,
|
||||
}
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"ID": file.ID,
|
||||
"fileName": file.FileName,
|
||||
"fileMd5": file.FileMd5,
|
||||
"filePath": file.FilePath,
|
||||
"chunkTotal": file.ChunkTotal,
|
||||
"isFinish": file.IsFinish,
|
||||
"exaFileChunk": chunks,
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,9 @@ type ApiGroup struct {
|
||||
DBApi
|
||||
AutoCodeApi
|
||||
AutoCodeHistoryApi
|
||||
AutoCodePackageApi
|
||||
AutoCodeTemplateApi
|
||||
AutoCodePluginApi
|
||||
}
|
||||
|
||||
// 业务层依赖
|
||||
@@ -42,6 +45,7 @@ var (
|
||||
exportTemplateUsecase *system.ExportTemplateUsecase
|
||||
autoCodeUsecase *system.AutoCodeUsecase
|
||||
autoCodeHistoryUsecase *system.AutoCodeHistoryUsecase
|
||||
autoCodePackageUsecase *system.AutoCodePackageUsecase
|
||||
)
|
||||
|
||||
// InitUsecases 初始化业务层依赖
|
||||
@@ -62,6 +66,7 @@ func InitUsecases(
|
||||
exportTemplate *system.ExportTemplateUsecase,
|
||||
autoCode *system.AutoCodeUsecase,
|
||||
autoCodeHistory *system.AutoCodeHistoryUsecase,
|
||||
autoCodePackage *system.AutoCodePackageUsecase,
|
||||
) {
|
||||
userUsecase = user
|
||||
apiUsecase = api
|
||||
@@ -79,4 +84,10 @@ func InitUsecases(
|
||||
exportTemplateUsecase = exportTemplate
|
||||
autoCodeUsecase = autoCode
|
||||
autoCodeHistoryUsecase = autoCodeHistory
|
||||
autoCodePackageUsecase = autoCodePackage
|
||||
}
|
||||
|
||||
// Api类型定义
|
||||
type AutoCodePackageApi struct{}
|
||||
type AutoCodeTemplateApi struct{}
|
||||
type AutoCodePluginApi struct{}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"kra/pkg/response"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// GetPackages 获取所有包
|
||||
// @Tags AutoCodePackage
|
||||
// @Summary 获取所有包
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=[]system.SysAutoCodePackage} "获取成功"
|
||||
// @Router /autoCode/getPackage [post]
|
||||
func GetPackages(c *gin.Context) {
|
||||
pkgs, err := autoCodePackageUsecase.All(c.Request.Context())
|
||||
if err != nil {
|
||||
response.FailWithMessage("获取失败: "+err.Error(), c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(pkgs, "获取成功", c)
|
||||
}
|
||||
|
||||
// DeletePackage 删除包
|
||||
// @Tags AutoCodePackage
|
||||
// @Summary 删除包
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body request.GetById true "删除包"
|
||||
// @Success 200 {object} response.Response{msg=string} "删除成功"
|
||||
// @Router /autoCode/delPackage [post]
|
||||
func DeletePackage(c *gin.Context) {
|
||||
var req struct {
|
||||
ID uint `json:"id"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
if err := autoCodePackageUsecase.Delete(c.Request.Context(), req.ID); err != nil {
|
||||
response.FailWithMessage("删除失败: "+err.Error(), c)
|
||||
return
|
||||
}
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
|
||||
// GetTemplates 获取所有模版
|
||||
// @Tags AutoCodePackage
|
||||
// @Summary 获取所有模版
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {object} response.Response{data=[]string} "获取成功"
|
||||
// @Router /autoCode/getTemplates [get]
|
||||
func GetTemplates(c *gin.Context) {
|
||||
// 返回固定的模版列表
|
||||
templates := []string{"package", "plugin"}
|
||||
response.OkWithDetailed(templates, "获取成功", c)
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"kra/pkg/response"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// InstallPlugin 安装插件
|
||||
// @Tags AutoCodePlugin
|
||||
// @Summary 安装插件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param plug formData file true "插件文件"
|
||||
// @Success 200 {object} response.Response{data=[]interface{}} "安装成功"
|
||||
// @Router /autoCode/installPlugin [post]
|
||||
func InstallPlugin(c *gin.Context) {
|
||||
// TODO: 实现插件安装功能
|
||||
response.FailWithMessage("功能开发中", c)
|
||||
}
|
||||
|
||||
// PackagedPlugin 打包插件
|
||||
// @Tags AutoCodePlugin
|
||||
// @Summary 打包插件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param plugName query string true "插件名称"
|
||||
// @Success 200 {object} response.Response{msg=string} "打包成功"
|
||||
// @Router /autoCode/pubPlug [post]
|
||||
func PackagedPlugin(c *gin.Context) {
|
||||
// TODO: 实现插件打包功能
|
||||
response.FailWithMessage("功能开发中", c)
|
||||
}
|
||||
|
||||
// InitPluginMenu 初始化插件菜单
|
||||
// @Tags AutoCodePlugin
|
||||
// @Summary 初始化插件菜单
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body map[string]interface{} true "菜单信息"
|
||||
// @Success 200 {object} response.Response{msg=string} "初始化成功"
|
||||
// @Router /autoCode/initMenu [post]
|
||||
func InitPluginMenu(c *gin.Context) {
|
||||
// TODO: 实现插件菜单初始化功能
|
||||
response.FailWithMessage("功能开发中", c)
|
||||
}
|
||||
|
||||
// InitPluginAPI 初始化插件API
|
||||
// @Tags AutoCodePlugin
|
||||
// @Summary 初始化插件API
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body map[string]interface{} true "API信息"
|
||||
// @Success 200 {object} response.Response{msg=string} "初始化成功"
|
||||
// @Router /autoCode/initAPI [post]
|
||||
func InitPluginAPI(c *gin.Context) {
|
||||
// TODO: 实现插件API初始化功能
|
||||
response.FailWithMessage("功能开发中", c)
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"kra/pkg/response"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// PreviewCode 预览代码
|
||||
// @Tags AutoCodeTemplate
|
||||
// @Summary 预览创建后的代码
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body map[string]interface{} true "预览创建代码"
|
||||
// @Success 200 {object} response.Response{data=map[string]interface{}} "预览成功"
|
||||
// @Router /autoCode/preview [post]
|
||||
func PreviewCode(c *gin.Context) {
|
||||
// TODO: 实现代码预览功能
|
||||
response.FailWithMessage("功能开发中", c)
|
||||
}
|
||||
|
||||
// CreateCode 创建代码
|
||||
// @Tags AutoCodeTemplate
|
||||
// @Summary 自动代码模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body map[string]interface{} true "创建自动代码"
|
||||
// @Success 200 {object} response.Response{msg=string} "创建成功"
|
||||
// @Router /autoCode/createTemp [post]
|
||||
func CreateCode(c *gin.Context) {
|
||||
// TODO: 实现代码创建功能
|
||||
response.FailWithMessage("功能开发中", c)
|
||||
}
|
||||
|
||||
// AddFunc 增加方法
|
||||
// @Tags AutoCodeTemplate
|
||||
// @Summary 增加方法
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body map[string]interface{} true "增加方法"
|
||||
// @Success 200 {object} response.Response{msg=string} "注入成功"
|
||||
// @Router /autoCode/addFunc [post]
|
||||
func AddFunc(c *gin.Context) {
|
||||
// TODO: 实现方法注入功能
|
||||
response.FailWithMessage("功能开发中", c)
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"kra/pkg/response"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// 全局错误日志实例
|
||||
var errorLogger *zap.Logger
|
||||
|
||||
// ErrorCreator 错误记录创建接口
|
||||
type ErrorCreator interface {
|
||||
CreateError(form, info string) error
|
||||
}
|
||||
|
||||
// 全局错误创建器
|
||||
var errorCreator ErrorCreator
|
||||
|
||||
// SetErrorLogger 设置错误日志
|
||||
func SetErrorLogger(logger *zap.Logger) {
|
||||
errorLogger = logger
|
||||
}
|
||||
|
||||
// SetErrorCreator 设置错误创建器
|
||||
func SetErrorCreator(creator ErrorCreator) {
|
||||
errorCreator = creator
|
||||
}
|
||||
|
||||
// ErrorHandler 错误处理中间件
|
||||
// 用于统一处理请求过程中产生的错误
|
||||
func ErrorHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Next()
|
||||
|
||||
// 处理请求过程中产生的错误
|
||||
if len(c.Errors) > 0 {
|
||||
for _, e := range c.Errors {
|
||||
// 记录错误日志
|
||||
if errorLogger != nil {
|
||||
errorLogger.Error("请求错误",
|
||||
zap.String("path", c.Request.URL.Path),
|
||||
zap.String("method", c.Request.Method),
|
||||
zap.String("error", e.Error()),
|
||||
)
|
||||
}
|
||||
|
||||
// 保存错误到数据库
|
||||
if errorCreator != nil {
|
||||
_ = errorCreator.CreateError(c.Request.URL.Path, e.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// 如果还没有写入响应,返回错误信息
|
||||
if !c.Writer.Written() {
|
||||
lastErr := c.Errors.Last()
|
||||
response.FailWithMessage(lastErr.Error(), c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorResponse 错误响应结构
|
||||
type ErrorResponse struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
}
|
||||
|
||||
// HandleError 处理错误并返回响应
|
||||
func HandleError(c *gin.Context, err error, message string) {
|
||||
if errorLogger != nil {
|
||||
errorLogger.Error(message,
|
||||
zap.String("path", c.Request.URL.Path),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
|
||||
// 保存错误到数据库
|
||||
if errorCreator != nil {
|
||||
_ = errorCreator.CreateError(c.Request.URL.Path, err.Error())
|
||||
}
|
||||
|
||||
response.FailWithMessage(message, c)
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"kra/pkg/response"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
// LimitConfig IP限流配置
|
||||
type LimitConfig struct {
|
||||
// GenerationKey 根据业务生成key
|
||||
GenerationKey func(c *gin.Context) string
|
||||
// CheckOrMark 检查函数
|
||||
CheckOrMark func(key string, expire int, limit int) error
|
||||
// Expire key 过期时间(秒)
|
||||
Expire int
|
||||
// Limit 周期内限制次数
|
||||
Limit int
|
||||
}
|
||||
|
||||
var redisClient redis.UniversalClient
|
||||
|
||||
// SetRedisClient 设置Redis客户端
|
||||
func SetRedisClient(client redis.UniversalClient) {
|
||||
redisClient = client
|
||||
}
|
||||
|
||||
// LimitWithTime 返回限流中间件
|
||||
func (l LimitConfig) LimitWithTime() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if err := l.CheckOrMark(l.GenerationKey(c), l.Expire, l.Limit); err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"code": response.ERROR, "msg": err.Error()})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultGenerationKey 默认生成key
|
||||
func DefaultGenerationKey(c *gin.Context) string {
|
||||
return "KRA_Limit" + c.ClientIP()
|
||||
}
|
||||
|
||||
// DefaultCheckOrMark 默认检查函数
|
||||
func DefaultCheckOrMark(key string, expire int, limit int) error {
|
||||
if redisClient == nil {
|
||||
return nil // Redis未配置,跳过限流
|
||||
}
|
||||
return SetLimitWithTime(key, limit, time.Duration(expire)*time.Second)
|
||||
}
|
||||
|
||||
// DefaultLimit 默认限流中间件
|
||||
func DefaultLimit(expire, limit int) gin.HandlerFunc {
|
||||
return LimitConfig{
|
||||
GenerationKey: DefaultGenerationKey,
|
||||
CheckOrMark: DefaultCheckOrMark,
|
||||
Expire: expire,
|
||||
Limit: limit,
|
||||
}.LimitWithTime()
|
||||
}
|
||||
|
||||
// SetLimitWithTime 设置访问次数
|
||||
func SetLimitWithTime(key string, limit int, expiration time.Duration) error {
|
||||
ctx := context.Background()
|
||||
count, err := redisClient.Exists(ctx, key).Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
pipe := redisClient.TxPipeline()
|
||||
pipe.Incr(ctx, key)
|
||||
pipe.Expire(ctx, key, expiration)
|
||||
_, err = pipe.Exec(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
times, err := redisClient.Get(ctx, key).Int()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if times >= limit {
|
||||
t, err := redisClient.PTTL(ctx, key).Result()
|
||||
if err != nil {
|
||||
return errors.New("请求太过频繁,请稍后再试")
|
||||
}
|
||||
return errors.New("请求太过频繁, 请 " + t.String() + " 后尝试")
|
||||
}
|
||||
|
||||
return redisClient.Incr(ctx, key).Err()
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// LogLayout 日志layout
|
||||
type LogLayout struct {
|
||||
Time time.Time `json:"time"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query,omitempty"`
|
||||
Body string `json:"body,omitempty"`
|
||||
IP string `json:"ip"`
|
||||
UserAgent string `json:"user_agent"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Cost time.Duration `json:"cost"`
|
||||
Source string `json:"source"`
|
||||
}
|
||||
|
||||
// Logger 日志中间件配置
|
||||
type Logger struct {
|
||||
// Filter 用户自定义过滤
|
||||
Filter func(c *gin.Context) bool
|
||||
// FilterKeyword 关键字过滤
|
||||
FilterKeyword func(layout *LogLayout) bool
|
||||
// AuthProcess 鉴权处理
|
||||
AuthProcess func(c *gin.Context, layout *LogLayout)
|
||||
// Print 日志处理
|
||||
Print func(LogLayout)
|
||||
// Source 服务唯一标识
|
||||
Source string
|
||||
}
|
||||
|
||||
// SetLoggerMiddleware 设置日志中间件
|
||||
func (l Logger) SetLoggerMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
path := c.Request.URL.Path
|
||||
query := c.Request.URL.RawQuery
|
||||
|
||||
var body []byte
|
||||
if l.Filter != nil && !l.Filter(c) {
|
||||
body, _ = c.GetRawData()
|
||||
// 将原body塞回去
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
|
||||
}
|
||||
|
||||
c.Next()
|
||||
|
||||
cost := time.Since(start)
|
||||
layout := LogLayout{
|
||||
Time: time.Now(),
|
||||
Path: path,
|
||||
Query: query,
|
||||
IP: c.ClientIP(),
|
||||
UserAgent: c.Request.UserAgent(),
|
||||
Error: strings.TrimRight(c.Errors.ByType(gin.ErrorTypePrivate).String(), "\n"),
|
||||
Cost: cost,
|
||||
Source: l.Source,
|
||||
}
|
||||
|
||||
if l.Filter != nil && !l.Filter(c) {
|
||||
layout.Body = string(body)
|
||||
}
|
||||
|
||||
if l.AuthProcess != nil {
|
||||
l.AuthProcess(c, &layout)
|
||||
}
|
||||
|
||||
if l.FilterKeyword != nil {
|
||||
l.FilterKeyword(&layout)
|
||||
}
|
||||
|
||||
l.Print(layout)
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultLogger 默认日志中间件
|
||||
func DefaultLogger() gin.HandlerFunc {
|
||||
return Logger{
|
||||
Print: func(layout LogLayout) {
|
||||
v, _ := json.Marshal(layout)
|
||||
fmt.Println(string(v))
|
||||
},
|
||||
Source: "KRA",
|
||||
}.SetLoggerMiddleware()
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// TimeoutMiddleware 创建超时中间件
|
||||
// timeout: 超时时间(例如:time.Second * 30)
|
||||
// 使用示例: router.GET("path", middleware.TimeoutMiddleware(30*time.Second), HandleFunc)
|
||||
func TimeoutMiddleware(timeout time.Duration) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
ctx, cancel := context.WithTimeout(c.Request.Context(), timeout)
|
||||
defer cancel()
|
||||
|
||||
c.Request = c.Request.WithContext(ctx)
|
||||
|
||||
// 使用 buffered channel 避免 goroutine 泄漏
|
||||
done := make(chan struct{}, 1)
|
||||
panicChan := make(chan interface{}, 1)
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
select {
|
||||
case panicChan <- p:
|
||||
default:
|
||||
}
|
||||
}
|
||||
select {
|
||||
case done <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}()
|
||||
c.Next()
|
||||
}()
|
||||
|
||||
select {
|
||||
case p := <-panicChan:
|
||||
panic(p)
|
||||
case <-done:
|
||||
return
|
||||
case <-ctx.Done():
|
||||
c.Header("Connection", "close")
|
||||
c.AbortWithStatusJSON(http.StatusGatewayTimeout, gin.H{
|
||||
"code": 504,
|
||||
"msg": "请求超时",
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,13 @@ func (r *FileUploadRouter) InitFileUploadRouter(Router *gin.RouterGroup) {
|
||||
fileUploadRouter.POST("deleteFile", api.DeleteFile)
|
||||
fileUploadRouter.POST("editFileName", api.EditFileName)
|
||||
fileUploadRouter.POST("importURL", api.ImportURL)
|
||||
// 断点续传
|
||||
fileUploadRouter.POST("breakpointContinue", api.BreakpointContinue)
|
||||
fileUploadRouter.POST("breakpointContinueFinish", api.BreakpointContinueFinish)
|
||||
fileUploadRouter.POST("removeChunk", api.RemoveChunk)
|
||||
}
|
||||
{
|
||||
fileUploadRouterWithoutRecord.POST("getFileList", api.GetFileList)
|
||||
fileUploadRouterWithoutRecord.GET("findFile", api.FindFile)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
handler "kra/internal/server/handler/system"
|
||||
"kra/internal/server/middleware"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -12,11 +13,32 @@ type AutoCodeRouter struct{}
|
||||
func (s *AutoCodeRouter) InitAutoCodeRouter(Router *gin.RouterGroup, PublicRouter *gin.RouterGroup) {
|
||||
autoCodeRouter := Router.Group("autoCode").Use(middleware.OperationRecordMiddleware())
|
||||
autoCodeRouterWithoutRecord := Router.Group("autoCode")
|
||||
publicAutoCodeRouter := PublicRouter.Group("autoCode")
|
||||
{
|
||||
autoCodeRouterWithoutRecord.GET("getDB", autoCodeApi.GetDB) // 获取数据库
|
||||
autoCodeRouterWithoutRecord.GET("getTables", autoCodeApi.GetTables) // 获取对应数据库的表
|
||||
autoCodeRouterWithoutRecord.GET("getColumn", autoCodeApi.GetColumn) // 获取指定表所有字段信息
|
||||
}
|
||||
// 预留其他路由
|
||||
_ = autoCodeRouter
|
||||
{
|
||||
// 代码包管理
|
||||
autoCodeRouter.POST("getPackage", handler.GetPackages) // 获取所有包
|
||||
autoCodeRouter.POST("delPackage", handler.DeletePackage) // 删除包
|
||||
autoCodeRouter.GET("getTemplates", handler.GetTemplates) // 获取所有模版
|
||||
}
|
||||
{
|
||||
// 代码模板
|
||||
autoCodeRouter.POST("preview", handler.PreviewCode) // 预览代码
|
||||
autoCodeRouter.POST("createTemp", handler.CreateCode) // 创建代码
|
||||
autoCodeRouter.POST("addFunc", handler.AddFunc) // 增加方法
|
||||
}
|
||||
{
|
||||
// 插件管理
|
||||
autoCodeRouter.POST("pubPlug", handler.PackagedPlugin) // 打包插件
|
||||
autoCodeRouter.POST("installPlugin", handler.InstallPlugin) // 安装插件
|
||||
}
|
||||
{
|
||||
// 公开路由
|
||||
publicAutoCodeRouter.POST("initMenu", handler.InitPluginMenu) // 初始化插件菜单
|
||||
publicAutoCodeRouter.POST("initAPI", handler.InitPluginAPI) // 初始化插件API
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user