Administrator hace 1 año
padre
commit
e829234d44
Se han modificado 11 ficheros con 300 adiciones y 19 borrados
  1. 2 1
      db/SqlXorm.go
  2. 1 0
      domain/User.go
  3. 1 1
      file/config.yaml
  4. 3 2
      go.mod
  5. 8 5
      main.go
  6. 0 1
      server/Handler.go
  7. 137 0
      server/UploadFileHandler.go
  8. 2 3
      service/Gin.go
  9. 9 0
      service/login.http
  10. 6 6
      service/router/UserRouter.go
  11. 131 0
      util/share/json.go

+ 2 - 1
db/SqlXorm.go

@@ -20,7 +20,8 @@ func Open() {
 	}
 	//defer engine.Close()
 	Engin = engine
-
+	Engin.ShowSQL(true)
+	Engin.Logger().ShowSQL(true)
 	// 同步结构体到数据库
 	if err := engine.Sync2(
 		new(domain.User),

+ 1 - 0
domain/User.go

@@ -69,6 +69,7 @@ type File struct {
 	CreateTime    int64      `json:"createTime" xorm:"create_time"`                 // 创建时间,自动填充
 	UpdateTime    int64      `json:"updateTime" xorm:"update_time"`                 // 更新时间,自动填充
 	AccessTime    int64      `json:"accessTime" xorm:"access_time"`                 // 更新时间,自动填充
+	Children      []File     `json:"children"`                                      // 子文件
 }
 
 type FileAccess struct {

+ 1 - 1
file/config.yaml

@@ -1,5 +1,5 @@
 server:
-  port: 8080
+  port: 19966
 tcp:
   port: 8080
 file:

+ 3 - 2
go.mod

@@ -3,7 +3,10 @@ module file-manger-server
 go 1.23.4
 
 require (
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible
+	github.com/gin-gonic/gin v1.10.0
 	github.com/glebarez/sqlite v1.11.0
+	github.com/spf13/cast v1.7.1
 	gopkg.in/yaml.v3 v3.0.1
 	xorm.io/xorm v1.3.9
 )
@@ -13,11 +16,9 @@ require (
 	github.com/bytedance/sonic/loader v0.1.1 // indirect
 	github.com/cloudwego/base64x v0.1.4 // indirect
 	github.com/cloudwego/iasm v0.2.0 // indirect
-	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
 	github.com/dustin/go-humanize v1.0.1 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
-	github.com/gin-gonic/gin v1.10.0 // indirect
 	github.com/glebarez/go-sqlite v1.21.2 // indirect
 	github.com/go-playground/locales v0.14.1 // indirect
 	github.com/go-playground/universal-translator v0.18.1 // indirect

+ 8 - 5
main.go

@@ -3,7 +3,10 @@ package main
 import (
 	"encoding/binary"
 	"errors"
+	"file-manger-server/config"
+	"file-manger-server/db"
 	"file-manger-server/server"
+	"file-manger-server/service"
 	"fmt"
 	"io/fs"
 	"os"
@@ -13,12 +16,12 @@ import (
 )
 
 func main() {
-	//config.ReadConfig()
-	//db.Open()
-	////server.Run()
-	////service.RunGin()
+	config.ReadConfig()
+	db.Open()
+	go server.Run()
+	service.RunGin()
 	//TestHandlerReceiveFile()
-	TestFiles()
+	//TestFiles()
 }
 func TestHandlerReceiveFile() {
 	bytes := []byte{

+ 0 - 1
server/Handler.go

@@ -26,7 +26,6 @@ func HandlerReceiveFile(info *ConnInfo, msg []byte) {
 	if commandId == 0 {
 		InfoTransaction(info, msg, tranId)
 	} else if commandId == 1 {
-
 		err := InfoTransactionSplit(info, msg, tranId)
 		fmt.Println(err)
 	}

+ 137 - 0
server/UploadFileHandler.go

@@ -0,0 +1,137 @@
+package server
+
+import (
+	"errors"
+	"fmt"
+	"io/fs"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+	"sync"
+)
+
+type PathInfo struct {
+	Dirs  []string // 目录路径(包含所有层级)
+	Files []string // 文件路径
+}
+
+var pathPool = sync.Pool{
+	New: func() interface{} {
+		return &PathInfo{
+			Dirs:  make([]string, 0, 1024), // 预分配容量
+			Files: make([]string, 0, 4096),
+		}
+	},
+}
+
+func GetPathInfo(root string) (*PathInfo, error) {
+	//获取文件名
+	index := strings.LastIndex(root, "/")
+	if index == -1 {
+		index = strings.LastIndex(root, "\\")
+	}
+
+	// 复用对象减少内存分配[9](@ref)
+	info := pathPool.Get().(*PathInfo)
+
+	// 路径有效性校验[5,6](@ref)
+	root = filepath.Clean(root)
+	stat, err := os.Stat(root)
+	if err != nil {
+		if errors.Is(err, fs.ErrNotExist) {
+			return nil, &os.PathError{Op: "stat", Path: root, Err: err} // 增强错误信息[8](@ref)
+		}
+		return nil, err
+	}
+
+	// 文件直接返回[4](@ref)
+	if !stat.IsDir() {
+		info.Files = append(info.Files, root)
+		return info, nil
+	}
+
+	// 使用WalkDir优化遍历性能[4,9](@ref)
+	err = filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
+		if err != nil {
+			// 处理遍历错误但继续执行[7](@ref)
+			if errors.Is(err, fs.ErrPermission) {
+				return nil // 跳过权限错误
+			}
+			return err
+		}
+
+		// 排除根目录自身
+		if path == root {
+			return nil
+		}
+
+		// 动态扩容检测[9](@ref)
+		if len(info.Dirs)+len(info.Files) > 1e8 {
+			return errors.New("超出内存安全阈值(1,000,000条路径)")
+		}
+		//fmt.Println(path[len(RootFileName):])
+		if d.IsDir() {
+			info.Dirs = append(info.Dirs, path)
+		} else {
+			info.Files = append(info.Files, path)
+		}
+		return nil
+	})
+
+	if err != nil {
+		return nil, &os.PathError{Op: "walk", Path: root, Err: err} // 错误包装[6](@ref)
+	}
+
+	return info, nil
+}
+
+type FileHandler struct{}
+
+func (handler FileHandler) ReadFileToCommand(filePath string) {
+	_, err := GetPathInfo(filePath)
+	if err != nil {
+		fmt.Println(err)
+	}
+
+}
+func (handler FileHandler) CreateCommand(path string) error {
+	// 获取文件信息
+	fileInfo, err := os.Stat(path)
+	if err != nil {
+		return fmt.Errorf("路径获取失败: %v", err)
+	}
+
+	// 判断文件类型
+	if fileInfo.IsDir() {
+		// 处理目录
+		fmt.Printf("文件夹内容 [%s]:\n", path)
+		files, err := ioutil.ReadDir(path)
+		if err != nil {
+			return fmt.Errorf("目录读取失败: %v", err)
+		}
+
+		for _, f := range files {
+			fmt.Println(f.Name())
+		}
+	} else {
+		// 处理文件
+		fmt.Printf("文件内容 [%s]:\n", path)
+		data, err := ioutil.ReadFile(path)
+		if err != nil {
+			return fmt.Errorf("文件读取失败: %v", err)
+		}
+
+		// 打印前512字节的十六进制预览
+		maxPreview := 512
+		if len(data) < maxPreview {
+			maxPreview = len(data)
+		}
+		fmt.Printf("大小: %d 字节\n", len(data))
+		fmt.Printf("前%d字节预览(HEX):\n%x", maxPreview, data[:maxPreview])
+	}
+
+	return nil
+}
+
+func (handler FileHandler) ParsingByteArray() {}

+ 2 - 3
service/Gin.go

@@ -5,7 +5,6 @@ import (
 	"file-manger-server/db"
 	"file-manger-server/domain"
 	"file-manger-server/service/router"
-	"file-manger-server/util"
 	"fmt"
 	"github.com/gin-gonic/gin"
 )
@@ -31,14 +30,14 @@ func RunGin() {
 	if port == 0 {
 		port = 8080
 	}
-	engine.Run(fmt.Sprint(":", port))
+	engine.Run(fmt.Sprintf("0.0.0.0:%d", port))
 }
 
 func baseRouter() {
 	authRouter("/auth")
 	fileRouter("/file")
 	//权限校验
-	engine.Use(util.ValidateToken())
+	//engine.Use(util.ValidateToken())
 }
 
 func authRouter(rootPath string) {

+ 9 - 0
service/login.http

@@ -0,0 +1,9 @@
+POST http://localhost:19966/auth/login
+Content-Type: application/json
+
+{
+  "username": "admin",
+  "password": "123123"
+}
+
+###

+ 6 - 6
service/router/UserRouter.go

@@ -3,7 +3,9 @@ package router
 import (
 	"file-manger-server/service/service"
 	"file-manger-server/util"
+	"file-manger-server/util/share"
 	"github.com/gin-gonic/gin"
+	"github.com/spf13/cast"
 )
 
 //func GetAll(c *service.Context) {
@@ -22,12 +24,10 @@ type loginVo struct {
 }
 
 func Login(c *gin.Context) {
-	var data loginData
-	err := c.BindJSON(&data)
-	if err != nil {
-		c.JSON(200, CreateResultError(400, "参数错误"))
-	}
-	user, err := service.Login(data.Username, data.Password)
+	param := share.GetJsonAnyParam(c)
+	username, _ := param("username")
+	password, _ := param("password")
+	user, err := service.Login(cast.ToString(username), cast.ToString(password))
 	if err != nil {
 		c.JSON(200, CreateResultError(400, err.Error()))
 		return

+ 131 - 0
util/share/json.go

@@ -0,0 +1,131 @@
+package share
+
+import (
+	"crypto/rand"
+	"errors"
+	"fmt"
+	"github.com/dgrijalva/jwt-go"
+	"github.com/gin-gonic/gin"
+	"math/big"
+	"time"
+)
+
+const (
+	SECRETKEY = "20241101" //私钥
+)
+
+type CustomClaims struct {
+	UserId int64
+	jwt.StandardClaims
+}
+
+func GetJsonAnyParam(c *gin.Context) func(param string) (interface{}, error) {
+	jsonData := map[string]interface{}{}
+	err := c.BindJSON(&jsonData)
+
+	return func(param string) (interface{}, error) {
+		if err != nil {
+			return nil, err
+		}
+		value, err := func() (interface{}, error) {
+
+			i, exists := jsonData[param]
+			if !exists {
+				return nil, errors.New("缺少" + param + "字段")
+			}
+
+			return i, nil
+		}()
+		if err != nil {
+			return nil, err
+		}
+		return value, err
+	}
+}
+
+const ExpiresTime = 60 * 60 * 24
+
+func GenerateToken(userId string) (string, error) {
+	//maxAge := 60 * 60 * 24
+	// Create the Claims
+	claims := &jwt.StandardClaims{
+		ExpiresAt: time.Now().Add(time.Duration(ExpiresTime) * time.Second).Unix(), // 过期时间,必须设置,
+		Issuer:    userId,                                                          // 非必须,也可以填充用户名,
+	}
+
+	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+	tokenString, err := token.SignedString([]byte(SECRETKEY))
+	if err != nil {
+		fmt.Println(err)
+	}
+	return tokenString, err
+}
+func ParseToken(tokenString string) (jwt.MapClaims, error) {
+	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
+		// Don't forget to validate the alg is what you expect:
+		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
+			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
+		}
+
+		// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
+		return []byte(SECRETKEY), nil
+	})
+	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
+		return claims, nil
+	} else {
+		return nil, err
+	}
+}
+
+//权限判断,废弃
+//func JwtMiddleware() gin.HandlerFunc {
+//	return func(c *gin.Context) {
+//		tokenString := c.GetHeader("auth-sign")
+//		if tokenString == "" {
+//			c.JSON(401, gin.H{"message": "缺少token"})
+//			c.Abort()
+//			return
+//		}
+//
+//		token, err := ParseToken(tokenString)
+//
+//		if err != nil {
+//			c.JSON(401, gin.H{"message": "无效令牌"})
+//			c.Abort()
+//			return
+//		}
+//		users := make([]configs.MysqlData, 0)
+//		bools, err := configs.Engine.Table("user").
+//			Join("INNER", "role", "role.id = user.role_id").
+//			Join("INNER", "role_authority", "role_authority.authority_id = role.id").
+//			Join("INNER", "authority", "authority.id = role_authority.authority_id").
+//			Where("authority.authority_path=?", c.Request.URL.Path).
+//			Where("user.id = ?", token["iss"]).
+//			Exist(&users)
+//		if err == nil {
+//			fmt.Println(bools)
+//			if bools {
+//				c.Next()
+//			} else {
+//				c.JSON(200, gin.H{"message": "权限不足"})
+//				c.Abort()
+//				return
+//			}
+//		}
+//
+//	}
+//}
+
+func RandomInt(min, max *big.Int) *big.Int {
+	// 读取密码学安全的随机比特
+	byteLen := (max.BitLen() + 7) / 8
+	b := make([]byte, byteLen)
+	rand.Read(b)
+
+	// 将字节转换为大整数
+	r := new(big.Int).SetBytes(b)
+
+	// 需要将生成的大整数范围限制在[min,max]
+	r.Rem(r, new(big.Int).Sub(max, min)).Add(r, min)
+	return r
+}