tree_dao.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*
  2. * @description: 树结构数据库操作相关
  3. * @Author: CP
  4. * @Date: 2020-09-11 14:49:27
  5. * @FilePath: \construction_management\dao\tree_dao.go
  6. */
  7. package dao
  8. import (
  9. "errors"
  10. "fmt"
  11. "strconv"
  12. "strings"
  13. "github.com/go-xorm/xorm"
  14. "go.mod/models"
  15. )
  16. //数据库操作引擎
  17. type TreeDao struct {
  18. engine *xorm.Engine
  19. }
  20. //获得一个DAO对象
  21. func NewTreeDao(engine *xorm.Engine) *TreeDao {
  22. return &TreeDao{
  23. engine: engine,
  24. }
  25. }
  26. //id获得数据
  27. func (d *TreeDao) Get(id int, projectId int) *models.CmTree {
  28. // data := &models.CmTree{Id: id, ProjectId: projectId, Isdelete: 0}
  29. // // Get取到值后,会自动赋值到data中
  30. // ok, err := d.engine.Get(data)
  31. // if ok && err == nil {
  32. // return data
  33. // } else {
  34. // data.Id = 0
  35. // return data
  36. // }
  37. // fmt.Println("sqlid=")
  38. // fmt.Println(id)
  39. data := &models.CmTree{}
  40. _, err := d.engine.
  41. Where("id=? and project_id=? and isdelete=0", id, projectId).
  42. Get(data)
  43. // fmt.Println(data)
  44. if err != nil {
  45. data.Id = 0
  46. return data
  47. }
  48. return data
  49. }
  50. // 获得该目录下的标段
  51. func (d *TreeDao) GetBidsection(id int) []models.CmTree {
  52. datalist := make([]models.CmTree, 0)
  53. err := d.engine.
  54. Asc("serial").
  55. Where("parent_id=? and isfolder=0 and isdelete=0", id).
  56. Find(&datalist)
  57. if err != nil {
  58. return datalist
  59. } else {
  60. return datalist
  61. }
  62. }
  63. // 获得某一深度的 结构数据(不包含子集) 正序
  64. func (d *TreeDao) GetAllDepth(depth int, projectId int) []models.CmTree {
  65. datalist := make([]models.CmTree, 0)
  66. err := d.engine.
  67. Asc("serial").
  68. Where("depth=? and project_id=? and isdelete=0", depth, projectId).
  69. Find(&datalist)
  70. if err != nil {
  71. return datalist
  72. } else {
  73. return datalist
  74. }
  75. }
  76. // 获得该目录下所有的目录
  77. func (d *TreeDao) GetChildFolder(id int) []models.CmTree {
  78. datalist := make([]models.CmTree, 0)
  79. err := d.engine.
  80. Asc("serial").
  81. Where("parent_id=? and isfolder=1 and isdelete=0", id).
  82. Find(&datalist)
  83. if err != nil {
  84. return datalist
  85. } else {
  86. return datalist
  87. }
  88. }
  89. // 获得某一深度的某一归属 结构数据(不包含子集) 正序
  90. func (d *TreeDao) GetALLDepthByAttribution(depth int, projectId int, attribution string) []models.CmTree {
  91. datalist := make([]models.CmTree, 0)
  92. err := d.engine.
  93. Asc("serial").
  94. Where("depth=? and project_id=? and attribution like ? and isdelete=0", depth, projectId, attribution+"%").
  95. Find(&datalist)
  96. if err != nil {
  97. return datalist
  98. } else {
  99. return datalist
  100. }
  101. }
  102. // 获得该目录下所有的目录和标段
  103. func (d *TreeDao) GetFolderAndBid(projectId int, attribution string) []models.CmTree {
  104. datalist := make([]models.CmTree, 0)
  105. err := d.engine.
  106. Asc("serial").
  107. Where("project_id=? and attribution like ? and isdelete=0", projectId, attribution+"%").
  108. Find(&datalist)
  109. if err != nil {
  110. return datalist
  111. } else {
  112. return datalist
  113. }
  114. }
  115. // 获得标段的目录
  116. func (d *TreeDao) GetBidParentId(bidsectionId int, projectId int) *models.CmTree {
  117. data := &models.CmTree{}
  118. _, err := d.engine.
  119. Where("bidsection_id=? and project_id=? and isdelete=0", bidsectionId, projectId).
  120. Get(data)
  121. if err != nil {
  122. data.Id = 0
  123. return data
  124. }
  125. return data
  126. }
  127. // 删除目录以及下属目录所有数据
  128. func (d *TreeDao) DeleteFolderAndBid(id int, projectId int, attribution string) error {
  129. session := d.engine.NewSession()
  130. defer session.Close()
  131. err := session.Begin()
  132. if err != nil {
  133. return errors.New("删除出错-db")
  134. }
  135. // 删除树结构中 目录和资源
  136. data := &models.CmTree{Isdelete: 1}
  137. _, err = session.
  138. Where("id=? or (project_id=? and attribution like ?) and isdelete=0", id, projectId, attribution+"%").
  139. Update(data)
  140. if err != nil {
  141. session.Rollback()
  142. return errors.New("删除目录出错")
  143. }
  144. // 获得已删除不是目录的资源
  145. datalist := make([]models.CmTree, 0)
  146. err = d.engine.
  147. Where("project_id=? and isdelete=1 and isfolder=0", projectId).
  148. Find(&datalist)
  149. // 删除标段
  150. if len(datalist) > 0 {
  151. idList := []string{}
  152. for _, bidData := range datalist {
  153. idList = append(idList, strconv.Itoa(bidData.Id))
  154. }
  155. inId := strings.Join(idList, ",")
  156. _, err = session.Exec("UPDATE cm_bidsection SET `isdelete` = 1 where id in (?)", inId)
  157. if err != nil {
  158. session.Rollback()
  159. return errors.New("删除标段出错")
  160. }
  161. }
  162. err = session.Commit()
  163. if err != nil {
  164. session.Rollback()
  165. return errors.New("删除出错-db")
  166. }
  167. return nil
  168. }
  169. // 移动目录
  170. func (d *TreeDao) Move(treeNode *models.CmTree, moveFolder *models.CmTree) error {
  171. session := d.engine.NewSession()
  172. defer session.Close()
  173. err := session.Begin()
  174. if err != nil {
  175. return errors.New("移动出错-db")
  176. }
  177. // 原目录父节点替换目标目录的ID
  178. _, err = session.Exec("UPDATE cm_tree SET `parent_id` = ? where id = ? and isdelete=0", moveFolder.Id, treeNode.Id)
  179. if err != nil {
  180. return err //errors.New("移动目录出错---")
  181. }
  182. // data := &models.CmTree{ParentId: moveFolder.Id}
  183. // _, err = session.
  184. // Where("id=? and isdelete=0", treeNode.Id).
  185. // Update(data)
  186. // if err != nil {
  187. // session.Rollback()
  188. // return err //errors.New("移动目录出错---")
  189. // }
  190. // 移动目录的归属和标段的归属关系--TODO 效率问题在修改
  191. // 1-原来目录的归属
  192. attribution := fmt.Sprintf("%s%d-", treeNode.Attribution, treeNode.Serial)
  193. // 2-移动后目录的归属--跟目录的话,所属为空
  194. movrAttribution := ""
  195. if moveFolder.Id != 0 {
  196. movrAttribution = fmt.Sprintf("%s%d-", moveFolder.Attribution, moveFolder.Serial)
  197. }
  198. // 3-获得移动后最大序列号
  199. depth := moveFolder.Depth + 1
  200. datalist := d.GetALLDepthByAttribution(depth, moveFolder.ProjectId, movrAttribution)
  201. maxIndex := len(datalist)
  202. serial := 0
  203. if maxIndex != 0 {
  204. serial = datalist[maxIndex-1].Serial + 1
  205. }
  206. // 3-1 深度差=原目录depth-目标目录depth
  207. difference := (treeNode.Depth - 1) - moveFolder.Depth
  208. // 移动后目录depth=原目录depth-差
  209. // 4-移动原目录或标段-最大序号
  210. _, err = session.Exec("UPDATE cm_tree SET `attribution` = ?,`serial` = ?,`depth` =`depth` - ? where id = ? and isdelete=0",
  211. movrAttribution, serial, difference, treeNode.Id)
  212. if err != nil {
  213. session.Rollback()
  214. return errors.New("移动目录或标段出错")
  215. }
  216. //
  217. // 5-移动原目录下所有子目录和标段-项目下
  218. movrAttribution = fmt.Sprintf("%s%d-", movrAttribution, serial)
  219. _, err = session.Exec("UPDATE cm_tree SET `attribution` = replace(`attribution`, '"+attribution+"', '"+movrAttribution+"') "+
  220. ",`depth` =`depth` - ? where attribution like ? and project_id=? and isdelete=0", difference, attribution+"%", treeNode.ProjectId)
  221. //_, err = session.Exec("UPDATE from cm_tree SET `attribution` = replace(`attribution`, ?, ?) where attribution like ?", attribution,movrAttribution,attribution+"%")
  222. if err != nil {
  223. session.Rollback()
  224. return errors.New("移动目录或标段出错")
  225. }
  226. // 6-更新depth
  227. // 6-1原目录深度差
  228. //difference := treeNode.Depth - moveFolder.Depth
  229. // 原目录depth-差,移动后的depth
  230. err = session.Commit()
  231. if err != nil {
  232. session.Rollback()
  233. return errors.New("移动出错-db")
  234. }
  235. return nil
  236. }
  237. // 获得项目文件夹
  238. func (d *TreeDao) GetAllTree(projectId int) []models.CmTree {
  239. datalist := make([]models.CmTree, 0)
  240. err := d.engine.
  241. Asc("id").
  242. Where("project_id=? and isdelete=0", projectId).
  243. Find(&datalist)
  244. if err != nil {
  245. return datalist
  246. } else {
  247. return datalist
  248. }
  249. }
  250. // treeNode重命名
  251. func (d *TreeDao) Rename(data *models.CmTree, columns []string) error {
  252. session := d.engine.NewSession()
  253. defer session.Close()
  254. err := session.Begin()
  255. if err != nil {
  256. return errors.New("重命名失败-db")
  257. }
  258. // 重命名treeNode
  259. _, err = d.engine.Id(data.Id).MustCols(columns...).Update(data)
  260. if err != nil {
  261. session.Rollback()
  262. return errors.New("标段重命名失败")
  263. }
  264. // 重命名标段
  265. bidsection := models.CmBidsection{}
  266. bidsection.Id = data.BidsectionId
  267. bidsection.Name = data.Name
  268. _, err = d.engine.Id(bidsection.Id).MustCols(columns...).Update(bidsection)
  269. if err != nil {
  270. session.Rollback()
  271. return errors.New("标段重命名失败-bid")
  272. }
  273. err = session.Commit()
  274. if err != nil {
  275. session.Rollback()
  276. return errors.New("重命名失败-db")
  277. }
  278. return nil
  279. }
  280. //创建
  281. func (d *TreeDao) Create(data *models.CmTree) error {
  282. _, err := d.engine.Insert(data)
  283. return err
  284. }
  285. // 更新
  286. func (d *TreeDao) Update(data *models.CmTree, columns []string) error {
  287. _, err := d.engine.Id(data.Id).MustCols(columns...).Update(data)
  288. return err
  289. }