/* * @description:层级文件夹数据操作相关 * @Author: CP * @Date: 2020-09-11 14:43:58 * @FilePath: \construction_management\services\tree_service.go */ package services import ( "encoding/json" "errors" "fmt" "log" "strconv" "time" "github.com/kataras/iris/v12" "go.mod/comm" "go.mod/conf" "go.mod/dao" "go.mod/datasource" "go.mod/models" "go.mod/web/viewmodels" ) //定义项目Service接口 type TreeService interface { //ValidManager(code string, account string, password string) error ValidRule(ctx iris.Context) (viewmodels.Tree, error) Create(data viewmodels.Tree) error GetAllProject(int) *viewmodels.Tree Rename(viewmodels.Tree) error GetFolderAndBid(string) ([]models.CmTree, error) DeleteFolderAndBid(string) error } //返回service操作类 type treeService struct { dao *dao.TreeDao } //创建项目service func NewTreeService() TreeService { return &treeService{ dao: dao.NewTreeDao(datasource.InstanceDbMaster()), } } // 文件夹规则验证 func (s *treeService) ValidRule(ctx iris.Context) (viewmodels.Tree, error) { folderVaild := viewmodels.Tree{} err := ctx.ReadForm(&folderVaild) if err != nil { log.Println("folder-ValidRule-ReadForm转换异常, error=", err) return folderVaild, err } err = folderVaild.Validate() if err != nil { log.Println("文件夹验证, error=", err) return folderVaild, err } return folderVaild, nil } // 获得项目下 相关文件夹-整个树结构 func (s *treeService) GetAllProject(projectId int) *viewmodels.Tree { datalist := s.dao.GetAllTree(projectId) folderlist := make([]viewmodels.Tree, 0) // 生成根 folder := viewmodels.Tree{} id, _ := comm.AesEncrypt(strconv.Itoa(0), conf.SignSecret) parentId, _ := comm.AesEncrypt(strconv.Itoa(-1), conf.SignSecret) folder.Id = id folder.Name = "root" folder.ParentId = parentId folderlist = append(folderlist, folder) // 加入数据 for _, data := range datalist { folder := viewmodels.Tree{} //folder.Id = comm.Encrypt([]byte(conf.SignSecret), []byte(strconv.Itoa(data.Id))) id, _ := comm.AesEncrypt(strconv.Itoa(data.Id), conf.SignSecret) parentId, _ := comm.AesEncrypt(strconv.Itoa(data.ParentId), conf.SignSecret) projectId, _ := comm.AesEncrypt(strconv.Itoa(data.ProjectId), conf.SignSecret) serial, _ := comm.AesEncrypt(strconv.Itoa(data.Serial), conf.SignSecret) folder.Id = id folder.Name = data.Name folder.ParentId = parentId folder.ProjectId = projectId folder.Depth = data.Depth + 1 folder.Serial = serial folder.Leaf = true folder.CreateTime = data.CreateTime.Format(conf.SysTimeform) folderlist = append(folderlist, folder) } var data []*viewmodels.Tree data = make([]*viewmodels.Tree, 0) for i, _ := range folderlist { var a *viewmodels.Tree a = &folderlist[i] data = append(data, a) } node := &folderlist[0] //父节点 maketree(data, node) //调用生成tree //transformjson(node) //转化为json return node } // 新增一个文件夹 func (s *treeService) Create(data viewmodels.Tree) error { // 类型校验 folder := models.CmTree{} folder.Name = data.Name ProjectId, err := strconv.Atoi(data.ProjectId) if err != nil { return err } // 获得该目录ID Id, err := comm.AesDecrypt(data.Id, conf.SignSecret) if err != nil { return err } IdInt, err1 := strconv.Atoi(Id) if err1 != nil { return err1 } // 该目录中是否有标段 bidlist := s.dao.GetBidsection(IdInt) if len(bidlist) > 0 { return errors.New("该文件夹已存在标段,不能在新增目录") } // 获得该深度的文件夹最大序号 datalist := s.dao.GetAllDepth(data.Depth, ProjectId) maxIndex := len(datalist) serial := 0 if maxIndex != 0 { serial = datalist[maxIndex-1].Serial + 1 } // 设置归属 if data.Depth != 0 { treeNode := s.dao.Get(IdInt) if treeNode.Id == 0 { return errors.New("上级目录不正确") } folder.Attribution = treeNode.Attribution + strconv.Itoa(treeNode.Serial) + "-" folder.ParentId = IdInt } folder.ProjectId = ProjectId folder.Serial = serial folder.Depth = data.Depth folder.Isfolder = 1 folder.CreateTime = time.Now() folder.UpdateTime = time.Now() err = s.dao.Create(&folder) if err != nil { return errors.New("添加目录出错") } return nil } // 重命名 func (s *treeService) Rename(data viewmodels.Tree) error { // 获得该目录ID Id, err := comm.AesDecrypt(data.Id, conf.SignSecret) if err != nil { return err } IdInt, err1 := strconv.Atoi(Id) if err1 != nil { return err1 } // 装配需要更新的数据 folder := models.CmTree{} folder.Id = IdInt folder.Name = data.Name err = s.dao.Update(&folder, []string{"Name"}) if err != nil { return errors.New("目录重命名出错") } return nil } // 获得该目录下所有的目录和标段 func (s *treeService) GetFolderAndBid(id string) ([]models.CmTree, error) { // 获得该目录ID id, err := comm.AesDecrypt(id, conf.SignSecret) if err != nil { return nil, errors.New("目录解析错误") } IdInt, err := strconv.Atoi(id) if err != nil { return nil, errors.New("目录解析错误") } // 获得该目录下所有数据 folder := s.dao.Get(IdInt) attribution := fmt.Sprintf("%s%d-", folder.Attribution, folder.Serial) // 获得目录归属 dataList := s.dao.GetFolderAndBid(folder.ProjectId, attribution) return dataList, nil } // 删除该目录和所属的目录和标段 func (s *treeService) DeleteFolderAndBid(id string) error { // 获得该目录ID id, err := comm.AesDecrypt(id, conf.SignSecret) if err != nil { return errors.New("目录解析错误") } IdInt, err := strconv.Atoi(id) if err != nil { return errors.New("目录解析错误") } // 获得该目录下 归属关系 folder := s.dao.Get(IdInt) attribution := fmt.Sprintf("%s%d-", folder.Attribution, folder.Serial) // --逻辑删除 目录和数据 err = s.dao.DeleteFolderAndBid(folder.Id, folder.ProjectId, attribution) if err != nil { return err } // TODO -加入堆栈 物理删除数据 return nil } // 创建一颗树 func maketree(Data []*viewmodels.Tree, node *viewmodels.Tree) { //参数为父节点,添加父节点的子节点指针切片 childs, _ := havechild(Data, node) //判断节点是否有子节点并返回 if childs != nil { // fmt.Printf("\n") // fmt.Println(*node) // fmt.Println("子节点:") // for _, v := range childs { // fmt.Println(*v) // } //打印 // 往父节点添加子节点 node.Children = append(node.Children, childs[0:]...) //添加子节点 for _, v := range childs { //查询子节点的子节点,并添加到子节点 _, has := havechild(Data, v) if has { // 递归添加节点 maketree(Data, v) } else { // 叶子节点 node.Leaf = false } } } } // 是否有子树 func havechild(Data []*viewmodels.Tree, node *viewmodels.Tree) (child []*viewmodels.Tree, yes bool) { for _, v := range Data { if v.ParentId == node.Id { child = append(child, v) } } if child != nil { yes = true } return } func transformjson(Data *viewmodels.Tree) { //转为json Jsondata, _ := json.Marshal(Data) fmt.Println(string(Jsondata)) } //now := comm.NowUnix() //comm.FormatFromUnixTime(now) // ParentIdInt := 0 // if data.ParentId != "" { // ParentId, err := comm.AesDecrypt(data.ParentId, conf.SignSecret) // if err != nil { // return err // } // ParentIdInt, err = strconv.Atoi(ParentId) // if err != nil { // ParentIdInt = 0 // } // }