token_bind.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "sort"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "github.com/jinzhu/gorm"
  10. "go-common/app/admin/main/aegis/model"
  11. "go-common/app/admin/main/aegis/model/net"
  12. "go-common/library/ecode"
  13. "go-common/library/log"
  14. "go-common/library/xstr"
  15. )
  16. func (s *Service) checkBindToken(c context.Context, tokenID []int64) (tokenMap map[string]*net.Token, err error, msg string) {
  17. var (
  18. tokens []*net.Token
  19. )
  20. tokenMap = map[string]*net.Token{}
  21. if len(tokenID) == 0 {
  22. return
  23. }
  24. if tokens, err = s.gorm.Tokens(c, tokenID); err != nil {
  25. log.Error("checkBindToken s.gorm.Tokens error(%v)", err)
  26. return
  27. }
  28. for _, tk := range tokens {
  29. if !tk.IsAssign() {
  30. err = ecode.AegisTokenNotAssign
  31. msg = fmt.Sprintf(ecode.AegisTokenNotAssign.Message(), tk.ChName)
  32. return
  33. }
  34. id := strconv.FormatInt(tk.ID, 10)
  35. tokenMap[id] = tk
  36. }
  37. if len(tokenID) == len(tokens) {
  38. return
  39. }
  40. for _, id := range tokenID {
  41. if _, exist := tokenMap[strconv.FormatInt(id, 10)]; !exist {
  42. err = ecode.AegisTokenNotFound
  43. msg = fmt.Sprintf("id=%d的令牌 %s", id, ecode.AegisTokenNotAssign.Message())
  44. return
  45. }
  46. }
  47. return
  48. }
  49. func (s *Service) fetchOldBindAndLog(c context.Context, elementID int64, tp []int8) (all map[int64]*net.TokenBind, availableLog []string, err error) {
  50. var (
  51. oldBindMap map[int64][]*net.TokenBind
  52. oldBindToken map[int64][]*net.Token
  53. )
  54. all = map[int64]*net.TokenBind{}
  55. availableLog = []string{}
  56. if oldBindMap, err = s.gorm.TokenBindByElement(c, []int64{elementID}, tp, false); err != nil {
  57. log.Error("fetchOldBindAndLog s.gorm.TokenBindByElement error(%v)", err)
  58. return
  59. }
  60. oldBindAvailable := []*net.TokenBind{}
  61. allBindMap := map[int64]*net.TokenBind{}
  62. for _, item := range oldBindMap[elementID] {
  63. allBindMap[item.ID] = item
  64. oldBindAvailable = append(oldBindAvailable, item)
  65. }
  66. if oldBindToken, err = s.bindTokens(c, oldBindAvailable); err != nil {
  67. log.Error("fetchOldBindAndLog s.bindTokens error(%v)", err)
  68. return
  69. }
  70. for bindID, items := range oldBindToken {
  71. sub := []string{}
  72. for _, item := range items {
  73. sub = append(sub, item.FormatLog())
  74. }
  75. chname := ""
  76. tp := int8(0)
  77. if allBindMap[bindID] != nil {
  78. chname = allBindMap[bindID].ChName
  79. tp = allBindMap[bindID].Type
  80. }
  81. availableLog = append(availableLog, fmt.Sprintf(net.BindLogTemp, chname, tp, strings.Join(sub, ",")))
  82. }
  83. all = allBindMap
  84. return
  85. }
  86. func (s *Service) compareFlowBind(c context.Context, tx *gorm.DB, flowID int64, tokenID []int64, isUpdate bool) (diff string, changed []int64, err error, msg string) {
  87. var (
  88. tokenMap map[string]*net.Token
  89. oldBindAll = map[int64]*net.TokenBind{}
  90. newFormatLog = []string{}
  91. oldFormatLog = []string{}
  92. disable = time.Now()
  93. recovered = net.Recovered
  94. existTokenID = map[string]int{}
  95. )
  96. log.Info("compareFlowBind start flow(%d) tokenid(%+v) isUpdate(%v)", flowID, tokenID, isUpdate)
  97. //新绑定查询,检查是否为赋值语句token & token是否存在
  98. if len(tokenID) > 0 {
  99. if tokenMap, err, msg = s.checkBindToken(c, tokenID); err != nil {
  100. log.Error("compareFlowBind s.checkBindToken error(%v)", err)
  101. return
  102. }
  103. for _, item := range tokenMap {
  104. newFormatLog = append(newFormatLog, fmt.Sprintf(net.BindLogTemp, item.ChName, item.Type, item.FormatLog()))
  105. }
  106. }
  107. //获取现有所有绑定和可用绑定
  108. if isUpdate {
  109. if oldBindAll, oldFormatLog, err = s.fetchOldBindAndLog(c, flowID, []int8{net.BindTypeFlow}); err != nil {
  110. log.Error("compareFlowBind s.fetchOldBindAndLog error(%v)", err)
  111. return
  112. }
  113. }
  114. if len(tokenMap) == 0 && len(oldBindAll) == 0 {
  115. return
  116. }
  117. //从旧的中过滤新的
  118. for _, item := range oldBindAll {
  119. if _, exist := tokenMap[item.TokenID]; exist {
  120. existTokenID[item.TokenID] = 1
  121. if item.IsAvailable() {
  122. continue
  123. }
  124. item.DisableTime = recovered
  125. } else {
  126. item.DisableTime = disable
  127. }
  128. if err = s.gorm.UpdateFields(c, tx, net.TableTokenBind, item.ID, map[string]interface{}{"disable_time": item.DisableTime}); err != nil {
  129. log.Error("compareFlowBind s.gorm.UpdateFields error(%v)", err)
  130. return
  131. }
  132. changed = append(changed, item.ID)
  133. }
  134. //从新的中过滤旧的
  135. for tokenID, tk := range tokenMap {
  136. if _, exist := existTokenID[tokenID]; exist {
  137. continue
  138. }
  139. nw := &net.TokenBind{TokenID: tokenID, ChName: tk.ChName, ElementID: flowID, Type: net.BindTypeFlow}
  140. if err = s.gorm.AddItem(c, tx, nw); err != nil {
  141. log.Error("compareFlowBind s.gorm.AddItem error(%v)", err)
  142. return
  143. }
  144. changed = append(changed, nw.ID)
  145. }
  146. if len(changed) > 0 && (len(newFormatLog) > 0 || len(oldFormatLog) > 0) {
  147. diff = model.LogFieldTemp(model.LogFieldTokenID, strings.Join(newFormatLog, ";"), strings.Join(oldFormatLog, ";"), isUpdate)
  148. }
  149. log.Info("compareFlowBind end flow(%d) tokenid(%+v) isupdate(%v) diff(%s)", flowID, tokenID, isUpdate, diff)
  150. return
  151. }
  152. func (s *Service) compareTranBind(c context.Context, tx *gorm.DB, tranID int64, binds []*net.TokenBindParam, isUpdate bool) (diff string, changed []int64, err error, msg string) {
  153. var (
  154. relatedTokenID []int64
  155. tokenID = []int64{}
  156. existBindParam = map[int64]*net.TokenBindParam{}
  157. tokenMap map[string]*net.Token
  158. oldBindAll = map[int64]*net.TokenBind{}
  159. newFormatLog = []string{}
  160. oldFormatLog []string
  161. disable = time.Now()
  162. recovered = net.Recovered
  163. )
  164. log.Info("compareTranBind start transition(%d) binds(%+v) isUpdate(%v)", tranID, binds, isUpdate)
  165. //现有全部绑定关系和可用绑定
  166. if isUpdate {
  167. if oldBindAll, oldFormatLog, err = s.fetchOldBindAndLog(c, tranID, net.BindTranType); err != nil {
  168. log.Error("compareTranBind s.fetchOldBindAndLog error(%v)", err)
  169. return
  170. }
  171. }
  172. //新绑定处理
  173. for _, item := range binds {
  174. //是否已存在
  175. if item.ID > 0 && oldBindAll[item.ID] == nil {
  176. log.Error("compareTranBind binds(%+v) not found", item)
  177. err = ecode.RequestErr
  178. return
  179. }
  180. if item.ID > 0 {
  181. existBindParam[item.ID] = item
  182. }
  183. //tokenid排序重组
  184. if relatedTokenID, err = xstr.SplitInts(item.TokenID); err != nil {
  185. log.Error("compareTranBind xstr.SplitInts(%+v) error(%v)", item, err)
  186. return
  187. }
  188. if len(relatedTokenID) == 0 {
  189. log.Error("compareTranBind bind(%+v) tokenid empty ", item)
  190. err = ecode.RequestErr
  191. return
  192. }
  193. sort.Sort(net.Int64Slice(relatedTokenID))
  194. item.TokenID = xstr.JoinInts(relatedTokenID)
  195. tokenID = append(tokenID, relatedTokenID...)
  196. }
  197. //检查是否为赋值语句token & token是否存在
  198. if len(tokenID) > 0 {
  199. if tokenMap, err, msg = s.checkBindToken(c, tokenID); err != nil {
  200. log.Error("compareTranBind s.checkBindToken error(%v)", err)
  201. return
  202. }
  203. }
  204. for _, item := range binds {
  205. //前端没传中文名则自行组合
  206. nwLog := []string{}
  207. chname := item.ChName
  208. tkname := map[string]int64{}
  209. for _, tid := range strings.Split(item.TokenID, ",") {
  210. tk := tokenMap[tid]
  211. if tk == nil {
  212. continue
  213. }
  214. //token_name级别的过滤
  215. if tkname[tk.Name] > 0 {
  216. log.Error("compareTranBind bind(%+v) duplicated with token name(%s)", item, tk.Name)
  217. err = ecode.RequestErr
  218. return
  219. }
  220. tkname[tk.Name] = tk.ID
  221. if item.ChName == "" {
  222. chname = chname + tokenMap[tid].ChName
  223. }
  224. nwLog = append(nwLog, tokenMap[tid].FormatLog())
  225. }
  226. chnameMerge := []rune(chname)
  227. last := len(chnameMerge)
  228. if last > 16 {
  229. last = 16
  230. }
  231. item.ChName = string(chnameMerge[:last])
  232. newFormatLog = append(newFormatLog, fmt.Sprintf(net.BindLogTemp, item.ChName, item.Type, strings.Join(nwLog, ",")))
  233. }
  234. //从旧的中过滤新的
  235. for id, item := range oldBindAll {
  236. updateField := map[string]interface{}{}
  237. if newParam, exist := existBindParam[id]; exist {
  238. if !item.IsAvailable() {
  239. item.DisableTime = recovered
  240. updateField["disable_time"] = recovered
  241. }
  242. if item.TokenID != newParam.TokenID {
  243. item.TokenID = newParam.TokenID
  244. updateField["token_id"] = newParam.TokenID
  245. }
  246. if newParam.ChName != "" && newParam.ChName != item.ChName {
  247. item.ChName = newParam.ChName
  248. updateField["ch_name"] = newParam.ChName
  249. }
  250. if newParam.Type != item.Type {
  251. item.Type = newParam.Type
  252. updateField["type"] = newParam.Type
  253. }
  254. } else if item.IsAvailable() {
  255. item.DisableTime = disable
  256. updateField["disable_time"] = disable
  257. } else {
  258. continue
  259. }
  260. if len(updateField) == 0 {
  261. continue
  262. }
  263. if err = s.gorm.UpdateFields(c, tx, net.TableTokenBind, item.ID, updateField); err != nil {
  264. log.Error("compareTranBind s.gorm.UpdateFields error(%v)", err)
  265. return
  266. }
  267. changed = append(changed, item.ID)
  268. }
  269. //从新的中过滤旧的
  270. for _, newParam := range binds {
  271. if newParam.ID > 0 && oldBindAll[newParam.ID] != nil {
  272. continue
  273. }
  274. nw := &net.TokenBind{TokenID: newParam.TokenID, ChName: newParam.ChName, ElementID: tranID, Type: newParam.Type}
  275. if err = s.gorm.AddItem(c, tx, nw); err != nil {
  276. log.Error("compareTranBind s.gorm.AddItem error(%v)", err)
  277. return
  278. }
  279. changed = append(changed, nw.ID)
  280. }
  281. if len(changed) > 0 && (len(newFormatLog) > 0 || len(oldFormatLog) > 0) {
  282. diff = model.LogFieldTemp(model.LogFieldTokenID, strings.Join(newFormatLog, ";"), strings.Join(oldFormatLog, ";"), isUpdate)
  283. }
  284. log.Info("compareTranBind end transition(%d) binds(%+v) isupdate(%v) diff(%s)", tranID, binds, isUpdate, diff)
  285. return
  286. }
  287. func (s *Service) bindTokens(c context.Context, binds []*net.TokenBind) (result map[int64][]*net.Token, err error) {
  288. var (
  289. tokenIDSlice []int64
  290. tokens []*net.Token
  291. )
  292. result = map[int64][]*net.Token{}
  293. if len(binds) == 0 {
  294. return
  295. }
  296. tids := []int64{}
  297. bindTokenMap := map[int64][]int64{}
  298. for _, item := range binds {
  299. if tokenIDSlice, err = xstr.SplitInts(item.TokenID); err != nil {
  300. log.Error("tokenBindDetail xstr.SplitInts(%s) error(%v)", item.TokenID, err)
  301. return
  302. }
  303. bindTokenMap[item.ID] = tokenIDSlice
  304. if len(tokenIDSlice) == 0 {
  305. continue
  306. }
  307. tids = append(tids, tokenIDSlice...)
  308. }
  309. if len(tids) == 0 {
  310. return
  311. }
  312. if tokens, err = s.gorm.Tokens(c, tids); err != nil {
  313. log.Error("tokenBindDetail s.gorm.Tokens(%v) error(%v)", tids, err)
  314. return
  315. }
  316. if len(tokens) == 0 {
  317. return
  318. }
  319. tokenMap := map[int64]*net.Token{}
  320. for _, item := range tokens {
  321. tokenMap[item.ID] = item
  322. }
  323. for bindID, tidList := range bindTokenMap {
  324. result[bindID] = []*net.Token{}
  325. for _, id := range tidList {
  326. if tokenMap[id] == nil {
  327. continue
  328. }
  329. result[bindID] = append(result[bindID], tokenMap[id])
  330. }
  331. }
  332. return
  333. }
  334. //tokenBindDetail 一条绑定的详细信息,获取了token详情
  335. func (s *Service) tokenBindDetail(c context.Context, binds []*net.TokenBind) (result []*net.TokenBindDetail, err error) {
  336. var (
  337. tokenIDSlice []int64
  338. tokens []*net.Token
  339. )
  340. if len(binds) == 0 {
  341. return
  342. }
  343. details := make([]*net.TokenBindDetail, len(binds))
  344. //get tokens
  345. tids := []int64{}
  346. bindTokenMap := map[string][]int64{}
  347. for k, item := range binds {
  348. details[k] = &net.TokenBindDetail{
  349. ID: item.ID,
  350. Type: item.Type,
  351. ElementID: item.ElementID,
  352. TokenID: item.TokenID,
  353. ChName: item.ChName,
  354. DisableTime: item.DisableTime,
  355. Tokens: []*net.Token{},
  356. }
  357. if tokenIDSlice, err = xstr.SplitInts(item.TokenID); err != nil {
  358. log.Error("tokenBindDetail xstr.SplitInts(%s) error(%v)", item.TokenID, err)
  359. return
  360. } else if len(tokenIDSlice) == 0 {
  361. continue
  362. } else {
  363. tids = append(tids, tokenIDSlice...)
  364. }
  365. bindTokenMap[item.TokenID] = tokenIDSlice
  366. }
  367. if len(tids) == 0 {
  368. result = details
  369. return
  370. }
  371. if tokens, err = s.gorm.Tokens(c, tids); err == nil && len(tokens) == 0 {
  372. log.Error("tokenBindDetail s.gorm.Tokens(%v) not found", tids)
  373. result = details
  374. err = nil
  375. return
  376. }
  377. if err != nil {
  378. log.Error("TokenBindDetail find token error(%v) tids(%v)", err, tids)
  379. return
  380. }
  381. tokenMap := make(map[int64]*net.Token, len(tokens))
  382. for _, item := range tokens {
  383. tokenMap[item.ID] = item
  384. }
  385. //dispatch tokens to detail
  386. for _, item := range details {
  387. for _, id := range bindTokenMap[item.TokenID] {
  388. if tokenMap[id] != nil {
  389. item.Tokens = append(item.Tokens, tokenMap[id])
  390. }
  391. }
  392. }
  393. result = details
  394. return
  395. }