text字段筛选
This commit is contained in:
9
Makefile
9
Makefile
@@ -28,3 +28,12 @@ service:
|
|||||||
sudo cp webp.service /etc/systemd/system/webp.service
|
sudo cp webp.service /etc/systemd/system/webp.service
|
||||||
sudo systemctl enable webp
|
sudo systemctl enable webp
|
||||||
sudo cp webp.logrotate /etc/logrotate.d/webp
|
sudo cp webp.logrotate /etc/logrotate.d/webp
|
||||||
|
|
||||||
|
# 安装 zinc
|
||||||
|
|
||||||
|
|
||||||
|
# 安装 gorse
|
||||||
|
gorse:
|
||||||
|
export GORSE_DASHBOARD_USER="gorse"
|
||||||
|
export GORSE_DASHBOARD_PASS="gorse"
|
||||||
|
curl -fsSL https://gorse.io/playground | bash
|
||||||
|
18
README.md
18
README.md
@@ -1,11 +1,29 @@
|
|||||||
# webp
|
# webp
|
||||||
|
|
||||||
|
- [ ] 原始图像
|
||||||
|
- [ ] 缩略缓存
|
||||||
|
|
||||||
|
- [ ] 不同类型的用途(文章, 截图, 头像)
|
||||||
|
- [ ] 增量备份
|
||||||
|
|
||||||
|
cdn(img.gameui.net) -> main -> img
|
||||||
|
/articles/{id}/{hash}
|
||||||
|
/users/{id}/{hash}
|
||||||
|
|
||||||
|
UPDATE web_images SET description = '' WHERE description IS NULL;
|
||||||
|
ALTER TABLE web_images MODIFY description VARCHAR(255) DEFAULT '';
|
||||||
|
|
||||||
|
- [ ] 解析 cdn.gameui.net 到 cdn 服务, 并将 cdn 回源指向 def.gameui.net 其解析到新服务器
|
||||||
|
- [ ] 支持带参数下载指定尺寸图像
|
||||||
|
|
||||||
|
|
||||||
- [x] 提供webp生成服务
|
- [x] 提供webp生成服务
|
||||||
- [x] 提供流媒体服务
|
- [x] 提供流媒体服务
|
||||||
- [x] 点击播放之前不加载视频(减少流量消耗)
|
- [x] 点击播放之前不加载视频(减少流量消耗)
|
||||||
- [x] 使用封面图片替代加载视屏第一帧
|
- [x] 使用封面图片替代加载视屏第一帧
|
||||||
- [x] GraphQL 风格API
|
- [x] GraphQL 风格API
|
||||||
- [ ] 列表翻页
|
- [ ] 列表翻页
|
||||||
|
- [ ] OCR 查询支持
|
||||||
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
@@ -3,6 +3,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.satori.love/gameui/webp/models"
|
"git.satori.love/gameui/webp/models"
|
||||||
@@ -12,6 +13,39 @@ import (
|
|||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 自动生成 GraphQL 类型的函数
|
||||||
|
func generateGraphQLType(model interface{}) (*graphql.Object, error) {
|
||||||
|
modelType := reflect.TypeOf(model)
|
||||||
|
if modelType.Kind() != reflect.Struct {
|
||||||
|
return nil, fmt.Errorf("model must be a struct")
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := graphql.Fields{}
|
||||||
|
for i := 0; i < modelType.NumField(); i++ {
|
||||||
|
field := modelType.Field(i)
|
||||||
|
fieldType := graphql.String // 默认使用字符串类型
|
||||||
|
|
||||||
|
// 这里可以根据需要添加更多类型映射
|
||||||
|
switch field.Type.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
fieldType = graphql.String
|
||||||
|
case reflect.Int:
|
||||||
|
fieldType = graphql.Int
|
||||||
|
case reflect.Bool:
|
||||||
|
fieldType = graphql.Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
fields[field.Name] = &graphql.Field{
|
||||||
|
Type: fieldType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return graphql.NewObject(graphql.ObjectConfig{
|
||||||
|
Name: modelType.Name(),
|
||||||
|
Fields: fields,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewSchema(config Config) (graphql.Schema, error) {
|
func NewSchema(config Config) (graphql.Schema, error) {
|
||||||
|
|
||||||
// 打开数据库连接
|
// 打开数据库连接
|
||||||
@@ -27,8 +61,10 @@ func NewSchema(config Config) (graphql.Schema, error) {
|
|||||||
log.Fatalln("连接数据库失败", err)
|
log.Fatalln("连接数据库失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var user, article, text *graphql.Object
|
||||||
|
|
||||||
// 用户的可选字段
|
// 用户的可选字段
|
||||||
user := graphql.NewObject(graphql.ObjectConfig{
|
user = graphql.NewObject(graphql.ObjectConfig{
|
||||||
Name: "User",
|
Name: "User",
|
||||||
Description: "用户信息",
|
Description: "用户信息",
|
||||||
Fields: graphql.Fields{
|
Fields: graphql.Fields{
|
||||||
@@ -43,7 +79,7 @@ func NewSchema(config Config) (graphql.Schema, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 文章的可选字段
|
// 文章的可选字段
|
||||||
article := graphql.NewObject(graphql.ObjectConfig{
|
article = graphql.NewObject(graphql.ObjectConfig{
|
||||||
Name: "Article",
|
Name: "Article",
|
||||||
Description: "文章信息",
|
Description: "文章信息",
|
||||||
Fields: graphql.Fields{
|
Fields: graphql.Fields{
|
||||||
@@ -57,7 +93,7 @@ func NewSchema(config Config) (graphql.Schema, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 图像中的文字提取
|
// 图像中的文字提取
|
||||||
text := graphql.NewObject(graphql.ObjectConfig{
|
text = graphql.NewObject(graphql.ObjectConfig{
|
||||||
Name: "Text",
|
Name: "Text",
|
||||||
Description: "图像中的文字提取",
|
Description: "图像中的文字提取",
|
||||||
Fields: graphql.Fields{
|
Fields: graphql.Fields{
|
||||||
@@ -80,18 +116,41 @@ func NewSchema(config Config) (graphql.Schema, error) {
|
|||||||
"description": &graphql.Field{Type: graphql.String, Description: "图像描述"},
|
"description": &graphql.Field{Type: graphql.String, Description: "图像描述"},
|
||||||
"tags": &graphql.Field{Type: graphql.String, Description: "图像标签"},
|
"tags": &graphql.Field{Type: graphql.String, Description: "图像标签"},
|
||||||
"rank": &graphql.Field{Type: graphql.String, Description: "图像等级"},
|
"rank": &graphql.Field{Type: graphql.String, Description: "图像等级"},
|
||||||
"text": &graphql.Field{Type: graphql.NewList(text), Description: "图像中的文字"},
|
|
||||||
"comment_num": &graphql.Field{Type: graphql.Int, Description: "评论数"},
|
"comment_num": &graphql.Field{Type: graphql.Int, Description: "评论数"},
|
||||||
"article_category_top_id": &graphql.Field{Type: graphql.Int, Description: "文章分类顶级ID"},
|
"article_category_top_id": &graphql.Field{Type: graphql.Int, Description: "文章分类顶级ID"},
|
||||||
"praise_count": &graphql.Field{Type: graphql.Int, Description: "点赞数"},
|
"praise_count": &graphql.Field{Type: graphql.Int, Description: "点赞数"},
|
||||||
"collect_count": &graphql.Field{Type: graphql.Int, Description: "收藏数"},
|
"collect_count": &graphql.Field{Type: graphql.Int, Description: "收藏数"},
|
||||||
"create_time": &graphql.Field{Type: graphql.DateTime, Description: "图像创建时间"},
|
"create_time": &graphql.Field{Type: graphql.DateTime, Description: "图像创建时间"},
|
||||||
"update_time": &graphql.Field{Type: graphql.DateTime, Description: "图像更新时间"},
|
"update_time": &graphql.Field{Type: graphql.DateTime, Description: "图像更新时间"},
|
||||||
"user": &graphql.Field{Type: user, Description: "图像所属用户"},
|
|
||||||
"article": &graphql.Field{Type: article, Description: "图像所属文章"},
|
"article": &graphql.Field{Type: article, Description: "图像所属文章"},
|
||||||
|
"text": &graphql.Field{
|
||||||
|
Type: graphql.NewList(text),
|
||||||
|
Description: "图像中的文字",
|
||||||
|
Args: graphql.FieldConfigArgument{
|
||||||
|
"text": &graphql.ArgumentConfig{Type: graphql.String, Description: "筛选含有指定文字的列"},
|
||||||
|
},
|
||||||
|
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
||||||
|
if p.Args["text"] != nil {
|
||||||
|
var texts TextList
|
||||||
|
for _, text := range p.Source.(Image).Text {
|
||||||
|
fmt.Println("san", text.Text)
|
||||||
|
if strings.Contains(text.Text, p.Args["text"].(string)) {
|
||||||
|
texts = append(texts, text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return texts, nil
|
||||||
|
}
|
||||||
|
return p.Source.(Image).Text, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
image.AddFieldConfig("user", &graphql.Field{Type: user, Description: "图像所属用户"})
|
||||||
|
image.AddFieldConfig("similars", &graphql.Field{Type: graphql.NewList(image), Description: "相似的图像", Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
||||||
|
return []Image{}, nil
|
||||||
|
}})
|
||||||
|
|
||||||
// 将 list 中的字段提取出来用于查询
|
// 将 list 中的字段提取出来用于查询
|
||||||
get_fields := func(requestedFields []ast.Selection) (fields []string) {
|
get_fields := func(requestedFields []ast.Selection) (fields []string) {
|
||||||
for _, field := range requestedFields {
|
for _, field := range requestedFields {
|
||||||
@@ -108,6 +167,10 @@ func NewSchema(config Config) (graphql.Schema, error) {
|
|||||||
fields = append(fields, "article_id")
|
fields = append(fields, "article_id")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if fieldAST.Name.Value == "similars" {
|
||||||
|
// 跳过自定义字段
|
||||||
|
continue
|
||||||
|
}
|
||||||
fields = append(fields, fieldAST.Name.Value)
|
fields = append(fields, fieldAST.Name.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,18 +217,15 @@ func NewSchema(config Config) (graphql.Schema, error) {
|
|||||||
if where_str != "" {
|
if where_str != "" {
|
||||||
where_str = "WHERE " + where_str
|
where_str = "WHERE " + where_str
|
||||||
}
|
}
|
||||||
|
|
||||||
var query strings.Builder
|
var query strings.Builder
|
||||||
var users []User
|
var users []User
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
fields := strings.Join(get_fields(p.Info.FieldASTs[0].SelectionSet.Selections), ",")
|
fields := strings.Join(get_fields(p.Info.FieldASTs[0].SelectionSet.Selections), ",")
|
||||||
query.WriteString(fmt.Sprintf("SELECT %s FROM web_member %s LIMIT %d OFFSET %d", fields, where_str, 10, 0))
|
query.WriteString(fmt.Sprintf("SELECT %s FROM web_member %s LIMIT %d OFFSET %d", fields, where_str, 10, 0))
|
||||||
if err := connection.Select(&users, query.String()); err != nil {
|
if err := connection.Select(&users, query.String()); err != nil {
|
||||||
fmt.Println("获取用户列表失败", err)
|
fmt.Println("获取用户列表失败", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(users) > 0 {
|
if len(users) > 0 {
|
||||||
query.Reset()
|
query.Reset()
|
||||||
query.WriteString(fmt.Sprintf("SELECT COUNT(*) FROM web_member %s", where_str))
|
query.WriteString(fmt.Sprintf("SELECT COUNT(*) FROM web_member %s", where_str))
|
||||||
@@ -174,7 +234,6 @@ func NewSchema(config Config) (graphql.Schema, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"list": users,
|
"list": users,
|
||||||
"total": total,
|
"total": total,
|
||||||
@@ -308,7 +367,7 @@ func NewSchema(config Config) (graphql.Schema, error) {
|
|||||||
"total": 0,
|
"total": 0,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
where = append(where, fmt.Sprintf("id IN (%s) LIMIT %d", id_list_str, len(id_list)))
|
where = append(where, fmt.Sprintf("id IN (%s)", id_list_str))
|
||||||
}
|
}
|
||||||
|
|
||||||
where_str := strings.Join(where, " AND ")
|
where_str := strings.Join(where, " AND ")
|
||||||
@@ -342,17 +401,11 @@ func NewSchema(config Config) (graphql.Schema, error) {
|
|||||||
|
|
||||||
var images ImageList
|
var images ImageList
|
||||||
var q = query.String()
|
var q = query.String()
|
||||||
fmt.Println(q)
|
|
||||||
if err := connection.Select(&images, q); err != nil {
|
if err := connection.Select(&images, q); err != nil {
|
||||||
fmt.Println("获取图像列表失败", err)
|
fmt.Println("获取图像列表失败", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按照 id_list 的顺序重新排序
|
|
||||||
//if len(id_list) > 0 {
|
|
||||||
// images.SortByIDList(id_list)
|
|
||||||
//}
|
|
||||||
|
|
||||||
// 获取用户信息(如果图像列表不为空且请求字段中包含user)
|
// 获取用户信息(如果图像列表不为空且请求字段中包含user)
|
||||||
if len(images) > 0 && strings.Contains(fields, "user") {
|
if len(images) > 0 && strings.Contains(fields, "user") {
|
||||||
user_ids_str := images.ToAllUserID().ToString()
|
user_ids_str := images.ToAllUserID().ToString()
|
||||||
|
@@ -87,16 +87,15 @@ type Image struct {
|
|||||||
Tags string `json:"tags" db:"tags"`
|
Tags string `json:"tags" db:"tags"`
|
||||||
Rank string `json:"rank" db:"rank"`
|
Rank string `json:"rank" db:"rank"`
|
||||||
CommentNum int `json:"comment_num" db:"comment_num"`
|
CommentNum int `json:"comment_num" db:"comment_num"`
|
||||||
ArticleCategoryTopId int `json:"article_category_top_id" db:"article_category_top_id"`
|
|
||||||
PraiseCount int `json:"praise_count" db:"praise_count"`
|
PraiseCount int `json:"praise_count" db:"praise_count"`
|
||||||
CollectCount int `json:"collect_count" db:"collect_count"`
|
CollectCount int `json:"collect_count" db:"collect_count"`
|
||||||
ArticleID int `json:"article_id" db:"article_id"`
|
ArticleID int `json:"article_id" db:"article_id"`
|
||||||
UserID int `json:"user_id" db:"user_id"`
|
UserID int `json:"user_id" db:"user_id"`
|
||||||
User User `json:"user" db:"-"`
|
|
||||||
Article Article `json:"article" db:"-"`
|
|
||||||
CreateTime time.Time `json:"create_time" db:"create_time"`
|
CreateTime time.Time `json:"create_time" db:"create_time"`
|
||||||
UpdateTime time.Time `json:"update_time" db:"update_time"`
|
UpdateTime time.Time `json:"update_time" db:"update_time"`
|
||||||
Text TextList `json:"text" db:"text"`
|
Text TextList `json:"text" db:"text"`
|
||||||
|
User User `json:"user" db:"-"`
|
||||||
|
Article Article `json:"article" db:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TextList []struct {
|
type TextList []struct {
|
||||||
|
Reference in New Issue
Block a user