tree_contract_dao.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /*
  2. * @description: 合同项目节相关数据库操作
  3. * @Author: CP
  4. * @Date: 2020-11-02 11:37:32
  5. * @FilePath: \construction_management\dao\tree_contract_dao.go
  6. */
  7. package dao
  8. import (
  9. "errors"
  10. "fmt"
  11. "log"
  12. "strings"
  13. "github.com/go-xorm/xorm"
  14. "go.mod/models"
  15. "go.mod/web/viewmodels"
  16. )
  17. //数据库操作引擎
  18. type TreeContractDao struct {
  19. engine *xorm.Engine
  20. }
  21. //获得一个DAO对象
  22. func NewTreeContractDao(engine *xorm.Engine) *TreeContractDao {
  23. return &TreeContractDao{
  24. engine: engine,
  25. }
  26. }
  27. func (d *TreeContractDao) GetDetail(id int) *viewmodels.TreeSectionDetail {
  28. data := &viewmodels.TreeSectionDetail{}
  29. _, _ = d.engine.Sql("select t.name, s.content from cm_tree_contracts as t left join cm_contracts as s on t.contract_id = s.id where t.id = ?", id).Get(data)
  30. return data
  31. }
  32. // 获得本项目的合同项目节
  33. func (d *TreeContractDao) Get(treeId int) *models.CmTreeContracts {
  34. data := &models.CmTreeContracts{}
  35. _, err := d.engine.
  36. Where("tree_id=? ", treeId).
  37. Get(data)
  38. if err != nil {
  39. data.Id = 0
  40. return data
  41. }
  42. return data
  43. }
  44. // 获得项目下的项目节
  45. func (d *TreeContractDao) GetAll() []models.CmTreeContracts {
  46. datalist := make([]models.CmTreeContracts, 0)
  47. err := d.engine.
  48. Asc("id").
  49. Limit(5000, 0).
  50. Find(&datalist)
  51. if err != nil {
  52. return datalist
  53. } else {
  54. return datalist
  55. }
  56. }
  57. // 获得项目下的项目节不包含合同
  58. func (d *TreeContractDao) GetAllNotContract(bidsectionId int, projectId int, treeType int) []models.CmTreeContracts {
  59. datalist := make([]models.CmTreeContracts, 0)
  60. err := d.engine.
  61. Asc("id").
  62. Where("bidsection_id =? and project_id=? and tree_type=? and contract_id=0", bidsectionId, projectId, treeType).
  63. Limit(5000, 0).
  64. Find(&datalist)
  65. if err != nil {
  66. return datalist
  67. } else {
  68. return datalist
  69. }
  70. }
  71. // 获得最新ID
  72. func (d *TreeContractDao) GetLastId() *models.CmTreeContracts {
  73. data := &models.CmTreeContracts{}
  74. _, err := d.engine.
  75. Desc("id").
  76. Get(data)
  77. if err != nil {
  78. data.Id = 0
  79. return data
  80. }
  81. return data
  82. }
  83. // 获得项目节所有合同
  84. func (d *TreeContractDao) GetContractAll(bidsectionId int, projectId int) []models.CmTreeContracts {
  85. datalist := make([]models.CmTreeContracts, 0)
  86. err := d.engine.
  87. Asc("id").
  88. Where("bidsection_id =? and project_id=? and contract_id!=0 ", bidsectionId, projectId).
  89. Find(&datalist)
  90. if err != nil {
  91. return datalist
  92. } else {
  93. return datalist
  94. }
  95. }
  96. // 获得标段 项目节中已有的合同
  97. func (d *TreeContractDao) GetContract(bidsectionId int, projectId int, treeType int) []models.CmTreeContracts {
  98. datalist := make([]models.CmTreeContracts, 0)
  99. err := d.engine.
  100. Asc("id").
  101. Where("bidsection_id =? and project_id=? and contract_id!=0 and tree_type=?", bidsectionId, projectId, treeType).
  102. Find(&datalist)
  103. if err != nil {
  104. return datalist
  105. } else {
  106. return datalist
  107. }
  108. }
  109. // 获得节点的孩子
  110. func (d *TreeContractDao) GetChildren(parentId int) []models.CmTreeContracts {
  111. datalist := make([]models.CmTreeContracts, 0)
  112. err := d.engine.
  113. Asc("serial").
  114. Where("parent_id=?", parentId).
  115. Find(&datalist)
  116. if err != nil {
  117. return datalist
  118. } else {
  119. return datalist
  120. }
  121. }
  122. //根据序号和深度获得前一个兄弟节点
  123. func (d *TreeContractDao) GetElderBrother(serial int, depth int, parentId int) []models.CmTreeContracts {
  124. datalist := make([]models.CmTreeContracts, 0)
  125. err := d.engine.
  126. Desc("serial").
  127. Where("serial < ? and depth = ? and parent_id =? ", serial, depth, parentId).
  128. Find(&datalist)
  129. if err != nil {
  130. return datalist
  131. } else {
  132. return datalist
  133. }
  134. }
  135. //根据序号和深度获得后一个兄弟节点
  136. func (d *TreeContractDao) GetYoungerBrother(serial int, depth int, parentId int) []models.CmTreeContracts {
  137. datalist := make([]models.CmTreeContracts, 0)
  138. err := d.engine.
  139. Asc("serial").
  140. Where("serial > ? and depth = ? and parent_id =? ", serial, depth, parentId).
  141. Find(&datalist)
  142. if err != nil {
  143. return datalist
  144. } else {
  145. return datalist
  146. }
  147. }
  148. // 获得最后一条项目节
  149. func (d *TreeContractDao) GetLast(projectId int, treeType int) *models.CmTreeContracts {
  150. data := &models.CmTreeContracts{}
  151. _, err := d.engine.
  152. Desc("id").
  153. Where("project_id=? and tree_type=?", projectId, treeType).
  154. Get(data)
  155. if err != nil {
  156. data.Id = 0
  157. return data
  158. }
  159. return data
  160. }
  161. // 获得谋归属下的项目节
  162. func (d *TreeContractDao) GetAttribution(attribution string) []models.CmTreeContracts {
  163. datalist := make([]models.CmTreeContracts, 0)
  164. err := d.engine.
  165. Asc("serial").
  166. Where("attribution like ? ", attribution+"%").
  167. Find(&datalist)
  168. if err != nil {
  169. return datalist
  170. } else {
  171. return datalist
  172. }
  173. }
  174. // 获得谋归属下的项目节-合同
  175. func (d *TreeContractDao) GetAttributionContract(section *models.CmTreeContracts) []models.CmTreeContracts {
  176. // attribution := section.Attribution
  177. attribution := fmt.Sprintf("%s-", section.Code)
  178. datalist := make([]models.CmTreeContracts, 0)
  179. err := d.engine.
  180. Asc("serial").
  181. Where("(attribution like ? or id =? ) and project_id=? contract_id!=0", attribution+"%", section.Id).
  182. Find(&datalist)
  183. if err != nil {
  184. return datalist
  185. } else {
  186. return datalist
  187. }
  188. }
  189. // 项目节升降级
  190. func (d *TreeContractDao) MoveDepth(section *models.CmTreeContracts, elderBrother *models.CmTreeContracts, operation string) error {
  191. session := d.engine.NewSession()
  192. defer session.Close()
  193. err := session.Begin()
  194. if err != nil {
  195. return errors.New("操作失败-db")
  196. }
  197. // 降级
  198. if operation == "downDepth" {
  199. // 1.前一个兄弟节点
  200. // fmt.Println(elderBrother)
  201. // 2.把节点移动到兄弟节点的下级,成为兄弟的孩子
  202. // 2-1 节点的父亲为兄弟的ID
  203. // 2-2 节点的深度 +1
  204. // 2-3 节点归属为兄弟归属+序号
  205. attribution := fmt.Sprintf("%s%d-", elderBrother.Attribution, elderBrother.Serial)
  206. // 2-4 序号 没有孩子序号为1,有孩子 最大孩子序号+1
  207. // 2-4-1 获得上一位哥的孩子们
  208. elderBrotherChildren := d.GetChildren(elderBrother.TreeId)
  209. serial := 1
  210. if len(elderBrotherChildren) != 0 {
  211. serial = elderBrotherChildren[len(elderBrotherChildren)-1].Serial + 1
  212. }
  213. // 2-5 项目节编号
  214. // 原编号
  215. // section.Code
  216. // 移动后编号
  217. moveCode := fmt.Sprintf("%s%d", attribution, serial)
  218. _, err = session.Exec("UPDATE cm_tree_contracts SET `parent_id` = ?,attribution= ? , serial = ? ,`code` = replace(`code`, '"+section.Code+"', '"+moveCode+"')"+
  219. ",`depth` =`depth` + ? where id = ?", elderBrother.TreeId, attribution, serial, 1, section.Id)
  220. if err != nil {
  221. session.Rollback()
  222. return errors.New("降级失败")
  223. }
  224. // 3.更新节点下的归属
  225. // 3-1 节点的所有孩子的归属
  226. // 原节点 孩子的归属
  227. attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
  228. // 降级后的 孩子归属
  229. moveAttributionChildren := fmt.Sprintf("%s%d-", attribution, serial)
  230. // 3-2 降级 深度+1
  231. _, err = session.Exec("UPDATE cm_tree_contracts SET "+
  232. "`depth` =`depth` + ? where attribution like ? ", 1, attributionChildren+"%")
  233. if err != nil {
  234. session.Rollback()
  235. return errors.New("降级失败")
  236. }
  237. // 3-3--替换 归属和编号
  238. // "`attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') ,`code` = replace(`code`, '"+section.Code+"', '"+moveCode+"'),"
  239. err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, section.Code, moveCode)
  240. if err != nil {
  241. session.Rollback()
  242. return errors.New("降级失败")
  243. }
  244. } else if operation == "upDepth" {
  245. // 升级
  246. // 1.父亲节点
  247. sectionFather := d.Get(section.ParentId)
  248. if sectionFather.Id == 0 {
  249. session.Rollback()
  250. return errors.New("升级-未找到上级项目节")
  251. }
  252. // 2.原节点的父亲ID字段升级为爷爷ID
  253. // 2-1 升级 深度-1
  254. // 2-2 序号 爷爷的孩子们的 序号+1
  255. grandpaChildren := d.GetChildren(sectionFather.ParentId)
  256. serial := 1
  257. if len(grandpaChildren) != 0 {
  258. serial = grandpaChildren[len(grandpaChildren)-1].Serial + 1
  259. }
  260. // 2-3 归属 原父亲的归属
  261. // 移动后编号-需替换原编号 节点2-1-1 升级后的父节点归属 2- 加上爷爷最大孩子的序号+1
  262. moveCode := fmt.Sprintf("%s%d", sectionFather.Attribution, serial)
  263. // 升级的项目节
  264. _, err = session.Exec("UPDATE cm_tree_contracts SET `parent_id` = ?,attribution= ? , serial = ? ,`code` = replace(`code`, '"+section.Code+"', '"+moveCode+"')"+
  265. ",`depth` =`depth` - ? where id = ? ", sectionFather.ParentId, sectionFather.Attribution, serial, 1, section.Id)
  266. if err != nil {
  267. session.Rollback()
  268. return errors.New("升级失败")
  269. }
  270. // 3.更新节点下的归属,深度
  271. // 原节点 孩子的归属
  272. attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
  273. // 升级后的 孩子归属
  274. moveAttributionChildren := fmt.Sprintf("%s%d-", sectionFather.Attribution, serial)
  275. // 深度 -1
  276. _, err = session.Exec("UPDATE cm_tree_contracts SET `attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') "+
  277. ",`depth` =`depth` - ? where attribution like ? ", 1, attributionChildren+"%")
  278. if err != nil {
  279. session.Rollback()
  280. return errors.New("升级失败")
  281. }
  282. // 3-1
  283. err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, section.Code, moveCode)
  284. if err != nil {
  285. session.Rollback()
  286. return errors.New("升级失败")
  287. }
  288. } else {
  289. return errors.New("参数错误")
  290. }
  291. err = session.Commit()
  292. if err != nil {
  293. session.Rollback()
  294. return errors.New("操作失败-db")
  295. }
  296. return nil
  297. }
  298. // 合同项目节上下移动
  299. func (d *TreeContractDao) MoveSerial(section *models.CmTreeContracts, brother *models.CmTreeContracts, operation string) error {
  300. session := d.engine.NewSession()
  301. defer session.Close()
  302. err := session.Begin()
  303. if err != nil {
  304. return errors.New("操作失败-db")
  305. }
  306. //1.上下移
  307. // 1.项目节序号替换为兄弟序号
  308. _, err = session.Exec("UPDATE cm_tree_contracts SET serial = ? , `code` = replace(`code`, '"+section.Code+"', '"+brother.Code+"') where id = ?", brother.Serial, section.Id)
  309. if err != nil {
  310. session.Rollback()
  311. return errors.New("移动失败")
  312. }
  313. // 兄弟序号替换为项目节序号
  314. _, err = session.Exec("UPDATE cm_tree_contracts SET serial = ? , `code` = replace(`code`, '"+brother.Code+"', '"+section.Code+"') where id = ?", section.Serial, brother.Id)
  315. if err != nil {
  316. session.Rollback()
  317. return errors.New("移动失败")
  318. }
  319. //2.项目节孩子们 归属设置
  320. // 原节点 孩子的归属
  321. attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
  322. // 移动后的 孩子归属和编号
  323. moveAttributionChildren := fmt.Sprintf("%s%d-", brother.Attribution, brother.Serial)
  324. err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, section.Code, brother.Code)
  325. if err != nil {
  326. session.Rollback()
  327. return errors.New("移动失败")
  328. }
  329. // _, err = session.Exec("UPDATE cm_tree_contracts SET `attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') "+
  330. // "`code` = replace(`code`, '"+attributionChildren+"', '"+moveAttributionChildren+"') where attribution like ? and project_id=? and bidsection_id=? ", attributionChildren+"%", projectId, bidsectionId)
  331. // if err != nil {
  332. // session.Rollback()
  333. // return errors.New("移动失败")
  334. // }
  335. // 3.兄弟节点孩子们 归属设置
  336. // 兄弟节点 孩子的归属
  337. attributionChildren = fmt.Sprintf("%s%d-", brother.Attribution, brother.Serial)
  338. // 移动后的 孩子归属
  339. moveAttributionChildren = fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
  340. err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, brother.Code, section.Code)
  341. if err != nil {
  342. session.Rollback()
  343. return errors.New("移动失败")
  344. }
  345. err = session.Commit()
  346. if err != nil {
  347. session.Rollback()
  348. return errors.New("操作失败-db")
  349. }
  350. return nil
  351. }
  352. // 修改项目节序号
  353. func (d *TreeContractDao) UpdateSerial(section *models.CmTreeContracts, serial int) error {
  354. session := d.engine.NewSession()
  355. defer session.Close()
  356. err := session.Begin()
  357. if err != nil {
  358. return errors.New("操作失败-db")
  359. }
  360. // 1.更新项目节序号和项目节编号
  361. moveCode := fmt.Sprintf("%s%d", section.Attribution, serial)
  362. _, err = session.Exec("UPDATE cm_tree_contracts SET serial = ? , `code` = ? where id = ? ", serial, moveCode, section.Id)
  363. if err != nil {
  364. session.Rollback()
  365. log.Println("合同项目节序号更新 error=", err)
  366. return errors.New("更新序号失败")
  367. }
  368. // 2.更新项目节子孙们的序号和归属
  369. // 2-1归属 项目节 孩子归属
  370. attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
  371. // 2-2 序号更新后的 孩子归属
  372. moveAttributionChildren := fmt.Sprintf("%s%d-", section.Attribution, serial)
  373. // 2-3 项目节 孩子的编号
  374. code := fmt.Sprintf("%s%d", section.Attribution, section.Serial)
  375. err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, code, moveCode)
  376. if err != nil {
  377. session.Rollback()
  378. log.Println("合同项目节序号更新 error=", err)
  379. return errors.New("更新序号失败")
  380. }
  381. err = session.Commit()
  382. if err != nil {
  383. session.Rollback()
  384. return errors.New("操作失败-db")
  385. }
  386. return nil
  387. }
  388. // 插入多条数据
  389. func (d *TreeContractDao) CreateAll(data []*models.CmTreeContracts) error {
  390. session := d.engine.NewSession()
  391. defer session.Close()
  392. err := session.Begin()
  393. if err != nil {
  394. return errors.New("新增失败-db")
  395. }
  396. // 新增
  397. for _, item := range data {
  398. _, err := session.Insert(item)
  399. if err != nil {
  400. log.Println(" error=", err)
  401. session.Rollback()
  402. return errors.New("新增失败")
  403. }
  404. }
  405. err = session.Commit()
  406. if err != nil {
  407. session.Rollback()
  408. return errors.New("新增失败-db")
  409. }
  410. return nil
  411. }
  412. // 新增项目节
  413. func (d *TreeContractDao) Create(data *models.CmTreeContracts) (*models.CmTreeContracts, error) {
  414. session := d.engine.NewSession()
  415. defer session.Close()
  416. err := session.Begin()
  417. if err != nil {
  418. return nil, errors.New("新增失败-db")
  419. }
  420. _, err = session.Insert(data)
  421. if err != nil {
  422. log.Println(" error=", err)
  423. return nil, errors.New("新增失败")
  424. }
  425. // 插入成功后,ID自动赋值到data.Id里
  426. // fmt.Println("=======================================")
  427. // fmt.Println(data)
  428. // 更新合同节树ID
  429. // data.TreeId = data.Id
  430. // _, err = session.Id(data.Id).Update(data)
  431. // if err != nil {
  432. // log.Println(" error=", err)
  433. // return errors.New("新增失败")
  434. // }
  435. err = session.Commit()
  436. if err != nil {
  437. session.Rollback()
  438. return nil, errors.New("新增失败-db")
  439. }
  440. return data, nil
  441. }
  442. // 保存项目节
  443. func (d *TreeContractDao) Save(section *models.CmTreeContracts, columns []string) error {
  444. _, err := d.engine.Id(section.Id).MustCols(columns...).Update(section)
  445. if err != nil {
  446. return errors.New("保存失败")
  447. }
  448. return nil
  449. }
  450. // 删除项目节
  451. func (d *TreeContractDao) Delete(section *models.CmTreeContracts) error {
  452. session := d.engine.NewSession()
  453. defer session.Close()
  454. err := session.Begin()
  455. if err != nil {
  456. return errors.New("删除失败-db")
  457. }
  458. // 1. 删除项目节
  459. _, err = session.Where("id = ? ", section.Id).Delete(section)
  460. if err != nil {
  461. session.Rollback()
  462. return errors.New("删除失败")
  463. }
  464. // 孩子们的归属
  465. attribution := fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
  466. // 2. 删除项目节孩子们
  467. _, err = session.Exec("DELETE FROM `cm_tree_contracts` WHERE attribution like ? ", attribution+"%")
  468. if err != nil {
  469. session.Rollback()
  470. return errors.New("删除失败")
  471. }
  472. err = session.Commit()
  473. if err != nil {
  474. session.Rollback()
  475. return errors.New("删除失败-db")
  476. }
  477. return nil
  478. }
  479. //替换项目节归属
  480. func (d *TreeContractDao) replaceContractAttribution(session *xorm.Session, attributionChildren string, moveAttributionChildren string, code string, moveCode string) error {
  481. // 1.获得需要替换的数据
  482. sectionData := d.GetAttribution(attributionChildren)
  483. if len(sectionData) == 0 {
  484. return nil
  485. }
  486. attributionSql := " attribution = case id "
  487. codeSql := " code = case id "
  488. idList := make([]int, 0)
  489. for _, item := range sectionData {
  490. // section := &models.CmTreeContracts{}
  491. // section.Id = item.Id
  492. // 替换归属
  493. attributionSql += fmt.Sprintf("when %d then '%s' ", item.Id, strings.Replace(item.Attribution, attributionChildren, moveAttributionChildren, 1))
  494. //section.Attribution = strings.Replace(item.Attribution, attributionChildren, moveAttributionChildren, 1)
  495. // 替换编号
  496. codeSql += fmt.Sprintf("when %d then '%s' ", item.Id, strings.Replace(item.Code, code, moveCode, 1))
  497. // section.Code = strings.Replace(item.Code, code, moveCode, 1)
  498. idList = append(idList, item.Id)
  499. }
  500. attributionSql += " end, "
  501. codeSql += " end "
  502. id := strings.Replace(strings.Trim(fmt.Sprint(idList), "[]"), " ", ",", -1)
  503. sql := "update cm_tree_contracts set " + attributionSql + codeSql + " WHERE id IN (" + id + ")"
  504. _, err := session.Exec(sql)
  505. if err != nil {
  506. log.Println("替换项目节归属, error=", err)
  507. return err
  508. }
  509. return nil
  510. }