project_module_files.go 13.2 KB
package project_module_files

import (
	"github.com/tiptok/gocomm/common"
	"github.com/tiptok/gocomm/pkg/log"
	"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/application/factory"
	"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/domain"
	"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/infrastructure/dao"
	"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/infrastructure/utils"
	"gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol"
	protocolx "gitlab.fjmaimaimai.com/mmm-go/godevp/pkg/protocol/project_module_files"
	"path/filepath"
	"strings"
	"time"
)

type ProjectModuleFilesService struct {
}

func (svr *ProjectModuleFilesService) CreateProjectModuleFiles(header *protocol.RequestHeader, request *protocolx.CreateProjectModuleFilesRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _   = factory.CreateTransactionContext(nil)
		ProjectModuleVersion, _ = factory.CreateProjectModuleVersionRepository(transactionContext)
	)
	rsp = &protocolx.CreateProjectModuleFilesResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	newProjectModuleFiles := &domain.ProjectModuleFiles{
		ProjectModuleId:        request.ProjectModuleId,
		ProjectModuleVersionId: request.ProjectModuleVersionId,
		ParentId:               request.ParentId,
		FileType:               request.FileType,
		FileName:               request.FileName,
		FileKey:                request.FileName,
		CodeBlock:              request.CodeBlock,
		Remark:                 request.Remark,
		CreateTime:             time.Now(),
		UpdateTime:             time.Now(),
		Path:                   request.FileKey,
	}

	if _, err = ProjectModuleVersion.FindOne(map[string]interface{}{"id": request.ProjectModuleVersionId, "projectModuleId": request.ProjectModuleId}); err != nil {
		err = protocol.NewCustomMessage(1, "项目版本不存在")
		return
	}
	// TODO:判断是否重名
	var ProjectModuleFilesRepository, _ = factory.CreateProjectModuleFilesRepository(transactionContext)
	if rsp, err = svr.save(newProjectModuleFiles, ProjectModuleFilesRepository); err != nil {
		return
	}
	err = transactionContext.CommitTransaction()
	return
}

func (svr *ProjectModuleFilesService) UpdateProjectModuleFiles(header *protocol.RequestHeader, request *protocolx.UpdateProjectModuleFilesRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _    = factory.CreateTransactionContext(nil)
		ProjectModuleFilesDao, _ = dao.NewProjectModuleFilesDao(transactionContext)
	)
	rsp = &protocolx.UpdateProjectModuleFilesResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
		return
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var ProjectModuleFilesRepository, _ = factory.CreateProjectModuleFilesRepository(transactionContext)
	var projectModuleFiles *domain.ProjectModuleFiles
	var oldFileName string
	if projectModuleFiles, err = ProjectModuleFilesRepository.FindOne(map[string]interface{}{"id": request.Id}); err != nil {
		return
	}
	oldFileName = projectModuleFiles.FileName
	if err = projectModuleFiles.Update(common.ObjectToMap(request)); err != nil {
		return
	}
	if projectModuleFiles, err = ProjectModuleFilesRepository.Save(projectModuleFiles); err != nil {
		return
	}

	// 更新文件名称,修改子节点跟本身的路径  1.文件夹 2.文件
	if request.FileName != oldFileName {
		// TODO:判断是否重名
		var oldPath = projectModuleFiles.Path
		var newPath string
		if index := strings.LastIndex(projectModuleFiles.Path, oldFileName); index > 0 {
			newPath = projectModuleFiles.Path[:index] + request.FileName
			projectModuleFiles.Path = newPath
		}
		if projectModuleFiles.FileType == domain.Dir {
			if err = ProjectModuleFilesDao.UpdateFilesPath(projectModuleFiles.ProjectModuleId, projectModuleFiles.ProjectModuleVersionId, oldPath, newPath); err != nil {
				return
			}
		}
	}
	// TODO:移动文件文件夹时pid变更,底下路径需要都变掉

	// TODO:变更记录
	err = transactionContext.CommitTransaction()
	return
}

func (svr *ProjectModuleFilesService) GetProjectModuleFiles(header *protocol.RequestHeader, request *protocolx.GetProjectModuleFilesRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
	)
	rsp = &protocolx.GetProjectModuleFilesResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var ProjectModuleFilesRepository, _ = factory.CreateProjectModuleFilesRepository(transactionContext)
	var projectModuleFiles *domain.ProjectModuleFiles
	if projectModuleFiles, err = ProjectModuleFilesRepository.FindOne(common.ObjectToMap(request)); err != nil {
		return
	}
	rsp = projectModuleFiles
	err = transactionContext.CommitTransaction()
	return
}

