sandbox.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. package sandbox
  2. import (
  3. "encoding/json"
  4. "eta_gn/eta_api/models"
  5. "eta_gn/eta_api/models/company"
  6. "eta_gn/eta_api/models/sandbox"
  7. "eta_gn/eta_api/models/sandbox/request"
  8. "eta_gn/eta_api/models/system"
  9. "eta_gn/eta_api/services/alarm_msg"
  10. "eta_gn/eta_api/utils"
  11. "fmt"
  12. "strconv"
  13. "strings"
  14. "time"
  15. )
  16. func AddSandboxDraft(sandboxId int, req request.AddAndEditSandbox, opUserId int, opUserName string) (sandboxDraftInfo *sandbox.SandboxDraft, err error) {
  17. lastSandboxDraft, err := sandbox.GetLastSandboxDraftById(sandboxId)
  18. if err != nil && !utils.IsErrNoRow(err) {
  19. return
  20. }
  21. if lastSandboxDraft != nil {
  22. var isUpdateName, isUpdateContent bool
  23. if lastSandboxDraft.Name != utils.TrimStr(req.Name) {
  24. isUpdateName = true
  25. }
  26. if checkoutContent(lastSandboxDraft.Content, req.Content) {
  27. isUpdateContent = true
  28. }
  29. if isUpdateName == false && isUpdateContent == false {
  30. return
  31. }
  32. }
  33. chartPermissionInfo, err := company.GetChartPermissionListById(req.ChartPermissionId)
  34. if err != nil {
  35. return
  36. }
  37. sandboxDraftInfo = &sandbox.SandboxDraft{
  38. SandboxId: sandboxId,
  39. Name: utils.TrimStr(req.Name),
  40. ChartPermissionId: req.ChartPermissionId,
  41. ChartPermissionName: chartPermissionInfo.PermissionName,
  42. Content: req.Content,
  43. OpUserId: opUserId,
  44. OpUserName: opUserName,
  45. CreateTime: time.Now(),
  46. }
  47. err = sandbox.AddSandboxDraft(sandboxDraftInfo)
  48. return
  49. }
  50. func UpdateSandboxEditMark(sandboxId, nowUserId, status int, nowUserName string) (ret models.MarkReportResp, err error) {
  51. key := fmt.Sprint(`crm:sandbox:edit:`, sandboxId)
  52. opUserId, e := utils.Rc.RedisInt(key)
  53. var opUser models.MarkReportItem
  54. if e != nil {
  55. opUserInfoStr, tErr := utils.Rc.RedisString(key)
  56. if tErr == nil {
  57. tErr = json.Unmarshal([]byte(opUserInfoStr), &opUser)
  58. if tErr == nil {
  59. opUserId = opUser.AdminId
  60. }
  61. }
  62. }
  63. if opUserId > 0 && opUserId != nowUserId {
  64. editor := opUser.Editor
  65. if editor == "" {
  66. otherInfo, e := system.GetSysAdminById(opUserId)
  67. if e != nil {
  68. err = fmt.Errorf("查询其他编辑者信息失败")
  69. return
  70. }
  71. editor = otherInfo.RealName
  72. }
  73. ret.Status = 1
  74. ret.Msg = fmt.Sprintf("当前%s正在编辑中", editor)
  75. ret.Editor = editor
  76. return
  77. }
  78. if status == 1 {
  79. nowUser := &models.MarkReportItem{AdminId: nowUserId, Editor: nowUserName}
  80. bt, e := json.Marshal(nowUser)
  81. if e != nil {
  82. err = fmt.Errorf("格式化编辑者信息失败")
  83. return
  84. }
  85. if opUserId > 0 {
  86. utils.Rc.Do("SETEX", key, int64(300), string(bt)) //3分钟缓存
  87. } else {
  88. utils.Rc.SetNX(key, string(bt), time.Second*60*5) //3分钟缓存
  89. }
  90. } else if status == 0 {
  91. _ = utils.Rc.Delete(key)
  92. }
  93. return
  94. }
  95. func DeleteSandbox(sandboxId int) (err error) {
  96. sandboxInfo, err := sandbox.GetSandboxById(sandboxId)
  97. if err != nil {
  98. return
  99. }
  100. sandboxInfo.IsDelete = 1
  101. var updateSandboxColumn = []string{"IsDelete"}
  102. err = sandboxInfo.Update(updateSandboxColumn)
  103. return
  104. }
  105. func GetSandboxVersionDetailByCode(sandboxVersionCode string) (sandboxVersionInfo *sandbox.SandboxVersion, err error) {
  106. sandboxVersionInfo, err = sandbox.GetSandboxVersionBySandboxVersionCode(sandboxVersionCode)
  107. return
  108. }
  109. func GetLastSandboxInfo(sandboxId int) (sandboxInfo *sandbox.Sandbox, err error) {
  110. sandboxInfo, err = sandbox.GetSandboxById(sandboxId)
  111. return
  112. return
  113. }
  114. func GenerateCode() string {
  115. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  116. return utils.MD5(fmt.Sprint("sandbox_") + timestamp)
  117. }
  118. func GenerateVersionCode(sandboxId, sandboxVersion int) string {
  119. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  120. return utils.MD5(fmt.Sprint("sandbox_version_", sandboxId, "_", sandboxVersion) + timestamp)
  121. }
  122. type ContentStruct struct {
  123. Cells []struct {
  124. Attrs struct {
  125. Line struct {
  126. SourceMarker bool `json:"sourceMarker"`
  127. Stroke string `json:"stroke"`
  128. StrokeDasharray string `json:"strokeDasharray"`
  129. } `json:"line"`
  130. Rect struct {
  131. Fill string `json:"fill"`
  132. Stroke string `json:"stroke"`
  133. StrokeDasharray interface{} `json:"strokeDasharray"`
  134. StrokeWidth int64 `json:"strokeWidth"`
  135. } `json:"rect"`
  136. Text struct {
  137. Fill string `json:"fill"`
  138. FontSize float64 `json:"fontSize"`
  139. FontWeight string `json:"fontWeight"`
  140. LineHeight float64 `json:"lineHeight"`
  141. Text string `json:"text"`
  142. TextWrap struct {
  143. Text string `json:"text"`
  144. Width int64 `json:"width"`
  145. } `json:"textWrap"`
  146. } `json:"text"`
  147. } `json:"attrs"`
  148. Data struct {
  149. Key string `json:"key"`
  150. } `json:"data"`
  151. ID string `json:"id"`
  152. Ports struct {
  153. Groups struct {
  154. Port_bottom struct {
  155. Attrs struct {
  156. Circle struct {
  157. Fill string `json:"fill"`
  158. Magnet bool `json:"magnet"`
  159. R int64 `json:"r"`
  160. Stroke string `json:"stroke"`
  161. StrokeWidth int64 `json:"strokeWidth"`
  162. } `json:"circle"`
  163. } `json:"attrs"`
  164. Position string `json:"position"`
  165. ZIndex int64 `json:"zIndex"`
  166. } `json:"port-bottom"`
  167. Port_left struct {
  168. Attrs struct {
  169. Circle struct {
  170. Fill string `json:"fill"`
  171. Magnet bool `json:"magnet"`
  172. R int64 `json:"r"`
  173. Stroke string `json:"stroke"`
  174. StrokeWidth int64 `json:"strokeWidth"`
  175. } `json:"circle"`
  176. } `json:"attrs"`
  177. Position string `json:"position"`
  178. ZIndex int64 `json:"zIndex"`
  179. } `json:"port-left"`
  180. Port_right struct {
  181. Attrs struct {
  182. Circle struct {
  183. Fill string `json:"fill"`
  184. Magnet bool `json:"magnet"`
  185. R int64 `json:"r"`
  186. Stroke string `json:"stroke"`
  187. StrokeWidth int64 `json:"strokeWidth"`
  188. } `json:"circle"`
  189. } `json:"attrs"`
  190. Position string `json:"position"`
  191. ZIndex int64 `json:"zIndex"`
  192. } `json:"port-right"`
  193. Port_top struct {
  194. Attrs struct {
  195. Circle struct {
  196. Fill string `json:"fill"`
  197. Magnet bool `json:"magnet"`
  198. R int64 `json:"r"`
  199. Stroke string `json:"stroke"`
  200. StrokeWidth int64 `json:"strokeWidth"`
  201. } `json:"circle"`
  202. } `json:"attrs"`
  203. Position string `json:"position"`
  204. ZIndex int64 `json:"zIndex"`
  205. } `json:"port-top"`
  206. } `json:"groups"`
  207. Items []struct {
  208. Group string `json:"group"`
  209. ID string `json:"id"`
  210. } `json:"items"`
  211. } `json:"ports"`
  212. Position struct {
  213. X float64 `json:"x"`
  214. Y float64 `json:"y"`
  215. } `json:"position"`
  216. Shape string `json:"shape"`
  217. Size struct {
  218. Height float64 `json:"height"`
  219. Width float64 `json:"width"`
  220. } `json:"size"`
  221. Source struct {
  222. Cell string `json:"cell"`
  223. Port string `json:"port"`
  224. } `json:"source"`
  225. Target struct {
  226. Cell string `json:"cell"`
  227. Port string `json:"port"`
  228. } `json:"target"`
  229. ZIndex int64 `json:"zIndex"`
  230. } `json:"cells"`
  231. }
  232. type SendBoxNodeData struct {
  233. linkData []SandBoxLinkData `json:"linkData"`
  234. linkFold bool `json:"linkFold"`
  235. }
  236. type SandBoxLinkData struct {
  237. RId string `json:"RId"`
  238. Id int `json:"Id"`
  239. Name string `json:"Name"`
  240. Type int `json:"Type"`
  241. Editing bool `json:"editing"`
  242. DatabaseType int `json:"databaseType"`
  243. DetailParams SandBoxDetailParams `json:"detailParams"`
  244. }
  245. type SandBoxDetailParams struct {
  246. Code string `json:"code"`
  247. Id int `json:"id"`
  248. ClassifyId int `json:"classifyId"`
  249. }
  250. func checkoutContent(oldContent, reqContent string) (isUpdate bool) {
  251. defer func() {
  252. if utils.MD5(oldContent) != utils.MD5(reqContent) {
  253. isUpdate = true
  254. }
  255. }()
  256. var oldContentInfo, reqContentInfo ContentStruct
  257. err := json.Unmarshal([]byte(oldContent), &oldContentInfo)
  258. if err != nil {
  259. fmt.Println("old json.Unmarshal err:", err)
  260. return
  261. }
  262. oldContentInfoByte, err := json.Marshal(oldContentInfo)
  263. if err != nil {
  264. fmt.Println("old json.Marshal err:", err)
  265. return
  266. }
  267. oldContent = string(oldContentInfoByte)
  268. err = json.Unmarshal([]byte(reqContent), &reqContentInfo)
  269. if err != nil {
  270. fmt.Println("req json.Unmarshal err:", err)
  271. return
  272. }
  273. reqContentInfoByte, err := json.Marshal(reqContentInfo)
  274. if err != nil {
  275. fmt.Println("req json.Marshal err:", err)
  276. return
  277. }
  278. reqContent = string(reqContentInfoByte)
  279. return
  280. }
  281. func sandboxClassifyHaveChild(allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) (childs []*sandbox.SandboxClassifyItems, yes bool) {
  282. for _, v := range allNode {
  283. if v.ParentId == node.SandboxClassifyId {
  284. childs = append(childs, v)
  285. }
  286. }
  287. if len(childs) > 0 {
  288. yes = true
  289. }
  290. return
  291. }
  292. func SandboxClassifyItemsMakeTree(sysUser *system.Admin, allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) {
  293. childs, _ := sandboxClassifyHaveChild(allNode, node) //判断节点是否有子节点并返回
  294. if len(childs) > 0 {
  295. node.Children = append(node.Children, childs[0:]...) //添加子节点
  296. for _, v := range childs { //查询子节点的子节点,并添加到子节点
  297. _, has := sandboxClassifyHaveChild(allNode, v)
  298. if has {
  299. SandboxClassifyItemsMakeTree(sysUser, allNode, v) //递归添加节点
  300. } else {
  301. childrenArr := make([]*sandbox.SandboxClassifyItems, 0)
  302. v.Children = childrenArr
  303. }
  304. }
  305. } else {
  306. childrenArr := make([]*sandbox.SandboxClassifyItems, 0)
  307. node.Children = childrenArr
  308. }
  309. }
  310. func GetSandboxClassifyListForMe(adminInfo system.Admin, resp *sandbox.SandboxClassifyListResp, sandboxClassifyId int) (errMsg string, err error) {
  311. rootList, err := sandbox.GetSandboxClassifyByParentId(sandboxClassifyId)
  312. if err != nil && !utils.IsErrNoRow(err) {
  313. errMsg = "获取失败"
  314. return
  315. }
  316. classifyAll, err := sandbox.GetSandboxClassifyByParentId(sandboxClassifyId)
  317. if err != nil && !utils.IsErrNoRow(err) {
  318. errMsg = "获取失败"
  319. return
  320. }
  321. sandboxAll, err := sandbox.GetSandboxInfoByAdminId(adminInfo.AdminId)
  322. if err != nil && !utils.IsErrNoRow(err) {
  323. errMsg = "获取失败"
  324. return
  325. }
  326. sandListMap := make(map[int][]*sandbox.SandboxClassifyItems)
  327. for _, v := range sandboxAll {
  328. if _, ok := sandListMap[v.SandboxClassifyId]; !ok {
  329. list := make([]*sandbox.SandboxClassifyItems, 0)
  330. list = append(list, v)
  331. sandListMap[v.SandboxClassifyId] = list
  332. } else {
  333. sandListMap[v.SandboxClassifyId] = append(sandListMap[v.SandboxClassifyId], v)
  334. }
  335. }
  336. nodeAll := make([]*sandbox.SandboxClassifyItems, 0)
  337. for k := range rootList {
  338. rootNode := rootList[k]
  339. SandboxClassifyItemsMakeTree(&adminInfo, classifyAll, rootNode)
  340. nodeAll = append(nodeAll, rootNode)
  341. }
  342. newAll := SandboxItemsMakeTree(nodeAll, sandListMap, sandboxClassifyId)
  343. resp.AllNodes = newAll
  344. return
  345. }
  346. func HandleNoPermissionSandbox(allNodes []*sandbox.SandboxClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*sandbox.SandboxClassifyItems) {
  347. newAllNodes = make([]*sandbox.SandboxClassifyItems, 0)
  348. for _, node := range allNodes {
  349. tmpNodeInfo := *node
  350. tmpNodeList := make([]*sandbox.SandboxClassifyItems, 0)
  351. if node.Children != nil {
  352. for _, chartList := range node.Children {
  353. tmpInfo := *chartList
  354. tmpList := make([]*sandbox.SandboxClassifyItems, 0)
  355. if chartList.Children != nil {
  356. for _, chartInfo := range chartList.Children {
  357. thirdInfo := *chartInfo
  358. thirdList := make([]*sandbox.SandboxClassifyItems, 0)
  359. if _, ok := noPermissionChartIdMap[chartInfo.SandboxId]; ok {
  360. continue
  361. }
  362. tmpList = append(tmpList, chartInfo)
  363. if chartInfo.Children != nil {
  364. for _, thirdChart := range chartInfo.Children {
  365. if _, ok := noPermissionChartIdMap[chartInfo.SandboxId]; ok {
  366. continue
  367. }
  368. thirdList = append(thirdList, thirdChart)
  369. }
  370. }
  371. thirdInfo.Children = thirdList
  372. tmpList = append(tmpList, &thirdInfo)
  373. }
  374. }
  375. tmpInfo.Children = tmpList
  376. tmpNodeList = append(tmpNodeList, &tmpInfo)
  377. }
  378. }
  379. tmpNodeInfo.Children = tmpNodeList
  380. newAllNodes = append(newAllNodes, &tmpNodeInfo)
  381. }
  382. return
  383. }
  384. func AddSandboxV2(req request.AddAndEditSandboxV2, opUserId int, opUserName string) (resp *sandbox.SandboxSaveResp, err error) {
  385. resp = new(sandbox.SandboxSaveResp)
  386. sandboxInfo := &sandbox.Sandbox{
  387. Name: utils.TrimStr(req.Name),
  388. Code: GenerateCode(),
  389. Content: req.Content,
  390. MindmapData: req.MindmapData,
  391. PicUrl: utils.TrimStr(req.PicUrl),
  392. SysUserId: opUserId,
  393. SysUserName: opUserName,
  394. IsDelete: 0,
  395. ModifyTime: time.Now(),
  396. CreateTime: time.Now(),
  397. SandboxClassifyId: req.SandboxClassifyId,
  398. Sort: 0,
  399. Style: req.Style,
  400. }
  401. err = sandbox.AddSandbox(sandboxInfo)
  402. if err != nil {
  403. return
  404. }
  405. resp.Sandbox = sandboxInfo
  406. return
  407. }
  408. func SandboxItemsMakeTree(allNode []*sandbox.SandboxClassifyItems, sandListMap map[int][]*sandbox.SandboxClassifyItems, sandboxClassifyId int) (nodeAll []*sandbox.SandboxClassifyItems) {
  409. for k := range allNode {
  410. if len(allNode[k].Children) > 0 {
  411. SandboxItemsMakeTree(allNode[k].Children, sandListMap, sandboxClassifyId)
  412. allNode = append(allNode, sandListMap[allNode[k].ParentId]...)
  413. nodeAll = allNode
  414. } else if k == len(allNode)-1 {
  415. allNode = append(allNode, sandListMap[allNode[k].ParentId]...)
  416. nodeAll = allNode
  417. }
  418. }
  419. if len(allNode) == 0 {
  420. nodeAll = append(nodeAll, sandListMap[sandboxClassifyId]...)
  421. }
  422. return
  423. }
  424. func SandboxClassifyHaveChild(allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) (childs []*sandbox.SandboxClassifyItems, yes bool) {
  425. for _, v := range allNode {
  426. if v.ParentId == node.SandboxClassifyId {
  427. childs = append(childs, v)
  428. }
  429. }
  430. if len(childs) > 0 {
  431. yes = true
  432. }
  433. return
  434. }
  435. func SandboxClassifyItemsMakeTreeV2(sysUser *system.Admin, allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) {
  436. childs, _ := sandboxClassifyHaveChildV2(allNode, node) //判断节点是否有子节点并返回
  437. if len(childs) > 0 {
  438. node.Children = append(node.Children, childs[0:]...) //添加子节点
  439. for _, v := range childs { //查询子节点的子节点,并添加到子节点
  440. _, has := sandboxClassifyHaveChildV2(allNode, v)
  441. if has {
  442. SandboxClassifyItemsMakeTreeV2(sysUser, allNode, v) //递归添加节点
  443. } else {
  444. }
  445. }
  446. } else {
  447. }
  448. }
  449. func sandboxClassifyHaveChildV2(allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) (childs []*sandbox.SandboxClassifyItems, yes bool) {
  450. for _, v := range allNode {
  451. if v.ParentId == node.SandboxClassifyId && node.SandboxId == 0 {
  452. childs = append(childs, v)
  453. }
  454. }
  455. if len(childs) > 0 {
  456. yes = true
  457. }
  458. return
  459. }
  460. func GetSandBoxEdbIdsByContent(content string) (edbInfoIds []int, err error) {
  461. var contentInfo sandbox.ContentDataStruct
  462. err = json.Unmarshal([]byte(content), &contentInfo)
  463. if err != nil {
  464. err = fmt.Errorf("json.Unmarshal err:%s", err.Error())
  465. return
  466. }
  467. for _, node := range contentInfo.Cells {
  468. if node.Data == nil {
  469. continue
  470. }
  471. for _, v := range node.Data.LinkData {
  472. if v.Type == 1 {
  473. edbInfoIds = append(edbInfoIds, v.Id)
  474. }
  475. }
  476. }
  477. return
  478. }
  479. func ReplaceEdbInSandbox(oldEdbInfoId, newEdbInfoId int) (err error) {
  480. updateTotal := 0
  481. logMsg := ""
  482. defer func() {
  483. if err != nil {
  484. go alarm_msg.SendAlarmMsg("替换沙盘中的指标记录失败提醒,errmsg:"+err.Error(), 3)
  485. }
  486. if logMsg != "" {
  487. utils.FileLog.Info(fmt.Sprintf("替换ETA逻辑的指标记录,替换总数:%d,旧的指标id:%d,新的指标id:%d;%s", updateTotal, oldEdbInfoId, newEdbInfoId, logMsg))
  488. }
  489. }()
  490. total, err := sandbox.GetSandboxListCountByCondition("", []interface{}{})
  491. if err != nil {
  492. err = fmt.Errorf("查询沙盘总数失败 Err:%s", err)
  493. return
  494. }
  495. totalPage := (total + 99) / 100 // 使用整数除法,并添加一页以防有余数
  496. updateSandBox := make([]sandbox.Sandbox, 0)
  497. for i := 0; i < totalPage; i += 1 {
  498. startSize := i * 100
  499. list, e := sandbox.GetSandboxListByCondition("", []interface{}{}, startSize, 100)
  500. if e != nil {
  501. err = fmt.Errorf("查询沙盘列表失败 Err:%s", e)
  502. return
  503. }
  504. for _, v := range list {
  505. sandOldEdbId := fmt.Sprintf(`"RId":"1-%d","Id":%d,`, oldEdbInfoId, oldEdbInfoId)
  506. if strings.Contains(v.Content, sandOldEdbId) {
  507. sandNewEdbId := fmt.Sprintf(`"RId":"1-%d","Id":%d,`, newEdbInfoId, newEdbInfoId)
  508. v.Sandbox.Content = strings.ReplaceAll(v.Content, sandOldEdbId, sandNewEdbId)
  509. updateSandBox = append(updateSandBox, v.Sandbox)
  510. logMsg += `涉及到的逻辑id:` + strconv.Itoa(v.Sandbox.SandboxId) + ";"
  511. if len(updateSandBox) > 100 {
  512. err = sandbox.UpdateSandboxContent(updateSandBox)
  513. if err != nil {
  514. err = fmt.Errorf("更新沙盘表失败 Err:%s", err)
  515. return
  516. }
  517. updateTotal += len(updateSandBox)
  518. updateSandBox = make([]sandbox.Sandbox, 0)
  519. }
  520. }
  521. }
  522. }
  523. if len(updateSandBox) > 0 {
  524. err = sandbox.UpdateSandboxContent(updateSandBox)
  525. if err != nil {
  526. err = fmt.Errorf("更新沙盘表失败 Err:%s", err)
  527. return
  528. }
  529. updateTotal += len(updateSandBox)
  530. }
  531. return
  532. }
  533. func GetSandBoxParentIds(classifyId int, classifymap map[int]*sandbox.SandboxClassifyItems, parentIds *[]int) {
  534. if item, ok := classifymap[classifyId]; ok {
  535. if item.ParentId == 0 {
  536. return
  537. }
  538. *parentIds = append(*parentIds, item.ParentId)
  539. GetSandBoxParentIds(item.ParentId, classifymap, parentIds)
  540. }
  541. }
  542. func GetSandBoxClassifyChildIds(classifyId int, classifymap map[int]*sandbox.SandboxClassifyItems, childIds *[]int) {
  543. for _, item := range classifymap {
  544. if item.ParentId == classifyId {
  545. *childIds = append(*childIds, item.SandboxClassifyId)
  546. GetSandBoxClassifyChildIds(item.SandboxClassifyId, classifymap, childIds)
  547. }
  548. }
  549. }