diff --git a/api/graphql.go b/api/graphql.go index 8208377..ea093c2 100644 --- a/api/graphql.go +++ b/api/graphql.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "reflect" + "regexp" "strconv" "strings" @@ -174,6 +175,7 @@ func NewSchema(config Config) (graphql.Schema, error) { "collect_count": &graphql.Field{Type: graphql.Int, Description: "收藏数"}, "create_time": &graphql.Field{Type: graphql.DateTime, Description: "图像创建时间"}, "update_time": &graphql.Field{Type: graphql.DateTime, Description: "图像更新时间"}, + "activity": &graphql.Field{Type: graphql.Boolean, Description: "图像活动"}, "article": &graphql.Field{Type: article, Description: "图像所属文章"}, "praise": &graphql.Field{Type: graphql.Boolean, Description: "当前用户是否点赞", Resolve: func(p graphql.ResolveParams) (interface{}, error) { var user_id = p.Context.Value("user_id").(int) @@ -397,34 +399,34 @@ func NewSchema(config Config) (graphql.Schema, error) { }), Args: graphql.FieldConfigArgument{ "praise": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中指定用户点赞过的"}, - "era": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中指定上线年份的"}, - "device": &graphql.ArgumentConfig{Type: graphql.String, Description: "游戏设备"}, - "sort": &graphql.ArgumentConfig{Type: graphql.String, Description: "排序方法", DefaultValue: "id"}, - "order": &graphql.ArgumentConfig{Type: orderType, Description: "排序方向", DefaultValue: "ASC"}, - "orientation": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选横屏竖屏图像"}, "follower": &graphql.ArgumentConfig{Type: graphql.Int, Description: "获取指定ID用户的关注列表发布的图像"}, "interest": &graphql.ArgumentConfig{Type: graphql.Int, Description: "获取指定ID用户的兴趣推荐图像"}, "similar": &graphql.ArgumentConfig{Type: graphql.Int, Description: "获取与指定ID图像相似的图像"}, "id": &graphql.ArgumentConfig{Type: graphql.Int, Description: "获取指定ID的图像"}, "width": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中指定宽度的"}, "height": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中指定高度的"}, + "comment_num": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中评论数等于指定值的"}, + "praise_count": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中点赞数等于指定值的"}, + "collect_count": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中收藏数等于指定值的"}, + "article_id": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中属于指定文章ID的"}, + "user_id": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中属于指定用户ID的"}, + "era": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中指定上线年份的"}, + "device": &graphql.ArgumentConfig{Type: graphql.String, Description: "游戏设备"}, + "sort": &graphql.ArgumentConfig{Type: graphql.String, Description: "排序方法", DefaultValue: "id"}, + "orientation": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选横屏竖屏图像"}, "content": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中含有指定内容的"}, "remark": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中含有指定备注的"}, "description": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中含有指定描述的"}, "tags": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中含有指定标签的"}, "rank": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中含有指定等级的"}, "text": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中含有指定文字的"}, - "comment_num": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中评论数等于指定值的"}, - "praise_count": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中点赞数等于指定值的"}, - "collect_count": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中收藏数等于指定值的"}, - "article_id": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中属于指定文章ID的"}, - "user_id": &graphql.ArgumentConfig{Type: graphql.Int, Description: "筛选图像中属于指定用户ID的"}, "create_time": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中创建时间等于指定值的"}, "update_time": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选图像中更新时间等于指定值的"}, "first": &graphql.ArgumentConfig{Type: graphql.Int, Description: "翻页参数(傳回清單中的前n個元素)"}, "last": &graphql.ArgumentConfig{Type: graphql.Int, Description: "翻页参数(傳回清單中的最後n個元素)"}, "after": &graphql.ArgumentConfig{Type: graphql.Int, Description: "翻页参数(傳回清單中指定遊標之後的元素)"}, "before": &graphql.ArgumentConfig{Type: graphql.Int, Description: "翻页参数(傳回清單中指定遊標之前的元素)"}, + "order": &graphql.ArgumentConfig{Type: orderType, Description: "排序方向", DefaultValue: "ASC"}, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { // 定义参数结构体 @@ -443,7 +445,7 @@ func NewSchema(config Config) (graphql.Schema, error) { var total int var images []Image - var query = goqu.Dialect("mysql").Select("web_images.id", goqu.L("ROW_NUMBER() OVER(ORDER BY id ASC)").As("row_num")).From("web_images") + var query = goqu.Dialect("mysql").From("web_images") // 参数映射 var argFormat = []string{"id", "width", "height", "content", "remark", "description", "tags", "rank", "comment_num", "praise_count", "collect_count", "article_id", "user_id"} @@ -504,22 +506,9 @@ func NewSchema(config Config) (graphql.Schema, error) { item = append(item, int(id)) } - toGoquExpressions := func(ids []int) []goqu.Expression { - expressions := make([]goqu.Expression, len(ids)) - for i, id := range ids { - expressions[i] = goqu.V(id) - } - return expressions - } - - expressions := toGoquExpressions(item) - interfaceExpressions := make([]interface{}, len(expressions)) - for i, expr := range expressions { - interfaceExpressions[i] = expr - } - - query = query.Where(goqu.Ex{"web_images.id": goqu.Op{"in": item}}). - Order(goqu.Func("FIELD", append([]interface{}{goqu.I("web_images.id")}, interfaceExpressions...)...).Asc()) + query = query.Where(goqu.Ex{"web_images.id": goqu.Op{"in": item}}).Select("web_images.id", goqu.L( + fmt.Sprintf("ROW_NUMBER() OVER(ORDER BY FIELD(%s, %s))", "web_images.id", regexp.MustCompile(`[\[\]]`).ReplaceAllString(strings.Join(strings.Fields(fmt.Sprint(item)), ", "), "")), + ).As("row_num")) } // 筛选:兴趣推荐 @@ -592,8 +581,8 @@ func NewSchema(config Config) (graphql.Schema, error) { // 取所有数据的前N条 var cursor string - if args.After != 0 { - cursor = fmt.Sprintf(`WHERE row_num > (SELECT row_num FROM RankedArticles WHERE RankedArticles.id = %d)`, args.After) + if p.Args["after"] != nil { + cursor = fmt.Sprintf(`WHERE row_num > (SELECT row_num FROM RankedArticles WHERE RankedArticles.id = %d)`, p.Args["after"].(int)) } var limit int = 10 @@ -603,15 +592,15 @@ func NewSchema(config Config) (graphql.Schema, error) { limit = args.Last } - // 取大于游标的数据 sql = fmt.Sprintf(` - WITH RankedArticles AS (%s) - SELECT web_images.* FROM web_images JOIN( - SELECT RankedArticles.id FROM RankedArticles %s ORDER BY row_num LIMIT %d - ) AS LimitedRanked ON web_images.id = LimitedRanked.id; + WITH RankedArticles AS (%s) + SELECT * FROM web_images INNER JOIN( + SELECT id, row_num FROM RankedArticles %s + ) AS LimitedRanked ON LimitedRanked.id = web_images.id + ORDER BY LimitedRanked.row_num LIMIT %d `, sql, cursor, limit) - fmt.Println(sql) + fmt.Println("cursor:", cursor, limit) if err := db.Raw(sql).Scan(&images).Error; err != nil { fmt.Println("获取图像列表失败", err) @@ -629,7 +618,8 @@ func NewSchema(config Config) (graphql.Schema, error) { find = find.Preload(item) } - if err := find.Find(&images).Error; err != nil { + orderClause := fmt.Sprintf("FIELD(id, %s)", regexp.MustCompile(`[\[\]]`).ReplaceAllString(strings.Join(strings.Fields(fmt.Sprint(ids)), ","), "")) + if err := find.Order(orderClause).Find(&images).Error; err != nil { fmt.Println("获取图像列表失败", err) return nil, err }