@@ -0,0 +1,396 @@
|
||||
package aiService
|
||||
|
||||
import (
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/httputil"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/redis"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type AiService struct {
|
||||
c *Conf
|
||||
}
|
||||
|
||||
type Conf struct {
|
||||
AppId int
|
||||
Url string
|
||||
Redis *redis.Client
|
||||
}
|
||||
|
||||
type Option func(c *Conf)
|
||||
|
||||
func NewAiService(opts ...Option) *AiService {
|
||||
c := &Conf{}
|
||||
for _, opt := range opts {
|
||||
opt(c)
|
||||
}
|
||||
return &AiService{
|
||||
c: c,
|
||||
}
|
||||
}
|
||||
|
||||
func Redis(r *redis.Client) Option {
|
||||
return func(c *Conf) {
|
||||
c.Redis = r
|
||||
}
|
||||
}
|
||||
|
||||
func AppId(appId int) Option {
|
||||
return func(c *Conf) {
|
||||
c.AppId = appId
|
||||
}
|
||||
}
|
||||
|
||||
func Url(url string) Option {
|
||||
return func(c *Conf) {
|
||||
c.Url = url
|
||||
}
|
||||
}
|
||||
|
||||
type msg struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
func (m *AiService) getParams(p interface{}) (params map[string]interface{}) {
|
||||
req := structs.New(p)
|
||||
fields := req.Fields()
|
||||
params = make(map[string]interface{})
|
||||
for _, field := range fields {
|
||||
jsonTag := field.Tag("json")
|
||||
tagList := strings.Split(jsonTag, ",")
|
||||
key := field.Name()
|
||||
omitempty := ""
|
||||
if len(tagList) > 0 {
|
||||
key = tagList[0]
|
||||
}
|
||||
if len(tagList) > 1 {
|
||||
omitempty = tagList[1]
|
||||
}
|
||||
kind := reflect.TypeOf(field.Value()).Kind()
|
||||
// 如果是0值忽略或者空指针,不需要传
|
||||
if field.IsZero() && (kind == reflect.Ptr || omitempty == "omitempty") {
|
||||
continue
|
||||
}
|
||||
if kind == reflect.Ptr {
|
||||
// 通过指针取值
|
||||
params[key] = reflect.ValueOf(field.Value()).Elem().Interface()
|
||||
} else {
|
||||
params[key] = field.Value()
|
||||
}
|
||||
}
|
||||
params["appId"] = m.c.AppId
|
||||
return
|
||||
}
|
||||
|
||||
func (s *AiService) getTemplateList(p *TemplateListReq) (result TemplateListResp, err error) {
|
||||
var retMsg msg
|
||||
path := "/api/ai/template/all"
|
||||
params := s.getParams(p)
|
||||
code, err := httputil.DefaultClientGetWithResp(&retMsg, common.BindUrl(s.c.Url, path), nil, params)
|
||||
if err != nil {
|
||||
log.Error("AiService GetTemplateList fail", log.Any("params", params), log.E(err))
|
||||
err = errors.New("AiService GetTemplateList fail")
|
||||
return
|
||||
}
|
||||
if code != 200 {
|
||||
log.Error("AiService GetTemplateList fail", log.Any("params", params), log.Any("code", code))
|
||||
err = errors.New("AiService GetTemplateList fail")
|
||||
return
|
||||
}
|
||||
|
||||
if retMsg.Code != 200 {
|
||||
log.Error("AiService GetTemplateList fail", log.Any("params", params), log.Any("retMsg", retMsg))
|
||||
err = errors.New("AiService GetTemplateList fail")
|
||||
return
|
||||
}
|
||||
|
||||
b, err := json.Marshal(retMsg.Data)
|
||||
if err != nil {
|
||||
log.Error("AiService GetTemplateList json.Marshal fail", log.Any("params", params), log.E(err))
|
||||
err = errors.New("AiService GetTemplateList json.Marshal fail")
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(b, &result); err != nil {
|
||||
log.Error("AiService GetTemplateList json.Unmarshal fail", log.Any("params", params), log.Any("data", string(b)), log.E(err))
|
||||
err = errors.New("AiService GetTemplateList json.Unmarshal fail")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type TemplateDetailReq struct {
|
||||
Ids []primitive.ObjectID `json:"ids" binding:"required"`
|
||||
}
|
||||
|
||||
func (s *AiService) getTemplateDetail(p *TemplateDetailReq) (result TemplateDetailResp, err error) {
|
||||
var retMsg msg
|
||||
path := "/api/ai/template/detail"
|
||||
params := s.getParams(p)
|
||||
code, err := httputil.DefaultClientPostJsonWithResp(&retMsg, common.BindUrl(s.c.Url, path), nil, params)
|
||||
if err != nil {
|
||||
log.Error("AiService GetTemplateDetail fail", log.Any("params", params), log.E(err))
|
||||
err = errors.New("AiService GetTemplateDetail fail")
|
||||
return
|
||||
}
|
||||
if code != 200 {
|
||||
log.Error("AiService GetTemplateDetail fail", log.Any("params", params), log.Any("code", code))
|
||||
err = errors.New("AiService GetTemplateDetail fail")
|
||||
return
|
||||
}
|
||||
|
||||
if retMsg.Code != 200 {
|
||||
log.Error("AiService GetTemplateDetail fail", log.Any("params", params), log.Any("retMsg", retMsg))
|
||||
err = errors.New("AiService GetTemplateDetail fail")
|
||||
return
|
||||
}
|
||||
|
||||
b, err := json.Marshal(retMsg.Data)
|
||||
if err != nil {
|
||||
log.Error("AiService GetTemplateDetail json.Marshal fail", log.Any("params", params), log.E(err))
|
||||
err = errors.New("AiService GetTemplateDetail json.Marshal fail")
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(b, &result); err != nil {
|
||||
log.Error("AiService GetTemplateDetail json.Unmarshal fail", log.Any("params", params), log.Any("data", string(b)), log.E(err))
|
||||
err = errors.New("AiService GetTemplateDetail json.Unmarshal fail")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *AiService) Sync() (err error) {
|
||||
if s.c.Redis == nil {
|
||||
return errors.New("redis is nil")
|
||||
}
|
||||
resp, err := s.getTemplateList(&TemplateListReq{})
|
||||
if err != nil {
|
||||
log.Error("AI Template sync fail", log.E(err))
|
||||
return
|
||||
}
|
||||
for _, template := range resp.TemplateList {
|
||||
b, err := json.Marshal(template)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
// 将模版数据写入redis
|
||||
s.c.Redis.Set(AiTemplateKey(template.ID), string(b), time.Hour*24*7)
|
||||
}
|
||||
var imageCategoryList []Category
|
||||
var videoCategoryList []Category
|
||||
for _, v := range resp.CategoryList {
|
||||
if v.Type == 0 {
|
||||
imageCategoryList = append(imageCategoryList, v)
|
||||
} else {
|
||||
videoCategoryList = append(videoCategoryList, v)
|
||||
}
|
||||
}
|
||||
// 将数据写入写入redis
|
||||
b0, err := json.Marshal(imageCategoryList)
|
||||
if err != nil {
|
||||
log.Error("AI Template json.Marshal(imageCategoryList) fail", log.E(err))
|
||||
return
|
||||
}
|
||||
b1, err := json.Marshal(videoCategoryList)
|
||||
if err != nil {
|
||||
log.Error("AI Template json.Marshal(videoCategoryList) fail", log.E(err))
|
||||
return
|
||||
}
|
||||
err = s.c.Redis.Set(AiCategoryKey(0), string(b0), time.Hour*24*7)
|
||||
if err != nil {
|
||||
log.Error("AI Template Redis.Set(AiCategoryKey(0) fail", log.E(err))
|
||||
return
|
||||
}
|
||||
err = s.c.Redis.Set(AiCategoryKey(1), string(b1), time.Hour*24*7)
|
||||
if err != nil {
|
||||
log.Error("AI Template Redis.Set(AiCategoryKey(1) fail", log.E(err))
|
||||
return
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AiService) GetTemplateList(types int, categoryId string) (categoryList []*Category, queryCategoryId string, templateList []*Template, err error) {
|
||||
if s.c.Redis == nil {
|
||||
err = errors.New("redis nil")
|
||||
return
|
||||
}
|
||||
// 获取分类列表
|
||||
val, err := s.c.Redis.Get(AiCategoryKey(types))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if val == nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal([]byte(*val), &categoryList)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(categoryList) == 0 {
|
||||
return
|
||||
}
|
||||
if categoryId == "" {
|
||||
queryCategoryId = categoryList[0].ID.Hex()
|
||||
} else {
|
||||
queryCategoryId = categoryId
|
||||
}
|
||||
templateIds := []primitive.ObjectID{}
|
||||
for _, v := range categoryList {
|
||||
if v.ID.Hex() == queryCategoryId {
|
||||
templateIds = v.TemplateIds
|
||||
break
|
||||
}
|
||||
}
|
||||
keys := []string{}
|
||||
for _, templateId := range templateIds {
|
||||
keys = append(keys, AiTemplateKey(templateId))
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
return
|
||||
}
|
||||
// 通过id查找这个模版
|
||||
res, err := s.c.Redis.MGet(keys...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, v := range res {
|
||||
templateVal, ok := v.(string)
|
||||
if !ok || templateVal == "" {
|
||||
continue
|
||||
}
|
||||
item := Template{}
|
||||
err = json.Unmarshal([]byte(templateVal), &item)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if item.ModuleType != types {
|
||||
continue
|
||||
}
|
||||
templateList = append(templateList, &item)
|
||||
}
|
||||
return categoryList, queryCategoryId, templateList, nil
|
||||
}
|
||||
|
||||
func (s *AiService) GetTemplate(id primitive.ObjectID) (template Template, err error) {
|
||||
if id.IsZero() {
|
||||
return
|
||||
}
|
||||
if s.c.Redis == nil {
|
||||
err = errors.New("redis nil")
|
||||
return
|
||||
}
|
||||
// 从缓存中获取数据
|
||||
val, err := s.c.Redis.Get(AiTemplateKey(id))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if val != nil && *val != "" {
|
||||
err = json.Unmarshal([]byte(*val), &template)
|
||||
if err == nil {
|
||||
return template, nil
|
||||
}
|
||||
}
|
||||
// 如果获取不到,尝试从ai服务获取
|
||||
res, err := s.getTemplateDetail(&TemplateDetailReq{
|
||||
Ids: []primitive.ObjectID{id},
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(res.List) == 0 {
|
||||
return
|
||||
}
|
||||
template = res.List[0]
|
||||
common.Go(func() {
|
||||
b, err := json.Marshal(template)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 将模版数据写入redis
|
||||
s.c.Redis.Set(AiTemplateKey(template.ID), string(b), time.Hour*48)
|
||||
})
|
||||
return template, nil
|
||||
}
|
||||
|
||||
func (s *AiService) GetTemplateByIds(ids []primitive.ObjectID) (templateList []Template, err error) {
|
||||
if len(ids) == 0 {
|
||||
return
|
||||
}
|
||||
if s.c.Redis == nil {
|
||||
err = errors.New("redis nil")
|
||||
return
|
||||
}
|
||||
|
||||
keys := []string{}
|
||||
for _, id := range ids {
|
||||
keys = append(keys, AiTemplateKey(id))
|
||||
}
|
||||
// 从缓存中获取数据
|
||||
list, err := s.c.Redis.MGet(keys...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
noFoundKey := []int{}
|
||||
for k, v := range list {
|
||||
if v == nil {
|
||||
noFoundKey = append(noFoundKey, k)
|
||||
continue
|
||||
}
|
||||
val, ok := v.(string)
|
||||
if !ok || val == "" {
|
||||
noFoundKey = append(noFoundKey, k)
|
||||
continue
|
||||
}
|
||||
item := Template{}
|
||||
err = json.Unmarshal([]byte(val), &item)
|
||||
if err != nil {
|
||||
noFoundKey = append(noFoundKey, k)
|
||||
continue
|
||||
}
|
||||
templateList = append(templateList, item)
|
||||
}
|
||||
noFoundIds := []primitive.ObjectID{}
|
||||
for _, k := range noFoundKey {
|
||||
noFoundIds = append(noFoundIds, ids[k])
|
||||
}
|
||||
if len(noFoundIds) == 0 {
|
||||
return
|
||||
}
|
||||
// 如果获取不到,尝试从ai服务获取
|
||||
res, err := s.getTemplateDetail(&TemplateDetailReq{
|
||||
Ids: noFoundIds,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(res.List) == 0 {
|
||||
return
|
||||
}
|
||||
templateList = append(templateList, res.List...)
|
||||
common.Go(func() {
|
||||
// 将查到的写入redis
|
||||
for _, template := range res.List {
|
||||
b, err := json.Marshal(template)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 将模版数据写入redis
|
||||
s.c.Redis.Set(AiTemplateKey(template.ID), string(b), time.Hour*48)
|
||||
}
|
||||
|
||||
})
|
||||
return templateList, nil
|
||||
}
|
||||
Reference in New Issue
Block a user