func (svr *ProjectModuleFilesService) DeleteProjectModuleFiles(header *protocol.RequestHeader, request *protocolx.DeleteProjectModuleFilesRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
	)
	rsp = &protocolx.DeleteProjectModuleFilesResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var ProjectModuleFilesRepository, _ = factory.CreateProjectModuleFilesRepository(transactionContext)
	var projectModuleFiles *domain.ProjectModuleFiles
	if projectModuleFiles, err = ProjectModuleFilesRepository.FindOne(map[string]interface{}{"id": request.Id}); err != nil {
		err = protocol.NewCustomMessage(1, "文件不存在")
		return
	}
	if projectModuleFiles.FileType == domain.Dir {
		if count, _, e := ProjectModuleFilesRepository.Find(map[string]interface{}{"parentId": request.Id}); e == nil && count > 0 {
			err = protocol.NewCustomMessage(1, "文件夹不为空")
			return
		}
	}
	if projectModuleFiles, err = ProjectModuleFilesRepository.Remove(projectModuleFiles); err != nil {
		return
	}
	rsp = projectModuleFiles
	err = transactionContext.CommitTransaction()
	return
}

func (svr *ProjectModuleFilesService) ListProjectModuleFiles(header *protocol.RequestHeader, request *protocolx.ListProjectModuleFilesRequest) (rsp interface{}, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
	)
	rsp = &protocolx.ListProjectModuleFilesResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
		return
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	var ProjectModuleFilesRepository, _ = factory.CreateProjectModuleFilesRepository(transactionContext)
	var projectModuleFiles []*domain.ProjectModuleFiles
	var total int64
	if total, projectModuleFiles, err = ProjectModuleFilesRepository.Find(common.ObjectToMap(request)); err != nil {
		return
	}
	rsp = map[string]interface{}{
		"total": total,
		"list":  utils.LoadCustomField(projectModuleFiles, "Id", "FileType", "FileName", "ParentId", "Path", "CodeBlock"),
	}
	if request.StructType == "tree" {
		rsp = map[string]interface{}{
			"total": total,
			"list":  svr.traverseModuleFiles(projectModuleFiles),
		}
	}
	err = transactionContext.CommitTransaction()
	return
}

