本站源代码
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

319 lines
8.1KB

  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package user
  6. import (
  7. "code.gitea.io/gitea/services/mailer"
  8. "fmt"
  9. "path"
  10. "strings"
  11. "strconv"
  12. "code.gitea.io/gitea/models"
  13. "code.gitea.io/gitea/modules/base"
  14. "code.gitea.io/gitea/modules/context"
  15. "code.gitea.io/gitea/modules/setting"
  16. "code.gitea.io/gitea/modules/util"
  17. "code.gitea.io/gitea/routers/repo"
  18. )
  19. const (
  20. tplFollowers base.TplName = "user/meta/followers"
  21. )
  22. // GetUserByName get user by name
  23. func GetUserByName(ctx *context.Context, name string) *models.User {
  24. user, err := models.GetUserByName(name)
  25. if err != nil {
  26. if models.IsErrUserNotExist(err) {
  27. ctx.NotFound("GetUserByName", nil)
  28. } else {
  29. ctx.ServerError("GetUserByName", err)
  30. }
  31. return nil
  32. }
  33. return user
  34. }
  35. // GetUserByParams returns user whose name is presented in URL paramenter.
  36. func GetUserByParams(ctx *context.Context) *models.User {
  37. return GetUserByName(ctx, ctx.Params(":username"))
  38. }
  39. // Profile render user's profile page
  40. func Profile(ctx *context.Context) {
  41. uname := ctx.Params(":username")
  42. // Special handle for FireFox requests favicon.ico.
  43. if uname == "favicon.ico" {
  44. ctx.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png"))
  45. return
  46. } else if strings.HasSuffix(uname, ".png") {
  47. ctx.Error(404)
  48. return
  49. }
  50. isShowKeys := false
  51. if strings.HasSuffix(uname, ".keys") {
  52. isShowKeys = true
  53. uname = strings.TrimSuffix(uname, ".keys")
  54. }
  55. isShowGPG := false
  56. if strings.HasSuffix(uname, ".gpg") {
  57. isShowGPG = true
  58. uname = strings.TrimSuffix(uname, ".gpg")
  59. }
  60. ctxUser := GetUserByName(ctx, uname)
  61. if ctx.Written() {
  62. return
  63. }
  64. // Show SSH keys.
  65. if isShowKeys {
  66. ShowSSHKeys(ctx, ctxUser.ID)
  67. return
  68. }
  69. // Show GPG keys.
  70. if isShowGPG {
  71. ShowGPGKeys(ctx, ctxUser.ID)
  72. return
  73. }
  74. if ctxUser.IsOrganization() {
  75. showOrgProfile(ctx)
  76. return
  77. }
  78. // Show OpenID URIs
  79. openIDs, err := models.GetUserOpenIDs(ctxUser.ID)
  80. if err != nil {
  81. ctx.ServerError("GetUserOpenIDs", err)
  82. return
  83. }
  84. ctx.Data["Title"] = ctxUser.DisplayName()
  85. ctx.Data["PageIsUserProfile"] = true
  86. ctx.Data["Owner"] = ctxUser
  87. ctx.Data["OpenIDs"] = openIDs
  88. ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap
  89. ctx.Data["HeatmapUser"] = ctxUser.Name
  90. showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID)
  91. orgs, err := models.GetOrgsByUserID(ctxUser.ID, showPrivate)
  92. if err != nil {
  93. ctx.ServerError("GetOrgsByUserIDDesc", err)
  94. return
  95. }
  96. ctx.Data["Orgs"] = orgs
  97. ctx.Data["HasOrgsVisible"] = models.HasOrgsVisible(orgs, ctx.User)
  98. tab := ctx.Query("tab")
  99. ctx.Data["TabName"] = tab
  100. page := ctx.QueryInt("page")
  101. if page <= 0 {
  102. page = 1
  103. }
  104. topicOnly := ctx.QueryBool("topic")
  105. var (
  106. repos []*models.Repository
  107. count int64
  108. total int
  109. orderBy models.SearchOrderBy
  110. )
  111. ctx.Data["SortType"] = ctx.Query("sort")
  112. switch ctx.Query("sort") {
  113. case "newest":
  114. orderBy = models.SearchOrderByNewest
  115. case "oldest":
  116. orderBy = models.SearchOrderByOldest
  117. case "recentupdate":
  118. orderBy = models.SearchOrderByRecentUpdated
  119. case "leastupdate":
  120. orderBy = models.SearchOrderByLeastUpdated
  121. case "reversealphabetically":
  122. orderBy = models.SearchOrderByAlphabeticallyReverse
  123. case "alphabetically":
  124. orderBy = models.SearchOrderByAlphabetically
  125. case "moststars":
  126. orderBy = models.SearchOrderByStarsReverse
  127. case "feweststars":
  128. orderBy = models.SearchOrderByStars
  129. case "mostforks":
  130. orderBy = models.SearchOrderByForksReverse
  131. case "fewestforks":
  132. orderBy = models.SearchOrderByForks
  133. default:
  134. ctx.Data["SortType"] = "recentupdate"
  135. orderBy = models.SearchOrderByRecentUpdated
  136. }
  137. keyword := strings.Trim(ctx.Query("q"), " ")
  138. ctx.Data["Keyword"] = keyword
  139. switch tab {
  140. case "activity":
  141. retrieveFeeds(ctx, models.GetFeedsOptions{RequestedUser: ctxUser,
  142. IncludePrivate: showPrivate,
  143. OnlyPerformedBy: true,
  144. IncludeDeleted: false,
  145. })
  146. if ctx.Written() {
  147. return
  148. }
  149. case "stars":
  150. ctx.Data["PageIsProfileStarList"] = true
  151. repos, count, err = models.SearchRepository(&models.SearchRepoOptions{
  152. Keyword: keyword,
  153. OrderBy: orderBy,
  154. Private: ctx.IsSigned,
  155. UserIsAdmin: ctx.IsUserSiteAdmin(),
  156. UserID: ctx.Data["SignedUserID"].(int64),
  157. Page: page,
  158. PageSize: setting.UI.User.RepoPagingNum,
  159. StarredByID: ctxUser.ID,
  160. Collaborate: util.OptionalBoolFalse,
  161. TopicOnly: topicOnly,
  162. IncludeDescription: setting.UI.SearchRepoDescription,
  163. })
  164. if err != nil {
  165. ctx.ServerError("SearchRepository", err)
  166. return
  167. }
  168. total = int(count)
  169. default:
  170. repos, count, err = models.SearchRepository(&models.SearchRepoOptions{
  171. Keyword: keyword,
  172. OwnerID: ctxUser.ID,
  173. OrderBy: orderBy,
  174. Private: ctx.IsSigned,
  175. UserIsAdmin: ctx.IsUserSiteAdmin(),
  176. UserID: ctx.Data["SignedUserID"].(int64),
  177. Page: page,
  178. IsProfile: true,
  179. PageSize: setting.UI.User.RepoPagingNum,
  180. Collaborate: util.OptionalBoolFalse,
  181. TopicOnly: topicOnly,
  182. IncludeDescription: setting.UI.SearchRepoDescription,
  183. })
  184. if err != nil {
  185. ctx.ServerError("SearchRepository", err)
  186. return
  187. }
  188. total = int(count)
  189. }
  190. ctx.Data["Repos"] = repos
  191. ctx.Data["Total"] = total
  192. pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5)
  193. pager.SetDefaultParams(ctx)
  194. ctx.Data["Page"] = pager
  195. ctx.Data["ShowUserEmail"] = len(ctxUser.Email) > 0 && ctx.IsSigned && (!ctxUser.KeepEmailPrivate || ctxUser.ID == ctx.User.ID)
  196. ctx.HTML(200, tplProfile)
  197. }
  198. // Followers render user's followers page
  199. func Followers(ctx *context.Context) {
  200. u := GetUserByParams(ctx)
  201. if ctx.Written() {
  202. return
  203. }
  204. ctx.Data["Title"] = u.DisplayName()
  205. ctx.Data["CardsTitle"] = ctx.Tr("user.followers")
  206. ctx.Data["PageIsFollowers"] = true
  207. ctx.Data["Owner"] = u
  208. repo.RenderUserCards(ctx, u.NumFollowers, u.GetFollowers, tplFollowers)
  209. }
  210. // Following render user's followering page
  211. func Following(ctx *context.Context) {
  212. u := GetUserByParams(ctx)
  213. if ctx.Written() {
  214. return
  215. }
  216. ctx.Data["Title"] = u.DisplayName()
  217. ctx.Data["CardsTitle"] = ctx.Tr("user.following")
  218. ctx.Data["PageIsFollowing"] = true
  219. ctx.Data["Owner"] = u
  220. repo.RenderUserCards(ctx, u.NumFollowing, u.GetFollowing, tplFollowers)
  221. }
  222. // Action response for follow/unfollow user request
  223. func Action(ctx *context.Context) {
  224. u := GetUserByParams(ctx)
  225. if ctx.Written() {
  226. return
  227. }
  228. var err error
  229. switch ctx.Params(":action") {
  230. case "follow":
  231. err = models.FollowUser(ctx.User.ID, u.ID)
  232. case "unfollow":
  233. err = models.UnfollowUser(ctx.User.ID, u.ID)
  234. }
  235. if err != nil {
  236. ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
  237. return
  238. }
  239. ctx.RedirectToFirst(ctx.Query("redirect_to"), u.HomeLink())
  240. }
  241. func TransferP(ctx *context.Context) {
  242. //减少发送者点数
  243. //增加接收者点数
  244. //创建transfer记录
  245. u := GetUserByParams(ctx)
  246. var err error
  247. Qty, err := strconv.Atoi(ctx.Query("qty"))
  248. if err != nil {
  249. ctx.Flash.Error("请输入数字")
  250. return
  251. }
  252. if Qty < 1 {
  253. ctx.Flash.Error("请至少发1个红包!")
  254. ctx.RedirectToFirst(ctx.Query("redirect_to"), u.HomeLink())
  255. return
  256. }
  257. repoPoint,err :=models.GetRepoPointByUserID(ctx.User.ID)
  258. if err !=nil {
  259. ctx.ServerError("GetUserByName", err)
  260. return
  261. }
  262. if ctx.User.Point - repoPoint < Qty {
  263. ctx.Flash.Error(fmt.Sprintf("余额不足,转出红包数目应该少于(个人账户余额减去个人名下仓库需要支出的红包数目!个人余额%d;名下仓库需要支出%d",ctx.User.Point,repoPoint))
  264. ctx.RedirectToFirst(ctx.Query("redirect_to"), u.HomeLink())
  265. return
  266. }
  267. why := ctx.Query("why")
  268. err = models.TransferPoint(ctx.User.Name,
  269. why,
  270. u.Name,
  271. Qty)
  272. if err != nil {
  273. ctx.ServerError("Transfer", err)
  274. return
  275. }
  276. //发通知邮件给接受积分的人
  277. mailer.SendRecievePointNotifyMail(ctx.User, //积分发送者
  278. u, //积分接受者
  279. Qty, //积分点数
  280. why) //原因
  281. ctx.RedirectToFirst(ctx.Query("redirect_to"), u.HomeLink())
  282. }
上海开阖软件有限公司 沪ICP备12045867号-1