// ReadCatResources 某个分类的资源列表 func (ResourceController) ReadCatResources(ctx echo.Context) error { curPage := goutils.MustInt(ctx.QueryParam("p"), 1) paginator := logic.NewPaginator(curPage) catid := goutils.MustInt(ctx.Param("catid")) resources, total := logic.DefaultResource.FindByCatid(ctx, paginator, catid) pageHtml := paginator.SetTotal(total).GetPageHtml(ctx.Request().URL().Path()) return render(ctx, "resources/index.html", map[string]interface{}{"activeResources": "active", "resources": resources, "categories": logic.AllCategory, "page": template.HTML(pageHtml), "curCatid": catid}) }
// NodeTopics 某节点下的主题列表 func (TopicController) NodeTopics(ctx echo.Context) error { curPage := goutils.MustInt(ctx.QueryParam("p"), 1) paginator := logic.NewPaginator(curPage) querystring, nid := "nid=?", goutils.MustInt(ctx.Param("nid")) topics := logic.DefaultTopic.FindAll(ctx, paginator, "topics.mtime DESC", querystring, nid) total := logic.DefaultTopic.Count(ctx, querystring, nid) pageHtml := paginator.SetTotal(total).GetPageHtml(ctx.Request().URL().Path()) // 当前节点信息 node := logic.GetNode(nid) return render(ctx, "topics/node.html", map[string]interface{}{"activeTopics": "active", "topics": topics, "page": template.HTML(pageHtml), "total": total, "node": node}) }
// ReadingList 晨读列表页 func (ReadingController) ReadingList(ctx echo.Context) error { limit := 20 lastId := goutils.MustInt(ctx.QueryParam("lastid")) rtype := goutils.MustInt(ctx.QueryParam("rtype"), model.RtypeGo) readings := logic.DefaultReading.FindBy(ctx, limit+5, rtype, lastId) num := len(readings) if num == 0 { if lastId == 0 { return ctx.Redirect(http.StatusSeeOther, "/") } else { return ctx.Redirect(http.StatusSeeOther, "/readings") } } var ( hasPrev, hasNext bool prevId, nextId int ) if lastId > 0 { prevId = lastId // 避免因为项目下线,导致判断错误(所以 > 5) if prevId-readings[0].Id > 5 { hasPrev = false } else { prevId += limit hasPrev = true } } if num > limit { hasNext = true readings = readings[:limit] nextId = readings[limit-1].Id } else { nextId = readings[num-1].Id } pageInfo := map[string]interface{}{ "has_prev": hasPrev, "prev_id": prevId, "has_next": hasNext, "next_id": nextId, } return render(ctx, "readings/list.html", map[string]interface{}{"activeReadings": "active", "readings": readings, "page": pageInfo, "rtype": rtype}) }
// Detail 文章详细页 func (ArticleController) Detail(ctx echo.Context) error { article, prevNext, err := logic.DefaultArticle.FindByIdAndPreNext(ctx, goutils.MustInt(ctx.Param("id"))) if err != nil { return ctx.Redirect(http.StatusSeeOther, "/articles") } if article == nil || article.Id == 0 || article.Status == model.ArticleStatusOffline { return ctx.Redirect(http.StatusSeeOther, "/articles") } likeFlag := 0 hadCollect := 0 me, ok := ctx.Get("user").(*model.Me) if ok { likeFlag = logic.DefaultLike.HadLike(ctx, me.Uid, article.Id, model.TypeArticle) hadCollect = logic.DefaultFavorite.HadFavorite(ctx, me.Uid, article.Id, model.TypeArticle) } logic.Views.Incr(Request(ctx), model.TypeArticle, article.Id) // 为了阅读数即时看到 article.Viewnum++ return render(ctx, "articles/detail.html,common/comment.html", map[string]interface{}{"activeArticles": "active", "article": article, "prev": prevNext[0], "next": prevNext[1], "likeflag": likeFlag, "hadcollect": hadCollect}) }
// FindOne 某个wiki页面详细信息 func (WikiLogic) FindOne(ctx context.Context, uri string) *model.Wiki { objLog := GetLogger(ctx) wiki := &model.Wiki{} if _, err := MasterDB.Where("uri=?", uri).Get(wiki); err != nil { objLog.Errorln("wiki logic FindOne error:", err) return nil } if wiki.Id == 0 { return nil } uidSet := set.New(set.NonThreadSafe) uidSet.Add(wiki.Uid) if wiki.Cuid != "" { cuids := strings.Split(wiki.Cuid, ",") for _, cuid := range cuids { uidSet.Add(goutils.MustInt(cuid)) } } wiki.Users = DefaultUser.FindUserInfos(ctx, set.IntSlice(uidSet)) return wiki }
func (self InstallController) SetupConfig(ctx echo.Context) error { // config/env.ini 存在 if db.MasterDB != nil { if logic.DefaultInstall.IsTableExist(ctx) { return ctx.Redirect(http.StatusSeeOther, "/") } return ctx.Redirect(http.StatusSeeOther, "/install/do") } step := goutils.MustInt(ctx.QueryParam("step")) if step == 2 { err := self.genConfig(ctx) if err != nil { data := map[string]interface{}{ "dbhost": ctx.FormValue("dbhost"), "dbport": ctx.FormValue("dbport"), "dbname": ctx.FormValue("dbname"), "uname": ctx.FormValue("uname"), "err_type": 1, } if err == db.ConnectDBErr { data["err_type"] = 1 } else if err == db.UseDBErr { data["err_type"] = 2 } return renderInstall(ctx, "install/setup-err.html", data) } } return renderInstall(ctx, "install/setup-config.html", map[string]interface{}{"step": step}) }
// 消息列表 func (MessageController) ReadList(ctx echo.Context) error { user := ctx.Get("user").(*model.Me) msgtype := ctx.Param("msgtype") if msgtype == "" { msgtype = "system" } curPage := goutils.MustInt(ctx.QueryParam("p"), 1) paginator := logic.NewPaginator(curPage) var ( messages []map[string]interface{} total int64 ) switch msgtype { case "system": messages = logic.DefaultMessage.FindSysMsgsByUid(ctx, user.Uid, paginator) total = logic.DefaultMessage.SysMsgCount(ctx, user.Uid) case "inbox": messages = logic.DefaultMessage.FindToMsgsByUid(ctx, user.Uid, paginator) total = logic.DefaultMessage.ToMsgCount(ctx, user.Uid) case "outbox": messages = logic.DefaultMessage.FindFromMsgsByUid(ctx, user.Uid, paginator) total = logic.DefaultMessage.FromMsgCount(ctx, user.Uid) default: return ctx.Redirect(http.StatusSeeOther, "/") } pageHtml := paginator.SetTotal(total).GetPageHtml(fmt.Sprintf("/message/%s", msgtype)) return render(ctx, "messages/list.html", map[string]interface{}{"messages": messages, "msgtype": msgtype, "page": template.HTML(pageHtml)}) }
// EmailUnsub 邮件订阅/退订页面 func (UserController) EmailUnsub(ctx echo.Context) error { token := ctx.FormValue("u") if token == "" { return ctx.Redirect(http.StatusSeeOther, "/") } // 校验 token 的合法性 email := ctx.FormValue("email") user := logic.DefaultUser.FindOne(ctx, "email", email) if user.Email == "" { return ctx.Redirect(http.StatusSeeOther, "/") } realToken := logic.DefaultEmail.GenUnsubscribeToken(user) if token != realToken { return ctx.Redirect(http.StatusSeeOther, "/") } if ctx.Request().Method() != "POST" { data := map[string]interface{}{ "email": email, "token": token, "unsubscribe": user.Unsubscribe, } return render(ctx, "user/email_unsub.html", data) } logic.DefaultUser.EmailSubscribe(ctx, user.Uid, goutils.MustInt(ctx.FormValue("unsubscribe"))) return success(ctx, nil) }
// Modify 修改主题 func (TopicController) Modify(ctx echo.Context) error { tid := goutils.MustInt(ctx.FormValue("tid")) if tid == 0 { return ctx.Redirect(http.StatusSeeOther, "/topics") } nodes := logic.GenNodes() if ctx.Request().Method() != "POST" { topics := logic.DefaultTopic.FindByTids([]int{tid}) if len(topics) == 0 { return ctx.Redirect(http.StatusSeeOther, "/topics") } return render(ctx, "topics/new.html", map[string]interface{}{"nodes": nodes, "topic": topics[0], "activeTopics": "active"}) } me := ctx.Get("user").(*model.Me) err := logic.DefaultTopic.Publish(ctx, me, ctx.FormParams()) if err != nil { if err == logic.NotModifyAuthorityErr { return fail(ctx, 1, "没有权限操作") } return fail(ctx, 2, "服务错误,请稍后重试!") } return success(ctx, nil) }
// ReadList 获得wiki列表 func (WikiController) ReadList(ctx echo.Context) error { limit := 20 lastId := goutils.MustInt(ctx.QueryParam("lastid")) wikis := logic.DefaultWiki.FindBy(ctx, limit+5, lastId) if wikis == nil { logger.Errorln("wiki controller: find wikis error") return ctx.Redirect(http.StatusSeeOther, "/wiki") } num := len(wikis) if num == 0 { if lastId == 0 { return ctx.Redirect(http.StatusSeeOther, "/") } return ctx.Redirect(http.StatusSeeOther, "/wiki") } var ( hasPrev, hasNext bool prevId, nextId int ) if lastId != 0 { prevId = lastId // 避免因为wiki下线,导致判断错误(所以 > 5) if prevId-wikis[0].Id > 5 { hasPrev = false } else { prevId += limit hasPrev = true } } if num > limit { hasNext = true wikis = wikis[:limit] nextId = wikis[limit-1].Id } else { nextId = wikis[num-1].Id } pageInfo := map[string]interface{}{ "has_prev": hasPrev, "prev_id": prevId, "has_next": hasNext, "next_id": nextId, } // 获取当前用户喜欢对象信息 // me, ok := ctx.Get("user").(*model.Me) // var likeFlags map[int]int // if ok { // likeFlags, _ = logic.DefaultLike.FindUserLikeObjects(ctx, me.Uid, model.TypeWiki, wikis[0].Id, nextId) // } return render(ctx, "wiki/list.html", map[string]interface{}{"wikis": wikis, "activeWiki": "active", "page": pageInfo}) }
// Like 喜欢(或取消喜欢) func (LikeController) Like(ctx echo.Context) error { form := ctx.FormParams() if !util.CheckInt(form, "objtype") || !util.CheckInt(form, "flag") { return fail(ctx, 1, "参数错误") } user := ctx.Get("user").(*model.Me) objid := goutils.MustInt(ctx.Param("objid")) objtype := goutils.MustInt(ctx.FormValue("objtype")) likeFlag := goutils.MustInt(ctx.FormValue("flag")) err := logic.DefaultLike.LikeObject(ctx, user.Uid, objid, objtype, likeFlag) if err != nil { return fail(ctx, 2, "服务器内部错误") } return success(ctx, nil) }
// ReadList 开源项目列表页 func (ProjectController) ReadList(ctx echo.Context) error { limit := 20 lastId := goutils.MustInt(ctx.QueryParam("lastid")) projects := logic.DefaultProject.FindBy(ctx, limit+5, lastId) num := len(projects) if num == 0 { if lastId == 0 { return ctx.Redirect(http.StatusSeeOther, "/") } else { return ctx.Redirect(http.StatusSeeOther, "/projects") } } var ( hasPrev, hasNext bool prevId, nextId int ) if lastId > 0 { prevId = lastId // 避免因为项目下线,导致判断错误(所以 > 5) if prevId-projects[0].Id > 5 { hasPrev = false } else { prevId += limit hasPrev = true } } if num > limit { hasNext = true projects = projects[:limit] nextId = projects[limit-1].Id } else { nextId = projects[num-1].Id } pageInfo := map[string]interface{}{ "has_prev": hasPrev, "prev_id": prevId, "has_next": hasNext, "next_id": nextId, } // 获取当前用户喜欢对象信息 me, ok := ctx.Get("user").(*model.Me) var likeFlags map[int]int if ok { likeFlags, _ = logic.DefaultLike.FindUserLikeObjects(ctx, me.Uid, model.TypeProject, projects[0].Id, nextId) } return render(ctx, "projects/list.html", map[string]interface{}{"projects": projects, "activeProjects": "active", "page": pageInfo, "likeflags": likeFlags}) }
// Create 收藏(取消收藏) func (FavoriteController) Create(ctx echo.Context) error { objtype := goutils.MustInt(ctx.FormValue("objtype")) objid := goutils.MustInt(ctx.Param("objid")) collect := goutils.MustInt(ctx.FormValue("collect")) user := ctx.Get("user").(*model.Me) var err error if collect == 1 { err = logic.DefaultFavorite.Save(ctx, user.Uid, objid, objtype) } else { err = logic.DefaultFavorite.Cancel(ctx, user.Uid, objid, objtype) } if err != nil { return fail(ctx, 1, err.Error()) } return success(ctx, nil) }
// Create 评论(或回复) func (CommentController) Create(ctx echo.Context) error { user := ctx.Get("user").(*model.Me) // 入库 objid := goutils.MustInt(ctx.Param("objid")) comment, err := logic.DefaultComment.Publish(ctx, user.Uid, objid, ctx.FormParams()) if err != nil { return fail(ctx, 1, "服务器内部错误") } return success(ctx, comment) }
func initMaxOnlineNum() { maxRwMu.Lock() defer maxRwMu.Unlock() if maxOnlineNum == 0 { data, err := ioutil.ReadFile(getDataFile()) if err != nil { logger.Errorln("read data file error:", err) return } maxOnlineNum = goutils.MustInt(strings.TrimSpace(string(data))) } }
// ReadList 我的(某人的)收藏 func (FavoriteController) ReadList(ctx echo.Context) error { username := ctx.Param("username") user := logic.DefaultUser.FindOne(ctx, "username", username) if user == nil || user.Uid == 0 { return ctx.Redirect(http.StatusSeeOther, "/") } objtype := goutils.MustInt(ctx.QueryParam("objtype"), model.TypeArticle) p := goutils.MustInt(ctx.QueryParam("p"), 1) data := map[string]interface{}{"objtype": objtype, "user": user} rows := goutils.MustInt(ctx.QueryParam("rows"), 20) if rows > 20 { rows = 20 } favorites, total := logic.DefaultFavorite.FindUserFavorites(ctx, user.Uid, objtype, (p-1)*rows, rows) if total > 0 { objids := slices.StructsIntSlice(favorites, "Objid") switch objtype { case model.TypeTopic: data["topics"] = logic.DefaultTopic.FindByTids(objids) case model.TypeArticle: data["articles"] = logic.DefaultArticle.FindByIds(objids) case model.TypeResource: data["resources"] = logic.DefaultResource.FindByIds(objids) case model.TypeWiki: // data["wikis"] = logic.DefaultWiki.FindWikisByIds(objids) case model.TypeProject: data["projects"] = logic.DefaultProject.FindByIds(objids) } } uri := fmt.Sprintf("/favorites/%s?objtype=%d&rows=%d&", user.Username, objtype, rows) paginator := logic.NewPaginatorWithPerPage(p, rows) data["pageHtml"] = paginator.SetTotal(total).GetPageHtml(uri) return render(ctx, "favorite.html", data) }
func doCrawl(wbconf map[string]string, isAll bool) { crawlUrl := wbconf["incr_url"] if isAll { crawlUrl = wbconf["all_url"] } listselector := wbconf["listselector"] resultselector := wbconf["resultselector"] pageField := wbconf["page_field"] maxPage := 1 if isAll { maxPage = goutils.MustInt(wbconf["max_page"]) } // 个人博客,一般通过 tag 方式获取,这种处理方式和搜索不一样 if wbconf["keywords"] == "" { for p := maxPage; p >= 1; p-- { if pageField == "" { // 标题不包含 go 等关键词的,也入库 if err := parseArticleList(crawlUrl+strconv.Itoa(p), listselector, resultselector, false); err != nil { break } } } return } keywords := strings.Split(wbconf["keywords"], ",") for _, keyword := range keywords { for p := 1; p <= maxPage; p++ { curUrl := "" page := fmt.Sprintf("&%s=%d", pageField, p) if strings.Contains(crawlUrl, "%s") { curUrl = fmt.Sprintf(crawlUrl, keyword) + page } else { curUrl = crawlUrl + keyword + page } if err := parseArticleList(curUrl, listselector, resultselector, true); err != nil { logger.Errorln("parse article url error:", err) break } } } }
// CommentList 获取某对象的评论信息 func (CommentController) CommentList(ctx echo.Context) error { objid := goutils.MustInt(ctx.QueryParam("objid")) objtype := goutils.MustInt(ctx.QueryParam("objtype")) commentList, err := logic.DefaultComment.FindObjectComments(ctx, objid, objtype) if err != nil { return fail(ctx, 1, "服务器内部错误") } uids := slices.StructsIntSlice(commentList, "Uid") users := logic.DefaultUser.FindUserInfos(ctx, uids) result := map[string]interface{}{ "comments": commentList, } // json encode 不支持 map[int]... for uid, user := range users { result[strconv.Itoa(uid)] = user } return success(ctx, result) }
// websocket,统计在线用户数 // uri: /ws func (this *WebsocketController) Ws(wsConn *websocket.Conn) { defer wsConn.Close() this.mutex.Lock() this.ServerId++ serverId := this.ServerId this.mutex.Unlock() req := wsConn.Request() user := goutils.MustInt(req.FormValue("uid")) if user == 0 { user = int(goutils.Ip2long(goutils.RemoteIp(req))) } userData := logic.Book.AddUser(user, serverId) // 给自己发送消息,告诉当前在线用户数、历史最高在线人数 onlineInfo := map[string]int{"online": logic.Book.Len(), "maxonline": logic.MaxOnlineNum()} message := logic.NewMessage(logic.WsMsgOnline, onlineInfo) err := websocket.JSON.Send(wsConn, message) if err != nil { logger.Errorln("Sending onlineusers error:", err) } var clientClosed = false for { select { case message := <-userData.MessageQueue(serverId): if err := websocket.JSON.Send(wsConn, message); err != nil { clientClosed = true } // 心跳 case <-time.After(30e9): if err := websocket.JSON.Send(wsConn, ""); err != nil { clientClosed = true } } if clientClosed { logic.Book.DelUser(user, serverId) logger.Infoln("user:"******"client close") break } } // 用户退出时需要变更其他用户看到的在线用户数 if !logic.Book.UserIsOnline(user) { message := logic.NewMessage(logic.WsMsgOnline, map[string]int{"online": logic.Book.Len()}) go logic.Book.BroadcastAllUsersMessage(message) } }
// RecentComment 最新评论 func (SidebarController) RecentComment(ctx echo.Context) error { limit := goutils.MustInt(ctx.QueryParam("limit"), 10) recentComments := logic.DefaultComment.FindRecent(ctx, 0, -1, limit) uids := slices.StructsIntSlice(recentComments, "Uid") users := logic.DefaultUser.FindUserInfos(ctx, uids) result := map[string]interface{}{ "comments": recentComments, } // json encode 不支持 map[int]... for uid, user := range users { result[strconv.Itoa(uid)] = user } return success(ctx, result) }
func (TopicController) topicList(ctx echo.Context, view, orderBy, querystring string, args ...interface{}) error { curPage := goutils.MustInt(ctx.QueryParam("p"), 1) paginator := logic.NewPaginator(curPage) topics := logic.DefaultTopic.FindAll(ctx, paginator, orderBy, querystring, args...) total := logic.DefaultTopic.Count(ctx, querystring, args...) pageHtml := paginator.SetTotal(total).GetPageHtml(ctx.Request().URL().Path()) data := map[string]interface{}{ "topics": topics, "activeTopics": "active", "nodes": logic.GenNodes(), "view": view, "page": template.HTML(pageHtml), } return render(ctx, "topics/list.html", data) }
func (r *RpcServer) ListenAndServe(tcpAddr string) error { tcpPort, host := tcpAddr, "" tcpAddrs := strings.Split(tcpAddr, ":") if len(tcpAddrs) == 2 { host = tcpAddrs[0] tcpPort = tcpAddrs[1] } httpPort := strconv.Itoa(goutils.MustInt(tcpPort, 0) + HttpPortAdd) r.tcpAddr = tcpAddr r.httpAddr = host + ":" + httpPort go r.ListenTcpAndServe(tcpAddr) // r.ListenHttpAndServe(r.httpAddr) select {} }
// Publish 发表评论(或回复)。 // objid 注册的评论对象 // uid 评论人 func (self CommentLogic) Publish(ctx context.Context, uid, objid int, form url.Values) (*model.Comment, error) { objLog := GetLogger(ctx) objtype := goutils.MustInt(form.Get("objtype")) comment := &model.Comment{ Objid: objid, Objtype: objtype, Uid: uid, Content: form.Get("content"), } // TODO:评论楼层怎么处理,避免冲突?最后的楼层信息保存在内存中? // 暂时只是从数据库中取出最后的评论楼层 tmpCmt := &model.Comment{} _, err := MasterDB.Where("objid=? AND objtype=?", objid, objtype).OrderBy("ctime DESC").Get(tmpCmt) if err != nil { objLog.Errorln("post comment service error:", err) return nil, err } else { comment.Floor = tmpCmt.Floor + 1 } // 入评论库 _, err = MasterDB.Insert(comment) if err != nil { objLog.Errorln("post comment service error:", err) return nil, err } self.decodeCmtContent(ctx, comment) // 回调,不关心处理结果(有些对象可能不需要回调) if commenter, ok := commenters[objtype]; ok { objLog.Debugf("评论[objid:%d] [objtype:%d] [uid:%d] 成功,通知被评论者更新", objid, objtype, uid) go commenter.UpdateComment(comment.Cid, objid, uid, time.Now()) } // 发评论,活跃度+5 go DefaultUser.IncrUserWeight("uid", uid, 5) go self.sendSystemMsg(ctx, uid, objid, objtype, comment.Cid, form) return comment, nil }
// Send 发短消息 func (MessageController) Send(ctx echo.Context) error { content := ctx.FormValue("content") // 请求发送消息页面 if content == "" || ctx.Request().Method() != "POST" { username := ctx.FormValue("username") if username == "" { return ctx.Redirect(http.StatusSeeOther, "/") } user := logic.DefaultUser.FindOne(ctx, "username", username) return render(ctx, "messages/send.html", map[string]interface{}{"user": user}) } user := ctx.Get("user").(*model.Me) to := goutils.MustInt(ctx.FormValue("to")) ok := logic.DefaultMessage.SendMessageTo(ctx, user.Uid, to, content) if !ok { return fail(ctx, 1, "对不起,发送失败,请稍候再试!") } return success(ctx, nil) }
// Modify 修改项目 func (ProjectController) Modify(ctx echo.Context) error { id := goutils.MustInt(ctx.FormValue("id")) if id == 0 { return ctx.Redirect(http.StatusSeeOther, "/projects") } // 请求编辑项目页面 if ctx.Request().Method() != "POST" { project := logic.DefaultProject.FindOne(ctx, id) return render(ctx, "projects/new.html", map[string]interface{}{"project": project, "activeProjects": "active"}) } user := ctx.Get("user").(*model.Me) err := logic.DefaultProject.Publish(ctx, user, ctx.FormParams()) if err != nil { if err == logic.NotModifyAuthorityErr { return ctx.String(http.StatusForbidden, "没有权限") } return fail(ctx, 1, "内部服务错误!") } return success(ctx, nil) }
// Publish func (ReadingController) Publish(ctx echo.Context) error { var data = make(map[string]interface{}) if ctx.FormValue("submit") == "1" { user := ctx.Get("user").(*model.Me) errMsg, err := logic.DefaultReading.SaveReading(ctx, ctx.FormParams(), user.Username) if err != nil { return fail(ctx, 1, errMsg) } return success(ctx, nil) } id := goutils.MustInt(ctx.QueryParam("id")) if id != 0 { reading := logic.DefaultReading.FindById(ctx, id) if reading != nil { data["reading"] = reading } } return render(ctx, "reading/modify.html", data) }
// Search func (SearchController) Search(ctx echo.Context) error { q := ctx.QueryParam("q") field := ctx.QueryParam("f") p := goutils.MustInt(ctx.QueryParam("p"), 1) rows := 20 respBody, err := logic.DefaultSearcher.DoSearch(q, field, (p-1)*rows, rows) data := map[string]interface{}{ "respBody": respBody, "q": q, "f": field, } if err == nil { uri := "/search?q=" + q + "&f=" + field + "&" paginator := logic.NewPaginatorWithPerPage(p, rows) data["pageHtml"] = paginator.SetTotal(int64(respBody.NumFound)).GetPageHtml(uri) } return render(ctx, "search.html", data) }
// Detail 某个资源详细页 func (ResourceController) Detail(ctx echo.Context) error { id := goutils.MustInt(ctx.Param("id")) if id == 0 { return ctx.Redirect(http.StatusSeeOther, "/resources/cat/1") } resource, comments := logic.DefaultResource.FindById(ctx, id) if len(resource) == 0 { return ctx.Redirect(http.StatusSeeOther, "/resources/cat/1") } likeFlag := 0 hadCollect := 0 me, ok := ctx.Get("user").(*model.Me) if ok { id := resource["id"].(int) likeFlag = logic.DefaultLike.HadLike(ctx, me.Uid, id, model.TypeResource) hadCollect = logic.DefaultFavorite.HadFavorite(ctx, me.Uid, id, model.TypeResource) } logic.Views.Incr(Request(ctx), model.TypeResource, id) return render(ctx, "resources/detail.html,common/comment.html", map[string]interface{}{"activeResources": "active", "resource": resource, "comments": comments, "likeflag": likeFlag, "hadcollect": hadCollect}) }
// Modify 修改資源 func (ResourceController) Modify(ctx echo.Context) error { id := goutils.MustInt(ctx.FormValue("id")) if id == 0 { return ctx.Redirect(http.StatusSeeOther, "/resources/cat/1") } // 请求编辑資源页面 if ctx.Request().Method() != "POST" { resource := logic.DefaultResource.FindResource(ctx, id) return render(ctx, "resources/new.html", map[string]interface{}{"resource": resource, "activeResources": "active", "categories": logic.AllCategory}) } me := ctx.Get("user").(*model.Me) err := logic.DefaultResource.Publish(ctx, me, ctx.FormParams()) if err != nil { if err == logic.NotModifyAuthorityErr { return ctx.String(http.StatusForbidden, "没有权限修改") } return fail(ctx, 2, "内部服务错误,请稍候再试!") } return success(ctx, nil) }
// Detail 社区主题详细页 func (TopicController) Detail(ctx echo.Context) error { tid := goutils.MustInt(ctx.Param("tid")) if tid == 0 { return ctx.Redirect(http.StatusSeeOther, "/topics") } topic, replies, err := logic.DefaultTopic.FindByTid(ctx, tid) if err != nil { return ctx.Redirect(http.StatusSeeOther, "/topics") } likeFlag := 0 hadCollect := 0 user, ok := ctx.Get("user").(*model.Me) if ok { tid := topic["tid"].(int) likeFlag = logic.DefaultLike.HadLike(ctx, user.Uid, tid, model.TypeTopic) hadCollect = logic.DefaultFavorite.HadFavorite(ctx, user.Uid, tid, model.TypeTopic) } logic.Views.Incr(Request(ctx), model.TypeTopic, tid) return render(ctx, "topics/detail.html,common/comment.html", map[string]interface{}{"activeTopics": "active", "topic": topic, "replies": replies, "likeflag": likeFlag, "hadcollect": hadCollect}) }