Administrator hai 1 ano
pai
achega
a97a21b94b

+ 0 - 138
command_test.go

@@ -1,139 +1 @@
 package main
-
-//
-//func TestCommand(t *testing.T) {
-//	bytes := make([]byte, 0)
-//	bytes = append(bytes, 0x2a)
-//	command := "你好1"
-//	cmd := []byte(command)
-//	l := util.IntToBytes(int32(len(cmd)))
-//	bytes = append(bytes, l...)
-//	bytes = append(bytes, cmd...)
-//	bytes = append(bytes, util.Int16ToBytes(util.Crc16CCITT(cmd))...)
-//	fmt.Println(util.ToHexBytes(bytes))
-//}
-//func TestGetFiles(t *testing.T) {
-//	// 标准用法
-//	result, err := GetPathInfo("D:\\project\\my\\file-manger\\frontend\\node_modules")
-//	if err != nil {
-//		fmt.Printf("错误: %+v\n", err)
-//		return
-//	}
-//	fmt.Printf("找到 %d 目录\n", len(result.Dirs))
-//	fmt.Printf("找到 %d 文件\n", len(result.Files))
-//	time.Sleep(20 * time.Second)
-//	// 流式处理
-//	//paths, errs := StreamPathInfo("/bigdata")
-//	//for {
-//	//	select {
-//	//	case path, ok := <-paths:
-//	//		if !ok {
-//	//			return
-//	//		}
-//	//		fmt.Println(path)
-//	//	case err := <-errs:
-//	//		fmt.Println("错误:", err)
-//	//		return
-//	//	}
-//	//}
-//}
-//
-//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) {
-//	// 复用对象减少内存分配[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) > 1e6 {
-//			return errors.New("超出内存安全阈值(1,000,000条路径)")
-//		}
-//		fmt.Println(path)
-//		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
-//}
-//
-//// 流式处理版本(适用于超大数据集)
-//func StreamPathInfo(root string) (<-chan string, <-chan error) {
-//	paths := make(chan string, 1000)
-//	errs := make(chan error, 1)
-//
-//	go func() {
-//		defer close(paths)
-//		defer close(errs)
-//
-//		err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
-//			if err != nil {
-//				return err
-//			}
-//			if path != root {
-//				select {
-//				case paths <- path:
-//				default:
-//					return errors.New("消费者处理过慢")
-//				}
-//			}
-//			return nil
-//		})
-//
-//		if err != nil {
-//			errs <- &os.PathError{Op: "stream", Path: root, Err: err}
-//		}
-//	}()
-//
-//	return paths, errs
-//}

+ 11 - 0
data/ConstData.go

@@ -0,0 +1,11 @@
+package data
+
+import "os"
+
+//TODO 全局变量
+
+// ExitStatus 退出信号
+var ExitStatus = make(chan os.Signal)
+
+// PWDHashPrefix 密码哈希计算前缀
+var PWDHashPrefix = []byte("gujiheimao")

+ 2 - 1
db/SqlXorm.go

