package actions import ( "errors" "fmt" "github.com/fthvgb1/wp-go/helper/number" "github.com/fthvgb1/wp-go/helper/slice" str "github.com/fthvgb1/wp-go/helper/strings" "github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/config" "github.com/fthvgb1/wp-go/internal/pkg/dao" "github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/plugins" "github.com/fthvgb1/wp-go/internal/theme" "github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/model" "github.com/fthvgb1/wp-go/plugin/pagination" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "math" "net/http" "strconv" "strings" "sync/atomic" "time" ) type indexHandle struct { c *gin.Context session sessions.Session page int pageSize int title string titleL string titleR string search string author string totalPage int category string categoryType string where model.SqlBuilder orderBy string order string join model.SqlBuilder postType []any postStatus []any header string paginationStep int scene int status int } func newIndexHandle(ctx *gin.Context) *indexHandle { size := wpconfig.Options.Value("posts_per_page") si, _ := strconv.Atoi(size) return &indexHandle{ c: ctx, session: sessions.Default(ctx), page: 1, pageSize: si, paginationStep: 1, titleL: wpconfig.Options.Value("blogname"), titleR: wpconfig.Options.Value("blogdescription"), where: model.SqlBuilder{ {"post_type", "in", ""}, {"post_status", "in", ""}, }, orderBy: "post_date", join: model.SqlBuilder{}, postType: []any{"post"}, postStatus: []any{"publish"}, scene: plugins.Home, status: plugins.Ok, } } var months = slice.SimpleToMap(number.Range(1, 12, 1), func(v int) int { return v }) func (h *indexHandle) setTitleLR(l, r string) { h.titleL = l h.titleR = r } func (h *indexHandle) getTitle() string { h.title = fmt.Sprintf("%s-%s", h.titleL, h.titleR) return h.title } func (h *indexHandle) getSearchKey() string { return fmt.Sprintf("action:%s|%s|%s|%s|%s|%s|%d|%d", h.author, h.search, h.orderBy, h.order, h.category, h.categoryType, h.page, h.pageSize) } var orders = []string{"asc", "desc"} func (h *indexHandle) parseParams() (err error) { h.order = h.c.Query("order") if !slice.IsContained(h.order, orders) { order := config.Conf.Load().PostOrder h.order = "asc" if order != "" && slice.IsContained(order, orders) { h.order = order } } year := h.c.Param("year") if year != "" { y, er := strconv.Atoi(year) if er != nil { return err } if y > time.Now().Year() || y <= 1970 { return errors.New(str.Join("year err : ", year)) } h.where = append(h.where, []string{ "year(post_date)", year, }) } month := h.c.Param("month") if month != "" { m, err := strconv.Atoi(month) if err != nil { return err } if _, ok := months[m]; !ok { return errors.New(str.Join("months err ", month)) } h.where = append(h.where, []string{ "month(post_date)", month, }) ss := fmt.Sprintf("%s年%s月", year, strings.TrimLeft(month, "0")) h.header = fmt.Sprintf("月度归档: %s", ss) h.setTitleLR(ss, wpconfig.Options.Value("blogname")) h.scene = plugins.Archive } category := h.c.Param("category") if category == "" { category = h.c.Param("tag") if category != "" { allNames := cache.AllTagsNames(h.c) if _, ok := allNames[category]; !ok { return errors.New(str.Join("not exists tag ", category)) } h.categoryType = "post_tag" h.header = fmt.Sprintf("标签: %s", category) } } else { allNames := cache.AllCategoryNames(h.c) if _, ok := allNames[category]; !ok { return errors.New(str.Join("not exists category ", category)) } h.categoryType = "category" h.header = fmt.Sprintf("分类: %s", category) } h.category = category username := h.c.Param("author") if username != "" { allUsername, er := cache.GetAllUsername(h.c) if er != nil { err = er return } if _, ok := allUsername[username]; !ok { err = errors.New(str.Join("user ", username, " is not exists")) return } user, er := cache.GetUserByName(h.c, username) if er != nil { err = er return } h.author = username h.where = append(h.where, []string{ "post_author", "=", strconv.FormatUint(user.Id, 10), "int", }) } if category != "" { h.where = append(h.where, []string{ "d.name", category, }, []string{"taxonomy", h.categoryType}) h.join = append(h.join, []string{ "a", "left join", "wp_term_relationships b", "a.Id=b.object_id", }, []string{ "left join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id", }, []string{ "left join", "wp_terms d", "c.term_id=d.term_id", }) h.setTitleLR(category, wpconfig.Options.Value("blogname")) h.scene = plugins.Category } s := h.c.Query("s") if s != "" && strings.Replace(s, " ", "", -1) != "" { q := str.Join("%", s, "%") h.where = append(h.where, []string{ "and", "post_title", "like", q, "", "or", "post_content", "like", q, "", "or", "post_excerpt", "like", q, "", }, []string{"post_password", ""}) h.postType = append(h.postType, "page", "attachment") h.header = fmt.Sprintf("%s的搜索结果", s) h.setTitleLR(str.Join(`"`, s, `"`, "的搜索结果"), wpconfig.Options.Value("blogname")) h.search = s h.scene = plugins.Search } p := h.c.Query("paged") if p == "" { p = h.c.Param("page") } if p != "" { if pa, err := strconv.Atoi(p); err == nil { h.page = pa } } total := int(atomic.LoadInt64(&dao.TotalRaw)) if total > 0 && total < (h.page-1)*h.pageSize { h.page = 1 } if h.page > 1 && (h.category != "" || h.search != "" || month != "") { h.setTitleLR(fmt.Sprintf("%s-第%d页", h.titleL, h.page), wpconfig.Options.Value("blogname")) } return } func (h *indexHandle) getTotalPage(totalRaws int) int { h.totalPage = int(math.Ceil(float64(totalRaws) / float64(h.pageSize))) return h.totalPage } func Index(c *gin.Context) { h := newIndexHandle(c) var posts []models.Posts var totalRaw int var err error archive := cache.Archives(c) recent := cache.RecentPosts(c, 5) categoryItems := cache.Categories(c) recentComments := cache.RecentComments(c, 5) ginH := gin.H{ "err": err, "options": wpconfig.Options, "recentPosts": recent, "archives": archive, "categories": categoryItems, "search": h.search, "header": h.header, "recentComments": recentComments, } defer func() { code := http.StatusOK if err != nil { code = http.StatusNotFound if h.status == plugins.InternalErr { code = http.StatusInternalServerError c.Error(err) return } c.Error(err) h.status = plugins.Error } t := theme.GetTemplateName() theme.Hook(t, code, c, ginH, h.scene, h.status) }() err = h.parseParams() if err != nil { return } ginH["title"] = h.getTitle() if c.Param("month") != "" { posts, totalRaw, err = cache.GetMonthPostIds(c, c.Param("year"), c.Param("month"), h.page, h.pageSize, h.order) if err != nil { return } } else if h.search != "" { posts, totalRaw, err = cache.SearchPost(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, model.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.postStatus) } else { posts, totalRaw, err = cache.PostLists(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, model.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.postStatus) } if err != nil { h.status = plugins.Error logs.ErrPrintln(err, "获取数据错误") return } if len(posts) < 1 && h.category != "" { h.titleL = "未找到页面" h.status = plugins.Empty404 } pw := h.session.Get("post_password") plug := plugins.NewPostPlugin(c, h.scene) for i, post := range posts { plugins.PasswordProjectTitle(&posts[i]) if post.PostPassword != "" && pw != post.PostPassword { plugins.PasswdProjectContent(&posts[i]) } else { plugins.ApplyPlugin(plug, &posts[i]) } } for i, post := range recent { if post.PostPassword != "" && pw != post.PostPassword { plugins.PasswdProjectContent(&recent[i]) } } q := c.Request.URL.Query().Encode() if q != "" { q = fmt.Sprintf("?%s", q) } ginH["posts"] = posts ginH["totalPage"] = h.getTotalPage(totalRaw) ginH["currentPage"] = h.page ginH["title"] = h.getTitle() ginH["pagination"] = pagination.NewParsePagination(totalRaw, h.pageSize, h.page, h.paginationStep, q, c.Request.URL.Path) }