academy.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "reflect"
  6. "strings"
  7. "time"
  8. "go-common/app/admin/main/creative/model/academy"
  9. "go-common/app/interface/openplatform/article/model"
  10. "go-common/app/service/main/archive/api"
  11. "go-common/library/log"
  12. "github.com/jinzhu/gorm"
  13. )
  14. //Archive get one archive by rpc
  15. func (s *Service) Archive(c context.Context, aid int64) (res *api.Arc, err error) {
  16. if res, err = s.dao.Archive(c, aid); err != nil {
  17. log.Error("s.dao.Archive aid(%d)|err(%+v)", aid, err)
  18. }
  19. return
  20. }
  21. //Archives get archives by rpc
  22. func (s *Service) Archives(c context.Context, aids []int64) (res map[int64]*api.Arc, err error) {
  23. if res, err = s.dao.Archives(c, aids); err != nil {
  24. log.Error("s.dao.Archives aids(%d)|err(%+v)", aids, err)
  25. }
  26. return
  27. }
  28. //Articles get articles by rpc
  29. func (s *Service) Articles(c context.Context, aids []int64) (res map[int64]*model.Meta, err error) {
  30. if res, err = s.dao.ArticleMetas(c, aids); err != nil {
  31. log.Error("s.dao.ArticleMetas aids(%+v)|err(%+v)", aids, err)
  32. }
  33. return
  34. }
  35. //ArchivesWithES for es search
  36. func (s *Service) ArchivesWithES(c context.Context, aca *academy.EsParam) (res *academy.SearchResult, err error) {
  37. if res, err = s.dao.ArchivesWithES(c, aca); err != nil {
  38. log.Error("s.dao.ArchivesWithES aca(%+v)|err(%+v)", aca, err)
  39. }
  40. return
  41. }
  42. // Stats get archives stat.
  43. func (s *Service) Stats(c context.Context, aids []int64, ip string) (res map[int64]*api.Stat, err error) {
  44. if res, err = s.dao.Stats(c, aids, ip); err != nil {
  45. log.Error("s.dao.Archives aids(%d)|ip(%s)|err(%+v)", aids, ip, err)
  46. }
  47. return
  48. }
  49. //SearchKeywords for list search keywords.
  50. func (s *Service) SearchKeywords() (res []interface{}, err error) {
  51. var sks []*academy.SearchKeywords
  52. if err = s.DB.Where("state=0").Order("rank ASC").Find(&sks).Error; err != nil {
  53. log.Error("SearchKeywords error(%v)", err)
  54. return
  55. }
  56. if len(sks) == 0 {
  57. return
  58. }
  59. res = s.trees(sks, "ID", "ParentID", "Children")
  60. return
  61. }
  62. //trees for generate tree data set
  63. // data - orm result set
  64. // idFieldStr - primary key in table map to struct
  65. // pidFieldStr - top parent id in table map to struct
  66. // chFieldStr - struct child nodes
  67. func (s *Service) trees(data interface{}, idFieldStr, pidFieldStr, chFieldStr string) (res []interface{}) {
  68. if reflect.TypeOf(data).Kind() != reflect.Slice {
  69. return
  70. }
  71. sli := reflect.ValueOf(data)
  72. top := make(map[int64]interface{})
  73. res = make([]interface{}, 0, sli.Len())
  74. for i := 0; i < sli.Len(); i++ {
  75. v := sli.Index(i).Interface()
  76. if reflect.TypeOf(v).Kind() != reflect.Ptr {
  77. continue
  78. }
  79. if reflect.ValueOf(v).IsNil() {
  80. continue
  81. }
  82. getValue := reflect.ValueOf(v).Elem()
  83. getType := reflect.TypeOf(v).Elem()
  84. pid := getValue.FieldByName(pidFieldStr).Interface().(int64)
  85. if _, ok := getType.FieldByName(pidFieldStr); ok && pid == 0 {
  86. id := getValue.FieldByName(idFieldStr).Interface().(int64)
  87. top[id] = v
  88. res = append(res, v)
  89. }
  90. }
  91. for i := 0; i < sli.Len(); i++ {
  92. v := sli.Index(i).Interface()
  93. if reflect.TypeOf(v).Kind() != reflect.Ptr {
  94. continue
  95. }
  96. if reflect.ValueOf(v).IsNil() {
  97. continue
  98. }
  99. pid := reflect.ValueOf(v).Elem().FieldByName(pidFieldStr).Interface().(int64)
  100. if pid == 0 {
  101. continue
  102. }
  103. if p, ok := top[pid]; ok {
  104. ch := reflect.ValueOf(p).Elem().FieldByName(chFieldStr)
  105. ch.Set(reflect.Append(ch, reflect.ValueOf(v)))
  106. }
  107. }
  108. return
  109. }
  110. //SubSearchKeywords for add search keywords.
  111. func (s *Service) SubSearchKeywords(vs []*academy.SearchKeywords) (err error) {
  112. if len(vs) == 0 {
  113. return
  114. }
  115. origins := []*academy.SearchKeywords{}
  116. if err = s.DB.Model(&academy.SearchKeywords{}).Find(&origins).Error; err != nil {
  117. log.Error("SubSearchKeywords Find error(%v)", err)
  118. return
  119. }
  120. originMap := make(map[int64]*academy.SearchKeywords)
  121. for _, v := range origins {
  122. originMap[v.ID] = v
  123. }
  124. newParents := make([]*academy.SearchKeywords, 0)
  125. oldParents := make([]*academy.SearchKeywords, 0)
  126. children := make([]*academy.SearchKeywords, 0)
  127. newChildren := make([]*academy.SearchKeywords, 0)
  128. oldChildren := make([]*academy.SearchKeywords, 0)
  129. now := time.Now().Format("2006-01-02 15:04:05")
  130. for _, v := range vs {
  131. if v == nil {
  132. continue
  133. }
  134. v.Name = strings.TrimSpace(v.Name) //删除字符串前后空格
  135. if vv, ok := originMap[v.ID]; ok && vv != nil { //父节点为老的
  136. v.CTime = vv.CTime
  137. v.MTime = now
  138. oldParents = append(oldParents, v)
  139. if len(v.Children) > 0 {
  140. for _, vvv := range v.Children {
  141. vvv.ParentID = vv.ID //追加父节点ID
  142. vvv.CTime = now
  143. vvv.MTime = now
  144. children = append(children, vvv) //新老子节点同时存在
  145. }
  146. }
  147. } else {
  148. v.CTime = now
  149. v.MTime = now
  150. newParents = append(newParents, v)
  151. }
  152. }
  153. oldParents = append(oldParents, newParents...)
  154. tx := s.DB
  155. if len(oldParents) > 0 {
  156. if err = s.insertKeyWords(tx, oldParents); err != nil {
  157. return
  158. }
  159. }
  160. newParentsNames := make([]string, 0)
  161. for _, v := range newParents {
  162. newParentsNames = append(newParentsNames, v.Name)
  163. }
  164. var pidMap map[string]*academy.SearchKeywords
  165. if len(newParentsNames) > 0 {
  166. if pidMap, err = s.upRanks(tx, newParentsNames); err != nil {
  167. return
  168. }
  169. }
  170. newChildrenNames := make([]string, 0)
  171. for _, v := range newParents { //父节点为新的
  172. if v == nil {
  173. continue
  174. }
  175. if vv, ok := pidMap[v.Name]; ok && vv != nil {
  176. if len(v.Children) > 0 {
  177. for _, vvv := range v.Children {
  178. vvv.ParentID = vv.ID //追加父节点ID
  179. vvv.CTime = now
  180. vvv.MTime = now
  181. newChildren = append(newChildren, vvv)
  182. newChildrenNames = append(newChildrenNames, vvv.Name)
  183. }
  184. }
  185. }
  186. }
  187. for _, v := range children {
  188. if v == nil {
  189. continue
  190. }
  191. if vv, ok := originMap[v.ID]; ok && vv != nil {
  192. v.CTime = vv.CTime
  193. v.MTime = now
  194. oldChildren = append(oldChildren, v)
  195. } else {
  196. v.CTime = now
  197. v.MTime = now
  198. newChildren = append(newChildren, v)
  199. newChildrenNames = append(newChildrenNames, v.Name)
  200. }
  201. }
  202. oldChildren = append(oldChildren, newChildren...)
  203. if len(oldChildren) > 0 {
  204. if err = s.insertKeyWords(tx, oldChildren); err != nil {
  205. return
  206. }
  207. }
  208. if len(newChildrenNames) > 0 {
  209. if _, err = s.upRanks(tx, newChildrenNames); err != nil {
  210. return
  211. }
  212. }
  213. return
  214. }
  215. func (s *Service) insertKeyWords(tx *gorm.DB, vs []*academy.SearchKeywords) (err error) {
  216. if len(vs) == 0 {
  217. return
  218. }
  219. valSearks := make([]string, 0, len(vs))
  220. valSearksArgs := make([]interface{}, 0)
  221. for _, v := range vs {
  222. valSearks = append(valSearks, "(?, ?, ?, ?, ?, ?, ?, ?)")
  223. valSearksArgs = append(valSearksArgs, v.ID, v.Rank, v.ParentID, v.State, v.Name, v.Comment, v.CTime, v.MTime)
  224. }
  225. sqlStr := fmt.Sprintf("INSERT INTO academy_search_keywords (id, rank, parent_id, state, name, comment, ctime, mtime) VALUES %s "+
  226. "ON DUPLICATE KEY UPDATE id=VALUES(id), rank=VALUES(rank), parent_id=VALUES(parent_id), state=VALUES(state), name=VALUES(name), comment=VALUES(comment), ctime=VALUES(ctime), mtime=VALUES(mtime)", strings.Join(valSearks, ","))
  227. if err = tx.Exec(sqlStr, valSearksArgs...).Error; err != nil {
  228. log.Error("insertKeyWords error(%v)", err)
  229. }
  230. return
  231. }
  232. func (s *Service) upRanks(tx *gorm.DB, names []string) (pidMap map[string]*academy.SearchKeywords, err error) {
  233. if len(names) == 0 {
  234. return
  235. }
  236. setRanks := []*academy.SearchKeywords{}
  237. if err = s.DB.Model(&academy.SearchKeywords{}).Where("name IN(?)", names).Find(&setRanks).Error; err != nil {
  238. log.Error("upRanks Find error(%v)", err)
  239. return
  240. }
  241. upRankSQL := "UPDATE academy_search_keywords SET rank = CASE id "
  242. ids := make([]int64, 0)
  243. pidMap = make(map[string]*academy.SearchKeywords)
  244. for _, v := range setRanks {
  245. upRankSQL += fmt.Sprintf("WHEN %d THEN %d ", v.ID, v.ID)
  246. ids = append(ids, v.ID)
  247. pidMap[v.Name] = v
  248. }
  249. if len(ids) == 0 {
  250. return
  251. }
  252. upRankSQL += "END WHERE id IN (?)"
  253. if err = tx.Exec(upRankSQL, ids).Error; err != nil {
  254. log.Error("upRanks update rank ids(%+v) error(%v)", ids, err)
  255. }
  256. return
  257. }