@@ -12,7 +12,8 @@ import (
 var Engin *xorm.Engine
 
 func Open() {
-	os.OpenFile("file/file.db", os.O_RDWR|os.O_CREATE, 0666)
+	file, _ := os.OpenFile("file/file.db", os.O_CREATE, 0666)
+	file.Close()
 	// 连接SQLite数据库
 	engine, err := xorm.NewEngine("sqlite", "file/file.db")
 	if err != nil {

BIN=BIN
file/file.db


+ 7 - 0
main.go

@@ -16,13 +16,20 @@ import (
 )
 
 func main() {
+	//初始化
 	config.ReadConfig()
 	db.Open()
+
+	//tcp服务器启动
 	go server.Run()
+
+	//gin服务器启动
 	service.RunGin()
+	os.Exit(0) // 确保程序退出
 	//TestHandlerReceiveFile()
 	//TestFiles()
 }
+
 func TestHandlerReceiveFile() {
 	bytes := []byte{
 		0x00,

+ 47 - 31
server/Handler.go

@@ -18,57 +18,70 @@ type ReturnCommand interface {
 
 func HandlerReceiveFile(info *ConnInfo, msg []byte) {
 	var commandId = msg[0]
-
 	//事务id解析
-	var transactionId = msg[1:33]
+	var transactionId = msg[1:17]
 	fmt.Println(ToHexBytes(transactionId))
 	var tranId = ToHexBytes(transactionId)
 	if commandId == 0 {
-		InfoTransaction(info, msg, tranId)
+		InfoTransaction(info, msg, tranId, 16)
 	} else if commandId == 1 {
-		err := InfoTransactionSplit(info, msg, tranId)
+		err := InfoTransactionSplit(info, msg, tranId, 16)
 		fmt.Println(err)
 	}
-	//1. 接收基本元数据(事务id(32),len文件名(4+?),文件大小(8),相对路径(4+?),分片数量(按特定大小进行分片)(4),创建时间(8),修改时间(8),访问时间(8)=> 返回事务id,如果重复则返回错误 76+?
-	//2. 接收包含事务id的分片内容
 }
 
 // InfoTransaction 获取的事务数据内容
-func InfoTransaction(info *ConnInfo, msg []byte, transactionId string) error {
-
+func InfoTransaction(info *ConnInfo, msg []byte, transactionId string, transactionIdLen int) error {
+	// 获取数据,判断事务是否注册
 	fileUser, err := db.FileUserDao{}.Get(transactionId)
 	if err != nil {
 		return errors.New("FileUser transactionId is not found")
 	}
+	// 判断用户是否存在
 	if fileUser.UserId == 0 {
 		return errors.New("FileUser userId is not found")
 	}
-
-	var fileNameLength = binary.BigEndian.Uint32(msg[33:37])
-	var filename = string(msg[37 : 37+fileNameLength])
-	var fileSize = int64(binary.BigEndian.Uint64(msg[37+fileNameLength : 45+fileNameLength]))
-	var pathLength = binary.BigEndian.Uint32(msg[45+fileNameLength : 49+fileNameLength])
-	var path = string(msg[49+fileNameLength : 49+fileNameLength+pathLength])
+	var index = transactionIdLen + 1
+	// 文件名称长度
+	var fileNameLength = binary.BigEndian.Uint32(msg[index : index+4])
+	index += 4
+	// 文件名
+	var filename = string(msg[index : uint32(index)+fileNameLength])
+	index += int(fileNameLength)
+	// 文件大小
+	var fileSize = int64(binary.BigEndian.Uint64(msg[index : index+8]))
+	index += 8
+	// 路径长度
+	var pathLength = binary.BigEndian.Uint32(msg[index : index+4])
+	index += 4
+	// 路径
+	var path = string(msg[index : index+int(pathLength)])
+	index += int(pathLength)
+	// 添加专属路径 前缀
 	path = fmt.Sprint(config.Conf.File.Upload.Path, "/", fileUser.UserId, "/", transactionId, "/", path)
-
-	var splitCount = binary.BigEndian.Uint32(msg[49+fileNameLength+pathLength : 53+fileNameLength+pathLength])
-
-	var createTime = binary.BigEndian.Uint64(msg[53+fileNameLength+pathLength : 61+fileNameLength+pathLength])
-	var modifyTime = binary.BigEndian.Uint64(msg[61+fileNameLength+pathLength : 69+fileNameLength+pathLength])
-	var accessTime = binary.BigEndian.Uint64(msg[69+fileNameLength+pathLength : 77+fileNameLength+pathLength])
-
+	// 分片数量,文件被拆分了几份
+	var splitCount = binary.BigEndian.Uint32(msg[index : index+4])
+	index += 4
+	// 创建时间,修改时间,访问时间
+	var createTime = binary.BigEndian.Uint64(msg[index : index+8])
+	index += 8
+	var modifyTime = binary.BigEndian.Uint64(msg[index : index+8])
+	index += 8
+	var accessTime = binary.BigEndian.Uint64(msg[index : index+8])
+	index += 8
 	Type := ""
 	if fileSize == -1 {
 		Type = "folder"
 	} else {
 		Type = "file"
 	}
+	//文件扩展名
 	ExtensionName := ""
-	index := strings.Index(filename, ".")
-	if index != -1 {
-		ExtensionName = filename[index+1:]
+	suffixIndex := strings.Index(filename, ".")
+	if suffixIndex != -1 {
+		ExtensionName = filename[suffixIndex+1:]
 	}
-
+	//填充数据
 	file := domain.File{
 		Name:          filename,
 		Url:           path,
@@ -131,7 +144,7 @@ func InfoTransaction(info *ConnInfo, msg []byte, transactionId string) error {
 }
 
 // InfoTransactionSplit 获取的事务数据内容
-func InfoTransactionSplit(info *ConnInfo, msg []byte, transactionId string) error {
+func InfoTransactionSplit(info *ConnInfo, msg []byte, transactionId string, transactionIdLen int) error {
 	fileUser, err := db.FileUserDao{}.Get(transactionId)
 	if err != nil {
 		return errors.New("FileUser transactionId is not found")
@@ -139,12 +152,15 @@ func InfoTransactionSplit(info *ConnInfo, msg []byte, transactionId string) erro
 	if fileUser.UserId == 0 {
 		return errors.New("FileUser userId is not found")
 	}
-
-	var splitNum = binary.BigEndian.Uint32(msg[33:37])
-	var pathLength = binary.BigEndian.Uint32(msg[37:41])
-	var path = string(msg[41 : 41+pathLength])
+	var index = transactionIdLen + 1
+	var splitNum = binary.BigEndian.Uint32(msg[index : index+4])
+	index += 4
+	var pathLength = binary.BigEndian.Uint32(msg[index : index+4])
+	index += 4
+	var path = string(msg[index : index+int(pathLength)])
+	index += int(pathLength)
 	path = fmt.Sprint(config.Conf.File.Upload.Path, "/", fileUser.UserId, "/", transactionId, "/", path)
-	var content = msg[41+pathLength:]
+	var content = msg[index:]
 	err = insertDataAtPosition(path, int64(splitNum*1024), content)
 	return err
 	// 返回状态信息

+ 42 - 15
server/TCPServer.go

@@ -55,7 +55,7 @@ func (p *ConnPool) Add(conn net.Conn) error {
 	if p.currentConns.Load() >= p.maxConns {
 		return errors.New("connection limit reached")
 	}
-
+	fmt.Println(fmt.Sprintf("Ip \"%s\" connect.", conn.RemoteAddr()))
 	ci := &ConnInfo{
 		conn:         conn,
 		heartbeatTTL: HeartbeatInterval * 3,
@@ -114,32 +114,54 @@ func (p *ConnPool) cleanup() {
 // Shutdown 优雅关闭
 func (p *ConnPool) Shutdown() {
 	p.cancel()
-	p.connections.Range(func(key, value any) bool {
-		ci := value.(*ConnInfo)
-		ci.Close()
-		p.connections.Delete(key)
-		return true
-	})
+
+	// 设置关闭超时为60秒
+	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
+	defer cancel()
+
+	done := make(chan struct{})
+	go func() {
+		p.connections.Range(func(key, value any) bool {
+			ci := value.(*ConnInfo)
+			ci.Close()
+			p.connections.Delete(key)
+			return true
+		})
+		close(done)
+	}()
+
+	select {
+	case <-done:
+	case <-ctx.Done():
+		log.Println("强制关闭剩余连接")
+	}
 }
 
+var Pool *ConnPool
+
 func Run() {
-	pool := NewConnPool(MaxConnections)
-	pool.StartCleaner()
+	Pool = NewConnPool(MaxConnections)
+	Pool.StartCleaner()
 
-	listener, err := net.Listen("tcp", ":8080")
+	listener, err := net.Listen("tcp", "0.0.0.0:8080")
 	if err != nil {
 		log.Fatal(err)
 	}
-
 	// 信号处理
 	sigCh := make(chan os.Signal, 1)
 	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
 
+	// 修改信号处理goroutine
 	go func() {
 		<-sigCh
 		log.Println("Shutting down server...")
+		// 先关闭listener停止接受新连接
 		listener.Close()
-		pool.Shutdown()
+		// 然后关闭连接池
+		Pool.Shutdown()
+		// 添加退出等待逻辑
+		time.Sleep(1 * time.Second) // 等待处理中的请求完成
+		os.Exit(0)                  // 确保程序退出
 	}()
 
 	for {
@@ -152,13 +174,13 @@ func Run() {
 			continue
 		}
 
-		if err := pool.Add(conn); err != nil {
+		if err := Pool.Add(conn); err != nil {
 			conn.Close()
 			log.Printf("Reject connection: %v", err)
 			continue
 		}
 
-		go handleConnection(pool, conn)
+		go handleConnection(Pool, conn)
 	}
 }
 
@@ -184,6 +206,10 @@ func handleConnection(pool *ConnPool, conn net.Conn) {
 
 	// 消息处理循环
 	for {
+		if connInfo.closed.Load() {
+			ctx.Done()
+			return
+		}
 		// 设置读取超时
 		connInfo.conn.SetReadDeadline(time.Now().Add(ReadTimeout))
 
@@ -195,7 +221,8 @@ func handleConnection(pool *ConnPool, conn net.Conn) {
 			}
 			return
 		}
-
+		//处理业务
+		HandlerReceiveFile(connInfo, message)
 		// 更新活跃时间
 		connInfo.lastActive.Store(time.Now().UnixNano())
 

+ 30 - 0
server/UploadFileHandler.go

@@ -1,6 +1,7 @@
 package server
 
 import (
+	"encoding/binary"
 	"errors"
 	"fmt"
 	"io/fs"
@@ -133,5 +134,34 @@ func (handler FileHandler) CreateCommand(path string) error {
 
 	return nil
 }
+func CreateDirCommand(info os.FileInfo, baseUrl string, transactionId string) {
+	bytes := []byte{
+		0x00,
+	}
+	for i := 0; i < 32; i++ {
+		bytes = append(bytes, byte(i+3))
+	}
+	var fileName = info.Name()
+	//文件名长度
+	bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(fileName)))
+	//文件名
+	bytes = append(bytes, []byte(fileName)...)
+	//文件大小
+	bytes = binary.BigEndian.AppendUint64(bytes, uint64(info.Size()))
+
+	var path = "file/" + fileName
+	bytes = binary.BigEndian.AppendUint32(bytes, uint32(len(path)))
+	//文件路径
+	bytes = append(bytes, []byte(path)...)
+	//分片大小
+	bytes = binary.BigEndian.AppendUint32(bytes, uint32(0))
+	//创建时间
+	bytes = binary.BigEndian.AppendUint64(bytes, uint64(1999))
+	//修改时间
+	bytes = binary.BigEndian.AppendUint64(bytes, uint64(19999))
+	//最后访问时间
+	bytes = binary.BigEndian.AppendUint64(bytes, uint64(199999))
+
+}
 
 func (handler FileHandler) ParsingByteArray() {}

+ 43 - 0
server/协议.md

@@ -0,0 +1,43 @@
+# 程序协议
+
+## 协议解读流程
+
+1. 客户端通过gin获取tcp token,然后附上token连接上tcp服务器
+2. 上传文件
+    1. 通过gin获取事务id,服务器创建事务id文件夹
+    2. 附带上事务id,上传文件信息;
+        - 小文件(<1024):直接上传数据,并校验MD5
+        - 大文件(>1024):批量上传文件切片,校验文件数量,校验MD5。(后续需要有缺失错误文件切片补全指令)
+3. 下载文件,同上
+
+## 文件信息协议(包含部分小文件优化)
+
+文件相关数据信息,几相关协议长度
+
+1. **文件信息协议**
+
+   | 序号 | 名称     | 描述                                                  | 长度byte(值) | 类型     |
+      |----|--------|-----------------------------------------------------|-----------|--------|
+   | 1  | 数据头    | 用于识别指令类型                                            | 1         | byte   |
+   | 2  | 文件事务id | 用于标记文件事务                                            | 16        | []byte |
+   | 3  | 文件名长度  | 文件在指令中的长度                                           | 2         | uint16 |
+   | 4  | 文件名    | 文件名                                                 | 1~255     | []byte |
+   | 5  | 存储路径长度 | 存储路径长度                                              | 2         | uint16 |
+   | 6  | 存储路径   | 存储路径                                                | 1~4096    | []byte |
+   | 7  | 文件分片长度 | 文件拆分为多少份数据进行传输,=0,在序号11中一并上传,=-1,文件夹,>0则需要使用到分片传输协议 | 4         | uint32 |
+   | 8  | 创建时间   | time                                                | 8         | int64  |
+   | 9  | 修改时间   | time                                                | 8         | int64  |
+   | 10 | 最后访问时间 | time                                                | 8         | int64  |
+   | 11 | 文件内容   | 文件内容小于1024字节                                        | 8         | int64  | 
+
+2. **文件分片传输协议**
+
+   | 序号 | 名称       | 描述       | 长度byte(值) | 类型     |
+      |----|----------|----------|-----------|--------|
+   | 1  | 数据头      | 用于识别指令类型 | 1         | byte   |
+   | 2  | 文件事务id   | 用于标记文件事务 | 16        | []byte |
+   | 3  | 文件分片序号   | 文件分片序号   | 4         | uint32 |
+   | 4  | 文完整路径名长度 | 文完整路径名长度 | 4         | uint32 |
+   | 5  | 文件分片路径   | 文件分片路径   | 1~4096    | []byte |
+   | 6  | 文件分片内容   | 文件分片内容   | 1024      | []byte |
+

+ 8 - 18
service/Gin.go

@@ -2,35 +2,24 @@ package service
 
 import (
 	"file-manger-server/config"
-	"file-manger-server/db"
-	"file-manger-server/domain"
 	"file-manger-server/service/router"
 	"fmt"
 	"github.com/gin-gonic/gin"
 )
 
-var engine *gin.Engine
+var Engine *gin.Engine
 
 func RunGin() {
-	//判断 管理员是否存在
-	user := domain.User{}
-	db.Engin.Table("user").Where("username = ?", "admin").Get(&user)
-	if user.Id == 0 {
-		user.Name = "管理员"
-		user.Username = "admin"
-		user.Password = "123123"
-		db.Engin.Table("user").Insert(&user)
-	}
 
-	engine = gin.Default()
-	//engine.LoadHTMLGlob("service/template/*/*.*")
-	engine.Static("/static", "service/static")
+	Engine = gin.Default()
+	//engine.LoadHTMLGlob("dao/template/*/*.*")
+	Engine.Static("/static", "dao/static")
 	baseRouter()
 	var port = config.Conf.Server.Port
 	if port == 0 {
 		port = 8080
 	}
-	engine.Run(fmt.Sprintf("0.0.0.0:%d", port))
+	Engine.Run(fmt.Sprintf("0.0.0.0:%d", port))
 }
 
 func baseRouter() {
@@ -41,11 +30,12 @@ func baseRouter() {
 }
 
 func authRouter(rootPath string) {
-	group := engine.RouterGroup.Group(rootPath)
+	group := Engine.RouterGroup.Group(rootPath)
 	group.POST("/login", router.Login)
+	group.POST("/register", router.Register)
 }
 
 func fileRouter(rootPath string) {
-	group := engine.RouterGroup.Group(rootPath)
+	group := Engine.RouterGroup.Group(rootPath)
 	group.POST("/uploadInfo", router.UploadInfo)
 }

+ 20 - 0
service/dao/BaseDao.go

@@ -0,0 +1,20 @@
+package dao
+
+import (
+	"crypto/md5"
+	"file-manger-server/data"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+// PasswordHashCompute 计算密码的md5值
+func PasswordHashCompute(pwd string) string {
+	var sum = md5.Sum(append(data.PWDHashPrefix, []byte(pwd)...))
+	var hexBytes string
+	for b := range sum {
+		hexBytes = fmt.Sprint(hexBytes, strconv.FormatInt(int64(sum[b]), 16))
+	}
+	hexBytes = strings.TrimSpace(hexBytes)
+	return strings.ToUpper(hexBytes)
+}

+ 1 - 1
service/service/FileRouter.go → service/dao/FileRouter.go

@@ -1,4 +1,4 @@
-package service
+package dao
 
 import (
 	"file-manger-server/db"

+ 65 - 0
service/dao/UserDao.go

@@ -0,0 +1,65 @@
+package dao
+
+import (
+	"errors"
+	"file-manger-server/db"
+	"file-manger-server/domain"
+)
+
+type UserDao struct{}
+
+func (dao UserDao) TableName() string {
+	return "user"
+}
+func (dao UserDao) GetAll(user domain.User) ([]domain.User, int64, error) {
+	var users []domain.User
+	count, err := db.Engin.Table("user").FindAndCount(&users, &user)
+	return users, count, err
+}
+func (dao UserDao) GetById(id int64) (domain.User, error) {
+	var user domain.User
+	res, err := db.Engin.Table("user").Where("id=?", id).Get(&user)
+	if !res {
+		return user, errors.New("用户不存在")
+	}
+	return user, err
+}
+func (dao UserDao) GetByUsername(username string) (domain.User, error) {
+	var user domain.User
+	res, err := db.Engin.Table("user").Where("username=?", username).Get(&user)
+	if !res {
+		return user, errors.New("用户不存在")
+	}
+	return user, err
+}
+func (dao UserDao) Login(username, password string) (domain.User, error) {
+	var user domain.User
+	pwd := PasswordHashCompute(password)
+	_, err := db.Engin.Table("user").Where("username=? and password=?", username, pwd).Get(&user)
+	if err != nil {
+		return user, err
+	}
+	if user.Id != 0 {
+		return user, nil
+	} else {
+		return user, errors.New("用户名或密码错误")
+	}
+}
+
+// Register 简单注册功能
+func (dao UserDao) Register(username, password string) error {
+	count, err := db.Engin.Table("user").Where("username=?", username).Count()
+	if err != nil {
+		return err
+	}
+	if count > 0 {
+		return errors.New("用户名已存在")
+	}
+	user := domain.User{
+		Username: username,
+		Password: PasswordHashCompute(password),
+		Status:   1,
+	}
+	_, err = db.Engin.Table("user").Insert(&user)
+	return err
+}

+ 41 - 0
service/dao/service_test.go

@@ -0,0 +1,41 @@
+package dao
+
+import (
+	"file-manger-server/db"
+	"file-manger-server/domain"
+	"fmt"
+	"log"
+	"testing"
+)
+
+func TestPWDCompute(t *testing.T) {
+	fmt.Println(PasswordHashCompute("123123"))
+}
+func TestLoginDao(t *testing.T) {
+	//config.ReadConfig()
+	db.Open()
+	//InitDatabase()
+	login, err := Login("admin", "123123")
+	if err != nil {
+		fmt.Println(err)
+	}
+	fmt.Println(login)
+}
+func InitDatabase() {
+	count, err := db.Engin.Table("user").Where("username = ?", "admin").Count()
+	if err != nil {
+		log.Fatalf("数据库连接失败 1: %v", err)
+	}
+	if count == 0 {
+		user := domain.User{
+			Username: "admin",
+			Password: PasswordHashCompute("123123"),
+			Status:   1,
+		}
+		_, err = db.Engin.Table("user").Insert(&user)
+		if err != nil {
+			log.Fatalf("数据库连接失败 2: %v", err)
+		}
+	}
+
+}

+ 16 - 16
service/router/FileRouter.go

@@ -1,13 +1,15 @@
 package router
 
 import (
-	"crypto/rand"
+	"crypto/md5"
 	"file-manger-server/db"
-	"file-manger-server/domain"
+	"file-manger-server/service/dao"
 	"file-manger-server/util"
 	"fmt"
 	"github.com/gin-gonic/gin"
+	"strconv"
 	"strings"
+	"time"
 )
 
 func UploadInfo(c *gin.Context) {
@@ -17,29 +19,27 @@ func UploadInfo(c *gin.Context) {
 		c.JSON(200, CreateResultError(400, "token错误"))
 		return
 	}
-	var user domain.User
-	db.Engin.Table("user").Where("id =? ", claims.Id).Get(&user)
-	tid := ToHexBytes(random32Bytes())
+
+	user, err := dao.UserDao{}.GetById(claims.Id)
+	if err != nil || user.Id == 0 {
+		c.JSON(200, CreateResultError(400, "用户信息错误"))
+		return
+	}
+
+	tid := ToHexBytes(random16Bytes())
 	db.FileUserDao{}.Insert(tid, user.Id)
 	c.JSON(200, CreateResultData(gin.H{
 		"transactionId": tid,
 	}))
 }
-func ToHexBytes(bytes []byte) string {
+
+func ToHexBytes(bytes [16]byte) string {
 	var hexBytes string
 	for b := range bytes {
 		hexBytes = fmt.Sprint(hexBytes, fmt.Sprintf("%02X", bytes[b]))
 	}
 	return strings.TrimSpace(hexBytes)
 }
-func random32Bytes() []byte {
-	randomBytes := make([]byte, 32)
-	_, err := rand.Read(randomBytes)
-	if err != nil {
-		panic(err) // 处理错误(如随机源不可用)
-	}
-
-	// 直接使用 randomBytes(原始二进制)
-	//fmt.Printf("Raw Bytes: %v\n", randomBytes)
-	return randomBytes
+func random16Bytes() [16]byte {
+	return md5.Sum([]byte(strconv.FormatInt(time.Now().UnixNano(), 10)))
 }

+ 16 - 13
service/router/UserRouter.go

@@ -1,23 +1,13 @@
 package router
 
 import (
-	"file-manger-server/service/service"
+	"file-manger-server/service/dao"
 	"file-manger-server/util"
 	"file-manger-server/util/share"
 	"github.com/gin-gonic/gin"
 	"github.com/spf13/cast"
 )
 
-//func GetAll(c *service.Context) {
-//	var dao domain.UserDao
-//	dao.GetAll(entity.User{})
-//}
-
-type loginData struct {
-	Username string `json:"username"`
-	Password string `json:"password"`
-}
-
 type loginVo struct {
 	Token  string `json:"token"`
 	Expire int64  `json:"expire"`
@@ -27,7 +17,8 @@ func Login(c *gin.Context) {
 	param := share.GetJsonAnyParam(c)
 	username, _ := param("username")
 	password, _ := param("password")
-	user, err := service.Login(cast.ToString(username), cast.ToString(password))
+	userDao := dao.UserDao{}
+	user, err := userDao.Login(cast.ToString(username), cast.ToString(password))
 	if err != nil {
 		c.JSON(200, CreateResultError(400, err.Error()))
 		return
@@ -41,6 +32,18 @@ func Login(c *gin.Context) {
 		Token:  token,
 		Expire: expire,
 	}
-
 	c.JSON(200, CreateResultData(vo))
 }
+
+func Register(c *gin.Context) {
+	param := share.GetJsonAnyParam(c)
+	username, _ := param("username")
+	password, _ := param("password")
+	userDao := dao.UserDao{}
+	err := userDao.Register(cast.ToString(username), cast.ToString(password))
+	if err != nil {
+		c.JSON(200, CreateResultError(400, err.Error()))
+		return
+	}
+	c.JSON(200, CreateResult())
+}

+ 0 - 20
service/service/LoginDao.go

@@ -1,20 +0,0 @@
-package service
-
-import (
-	"errors"
-	"file-manger-server/db"
-	"file-manger-server/domain"
-)
-
-func Login(username, password string) (domain.User, error) {
-	var user domain.User
-	_, err := db.Engin.Table("user").Where("username=? and password=?", username, password).Get(&user)
-	if err != nil {
-		return user, err
-	}
-	if user.Id != 0 {
-		return user, nil
-	} else {
-		return user, errors.New("用户名或密码错误")
-	}
-}

+ 0 - 23
service/service/UserDao.go

@@ -1,23 +0,0 @@
-package service
-
-import (
-	"errors"
-	"file-manger-server/db"
-	"file-manger-server/domain"
-)
-
-type UserDao struct{}
-
-func (dao UserDao) GetAll(user domain.User) ([]domain.User, int64, error) {
-	var users []domain.User
-	count, err := db.Engin.Table("user").FindAndCount(&users, &user)
-	return users, count, err
-}
-func (dao UserDao) GetById(id int64) (domain.User, error) {
-	var user domain.User
-	res, err := db.Engin.Table("user").Where("id=?", id).Get(&user)
-	if !res {
-		return user, errors.New("用户不存在")
-	}
-	return user, err
-}

+ 0 - 68
upload/1/030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122/file/test.txt

@@ -1,68 +0,0 @@
-	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	//config.ReadConfig()
-	//db.Open()
-	////server.Run()
-	// server	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	if err != nil {
-		return errors.New("FileUser transactionId is not found")
-	}
-	if fileUser.UserId == 0 {
-		return errors.New("FileUser userId is not found")
-	}	//config.ReadConfig()
-	//db.Open()
-	////server.Run()
-	// server
-| end |