/* * @description: 合同项目节相关数据库操作 * @Author: CP * @Date: 2020-11-02 11:37:32 * @FilePath: \construction_management\dao\tree_contract_dao.go */ package dao import ( "errors" "fmt" "log" "strings" "github.com/go-xorm/xorm" "go.mod/models" ) //数据库操作引擎 type TreeContractDao struct { engine *xorm.Engine } //获得一个DAO对象 func NewTreeContractDao(engine *xorm.Engine) *TreeContractDao { return &TreeContractDao{ engine: engine, } } // 获得本项目的合同项目节 func (d *TreeContractDao) Get(treeId int, bidsectionId int, projectId int) *models.CmTreeContracts { data := &models.CmTreeContracts{} _, err := d.engine. Where("tree_id=? and bidsection_id =? and project_id=? ", treeId, bidsectionId, projectId). Get(data) if err != nil { data.Id = 0 return data } return data } // 获得项目下的项目节 func (d *TreeContractDao) GetAll(bidsectionId int, projectId int) []models.CmTreeContracts { datalist := make([]models.CmTreeContracts, 0) err := d.engine. Asc("id"). Where("bidsection_id =? and project_id=?", bidsectionId, projectId). Find(&datalist) if err != nil { return datalist } else { return datalist } } // 获得节点的孩子 func (d *TreeContractDao) GetChildren(parentId int, bidsectionId int, projectId int) []models.CmTreeContracts { datalist := make([]models.CmTreeContracts, 0) err := d.engine. Asc("serial"). Where("parent_id=? and bidsection_id=? and project_id=?", parentId, bidsectionId, projectId). Find(&datalist) if err != nil { return datalist } else { return datalist } } //根据序号和深度获得前一个兄弟节点 func (d *TreeContractDao) GetElderBrother(serial int, depth int, parentId int, bidsectionId int, projectId int) []models.CmTreeContracts { datalist := make([]models.CmTreeContracts, 0) err := d.engine. Desc("serial"). Where("serial < ? and depth = ? and bidsection_id=? and project_id=?", serial, depth, bidsectionId, projectId). Find(&datalist) if err != nil { return datalist } else { return datalist } } //根据序号和深度获得后一个兄弟节点 func (d *TreeContractDao) GetYoungerBrother(serial int, depth int, parentId int, bidsectionId int, projectId int) []models.CmTreeContracts { datalist := make([]models.CmTreeContracts, 0) err := d.engine. Asc("serial"). Where("serial > ? and depth = ? and bidsection_id=? and project_id=?", serial, depth, bidsectionId, projectId). Find(&datalist) if err != nil { return datalist } else { return datalist } } // 获得最后一条项目节 func (d *TreeContractDao) GetLast(projectId int) *models.CmTreeContracts { data := &models.CmTreeContracts{} _, err := d.engine. Desc("id"). Where("project_id=?", projectId). Get(data) if err != nil { data.Id = 0 return data } return data } // 获得谋归属下的项目节 func (d *TreeContractDao) GetAttribution(attribution string, projectId int, bidsectionId int) []models.CmTreeContracts { datalist := make([]models.CmTreeContracts, 0) err := d.engine. Asc("serial"). Where("attribution like ? and project_id=? and bidsection_id=?", attribution+"%", projectId, bidsectionId). Find(&datalist) if err != nil { return datalist } else { return datalist } } // 项目节升降级 func (d *TreeContractDao) MoveDepth(section *models.CmTreeContracts, elderBrother *models.CmTreeContracts, operation string, bidsectionId int, projectId int) error { session := d.engine.NewSession() defer session.Close() err := session.Begin() if err != nil { return errors.New("操作失败-db") } // 降级 if operation == "downDepth" { // 1.前一个兄弟节点 // fmt.Println(elderBrother) // 2.把节点移动到兄弟节点的下级,成为兄弟的孩子 // 2-1 节点的父亲为兄弟的ID // 2-2 节点的深度 +1 // 2-3 节点归属为兄弟归属+序号 attribution := fmt.Sprintf("%s%d-", elderBrother.Attribution, elderBrother.Serial) // 2-4 序号为1 // 2-5 项目节编号 // 原编号 // section.Code // 移动后编号 moveCode := attribution + "1" _, err = session.Exec("UPDATE cm_tree_contracts SET `parent_id` = ?,attribution= ? , serial = ? ,`code` = replace(`code`, '"+section.Code+"', '"+moveCode+"')"+ ",`depth` =`depth` + ? where id = ? ", elderBrother.TreeId, attribution, 1, 1, section.Id) if err != nil { session.Rollback() return errors.New("降级失败") } // 3.更新节点下的归属 // 3-1 节点的所有孩子的归属 // 原节点 孩子的归属 attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial) // 降级后的 孩子归属 moveAttributionChildren := fmt.Sprintf("%s%d-", attribution, 1) // 3-2 降级 深度+1 _, err = session.Exec("UPDATE cm_tree_contracts SET "+ "`depth` =`depth` + ? where attribution like ? and project_id=? and bidsection_id=? ", 1, attributionChildren+"%", projectId, bidsectionId) if err != nil { session.Rollback() return errors.New("降级失败") } // 3-3--替换 归属和编号 // "`attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') ,`code` = replace(`code`, '"+section.Code+"', '"+moveCode+"')," err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, section.Code, moveCode, projectId, bidsectionId) if err != nil { session.Rollback() return errors.New("降级失败") } } else if operation == "upDepth" { // 升级 // 1.父亲节点 sectionFather := d.Get(section.ParentId, bidsectionId, projectId) if sectionFather.Id == 0 { session.Rollback() return errors.New("升级-未找到上级项目节") } // 2.原节点的父亲ID字段升级为爷爷ID // 2-1 升级 深度-1 // 2-2 序号 原父亲的序号+1 // 2-3 归属 原父亲的归属 // 移动后编号-需替换原编号 节点2-1-1 升级后的父节点归属 2- 加上父节点的序号+1 1+1=2 2-2 moveCode := fmt.Sprintf("%s%d", sectionFather.Attribution, sectionFather.Serial+1) _, err = session.Exec("UPDATE cm_tree_contracts SET `parent_id` = ?,attribution= ? , serial = ? ,`code` = replace(`code`, '"+section.Code+"', '"+moveCode+"')"+ ",`depth` =`depth` - ? where id = ? ", sectionFather.ParentId, sectionFather.Attribution, sectionFather.Serial+1, 1, section.Id) if err != nil { session.Rollback() return errors.New("升级失败") } // 3.更新节点下的归属,深度 // 原节点 孩子的归属 attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial) // 升级后的 孩子归属 moveAttributionChildren := fmt.Sprintf("%s%d-", sectionFather.Attribution, sectionFather.Serial+1) // 深度 -1 _, err = session.Exec("UPDATE cm_tree_contracts SET `attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') "+ ",`depth` =`depth` - ? where attribution like ? and project_id=? and bidsection_id=? ", 1, attributionChildren+"%", projectId, bidsectionId) if err != nil { session.Rollback() return errors.New("升级失败") } // 3-1 err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, section.Code, moveCode, projectId, bidsectionId) if err != nil { session.Rollback() return errors.New("升级失败") } } else { return errors.New("参数错误") } err = session.Commit() if err != nil { session.Rollback() return errors.New("操作失败-db") } return nil } // 合同项目节上下移动 func (d *TreeContractDao) MoveSerial(section *models.CmTreeContracts, brother *models.CmTreeContracts, operation string, bidsectionId int, projectId int) error { session := d.engine.NewSession() defer session.Close() err := session.Begin() if err != nil { return errors.New("操作失败-db") } //1.上下移 // 1.项目节序号替换为兄弟序号 _, err = session.Exec("UPDATE cm_tree_contracts SET serial = ? , `code` = replace(`code`, '"+section.Code+"', '"+brother.Code+"') where id = ? ", brother.Serial, section.Id) if err != nil { session.Rollback() return errors.New("移动失败") } // 兄弟序号替换为项目节序号 _, err = session.Exec("UPDATE cm_tree_contracts SET serial = ? , `code` = replace(`code`, '"+brother.Code+"', '"+section.Code+"') where id = ? ", section.Serial, brother.Id) if err != nil { session.Rollback() return errors.New("移动失败") } //2.项目节孩子们 归属设置 // 原节点 孩子的归属 attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial) // 移动后的 孩子归属和编号 moveAttributionChildren := fmt.Sprintf("%s%d-", brother.Attribution, brother.Serial) err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, section.Code, brother.Code, projectId, bidsectionId) if err != nil { session.Rollback() return errors.New("移动失败") } // _, err = session.Exec("UPDATE cm_tree_contracts SET `attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') "+ // "`code` = replace(`code`, '"+attributionChildren+"', '"+moveAttributionChildren+"') where attribution like ? and project_id=? and bidsection_id=? ", attributionChildren+"%", projectId, bidsectionId) // if err != nil { // session.Rollback() // return errors.New("移动失败") // } // 3.兄弟节点孩子们 归属设置 // 兄弟节点 孩子的归属 attributionChildren = fmt.Sprintf("%s%d-", brother.Attribution, brother.Serial) // 移动后的 孩子归属 moveAttributionChildren = fmt.Sprintf("%s%d-", section.Attribution, section.Serial) err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, brother.Code, section.Code, projectId, bidsectionId) if err != nil { session.Rollback() return errors.New("移动失败") } // _, err = session.Exec("UPDATE cm_tree_contracts SET `attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') "+ // "`code` = replace(`code`, '"+attributionChildren+"', '"+moveAttributionChildren+"') where attribution like ? and project_id=? and bidsection_id=? ", attributionChildren+"%", projectId, bidsectionId) // if err != nil { // session.Rollback() // return errors.New("移动失败") // } // // 上移 // if operation == "upSerial" { // // 1.上一个大兄弟 // // fmt.Println(brother) // // 2.项目节 序号 兄弟的序号 // _, err = session.Exec("UPDATE cm_tree_contracts SET serial = ? "+ // " where id = ? ", brother.Serial, section.Id) // if err != nil { // session.Rollback() // return errors.New("上移失败") // } // // 3.兄弟的序号为 项目节序号 // _, err = session.Exec("UPDATE cm_tree_contracts SET serial = ? "+ // " where id = ? ", section.Serial, brother.Id) // if err != nil { // session.Rollback() // return errors.New("上移失败") // } // } else if operation == "downSerial" { // // 下移 // // 1.下一个兄弟 // // fmt.Println(brother) // // 2.项目节 序号 兄弟的序号 // } else { // return errors.New("参数错误") // } err = session.Commit() if err != nil { session.Rollback() return errors.New("操作失败-db") } return nil } // 插入多条数据 func (d *TreeContractDao) CreateAll(data []*models.CmTreeContracts) error { _, err := d.engine.Insert(data) return err } //替换项目节归属 func (d *TreeContractDao) replaceContractAttribution(session *xorm.Session, attributionChildren string, moveAttributionChildren string, code string, moveCode string, projectId int, bidsectionId int) error { // 1.获得需要替换的数据 sectionData := d.GetAttribution(attributionChildren, projectId, bidsectionId) if len(sectionData) == 0 { return nil } attributionSql := " attribution = case id " codeSql := " code = case id " idList := make([]int, 0) for _, item := range sectionData { // section := &models.CmTreeContracts{} // section.Id = item.Id // 替换归属 attributionSql += fmt.Sprintf("when %d then '%s' ", item.Id, strings.Replace(item.Attribution, attributionChildren, moveAttributionChildren, 1)) //section.Attribution = strings.Replace(item.Attribution, attributionChildren, moveAttributionChildren, 1) // 替换编号 codeSql += fmt.Sprintf("when %d then '%s' ", item.Id, strings.Replace(item.Code, code, moveCode, 1)) // section.Code = strings.Replace(item.Code, code, moveCode, 1) idList = append(idList, item.Id) } attributionSql += " end, " codeSql += " end " id := strings.Replace(strings.Trim(fmt.Sprint(idList), "[]"), " ", ",", -1) sql := "update cm_tree_contracts set " + attributionSql + codeSql + " WHERE id IN (" + id + ")" _, err := session.Exec(sql) if err != nil { log.Println("替换项目节归属, error=", err) return err } return nil }