user.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package service
  2. import (
  3. "context"
  4. "time"
  5. "go-common/app/admin/main/manager/model"
  6. "go-common/library/ecode"
  7. "go-common/library/log"
  8. "github.com/jinzhu/gorm"
  9. "github.com/pkg/errors"
  10. )
  11. // Auth return user's auth infomation.
  12. func (s *Service) Auth(c context.Context, username string) (res *model.Auth, err error) {
  13. var (
  14. user model.User
  15. resp *model.RespPerm
  16. )
  17. if err = s.dao.DB().Where("username = ?", username).First(&user).Error; err != nil {
  18. if err == ecode.NothingFound {
  19. err = ecode.Int(10001)
  20. return
  21. }
  22. err = errors.Wrapf(err, "s.dao.DB().user.fitst(%s)", username)
  23. return
  24. }
  25. res = &model.Auth{
  26. UID: user.ID,
  27. Username: user.Username,
  28. Nickname: user.Nickname,
  29. }
  30. if resp, err = s.permsByMid(c, user.ID); err != nil {
  31. err = errors.Wrapf(err, "s.permsByMid(%d)", user.ID)
  32. return
  33. }
  34. res.Perms = resp.Res
  35. res.Admin = resp.Admin
  36. var aa []*model.AuthAssign
  37. if result := s.dao.DB().Joins("left join auth_item on auth_item.id=auth_assignment.item_id").Where("auth_assignment.user_id=? and auth_item.type=?", user.ID, model.TypeGroup).Find(&aa); !result.RecordNotFound() {
  38. res.Assignable = true
  39. }
  40. return
  41. }
  42. // Permissions return user's permissions.
  43. func (s *Service) Permissions(c context.Context, username string) (res *model.Permissions, err error) {
  44. res = new(model.Permissions)
  45. var (
  46. user model.User
  47. resp *model.RespPerm
  48. )
  49. if err = s.dao.DB().Where("username = ?", username).First(&user).Error; err != nil {
  50. if err == gorm.ErrRecordNotFound {
  51. err = ecode.NothingFound
  52. }
  53. log.Error("find user username(%s) error(%v)", username, err)
  54. return
  55. }
  56. res.UID = user.ID
  57. if resp, err = s.permsByMid(c, user.ID); err != nil {
  58. if err == gorm.ErrRecordNotFound {
  59. err = ecode.NothingFound
  60. }
  61. log.Error("s.permsByMid(%d) error(%v)", user.ID, err)
  62. return
  63. }
  64. res.Perms = resp.Res
  65. res.Admin = resp.Admin
  66. res.Orgs = resp.Groups
  67. res.Roles = resp.Roles
  68. return
  69. }
  70. func (s *Service) permsByMid(c context.Context, mid int64) (resp *model.RespPerm, err error) {
  71. var (
  72. pointIDs []int64
  73. as []*model.AuthAssign
  74. )
  75. resp = &model.RespPerm{}
  76. resp.Res = make([]string, 0)
  77. resp.Groups = make([]*model.AuthOrg, 0)
  78. resp.Roles = make([]*model.AuthOrg, 0)
  79. if s.admins[mid] {
  80. resp.Admin = true
  81. for _, p := range s.pointList {
  82. resp.Res = append(resp.Res, p.Data)
  83. }
  84. return
  85. }
  86. if err = s.dao.DB().Where("user_id = ?", mid).Find(&as).Error; err != nil {
  87. err = errors.Wrapf(err, "s.dao.DB().user.find(%d)", mid)
  88. return
  89. }
  90. for _, a := range as {
  91. if info, found := s.orgAuth[a.ItemID]; found { // group & role information
  92. if info.Type == model.TypeRole {
  93. resp.Roles = append(resp.Roles, info)
  94. }
  95. if info.Type == model.TypeGroup {
  96. resp.Groups = append(resp.Groups, info)
  97. }
  98. }
  99. if vs, ok := s.roleAuth[a.ItemID]; ok {
  100. pointIDs = append(pointIDs, vs...)
  101. continue
  102. }
  103. if vs, ok := s.groupAuth[a.ItemID]; ok {
  104. pointIDs = append(pointIDs, vs...)
  105. }
  106. }
  107. repeat := map[string]byte{}
  108. for _, id := range pointIDs {
  109. if assign, ok := s.points[id]; ok {
  110. l := len(repeat)
  111. repeat[assign.Data] = 0
  112. if len(repeat) != l {
  113. resp.Res = append(resp.Res, assign.Data)
  114. }
  115. }
  116. }
  117. return
  118. }
  119. // Users get user list.
  120. func (s *Service) Users(c context.Context, pn, ps int) (res *model.UserPager, err error) {
  121. res = &model.UserPager{
  122. Pn: pn,
  123. Ps: ps,
  124. }
  125. var items []*model.User
  126. if err = s.dao.DB().Where("state = ?", model.UserStateOn).Offset((pn - 1) * ps).Limit(ps).Find(&items).Error; err != nil {
  127. if err != ecode.NothingFound {
  128. err = errors.Wrapf(err, "s.dao.DB().users.find(%d,%d)", pn, ps)
  129. return
  130. }
  131. err = nil
  132. }
  133. res.Items = items
  134. return
  135. }
  136. // UsersTotal get user total
  137. func (s *Service) UsersTotal(c context.Context) (total int64, err error) {
  138. var item *model.User
  139. if err = s.dao.DB().Model(&item).Where("state = ?", model.UserStateOn).Count(&total).Error; err != nil {
  140. err = errors.Wrap(err, "s.dao.DB().users.count")
  141. }
  142. return
  143. }
  144. // Heartbeat user activity record
  145. func (s *Service) Heartbeat(c context.Context, username string) (err error) {
  146. var user model.User
  147. if err = s.dao.DB().Where("username = ?", username).First(&user).Error; err != nil {
  148. if err == ecode.NothingFound {
  149. err = ecode.Int(10001)
  150. return
  151. }
  152. err = errors.Wrapf(err, "s.dao.DB().user.fitst(%s)", username)
  153. return
  154. }
  155. now := time.Now()
  156. if err = s.dao.DB().Exec("insert into user_heartbeat (uid,mtime) values (?,?) on duplicate key update mtime=?", user.ID, now, now).Error; err != nil {
  157. err = errors.Wrapf(err, "s.dao.DB().heartbeat(%d)", user.ID)
  158. }
  159. return
  160. }
  161. // loadUnames loads the relation of uid & unames in two maps
  162. func (s *Service) loadUnames() {
  163. var (
  164. err error
  165. items []*model.User
  166. unames = make(map[int64]string)
  167. unicknames = make(map[int64]string)
  168. uids = make(map[string]int64)
  169. )
  170. if err = s.dao.DB().Where("state = ?", model.UserStateOn).Find(&items).Error; err != nil {
  171. if err != ecode.NothingFound {
  172. log.Error("LoadUnames Error (%v)", err)
  173. return
  174. }
  175. if len(items) == 0 {
  176. log.Info("LoadUnames No Active User was found")
  177. return
  178. }
  179. }
  180. for _, v := range items {
  181. unames[v.ID] = v.Username
  182. unicknames[v.ID] = v.Nickname
  183. uids[v.Username] = v.ID
  184. }
  185. if length := len(unames); length != 0 {
  186. s.userNames = unames
  187. s.userNicknames = unicknames
  188. log.Info("LoadUnames Refresh Success! Lines:%d", length)
  189. }
  190. if length := len(uids); length != 0 {
  191. s.userIds = uids
  192. log.Info("LoadUIds Refresh Success! Lines:%d", length)
  193. }
  194. }
  195. // regularly load unames
  196. func (s *Service) loadUnamesproc() {
  197. var duration time.Duration
  198. if duration = time.Duration(s.c.UnameTicker); duration == 0 {
  199. duration = time.Duration(5 * time.Minute) // default value
  200. }
  201. ticker := time.NewTicker(duration)
  202. for range ticker.C {
  203. s.loadUnames()
  204. s.loadUdepts()
  205. }
  206. ticker.Stop()
  207. }
  208. // Unames treats the param "uids" and give back the unames data
  209. func (s *Service) Unames(c context.Context, uids []int64) (res map[int64]string) {
  210. res = make(map[int64]string)
  211. for _, v := range uids {
  212. if uname, ok := s.userNames[v]; ok {
  213. res[v] = uname
  214. }
  215. }
  216. return
  217. }
  218. // UIds treats the param "unames" and give back the uids data
  219. func (s *Service) UIds(c context.Context, unames []string) (res map[string]int64) {
  220. res = make(map[string]int64)
  221. for _, v := range unames {
  222. if uid, ok := s.userIds[v]; ok {
  223. res[v] = uid
  224. }
  225. }
  226. return
  227. }
  228. // loadUdeps loads the relation of uid & department in one map
  229. func (s *Service) loadUdepts() {
  230. var (
  231. items []*model.UserDept
  232. udepts = make(map[int64]string)
  233. )
  234. /**
  235. select `user`.id,user_department.`name` from `user` LEFT JOIN user_department on `user`.department_id = user_department.id where user_department.`status` = 1 and `user`.state = 0
  236. */
  237. err := s.dao.DB().Table("user").
  238. Select("user.id, user_department.`name` AS department").
  239. Joins("LEFT JOIN user_department ON `user`.department_id = user_department.id").
  240. Where("user_department.`status` = ?", model.UserDepOn).
  241. Where("state = ?", model.UserStateOn).Find(&items).Error
  242. if err != nil {
  243. if err != ecode.NothingFound {
  244. log.Error("loadUdepts Error (%v)", err)
  245. return
  246. }
  247. if len(items) == 0 {
  248. log.Info("loadUdepts No Active User was found")
  249. return
  250. }
  251. }
  252. for _, v := range items {
  253. udepts[v.ID] = v.Department
  254. }
  255. if length := len(udepts); length != 0 {
  256. s.userDeps = udepts
  257. log.Info("loadUdepts Refresh Success! Lines:%d", length)
  258. }
  259. }
  260. // Udepts treats the param "uids" and give back the users' department data
  261. func (s *Service) Udepts(c context.Context, uids []int64) (res map[int64]string) {
  262. res = make(map[int64]string)
  263. for _, v := range uids {
  264. if udept, ok := s.userDeps[v]; ok {
  265. res[v] = udept
  266. }
  267. }
  268. return
  269. }