/* * @description: 树结构数据库操作相关 * @Author: CP * @Date: 2020-09-11 14:49:27 * @FilePath: \construction_management\dao\tree_dao.go */ package dao import ( "errors" "fmt" "strconv" "strings" "github.com/go-xorm/xorm" "go.mod/models" ) //数据库操作引擎 type TreeDao struct { engine *xorm.Engine } //获得一个DAO对象 func NewTreeDao(engine *xorm.Engine) *TreeDao { return &TreeDao{ engine: engine, } } //id获得数据 func (d *TreeDao) Get(id int) *models.CmTree { data := &models.CmTree{Id: id, Isdelete: 0} //Get取到值后,会自动赋值到data中 ok, err := d.engine.Get(data) if ok && err == nil { return data } else { data.Id = 0 return data } } // 获得该目录下的标段 func (d *TreeDao) GetBidsection(id int) []models.CmTree { datalist := make([]models.CmTree, 0) err := d.engine. Asc("serial"). Where("parent_id=? and isfolder=0 and isdelete=0", id). Find(&datalist) if err != nil { return datalist } else { return datalist } } // 获得某一深度的 结构数据(不包含子集) 正序 func (d *TreeDao) GetAllDepth(depth int, projectId int) []models.CmTree { datalist := make([]models.CmTree, 0) err := d.engine. Asc("serial"). Where("depth=? and project_id=? and isdelete=0", depth, projectId). Find(&datalist) if err != nil { return datalist } else { return datalist } } // 获得该目录下所有的目录 func (d *TreeDao) GetChildFolder(id int) []models.CmTree { datalist := make([]models.CmTree, 0) err := d.engine. Asc("serial"). Where("parent_id=? and isdelete=0", id). Find(&datalist) if err != nil { return datalist } else { return datalist } } // 获得某一深度的某一归属 结构数据(不包含子集) 正序 func (d *TreeDao) GetALLDepthByAttribution(depth int, projectId int, attribution string) []models.CmTree { datalist := make([]models.CmTree, 0) err := d.engine. Asc("serial"). Where("depth=? and project_id=? and attribution like ? and isdelete=0", depth, projectId, attribution+"%"). Find(&datalist) if err != nil { return datalist } else { return datalist } } // 获得该目录下所有的目录和标段 func (d *TreeDao) GetFolderAndBid(projectId int, attribution string) []models.CmTree { datalist := make([]models.CmTree, 0) err := d.engine. Asc("serial"). Where("project_id=? and attribution like ? and isdelete=0", projectId, attribution+"%"). Find(&datalist) if err != nil { return datalist } else { return datalist } } // 删除目录以及下属目录所有数据 func (d *TreeDao) DeleteFolderAndBid(id int, projectId int, attribution string) error { session := d.engine.NewSession() defer session.Close() err := session.Begin() if err != nil { return errors.New("删除出错-db") } // 删除树结构中 目录和资源 data := &models.CmTree{Isdelete: 1} _, err = session. Where("id=? or (project_id=? and attribution like ?) and isdelete=0", id, projectId, attribution+"%"). Update(data) if err != nil { session.Rollback() return errors.New("删除目录出错") } // 获得已删除不是目录的资源 datalist := make([]models.CmTree, 0) err = d.engine. Where("project_id=? and isdelete=1 and isfolder=0", projectId). Find(&datalist) // 删除标段 if len(datalist) > 0 { idList := []string{} for _, bidData := range datalist { idList = append(idList, strconv.Itoa(bidData.Id)) } inId := strings.Join(idList, ",") _, err = session.Exec("UPDATE cm_tender SET `isdelete` = 1 where id in (?)", inId) if err != nil { session.Rollback() return errors.New("删除标段出错") } } err = session.Commit() if err != nil { session.Rollback() return errors.New("删除出错-db") } return nil } // 移动目录 func (d *TreeDao) Move(treeNode *models.CmTree, moveFolder *models.CmTree) error { session := d.engine.NewSession() defer session.Close() err := session.Begin() if err != nil { return errors.New("移动出错-db") } // 被移动跟目录-父亲节点转换 data := &models.CmTree{ParentId: moveFolder.Id} _, err = session. Where("id=? and isdelete=0", treeNode.Id). Update(data) if err != nil { session.Rollback() return errors.New("移动目录出错") } // 移动目录的归属和标段的归属关系--TODO 效率问题在修改 // 1-原来目录的归属 attribution := fmt.Sprintf("%s%d-", treeNode.Attribution, treeNode.Serial) // 2-移动后目录的归属 movrAttribution := fmt.Sprintf("%s%d-", moveFolder.Attribution, moveFolder.Serial) // 3-获得移动后最大序列号 depth := moveFolder.Depth + 1 datalist := d.GetALLDepthByAttribution(depth, moveFolder.ProjectId, movrAttribution) maxIndex := len(datalist) serial := 0 if maxIndex != 0 { serial = datalist[maxIndex-1].Serial + 1 } // 4-移动原目录货标段-最大序号 _, err = session.Exec("UPDATE cm_tree SET `attribution` = ?,`serial` = ? where id = ? and isdelete=0", movrAttribution, serial, treeNode.Id) if err != nil { session.Rollback() return errors.New("移动目录或标段出错") } // 5-移动原目录下所有子目录和标段 movrAttribution = fmt.Sprintf("%s%d-", movrAttribution, serial) _, err = session.Exec("UPDATE cm_tree SET `attribution` = replace(`attribution`, '"+attribution+"', '"+movrAttribution+"') where attribution like ? and isdelete=0", attribution+"%") //_, err = session.Exec("UPDATE from cm_tree SET `attribution` = replace(`attribution`, ?, ?) where attribution like ?", attribution,movrAttribution,attribution+"%") if err != nil { session.Rollback() return errors.New("移动目录或标段出错") } err = session.Commit() if err != nil { session.Rollback() return errors.New("移动出错-db") } return nil } // 获得项目文件夹 func (d *TreeDao) GetAllTree(projectId int) []models.CmTree { datalist := make([]models.CmTree, 0) err := d.engine. Asc("id"). Where("project_id=? and isdelete=0", projectId). Find(&datalist) if err != nil { return datalist } else { return datalist } } //创建 func (d *TreeDao) Create(data *models.CmTree) error { _, err := d.engine.Insert(data) return err } // 更新 func (d *TreeDao) Update(data *models.CmTree, columns []string) error { _, err := d.engine.Id(data.Id).MustCols(columns...).Update(data) return err }