123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- package service
- import (
- "context"
- "fmt"
- "sort"
- "strconv"
- "strings"
- "time"
- "github.com/jinzhu/gorm"
- "go-common/app/admin/main/aegis/model"
- "go-common/app/admin/main/aegis/model/net"
- "go-common/library/ecode"
- "go-common/library/log"
- "go-common/library/xstr"
- )
- func (s *Service) checkBindToken(c context.Context, tokenID []int64) (tokenMap map[string]*net.Token, err error, msg string) {
- var (
- tokens []*net.Token
- )
- tokenMap = map[string]*net.Token{}
- if len(tokenID) == 0 {
- return
- }
- if tokens, err = s.gorm.Tokens(c, tokenID); err != nil {
- log.Error("checkBindToken s.gorm.Tokens error(%v)", err)
- return
- }
- for _, tk := range tokens {
- if !tk.IsAssign() {
- err = ecode.AegisTokenNotAssign
- msg = fmt.Sprintf(ecode.AegisTokenNotAssign.Message(), tk.ChName)
- return
- }
- id := strconv.FormatInt(tk.ID, 10)
- tokenMap[id] = tk
- }
- if len(tokenID) == len(tokens) {
- return
- }
- for _, id := range tokenID {
- if _, exist := tokenMap[strconv.FormatInt(id, 10)]; !exist {
- err = ecode.AegisTokenNotFound
- msg = fmt.Sprintf("id=%d的令牌 %s", id, ecode.AegisTokenNotAssign.Message())
- return
- }
- }
- return
- }
- func (s *Service) fetchOldBindAndLog(c context.Context, elementID int64, tp []int8) (all map[int64]*net.TokenBind, availableLog []string, err error) {
- var (
- oldBindMap map[int64][]*net.TokenBind
- oldBindToken map[int64][]*net.Token
- )
- all = map[int64]*net.TokenBind{}
- availableLog = []string{}
- if oldBindMap, err = s.gorm.TokenBindByElement(c, []int64{elementID}, tp, false); err != nil {
- log.Error("fetchOldBindAndLog s.gorm.TokenBindByElement error(%v)", err)
- return
- }
- oldBindAvailable := []*net.TokenBind{}
- allBindMap := map[int64]*net.TokenBind{}
- for _, item := range oldBindMap[elementID] {
- allBindMap[item.ID] = item
- oldBindAvailable = append(oldBindAvailable, item)
- }
- if oldBindToken, err = s.bindTokens(c, oldBindAvailable); err != nil {
- log.Error("fetchOldBindAndLog s.bindTokens error(%v)", err)
- return
- }
- for bindID, items := range oldBindToken {
- sub := []string{}
- for _, item := range items {
- sub = append(sub, item.FormatLog())
- }
- chname := ""
- tp := int8(0)
- if allBindMap[bindID] != nil {
- chname = allBindMap[bindID].ChName
- tp = allBindMap[bindID].Type
- }
- availableLog = append(availableLog, fmt.Sprintf(net.BindLogTemp, chname, tp, strings.Join(sub, ",")))
- }
- all = allBindMap
- return
- }
- func (s *Service) compareFlowBind(c context.Context, tx *gorm.DB, flowID int64, tokenID []int64, isUpdate bool) (diff string, changed []int64, err error, msg string) {
- var (
- tokenMap map[string]*net.Token
- oldBindAll = map[int64]*net.TokenBind{}
- newFormatLog = []string{}
- oldFormatLog = []string{}
- disable = time.Now()
- recovered = net.Recovered
- existTokenID = map[string]int{}
- )
- log.Info("compareFlowBind start flow(%d) tokenid(%+v) isUpdate(%v)", flowID, tokenID, isUpdate)
- //新绑定查询,检查是否为赋值语句token & token是否存在
- if len(tokenID) > 0 {
- if tokenMap, err, msg = s.checkBindToken(c, tokenID); err != nil {
- log.Error("compareFlowBind s.checkBindToken error(%v)", err)
- return
- }
- for _, item := range tokenMap {
- newFormatLog = append(newFormatLog, fmt.Sprintf(net.BindLogTemp, item.ChName, item.Type, item.FormatLog()))
- }
- }
- //获取现有所有绑定和可用绑定
- if isUpdate {
- if oldBindAll, oldFormatLog, err = s.fetchOldBindAndLog(c, flowID, []int8{net.BindTypeFlow}); err != nil {
- log.Error("compareFlowBind s.fetchOldBindAndLog error(%v)", err)
- return
- }
- }
- if len(tokenMap) == 0 && len(oldBindAll) == 0 {
- return
- }
- //从旧的中过滤新的
- for _, item := range oldBindAll {
- if _, exist := tokenMap[item.TokenID]; exist {
- existTokenID[item.TokenID] = 1
- if item.IsAvailable() {
- continue
- }
- item.DisableTime = recovered
- } else {
- item.DisableTime = disable
- }
- if err = s.gorm.UpdateFields(c, tx, net.TableTokenBind, item.ID, map[string]interface{}{"disable_time": item.DisableTime}); err != nil {
- log.Error("compareFlowBind s.gorm.UpdateFields error(%v)", err)
- return
- }
- changed = append(changed, item.ID)
- }
- //从新的中过滤旧的
- for tokenID, tk := range tokenMap {
- if _, exist := existTokenID[tokenID]; exist {
- continue
- }
- nw := &net.TokenBind{TokenID: tokenID, ChName: tk.ChName, ElementID: flowID, Type: net.BindTypeFlow}
- if err = s.gorm.AddItem(c, tx, nw); err != nil {
- log.Error("compareFlowBind s.gorm.AddItem error(%v)", err)
- return
- }
- changed = append(changed, nw.ID)
- }
- if len(changed) > 0 && (len(newFormatLog) > 0 || len(oldFormatLog) > 0) {
- diff = model.LogFieldTemp(model.LogFieldTokenID, strings.Join(newFormatLog, ";"), strings.Join(oldFormatLog, ";"), isUpdate)
- }
- log.Info("compareFlowBind end flow(%d) tokenid(%+v) isupdate(%v) diff(%s)", flowID, tokenID, isUpdate, diff)
- return
- }
- 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) {
- var (
- relatedTokenID []int64
- tokenID = []int64{}
- existBindParam = map[int64]*net.TokenBindParam{}
- tokenMap map[string]*net.Token
- oldBindAll = map[int64]*net.TokenBind{}
- newFormatLog = []string{}
- oldFormatLog []string
- disable = time.Now()
- recovered = net.Recovered
- )
- log.Info("compareTranBind start transition(%d) binds(%+v) isUpdate(%v)", tranID, binds, isUpdate)
- //现有全部绑定关系和可用绑定
- if isUpdate {
- if oldBindAll, oldFormatLog, err = s.fetchOldBindAndLog(c, tranID, net.BindTranType); err != nil {
- log.Error("compareTranBind s.fetchOldBindAndLog error(%v)", err)
- return
- }
- }
- //新绑定处理
- for _, item := range binds {
- //是否已存在
- if item.ID > 0 && oldBindAll[item.ID] == nil {
- log.Error("compareTranBind binds(%+v) not found", item)
- err = ecode.RequestErr
- return
- }
- if item.ID > 0 {
- existBindParam[item.ID] = item
- }
- //tokenid排序重组
- if relatedTokenID, err = xstr.SplitInts(item.TokenID); err != nil {
- log.Error("compareTranBind xstr.SplitInts(%+v) error(%v)", item, err)
- return
- }
- if len(relatedTokenID) == 0 {
- log.Error("compareTranBind bind(%+v) tokenid empty ", item)
- err = ecode.RequestErr
- return
- }
- sort.Sort(net.Int64Slice(relatedTokenID))
- item.TokenID = xstr.JoinInts(relatedTokenID)
- tokenID = append(tokenID, relatedTokenID...)
- }
- //检查是否为赋值语句token & token是否存在
- if len(tokenID) > 0 {
- if tokenMap, err, msg = s.checkBindToken(c, tokenID); err != nil {
- log.Error("compareTranBind s.checkBindToken error(%v)", err)
- return
- }
- }
- for _, item := range binds {
- //前端没传中文名则自行组合
- nwLog := []string{}
- chname := item.ChName
- tkname := map[string]int64{}
- for _, tid := range strings.Split(item.TokenID, ",") {
- tk := tokenMap[tid]
- if tk == nil {
- continue
- }
- //token_name级别的过滤
- if tkname[tk.Name] > 0 {
- log.Error("compareTranBind bind(%+v) duplicated with token name(%s)", item, tk.Name)
- err = ecode.RequestErr
- return
- }
- tkname[tk.Name] = tk.ID
- if item.ChName == "" {
- chname = chname + tokenMap[tid].ChName
- }
- nwLog = append(nwLog, tokenMap[tid].FormatLog())
- }
- chnameMerge := []rune(chname)
- last := len(chnameMerge)
- if last > 16 {
- last = 16
- }
- item.ChName = string(chnameMerge[:last])
- newFormatLog = append(newFormatLog, fmt.Sprintf(net.BindLogTemp, item.ChName, item.Type, strings.Join(nwLog, ",")))
- }
- //从旧的中过滤新的
- for id, item := range oldBindAll {
- updateField := map[string]interface{}{}
- if newParam, exist := existBindParam[id]; exist {
- if !item.IsAvailable() {
- item.DisableTime = recovered
- updateField["disable_time"] = recovered
- }
- if item.TokenID != newParam.TokenID {
- item.TokenID = newParam.TokenID
- updateField["token_id"] = newParam.TokenID
- }
- if newParam.ChName != "" && newParam.ChName != item.ChName {
- item.ChName = newParam.ChName
- updateField["ch_name"] = newParam.ChName
- }
- if newParam.Type != item.Type {
- item.Type = newParam.Type
- updateField["type"] = newParam.Type
- }
- } else if item.IsAvailable() {
- item.DisableTime = disable
- updateField["disable_time"] = disable
- } else {
- continue
- }
- if len(updateField) == 0 {
- continue
- }
- if err = s.gorm.UpdateFields(c, tx, net.TableTokenBind, item.ID, updateField); err != nil {
- log.Error("compareTranBind s.gorm.UpdateFields error(%v)", err)
- return
- }
- changed = append(changed, item.ID)
- }
- //从新的中过滤旧的
- for _, newParam := range binds {
- if newParam.ID > 0 && oldBindAll[newParam.ID] != nil {
- continue
- }
- nw := &net.TokenBind{TokenID: newParam.TokenID, ChName: newParam.ChName, ElementID: tranID, Type: newParam.Type}
- if err = s.gorm.AddItem(c, tx, nw); err != nil {
- log.Error("compareTranBind s.gorm.AddItem error(%v)", err)
- return
- }
- changed = append(changed, nw.ID)
- }
- if len(changed) > 0 && (len(newFormatLog) > 0 || len(oldFormatLog) > 0) {
- diff = model.LogFieldTemp(model.LogFieldTokenID, strings.Join(newFormatLog, ";"), strings.Join(oldFormatLog, ";"), isUpdate)
- }
- log.Info("compareTranBind end transition(%d) binds(%+v) isupdate(%v) diff(%s)", tranID, binds, isUpdate, diff)
- return
- }
- func (s *Service) bindTokens(c context.Context, binds []*net.TokenBind) (result map[int64][]*net.Token, err error) {
- var (
- tokenIDSlice []int64
- tokens []*net.Token
- )
- result = map[int64][]*net.Token{}
- if len(binds) == 0 {
- return
- }
- tids := []int64{}
- bindTokenMap := map[int64][]int64{}
- for _, item := range binds {
- if tokenIDSlice, err = xstr.SplitInts(item.TokenID); err != nil {
- log.Error("tokenBindDetail xstr.SplitInts(%s) error(%v)", item.TokenID, err)
- return
- }
- bindTokenMap[item.ID] = tokenIDSlice
- if len(tokenIDSlice) == 0 {
- continue
- }
- tids = append(tids, tokenIDSlice...)
- }
- if len(tids) == 0 {
- return
- }
- if tokens, err = s.gorm.Tokens(c, tids); err != nil {
- log.Error("tokenBindDetail s.gorm.Tokens(%v) error(%v)", tids, err)
- return
- }
- if len(tokens) == 0 {
- return
- }
- tokenMap := map[int64]*net.Token{}
- for _, item := range tokens {
- tokenMap[item.ID] = item
- }
- for bindID, tidList := range bindTokenMap {
- result[bindID] = []*net.Token{}
- for _, id := range tidList {
- if tokenMap[id] == nil {
- continue
- }
- result[bindID] = append(result[bindID], tokenMap[id])
- }
- }
- return
- }
- //tokenBindDetail 一条绑定的详细信息,获取了token详情
- func (s *Service) tokenBindDetail(c context.Context, binds []*net.TokenBind) (result []*net.TokenBindDetail, err error) {
- var (
- tokenIDSlice []int64
- tokens []*net.Token
- )
- if len(binds) == 0 {
- return
- }
- details := make([]*net.TokenBindDetail, len(binds))
- //get tokens
- tids := []int64{}
- bindTokenMap := map[string][]int64{}
- for k, item := range binds {
- details[k] = &net.TokenBindDetail{
- ID: item.ID,
- Type: item.Type,
- ElementID: item.ElementID,
- TokenID: item.TokenID,
- ChName: item.ChName,
- DisableTime: item.DisableTime,
- Tokens: []*net.Token{},
- }
- if tokenIDSlice, err = xstr.SplitInts(item.TokenID); err != nil {
- log.Error("tokenBindDetail xstr.SplitInts(%s) error(%v)", item.TokenID, err)
- return
- } else if len(tokenIDSlice) == 0 {
- continue
- } else {
- tids = append(tids, tokenIDSlice...)
- }
- bindTokenMap[item.TokenID] = tokenIDSlice
- }
- if len(tids) == 0 {
- result = details
- return
- }
- if tokens, err = s.gorm.Tokens(c, tids); err == nil && len(tokens) == 0 {
- log.Error("tokenBindDetail s.gorm.Tokens(%v) not found", tids)
- result = details
- err = nil
- return
- }
- if err != nil {
- log.Error("TokenBindDetail find token error(%v) tids(%v)", err, tids)
- return
- }
- tokenMap := make(map[int64]*net.Token, len(tokens))
- for _, item := range tokens {
- tokenMap[item.ID] = item
- }
- //dispatch tokens to detail
- for _, item := range details {
- for _, id := range bindTokenMap[item.TokenID] {
- if tokenMap[id] != nil {
- item.Tokens = append(item.Tokens, tokenMap[id])
- }
- }
- }
- result = details
- return
- }
|