tree_service.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * @description:层级文件夹数据操作相关
  3. * @Author: CP
  4. * @Date: 2020-09-11 14:43:58
  5. * @FilePath: \construction_management\services\tree_service.go
  6. */
  7. package services
  8. import (
  9. "encoding/json"
  10. "errors"
  11. "fmt"
  12. "log"
  13. "strconv"
  14. "time"
  15. "github.com/kataras/iris/v12"
  16. "go.mod/comm"
  17. "go.mod/conf"
  18. "go.mod/dao"
  19. "go.mod/datasource"
  20. "go.mod/models"
  21. "go.mod/web/viewmodels"
  22. )
  23. //定义项目Service接口
  24. type TreeService interface {
  25. //ValidManager(code string, account string, password string) error
  26. ValidRule(ctx iris.Context) (viewmodels.Tree, error)
  27. Create(data viewmodels.Tree) error
  28. GetAllProject(int) *viewmodels.Tree
  29. Rename(treevm viewmodels.Tree, projectId int) error
  30. GetFolderAndBid(id int, projectId int) ([]models.CmTree, error)
  31. DeleteFolderAndBid(id int, projectId int) error
  32. Move(id int, moveId int, projectId int) error
  33. }
  34. //返回service操作类
  35. type treeService struct {
  36. dao *dao.TreeDao
  37. }
  38. //创建项目service
  39. func NewTreeService() TreeService {
  40. return &treeService{
  41. dao: dao.NewTreeDao(datasource.InstanceDbMaster()),
  42. }
  43. }
  44. // 文件夹规则验证
  45. func (s *treeService) ValidRule(ctx iris.Context) (viewmodels.Tree, error) {
  46. folderVaild := viewmodels.Tree{}
  47. err := ctx.ReadJSON(&folderVaild)
  48. if err != nil {
  49. log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
  50. return folderVaild, err
  51. }
  52. err = folderVaild.Validate()
  53. if err != nil {
  54. log.Println("文件夹验证, error=", err)
  55. return folderVaild, err
  56. }
  57. return folderVaild, nil
  58. }
  59. // 获得项目下 相关文件夹-整个树结构
  60. func (s *treeService) GetAllProject(projectId int) *viewmodels.Tree {
  61. datalist := s.dao.GetAllTree(projectId)
  62. folderlist := make([]viewmodels.Tree, 0)
  63. // 生成根
  64. folder := viewmodels.Tree{}
  65. id, _ := comm.AesEncrypt(strconv.Itoa(0), conf.SignSecret)
  66. parentId, _ := comm.AesEncrypt(strconv.Itoa(-1), conf.SignSecret)
  67. folder.Id = id
  68. folder.Name = "root"
  69. folder.ParentId = parentId
  70. folderlist = append(folderlist, folder)
  71. // 加入数据
  72. for _, data := range datalist {
  73. folder := viewmodels.Tree{}
  74. //folder.Id = comm.Encrypt([]byte(conf.SignSecret), []byte(strconv.Itoa(data.Id)))
  75. id, _ := comm.AesEncrypt(strconv.Itoa(data.Id), conf.SignSecret)
  76. parentId, _ := comm.AesEncrypt(strconv.Itoa(data.ParentId), conf.SignSecret)
  77. projectId, _ := comm.AesEncrypt(strconv.Itoa(data.ProjectId), conf.SignSecret)
  78. serial, _ := comm.AesEncrypt(strconv.Itoa(data.Serial), conf.SignSecret)
  79. folder.Id = id
  80. folder.Name = data.Name
  81. folder.ParentId = parentId
  82. folder.ProjectId = projectId
  83. folder.Depth = data.Depth + 1
  84. folder.Serial = serial
  85. folder.Ancounts = data.Ancounts
  86. folder.Isfolder = data.Isfolder
  87. folder.IsEnd = false
  88. //folder.Leaf = true
  89. folder.HasFolder = false
  90. folder.IsBid = false
  91. folder.CreateTime = data.CreateTime.Format(conf.SysTimeform)
  92. folderlist = append(folderlist, folder)
  93. }
  94. //fmt.Println(folderlist)
  95. var data []*viewmodels.Tree
  96. data = make([]*viewmodels.Tree, 0)
  97. for i, _ := range folderlist {
  98. var a *viewmodels.Tree
  99. a = &folderlist[i]
  100. data = append(data, a)
  101. }
  102. node := &folderlist[0] //父节点
  103. maketree(data, node) //调用生成tree
  104. //transformjson(node) //转化为json
  105. return node
  106. }
  107. // 新增一个文件夹
  108. func (s *treeService) Create(data viewmodels.Tree) error {
  109. // 类型校验
  110. folder := models.CmTree{}
  111. folder.Name = data.Name
  112. // 项目ID
  113. ProjectId, err := strconv.Atoi(data.ProjectId)
  114. if err != nil {
  115. return err
  116. }
  117. // 获得该目录ID
  118. Id, err := comm.AesDecrypt(data.Id, conf.SignSecret)
  119. if err != nil {
  120. return err
  121. }
  122. IdInt, err1 := strconv.Atoi(Id)
  123. if err1 != nil {
  124. return err1
  125. }
  126. // 该目录中是否有标段
  127. bidlist := s.dao.GetBidsection(IdInt)
  128. if len(bidlist) > 0 {
  129. return errors.New("该文件夹已存在标段,不能在新增目录")
  130. }
  131. // 获得该深度的文件夹最大序号
  132. serial := 0
  133. depth := data.Depth + 1
  134. if data.Depth == -1 {
  135. // 1-创建顶级目录--获得最大序号
  136. datalist := s.dao.GetAllDepth(depth, ProjectId)
  137. maxIndex := len(datalist)
  138. if maxIndex != 0 {
  139. serial = datalist[maxIndex-1].Serial + 1
  140. }
  141. } else {
  142. // 1-创建次目录-获得次级目录最大序号
  143. treeNode := s.dao.Get(IdInt, ProjectId)
  144. // 去除前端depth作用-在这里获得下级目录的深度
  145. depth = treeNode.Depth + 1
  146. if treeNode.Id == 0 {
  147. return errors.New("上级目录不正确")
  148. }
  149. attribution := fmt.Sprintf("%s%d-", treeNode.Attribution, treeNode.Serial)
  150. datalist := s.dao.GetALLDepthByAttribution(data.Depth, ProjectId, attribution)
  151. maxIndex := len(datalist)
  152. if maxIndex != 0 {
  153. serial = datalist[maxIndex-1].Serial + 1
  154. }
  155. // 设置归属
  156. folder.Attribution = attribution //treeNode.Attribution + strconv.Itoa(treeNode.Serial) + "-"
  157. folder.ParentId = IdInt
  158. }
  159. folder.ProjectId = ProjectId
  160. folder.Serial = serial
  161. folder.Depth = depth
  162. folder.Isfolder = 1
  163. folder.CreateTime = time.Now()
  164. folder.UpdateTime = time.Now()
  165. err = s.dao.Create(&folder)
  166. if err != nil {
  167. return errors.New("添加目录出错")
  168. }
  169. return nil
  170. }
  171. // 重命名
  172. func (s *treeService) Rename(data viewmodels.Tree, projectId int) error {
  173. // 获得该目录ID
  174. Id, err := comm.AesDecrypt(data.Id, conf.SignSecret)
  175. if err != nil {
  176. return err
  177. }
  178. IdInt, err1 := strconv.Atoi(Id)
  179. if err1 != nil {
  180. return err1
  181. }
  182. // 获得树信息
  183. treeData := s.dao.Get(IdInt, projectId)
  184. if treeData.Id == 0 {
  185. return errors.New("修改的目录不合法")
  186. }
  187. treeNode := models.CmTree{}
  188. treeNode.Id = IdInt
  189. treeNode.Name = data.Name
  190. if treeData.Isfolder == 1 {
  191. // 目录
  192. err = s.dao.Update(&treeNode, []string{"Name"})
  193. } else {
  194. // 标段
  195. treeNode.BidsectionId = treeData.BidsectionId
  196. err = s.dao.Rename(&treeNode, []string{"Name"})
  197. }
  198. if err != nil {
  199. return err
  200. }
  201. return nil
  202. }
  203. // 获得该目录下所有的目录和标段
  204. func (s *treeService) GetFolderAndBid(id int, projectId int) ([]models.CmTree, error) {
  205. // 获得该目录ID
  206. // id, err := comm.AesDecrypt(id, conf.SignSecret)
  207. // if err != nil {
  208. // return nil, errors.New("目录解析错误")
  209. // }
  210. // IdInt, err := strconv.Atoi(id)
  211. // if err != nil {
  212. // return nil, errors.New("目录解析错误")
  213. // }
  214. // 获得该目录下所有数据
  215. folder := s.dao.Get(id, projectId)
  216. if folder.Id == 0 {
  217. return nil, errors.New("目录不合法")
  218. }
  219. attribution := fmt.Sprintf("%s%d-", folder.Attribution, folder.Serial)
  220. // 获得目录归属
  221. dataList := s.dao.GetFolderAndBid(folder.ProjectId, attribution)
  222. return dataList, nil
  223. }
  224. // 删除该目录和所属的目录和标段
  225. func (s *treeService) DeleteFolderAndBid(id int, projectId int) error {
  226. // 获得该目录ID
  227. // id, err := comm.AesDecrypt(id, conf.SignSecret)
  228. // if err != nil {
  229. // return errors.New("目录解析错误")
  230. // }
  231. // IdInt, err := strconv.Atoi(id)
  232. // if err != nil {
  233. // return errors.New("目录解析错误")
  234. // }
  235. // 获得该目录下 归属关系
  236. folder := s.dao.Get(id, projectId)
  237. if folder.Id == 0 {
  238. return errors.New("目录不合法")
  239. }
  240. attribution := fmt.Sprintf("%s%d-", folder.Attribution, folder.Serial)
  241. // --逻辑删除 目录和数据
  242. err := s.dao.DeleteFolderAndBid(folder.Id, folder.ProjectId, attribution)
  243. if err != nil {
  244. return err
  245. }
  246. // TODO -加入堆栈 物理删除数据
  247. return nil
  248. }
  249. // 移动目录
  250. func (s *treeService) Move(id int, moveId int, projectId int) error {
  251. // 获得项目目录
  252. treeNode := s.dao.Get(id, projectId)
  253. if treeNode.Id == 0 {
  254. return errors.New("目录或标段解析错误")
  255. }
  256. moveFolder := s.dao.Get(moveId, projectId)
  257. if moveFolder.Id == 0 {
  258. return errors.New("目录解析错误")
  259. }
  260. // TODO
  261. // 移动的是目录
  262. if treeNode.Isfolder == 1 {
  263. // 1.目录下不能有标段
  264. // 被移动的目录存在标段
  265. moveBidList := s.dao.GetBidsection(moveId)
  266. if len(moveBidList) > 0 {
  267. return errors.New("该目录中存在标段,不能移动")
  268. }
  269. } else {
  270. // 标段
  271. // 1.移动的目录是否为叶子节点
  272. moveBidList := s.dao.GetChildFolder(moveId)
  273. if len(moveBidList) > 0 {
  274. return errors.New("该目录中存在其他目录,不能移动")
  275. }
  276. }
  277. err := s.dao.Move(treeNode, moveFolder)
  278. if err != nil {
  279. return err
  280. }
  281. return nil
  282. }
  283. // 创建一颗树
  284. func maketree(Data []*viewmodels.Tree, node *viewmodels.Tree) { //参数为父节点,添加父节点的子节点指针切片
  285. childs, _ := havechild(Data, node) //判断节点是否有子节点并返回
  286. if childs != nil {
  287. // fmt.Printf("\n")
  288. // fmt.Println(*node)
  289. // fmt.Println("子节点:")
  290. // for _, v := range childs {
  291. // fmt.Println(*v)
  292. // } //打印
  293. // 子节点总数
  294. Total := len(childs)
  295. node.ChildsTotal = Total
  296. // 标记最后一个元素
  297. end := Total - 1
  298. childs[end].IsEnd = true
  299. // 往父节点添加子节点
  300. node.Children = append(node.Children, childs[0:]...) //添加子节点
  301. for _, v := range childs { //查询子节点的子节点,并添加到子节点
  302. _, has := havechild(Data, v)
  303. if has {
  304. // 递归添加节点
  305. maketree(Data, v)
  306. }
  307. // else {
  308. // // 叶子节点
  309. // node.Leaf = false
  310. // }
  311. // 目录下是否包含标段
  312. if v.Isfolder == 0 {
  313. node.IsBid = true
  314. } else {
  315. node.HasFolder = true
  316. }
  317. }
  318. }
  319. }
  320. // 是否有子树
  321. func havechild(Data []*viewmodels.Tree, node *viewmodels.Tree) (child []*viewmodels.Tree, yes bool) {
  322. for _, v := range Data {
  323. if v.ParentId == node.Id {
  324. child = append(child, v)
  325. }
  326. }
  327. if child != nil {
  328. yes = true
  329. }
  330. return
  331. }
  332. func transformjson(Data *viewmodels.Tree) { //转为json
  333. Jsondata, _ := json.Marshal(Data)
  334. fmt.Println(string(Jsondata))
  335. }
  336. //now := comm.NowUnix()
  337. //comm.FormatFromUnixTime(now)
  338. // ParentIdInt := 0
  339. // if data.ParentId != "" {
  340. // ParentId, err := comm.AesDecrypt(data.ParentId, conf.SignSecret)
  341. // if err != nil {
  342. // return err
  343. // }
  344. // ParentIdInt, err = strconv.Atoi(ParentId)
  345. // if err != nil {
  346. // ParentIdInt = 0
  347. // }
  348. // }