func (svr *ProjectModuleFilesService) Import(header *protocol.RequestHeader, request *protocolx.ImportRequest) (rsp *protocolx.ImportResponse, err error) {
	var (
		transactionContext, _   = factory.CreateTransactionContext(nil)
		ProjectModuleVersion, _ = factory.CreateProjectModuleVersionRepository(transactionContext)
	)
	rsp = &protocolx.ImportResponse{}
	if err = request.ValidateCommand(); err != nil {
		err = protocol.NewCustomMessage(2, err.Error())
		return
	}
	if err = transactionContext.StartTransaction(); err != nil {
		log.Error(err)
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	if _, err = ProjectModuleVersion.FindOne(map[string]interface{}{"id": request.ProjectModuleVersionId, "projectModuleId": request.ProjectModuleId}); err != nil {
		err = protocol.NewCustomMessage(1, "项目版本不存在")
		return
	}

	var ProjectModuleFilesRepository, _ = factory.CreateProjectModuleFilesRepository(transactionContext)
	var mapParent map[string]*domain.ProjectModuleFiles = make(map[string]*domain.ProjectModuleFiles)

	for _, f := range request.ImportFiles {
		fileDir := filepath.Dir(f.FileName)
		fileBase := filepath.Base(f.FileName)
		filename := strings.Split(fileBase, ".")[0]
		var parentNode *domain.ProjectModuleFiles = &domain.ProjectModuleFiles{Path: "", ProjectModuleId: request.ProjectModuleId, ProjectModuleVersionId: request.ProjectModuleVersionId, Id: 0}
		var ok bool
		if len(fileDir) > 0 {
			// create dir node
			if parentNode, ok = mapParent[fileDir]; !ok {
				parentNodes, _ := svr.mkdirF(fileDir, request.ProjectModuleId, request.ProjectModuleVersionId, request.ParentId, ProjectModuleFilesRepository)
				for i := range parentNodes {
					mapParent[parentNodes[i].Path] = parentNodes[i]
				}
				// a/b/c/test.go  test.go 的parent node 就是 c (a/b/c 里面的最后一个)
				if len(parentNodes) > 0 {
					parentNode = parentNodes[len(parentNodes)-1]
				}
			}
		}

		//save new node
		newItem := &domain.ProjectModuleFiles{
			ProjectModuleId:        parentNode.ProjectModuleId,
			ProjectModuleVersionId: parentNode.ProjectModuleVersionId,
			ParentId:               parentNode.Id,
			FileType:               domain.File,
			FileName:               filename,
			FileKey:                filename,
			CodeBlock:              string(f.FileContent),
			Remark:                 "",
			CreateTime:             time.Now(),
			UpdateTime:             time.Now(),
			Path:                   filename,
		}
		if _, e := svr.save(newItem, ProjectModuleFilesRepository); e != nil {
			log.Error(e)
			continue
		}
	}

	log.Info("Receive files:", len(request.ImportFiles), request.ProjectModuleId, request.ProjectModuleVersionId, request.ParentId)
	err = transactionContext.CommitTransaction()
	return
}

func (svr *ProjectModuleFilesService) save(request *domain.ProjectModuleFiles, ProjectModuleFilesRepository domain.ProjectModuleFilesRepository) (rsp *domain.ProjectModuleFiles, err error) {
	if request.ParentId > 0 {
		if pfile, e := ProjectModuleFilesRepository.FindOne(map[string]interface{}{"id": request.ParentId, "projectModuleId": request.ProjectModuleId, "projectModuleVersionId": request.ProjectModuleVersionId}); e != nil {
			err = protocol.NewCustomMessage(1, "父节点不存在")
			return
		} else {
			request.Path = filepath.Join(pfile.Path, request.Path)
		}
	}
	if m, e := ProjectModuleFilesRepository.FindOne(map[string]interface{}{"fileKey": request.FileKey, "projectModuleId": request.ProjectModuleId, "projectModuleVersionId": request.ProjectModuleVersionId, "parentId": request.ParentId}); e == nil && m != nil {
		err = protocol.NewCustomMessage(1, "已存在 filekey:"+request.FileKey)
		rsp = m
		return
	}
	if m, e := ProjectModuleFilesRepository.Save(request); e != nil {
		err = e
		return
	} else {
		rsp = m
	}
	return
}
func (svr *ProjectModuleFilesService) mkdirF(fileDir string, mid, vid, pid int64, repository domain.ProjectModuleFilesRepository) (files []*domain.ProjectModuleFiles, err error) {
	fileDir = strings.ReplaceAll(fileDir, "/", "\\")
	dirs := strings.Split(fileDir, "\\")
	for _, dir := range dirs {
		//save new dir
		newItem := &domain.ProjectModuleFiles{
			ProjectModuleId:        mid,
			ProjectModuleVersionId: vid,
			ParentId:               pid,
			FileType:               domain.Dir,
			FileName:               dir,
			FileKey:                dir,
			CodeBlock:              "",
			Remark:                 "",
			CreateTime:             time.Now(),
			UpdateTime:             time.Now(),
			Path:                   dir,
		}
		if file, e := svr.save(newItem, repository); e != nil {
			if file != nil { //已存在
				pid = file.Id
				files = append(files, file)
			}
			continue
		} else {
			pid = file.Id
			files = append(files, file)
		}
	}
	return
}

func (svr *ProjectModuleFilesService) traverseModuleFiles(files []*domain.ProjectModuleFiles) interface{} {

	retSlice := make([]*protocolx.ModuleFiles, 0)

	for i := range files {
		if files[i].ParentId == 0 {
			retSlice = append(retSlice, &protocolx.ModuleFiles{ModuleFile: protocolx.NewModuleFile(files[i]), List: make([]*protocolx.ModuleFiles, 0)})
			continue
		}
		traverse(retSlice, files[i])
	}
	return retSlice
}

func traverse(list []*protocolx.ModuleFiles, file *domain.ProjectModuleFiles) {
	for i := range list {
		if list[i].Id == file.ParentId {
			list[i].List = append(list[i].List, &protocolx.ModuleFiles{ModuleFile: protocolx.NewModuleFile(file), List: make([]*protocolx.ModuleFiles, 0)})
			return
		}
		traverse(list[i].List, file)
	}
	return
}
func NewProjectModuleFilesService(options map[string]interface{}) *ProjectModuleFilesService {
	svr := &ProjectModuleFilesService{}
	return svr
}