tools.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package v2
  2. import (
  3. "context"
  4. "encoding/json"
  5. "go-common/library/net/metadata"
  6. "sort"
  7. "strconv"
  8. )
  9. // Pair ...
  10. // 自定义map排序结构
  11. type Pair struct {
  12. Key int64
  13. Value int64
  14. }
  15. // Gray ...
  16. // 自定义灰度策略结构
  17. type Gray struct {
  18. Key string
  19. Value int
  20. }
  21. // GrayRule ...
  22. // 自定义灰度策略
  23. type GrayRule struct {
  24. Name string `json:"name"`
  25. Mark string `json:"mark"`
  26. Value string `json:"value"`
  27. }
  28. // PairList ...
  29. // 自定义灰度策略
  30. type PairList []Pair
  31. // GrayList ...
  32. // 自定义灰度策略
  33. type GrayList []Gray
  34. // Swap
  35. // 自定义排序
  36. func (p PairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  37. // Len
  38. // 自定义排序
  39. func (p PairList) Len() int { return len(p) }
  40. // Less
  41. // 自定义排序
  42. func (p PairList) Less(i, j int) bool { return p[i].Value > p[j].Value }
  43. // Swap
  44. // 自定义排序
  45. func (p GrayList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  46. // Len
  47. // 自定义排序
  48. func (p GrayList) Len() int { return len(p) }
  49. // Less
  50. // 自定义排序
  51. func (p GrayList) Less(i, j int) bool { return p[i].Value < p[j].Value }
  52. // SortMap ...
  53. // 自定义排序
  54. func SortMap(input map[int64]int64) (sorted PairList) {
  55. p := make(PairList, len(input))
  56. i := 0
  57. for k, v := range input {
  58. p[i] = Pair{k, v}
  59. i++
  60. }
  61. sort.Sort(p)
  62. sorted = p
  63. return
  64. }
  65. // SortMapByValue ...
  66. // 自定义排序
  67. func SortMapByValue(m map[string]int) GrayList {
  68. p := make(GrayList, len(m))
  69. i := 0
  70. for k, v := range m {
  71. p[i] = Gray{k, v}
  72. i++
  73. }
  74. sort.Sort(p)
  75. return p
  76. }
  77. // RoleMap ...
  78. // 兼容主站个人认证信息
  79. // 见 http://info.bilibili.co/pages/viewpage.action?pageId=8742464
  80. // 当前与客户端约定为, 0:个人 1:企业 -1:没有
  81. func RoleMap(role int8) (changeType int64) {
  82. switch role {
  83. case 0:
  84. {
  85. changeType = -1
  86. }
  87. case 1, 2:
  88. {
  89. changeType = 0
  90. }
  91. case 3, 4, 5, 6:
  92. {
  93. changeType = 1
  94. }
  95. default:
  96. {
  97. changeType = -1
  98. }
  99. }
  100. return
  101. }
  102. // RParseInt ...
  103. // 转int
  104. func RParseInt(inputStr string, defaultValue int64) (output int64) {
  105. if mid, err := strconv.ParseInt(inputStr, 10, 64); err == nil {
  106. output = mid
  107. } else {
  108. output = defaultValue
  109. }
  110. return
  111. }
  112. // App531ABTest ...
  113. // ABTest
  114. func (s *IndexService) App531ABTest(ctx context.Context, content string) (grayType int64) {
  115. if len(content) == 0 {
  116. grayType = 0
  117. return
  118. }
  119. resultMap := make(map[string]int64)
  120. resultMap["double_small_card"] = 0
  121. resultMap["card_not_auto_play"] = 1
  122. resultMap["card_auto_play"] = 2
  123. typeMap := make([]string, 0)
  124. mr := &[]GrayRule{}
  125. if err := json.Unmarshal([]byte(content), mr); err != nil {
  126. grayType = 0
  127. return
  128. }
  129. ruleArr := *mr
  130. scoreMap := make(map[string]int)
  131. for _, v := range ruleArr {
  132. scoreMap[v.Mark] = int(RParseInt(v.Value, 100))
  133. }
  134. sortedScore := SortMapByValue(scoreMap)
  135. scoreEnd := make([]int, 0)
  136. for _, v := range sortedScore {
  137. scoreEnd = append(scoreEnd, v.Value)
  138. typeMap = append(typeMap, v.Key)
  139. }
  140. score1 := scoreEnd[0]
  141. score2 := scoreEnd[0] + scoreEnd[1]
  142. score3 := 100
  143. section1 := make(map[int]bool)
  144. section2 := make(map[int]bool)
  145. section3 := make(map[int]bool)
  146. for section1Loop := 0; section1Loop < score1; section1Loop++ {
  147. section1[section1Loop] = true
  148. }
  149. for sectionLoop2 := score1; sectionLoop2 < score2; sectionLoop2++ {
  150. section2[sectionLoop2] = true
  151. }
  152. for sectionLoop3 := score2; sectionLoop3 < score3; sectionLoop3++ {
  153. section3[sectionLoop3] = true
  154. }
  155. mid := GetUIDFromHeader(ctx)
  156. result := int(mid % 100)
  157. if scoreEnd[0] != 0 {
  158. if _, exist := section1[result]; exist {
  159. grayType = resultMap[typeMap[0]]
  160. return
  161. }
  162. }
  163. if scoreEnd[1] != 0 {
  164. if _, exist := section2[result]; exist {
  165. grayType = resultMap[typeMap[1]]
  166. return
  167. }
  168. }
  169. if scoreEnd[2] != 0 {
  170. if _, exist := section3[result]; exist {
  171. grayType = resultMap[typeMap[2]]
  172. return
  173. }
  174. }
  175. grayType = 0
  176. return
  177. }
  178. // GetUIDFromHeader ...
  179. // 获取uid
  180. func GetUIDFromHeader(ctx context.Context) (uid int64) {
  181. midInterface, isUIDSet := metadata.Value(ctx, metadata.Mid).(int64) // 大多使用header里的mid解析, 框架已封装请求的header
  182. mid := int64(0)
  183. if isUIDSet {
  184. mid = midInterface
  185. }
  186. uid = mid
  187. return
  188. }