update
This commit is contained in:
parent
a60608bdbc
commit
d6fabedb23
@ -33,6 +33,7 @@ import (
|
|||||||
"leafdev.top/Ecosystem/recommender/internal/service/jwks"
|
"leafdev.top/Ecosystem/recommender/internal/service/jwks"
|
||||||
"leafdev.top/Ecosystem/recommender/internal/service/post"
|
"leafdev.top/Ecosystem/recommender/internal/service/post"
|
||||||
"leafdev.top/Ecosystem/recommender/internal/service/stream"
|
"leafdev.top/Ecosystem/recommender/internal/service/stream"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/service/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Injectors from wire.go:
|
// Injectors from wire.go:
|
||||||
@ -52,7 +53,10 @@ func CreateApp() (*base.Application, error) {
|
|||||||
categoryService := category.NewService(query)
|
categoryService := category.NewService(query)
|
||||||
postController := application_v1.NewPostController(authService, applicationService, postService, categoryService)
|
postController := application_v1.NewPostController(authService, applicationService, postService, categoryService)
|
||||||
categoryController := application_v1.NewCategoryController(authService, applicationService, postService, categoryService)
|
categoryController := application_v1.NewCategoryController(authService, applicationService, postService, categoryService)
|
||||||
handlers := http.NewHandler(applicationController, application_v1ApplicationController, postController, categoryController)
|
userService := user.NewService(query, postService, loggerLogger)
|
||||||
|
redisRedis := redis.NewRedis(config)
|
||||||
|
userController := application_v1.NewUserController(authService, applicationService, userService, postService, loggerLogger, redisRedis)
|
||||||
|
handlers := http.NewHandler(applicationController, application_v1ApplicationController, postController, categoryController, userController)
|
||||||
api := router.NewApiRoute(handlers)
|
api := router.NewApiRoute(handlers)
|
||||||
swaggerRouter := router.NewSwaggerRoute()
|
swaggerRouter := router.NewSwaggerRoute()
|
||||||
ginLoggerMiddleware := middleware.NewGinLoggerMiddleware(loggerLogger)
|
ginLoggerMiddleware := middleware.NewGinLoggerMiddleware(loggerLogger)
|
||||||
@ -67,8 +71,7 @@ func CreateApp() (*base.Application, error) {
|
|||||||
grpcInterceptor := grpc.NewInterceptor(interceptorAuth, interceptorLogger)
|
grpcInterceptor := grpc.NewInterceptor(interceptorAuth, interceptorLogger)
|
||||||
grpcHandlers := grpc.NewHandler(documentService, grpcInterceptor)
|
grpcHandlers := grpc.NewHandler(documentService, grpcInterceptor)
|
||||||
handlerHandler := handler.NewHandler(grpcHandlers, handlers)
|
handlerHandler := handler.NewHandler(grpcHandlers, handlers)
|
||||||
serviceService := service.NewService(loggerLogger, jwksJWKS, streamService, authService, applicationService, postService, categoryService)
|
serviceService := service.NewService(loggerLogger, jwksJWKS, streamService, authService, applicationService, postService, categoryService, userService)
|
||||||
redisRedis := redis.NewRedis(config)
|
|
||||||
batchBatch := batch.NewBatch(loggerLogger)
|
batchBatch := batch.NewBatch(loggerLogger)
|
||||||
s3S3 := s3.NewS3(config)
|
s3S3 := s3.NewS3(config)
|
||||||
baseApplication := base.NewApplication(config, httpServer, handlerHandler, loggerLogger, serviceService, httpMiddleware, redisRedis, batchBatch, s3S3, db, query)
|
baseApplication := base.NewApplication(config, httpServer, handlerHandler, loggerLogger, serviceService, httpMiddleware, redisRedis, batchBatch, s3S3, db, query)
|
||||||
|
@ -22,6 +22,7 @@ redis:
|
|||||||
port: 6379
|
port: 6379
|
||||||
password: ""
|
password: ""
|
||||||
db: 0
|
db: 0
|
||||||
|
prefix: "recommender_"
|
||||||
|
|
||||||
jwks:
|
jwks:
|
||||||
url: ""
|
url: ""
|
||||||
|
125
docs/docs.go
125
docs/docs.go
@ -697,6 +697,120 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/applications/v1/users/_dislike": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "从用户的标签喜好中移除内容",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"application_api"
|
||||||
|
],
|
||||||
|
"summary": "Dislike",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "UserLikePost",
|
||||||
|
"name": "UserLikePost",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.UserLikePost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.ResponseBody"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/entity.Category"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.ResponseBody"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/applications/v1/users/_like": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "将标签附加到用户名",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"application_api"
|
||||||
|
],
|
||||||
|
"summary": "Like",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "UserLikePost",
|
||||||
|
"name": "UserLikePost",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.UserLikePost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.ResponseBody"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/entity.Category"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.ResponseBody"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
@ -900,6 +1014,17 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.UserLikePost": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"external_user_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"post_id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"response.ResponseBody": {
|
"response.ResponseBody": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -688,6 +688,120 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/applications/v1/users/_dislike": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "从用户的标签喜好中移除内容",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"application_api"
|
||||||
|
],
|
||||||
|
"summary": "Dislike",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "UserLikePost",
|
||||||
|
"name": "UserLikePost",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.UserLikePost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.ResponseBody"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/entity.Category"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.ResponseBody"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/applications/v1/users/_like": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "将标签附加到用户名",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"application_api"
|
||||||
|
],
|
||||||
|
"summary": "Like",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "UserLikePost",
|
||||||
|
"name": "UserLikePost",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.UserLikePost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.ResponseBody"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/entity.Category"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.ResponseBody"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
@ -891,6 +1005,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.UserLikePost": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"external_user_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"post_id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"response.ResponseBody": {
|
"response.ResponseBody": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -133,6 +133,13 @@ definitions:
|
|||||||
- target_id
|
- target_id
|
||||||
- title
|
- title
|
||||||
type: object
|
type: object
|
||||||
|
request.UserLikePost:
|
||||||
|
properties:
|
||||||
|
external_user_id:
|
||||||
|
type: string
|
||||||
|
post_id:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
response.ResponseBody:
|
response.ResponseBody:
|
||||||
properties:
|
properties:
|
||||||
data: {}
|
data: {}
|
||||||
@ -541,6 +548,72 @@ paths:
|
|||||||
summary: 新建资源
|
summary: 新建资源
|
||||||
tags:
|
tags:
|
||||||
- application_api
|
- application_api
|
||||||
|
/applications/v1/users/_dislike:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 从用户的标签喜好中移除内容
|
||||||
|
parameters:
|
||||||
|
- description: UserLikePost
|
||||||
|
in: body
|
||||||
|
name: UserLikePost
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.UserLikePost'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/response.ResponseBody'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/entity.Category'
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.ResponseBody'
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Dislike
|
||||||
|
tags:
|
||||||
|
- application_api
|
||||||
|
/applications/v1/users/_like:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 将标签附加到用户名
|
||||||
|
parameters:
|
||||||
|
- description: UserLikePost
|
||||||
|
in: body
|
||||||
|
name: UserLikePost
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.UserLikePost'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/response.ResponseBody'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/entity.Category'
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.ResponseBody'
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Like
|
||||||
|
tags:
|
||||||
|
- application_api
|
||||||
securityDefinitions:
|
securityDefinitions:
|
||||||
ApiKeyAuth:
|
ApiKeyAuth:
|
||||||
in: header
|
in: header
|
||||||
|
@ -34,6 +34,7 @@ func main() {
|
|||||||
entity.ApplicationToken{},
|
entity.ApplicationToken{},
|
||||||
entity.UserTagScore{},
|
entity.UserTagScore{},
|
||||||
entity.Category{},
|
entity.Category{},
|
||||||
|
entity.ExternalUser{},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Generate Type Safe API with Dynamic SQL defined on Querier interface for `model.User` and `model.Company`
|
// Generate Type Safe API with Dynamic SQL defined on Querier interface for `model.User` and `model.Company`
|
||||||
|
@ -53,6 +53,7 @@ type Redis struct {
|
|||||||
Host string `yaml:"host"`
|
Host string `yaml:"host"`
|
||||||
Port int `yaml:"port"`
|
Port int `yaml:"port"`
|
||||||
Password string `yaml:"password"`
|
Password string `yaml:"password"`
|
||||||
|
Prefix string `yaml:"prefix"`
|
||||||
DB int `yaml:"db"`
|
DB int `yaml:"db"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
type Redis struct {
|
type Redis struct {
|
||||||
Client *redis.Client
|
Client *redis.Client
|
||||||
Locker *redislock.Client
|
Locker *redislock.Client
|
||||||
|
config *conf.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRedis(c *conf.Config) *Redis {
|
func NewRedis(c *conf.Config) *Redis {
|
||||||
@ -32,7 +33,12 @@ func NewRedis(c *conf.Config) *Redis {
|
|||||||
var r = &Redis{
|
var r = &Redis{
|
||||||
Client: client,
|
Client: client,
|
||||||
Locker: locker,
|
Locker: locker,
|
||||||
|
config: c,
|
||||||
}
|
}
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Redis) Prefix(key string) string {
|
||||||
|
return fmt.Sprintf("%s:%s", r.config.Redis.Prefix, key)
|
||||||
|
}
|
||||||
|
486
internal/dao/external_users.gen.go
Normal file
486
internal/dao/external_users.gen.go
Normal file
@ -0,0 +1,486 @@
|
|||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
|
"gorm.io/gorm/schema"
|
||||||
|
|
||||||
|
"gorm.io/gen"
|
||||||
|
"gorm.io/gen/field"
|
||||||
|
|
||||||
|
"gorm.io/plugin/dbresolver"
|
||||||
|
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/entity"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newExternalUser(db *gorm.DB, opts ...gen.DOOption) externalUser {
|
||||||
|
_externalUser := externalUser{}
|
||||||
|
|
||||||
|
_externalUser.externalUserDo.UseDB(db, opts...)
|
||||||
|
_externalUser.externalUserDo.UseModel(&entity.ExternalUser{})
|
||||||
|
|
||||||
|
tableName := _externalUser.externalUserDo.TableName()
|
||||||
|
_externalUser.ALL = field.NewAsterisk(tableName)
|
||||||
|
_externalUser.Id = field.NewUint(tableName, "id")
|
||||||
|
_externalUser.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
|
_externalUser.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
|
_externalUser.Name = field.NewString(tableName, "name")
|
||||||
|
_externalUser.Email = field.NewString(tableName, "email")
|
||||||
|
_externalUser.ExternalId = field.NewString(tableName, "external_id")
|
||||||
|
_externalUser.Summary = field.NewString(tableName, "summary")
|
||||||
|
_externalUser.ApplicationId = field.NewUint(tableName, "application_id")
|
||||||
|
_externalUser.Application = externalUserBelongsToApplication{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Application", "entity.Application"),
|
||||||
|
}
|
||||||
|
|
||||||
|
_externalUser.fillFieldMap()
|
||||||
|
|
||||||
|
return _externalUser
|
||||||
|
}
|
||||||
|
|
||||||
|
type externalUser struct {
|
||||||
|
externalUserDo
|
||||||
|
|
||||||
|
ALL field.Asterisk
|
||||||
|
Id field.Uint
|
||||||
|
CreatedAt field.Time
|
||||||
|
UpdatedAt field.Time
|
||||||
|
Name field.String
|
||||||
|
Email field.String
|
||||||
|
ExternalId field.String
|
||||||
|
Summary field.String
|
||||||
|
ApplicationId field.Uint
|
||||||
|
Application externalUserBelongsToApplication
|
||||||
|
|
||||||
|
fieldMap map[string]field.Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUser) Table(newTableName string) *externalUser {
|
||||||
|
e.externalUserDo.UseTable(newTableName)
|
||||||
|
return e.updateTableName(newTableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUser) As(alias string) *externalUser {
|
||||||
|
e.externalUserDo.DO = *(e.externalUserDo.As(alias).(*gen.DO))
|
||||||
|
return e.updateTableName(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *externalUser) updateTableName(table string) *externalUser {
|
||||||
|
e.ALL = field.NewAsterisk(table)
|
||||||
|
e.Id = field.NewUint(table, "id")
|
||||||
|
e.CreatedAt = field.NewTime(table, "created_at")
|
||||||
|
e.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
|
e.Name = field.NewString(table, "name")
|
||||||
|
e.Email = field.NewString(table, "email")
|
||||||
|
e.ExternalId = field.NewString(table, "external_id")
|
||||||
|
e.Summary = field.NewString(table, "summary")
|
||||||
|
e.ApplicationId = field.NewUint(table, "application_id")
|
||||||
|
|
||||||
|
e.fillFieldMap()
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *externalUser) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||||
|
_f, ok := e.fieldMap[fieldName]
|
||||||
|
if !ok || _f == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
_oe, ok := _f.(field.OrderExpr)
|
||||||
|
return _oe, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *externalUser) fillFieldMap() {
|
||||||
|
e.fieldMap = make(map[string]field.Expr, 9)
|
||||||
|
e.fieldMap["id"] = e.Id
|
||||||
|
e.fieldMap["created_at"] = e.CreatedAt
|
||||||
|
e.fieldMap["updated_at"] = e.UpdatedAt
|
||||||
|
e.fieldMap["name"] = e.Name
|
||||||
|
e.fieldMap["email"] = e.Email
|
||||||
|
e.fieldMap["external_id"] = e.ExternalId
|
||||||
|
e.fieldMap["summary"] = e.Summary
|
||||||
|
e.fieldMap["application_id"] = e.ApplicationId
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUser) clone(db *gorm.DB) externalUser {
|
||||||
|
e.externalUserDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUser) replaceDB(db *gorm.DB) externalUser {
|
||||||
|
e.externalUserDo.ReplaceDB(db)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
type externalUserBelongsToApplication struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplication) Where(conds ...field.Expr) *externalUserBelongsToApplication {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplication) WithContext(ctx context.Context) *externalUserBelongsToApplication {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplication) Session(session *gorm.Session) *externalUserBelongsToApplication {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplication) Model(m *entity.ExternalUser) *externalUserBelongsToApplicationTx {
|
||||||
|
return &externalUserBelongsToApplicationTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
type externalUserBelongsToApplicationTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplicationTx) Find() (result *entity.Application, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplicationTx) Append(values ...*entity.Application) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplicationTx) Replace(values ...*entity.Application) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplicationTx) Delete(values ...*entity.Application) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplicationTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a externalUserBelongsToApplicationTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
type externalUserDo struct{ gen.DO }
|
||||||
|
|
||||||
|
type IExternalUserDo interface {
|
||||||
|
gen.SubQuery
|
||||||
|
Debug() IExternalUserDo
|
||||||
|
WithContext(ctx context.Context) IExternalUserDo
|
||||||
|
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||||
|
ReplaceDB(db *gorm.DB)
|
||||||
|
ReadDB() IExternalUserDo
|
||||||
|
WriteDB() IExternalUserDo
|
||||||
|
As(alias string) gen.Dao
|
||||||
|
Session(config *gorm.Session) IExternalUserDo
|
||||||
|
Columns(cols ...field.Expr) gen.Columns
|
||||||
|
Clauses(conds ...clause.Expression) IExternalUserDo
|
||||||
|
Not(conds ...gen.Condition) IExternalUserDo
|
||||||
|
Or(conds ...gen.Condition) IExternalUserDo
|
||||||
|
Select(conds ...field.Expr) IExternalUserDo
|
||||||
|
Where(conds ...gen.Condition) IExternalUserDo
|
||||||
|
Order(conds ...field.Expr) IExternalUserDo
|
||||||
|
Distinct(cols ...field.Expr) IExternalUserDo
|
||||||
|
Omit(cols ...field.Expr) IExternalUserDo
|
||||||
|
Join(table schema.Tabler, on ...field.Expr) IExternalUserDo
|
||||||
|
LeftJoin(table schema.Tabler, on ...field.Expr) IExternalUserDo
|
||||||
|
RightJoin(table schema.Tabler, on ...field.Expr) IExternalUserDo
|
||||||
|
Group(cols ...field.Expr) IExternalUserDo
|
||||||
|
Having(conds ...gen.Condition) IExternalUserDo
|
||||||
|
Limit(limit int) IExternalUserDo
|
||||||
|
Offset(offset int) IExternalUserDo
|
||||||
|
Count() (count int64, err error)
|
||||||
|
Scopes(funcs ...func(gen.Dao) gen.Dao) IExternalUserDo
|
||||||
|
Unscoped() IExternalUserDo
|
||||||
|
Create(values ...*entity.ExternalUser) error
|
||||||
|
CreateInBatches(values []*entity.ExternalUser, batchSize int) error
|
||||||
|
Save(values ...*entity.ExternalUser) error
|
||||||
|
First() (*entity.ExternalUser, error)
|
||||||
|
Take() (*entity.ExternalUser, error)
|
||||||
|
Last() (*entity.ExternalUser, error)
|
||||||
|
Find() ([]*entity.ExternalUser, error)
|
||||||
|
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.ExternalUser, err error)
|
||||||
|
FindInBatches(result *[]*entity.ExternalUser, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||||
|
Pluck(column field.Expr, dest interface{}) error
|
||||||
|
Delete(...*entity.ExternalUser) (info gen.ResultInfo, err error)
|
||||||
|
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||||
|
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||||
|
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||||
|
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||||
|
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||||
|
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||||
|
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||||
|
Attrs(attrs ...field.AssignExpr) IExternalUserDo
|
||||||
|
Assign(attrs ...field.AssignExpr) IExternalUserDo
|
||||||
|
Joins(fields ...field.RelationField) IExternalUserDo
|
||||||
|
Preload(fields ...field.RelationField) IExternalUserDo
|
||||||
|
FirstOrInit() (*entity.ExternalUser, error)
|
||||||
|
FirstOrCreate() (*entity.ExternalUser, error)
|
||||||
|
FindByPage(offset int, limit int) (result []*entity.ExternalUser, count int64, err error)
|
||||||
|
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||||
|
Scan(result interface{}) (err error)
|
||||||
|
Returning(value interface{}, columns ...string) IExternalUserDo
|
||||||
|
UnderlyingDB() *gorm.DB
|
||||||
|
schema.Tabler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Debug() IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Debug())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) WithContext(ctx context.Context) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.WithContext(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) ReadDB() IExternalUserDo {
|
||||||
|
return e.Clauses(dbresolver.Read)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) WriteDB() IExternalUserDo {
|
||||||
|
return e.Clauses(dbresolver.Write)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Session(config *gorm.Session) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Session(config))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Clauses(conds ...clause.Expression) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Clauses(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Returning(value interface{}, columns ...string) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Returning(value, columns...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Not(conds ...gen.Condition) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Not(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Or(conds ...gen.Condition) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Or(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Select(conds ...field.Expr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Select(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Where(conds ...gen.Condition) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Where(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Order(conds ...field.Expr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Order(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Distinct(cols ...field.Expr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Distinct(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Omit(cols ...field.Expr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Omit(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Join(table schema.Tabler, on ...field.Expr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Join(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) LeftJoin(table schema.Tabler, on ...field.Expr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.LeftJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) RightJoin(table schema.Tabler, on ...field.Expr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.RightJoin(table, on...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Group(cols ...field.Expr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Group(cols...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Having(conds ...gen.Condition) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Having(conds...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Limit(limit int) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Limit(limit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Offset(offset int) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Offset(offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Scopes(funcs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Unscoped() IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Unscoped())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Create(values ...*entity.ExternalUser) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return e.DO.Create(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) CreateInBatches(values []*entity.ExternalUser, batchSize int) error {
|
||||||
|
return e.DO.CreateInBatches(values, batchSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save : !!! underlying implementation is different with GORM
|
||||||
|
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||||
|
func (e externalUserDo) Save(values ...*entity.ExternalUser) error {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return e.DO.Save(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) First() (*entity.ExternalUser, error) {
|
||||||
|
if result, err := e.DO.First(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*entity.ExternalUser), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Take() (*entity.ExternalUser, error) {
|
||||||
|
if result, err := e.DO.Take(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*entity.ExternalUser), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Last() (*entity.ExternalUser, error) {
|
||||||
|
if result, err := e.DO.Last(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*entity.ExternalUser), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Find() ([]*entity.ExternalUser, error) {
|
||||||
|
result, err := e.DO.Find()
|
||||||
|
return result.([]*entity.ExternalUser), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*entity.ExternalUser, err error) {
|
||||||
|
buf := make([]*entity.ExternalUser, 0, batchSize)
|
||||||
|
err = e.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||||
|
defer func() { results = append(results, buf...) }()
|
||||||
|
return fc(tx, batch)
|
||||||
|
})
|
||||||
|
return results, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) FindInBatches(result *[]*entity.ExternalUser, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||||
|
return e.DO.FindInBatches(result, batchSize, fc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Attrs(attrs ...field.AssignExpr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Attrs(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Assign(attrs ...field.AssignExpr) IExternalUserDo {
|
||||||
|
return e.withDO(e.DO.Assign(attrs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Joins(fields ...field.RelationField) IExternalUserDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
e = *e.withDO(e.DO.Joins(_f))
|
||||||
|
}
|
||||||
|
return &e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Preload(fields ...field.RelationField) IExternalUserDo {
|
||||||
|
for _, _f := range fields {
|
||||||
|
e = *e.withDO(e.DO.Preload(_f))
|
||||||
|
}
|
||||||
|
return &e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) FirstOrInit() (*entity.ExternalUser, error) {
|
||||||
|
if result, err := e.DO.FirstOrInit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*entity.ExternalUser), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) FirstOrCreate() (*entity.ExternalUser, error) {
|
||||||
|
if result, err := e.DO.FirstOrCreate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
return result.(*entity.ExternalUser), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) FindByPage(offset int, limit int) (result []*entity.ExternalUser, count int64, err error) {
|
||||||
|
result, err = e.Offset(offset).Limit(limit).Find()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||||
|
count = int64(size + offset)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err = e.Offset(-1).Limit(-1).Count()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||||
|
count, err = e.Count()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = e.Offset(offset).Limit(limit).Scan(result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Scan(result interface{}) (err error) {
|
||||||
|
return e.DO.Scan(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e externalUserDo) Delete(models ...*entity.ExternalUser) (result gen.ResultInfo, err error) {
|
||||||
|
return e.DO.Delete(models)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *externalUserDo) withDO(do gen.Dao) *externalUserDo {
|
||||||
|
e.DO = *do.(*gen.DO)
|
||||||
|
return e
|
||||||
|
}
|
@ -20,6 +20,7 @@ var (
|
|||||||
Application *application
|
Application *application
|
||||||
ApplicationToken *applicationToken
|
ApplicationToken *applicationToken
|
||||||
Category *category
|
Category *category
|
||||||
|
ExternalUser *externalUser
|
||||||
Post *post
|
Post *post
|
||||||
PostTag *postTag
|
PostTag *postTag
|
||||||
Tag *tag
|
Tag *tag
|
||||||
@ -33,6 +34,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
|||||||
Application = &Q.Application
|
Application = &Q.Application
|
||||||
ApplicationToken = &Q.ApplicationToken
|
ApplicationToken = &Q.ApplicationToken
|
||||||
Category = &Q.Category
|
Category = &Q.Category
|
||||||
|
ExternalUser = &Q.ExternalUser
|
||||||
Post = &Q.Post
|
Post = &Q.Post
|
||||||
PostTag = &Q.PostTag
|
PostTag = &Q.PostTag
|
||||||
Tag = &Q.Tag
|
Tag = &Q.Tag
|
||||||
@ -47,6 +49,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
|||||||
Application: newApplication(db, opts...),
|
Application: newApplication(db, opts...),
|
||||||
ApplicationToken: newApplicationToken(db, opts...),
|
ApplicationToken: newApplicationToken(db, opts...),
|
||||||
Category: newCategory(db, opts...),
|
Category: newCategory(db, opts...),
|
||||||
|
ExternalUser: newExternalUser(db, opts...),
|
||||||
Post: newPost(db, opts...),
|
Post: newPost(db, opts...),
|
||||||
PostTag: newPostTag(db, opts...),
|
PostTag: newPostTag(db, opts...),
|
||||||
Tag: newTag(db, opts...),
|
Tag: newTag(db, opts...),
|
||||||
@ -62,6 +65,7 @@ type Query struct {
|
|||||||
Application application
|
Application application
|
||||||
ApplicationToken applicationToken
|
ApplicationToken applicationToken
|
||||||
Category category
|
Category category
|
||||||
|
ExternalUser externalUser
|
||||||
Post post
|
Post post
|
||||||
PostTag postTag
|
PostTag postTag
|
||||||
Tag tag
|
Tag tag
|
||||||
@ -78,6 +82,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
|
|||||||
Application: q.Application.clone(db),
|
Application: q.Application.clone(db),
|
||||||
ApplicationToken: q.ApplicationToken.clone(db),
|
ApplicationToken: q.ApplicationToken.clone(db),
|
||||||
Category: q.Category.clone(db),
|
Category: q.Category.clone(db),
|
||||||
|
ExternalUser: q.ExternalUser.clone(db),
|
||||||
Post: q.Post.clone(db),
|
Post: q.Post.clone(db),
|
||||||
PostTag: q.PostTag.clone(db),
|
PostTag: q.PostTag.clone(db),
|
||||||
Tag: q.Tag.clone(db),
|
Tag: q.Tag.clone(db),
|
||||||
@ -101,6 +106,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
|||||||
Application: q.Application.replaceDB(db),
|
Application: q.Application.replaceDB(db),
|
||||||
ApplicationToken: q.ApplicationToken.replaceDB(db),
|
ApplicationToken: q.ApplicationToken.replaceDB(db),
|
||||||
Category: q.Category.replaceDB(db),
|
Category: q.Category.replaceDB(db),
|
||||||
|
ExternalUser: q.ExternalUser.replaceDB(db),
|
||||||
Post: q.Post.replaceDB(db),
|
Post: q.Post.replaceDB(db),
|
||||||
PostTag: q.PostTag.replaceDB(db),
|
PostTag: q.PostTag.replaceDB(db),
|
||||||
Tag: q.Tag.replaceDB(db),
|
Tag: q.Tag.replaceDB(db),
|
||||||
@ -114,6 +120,7 @@ type queryCtx struct {
|
|||||||
Application IApplicationDo
|
Application IApplicationDo
|
||||||
ApplicationToken IApplicationTokenDo
|
ApplicationToken IApplicationTokenDo
|
||||||
Category ICategoryDo
|
Category ICategoryDo
|
||||||
|
ExternalUser IExternalUserDo
|
||||||
Post IPostDo
|
Post IPostDo
|
||||||
PostTag IPostTagDo
|
PostTag IPostTagDo
|
||||||
Tag ITagDo
|
Tag ITagDo
|
||||||
@ -127,6 +134,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
|||||||
Application: q.Application.WithContext(ctx),
|
Application: q.Application.WithContext(ctx),
|
||||||
ApplicationToken: q.ApplicationToken.WithContext(ctx),
|
ApplicationToken: q.ApplicationToken.WithContext(ctx),
|
||||||
Category: q.Category.WithContext(ctx),
|
Category: q.Category.WithContext(ctx),
|
||||||
|
ExternalUser: q.ExternalUser.WithContext(ctx),
|
||||||
Post: q.Post.WithContext(ctx),
|
Post: q.Post.WithContext(ctx),
|
||||||
PostTag: q.PostTag.WithContext(ctx),
|
PostTag: q.PostTag.WithContext(ctx),
|
||||||
Tag: q.Tag.WithContext(ctx),
|
Tag: q.Tag.WithContext(ctx),
|
||||||
|
@ -27,9 +27,15 @@ func newUserLike(db *gorm.DB, opts ...gen.DOOption) userLike {
|
|||||||
|
|
||||||
tableName := _userLike.userLikeDo.TableName()
|
tableName := _userLike.userLikeDo.TableName()
|
||||||
_userLike.ALL = field.NewAsterisk(tableName)
|
_userLike.ALL = field.NewAsterisk(tableName)
|
||||||
_userLike.UserId = field.NewString(tableName, "user_id")
|
_userLike.ExternalUserId = field.NewUint(tableName, "external_user_id")
|
||||||
_userLike.PostId = field.NewUint(tableName, "post_id")
|
_userLike.PostId = field.NewUint(tableName, "post_id")
|
||||||
_userLike.Type = field.NewString(tableName, "type")
|
_userLike.Type = field.NewString(tableName, "type")
|
||||||
|
_userLike.ApplicationId = field.NewUint(tableName, "application_id")
|
||||||
|
_userLike.Application = userLikeBelongsToApplication{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Application", "entity.Application"),
|
||||||
|
}
|
||||||
|
|
||||||
_userLike.fillFieldMap()
|
_userLike.fillFieldMap()
|
||||||
|
|
||||||
@ -39,10 +45,12 @@ func newUserLike(db *gorm.DB, opts ...gen.DOOption) userLike {
|
|||||||
type userLike struct {
|
type userLike struct {
|
||||||
userLikeDo
|
userLikeDo
|
||||||
|
|
||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
UserId field.String
|
ExternalUserId field.Uint
|
||||||
PostId field.Uint
|
PostId field.Uint
|
||||||
Type field.String
|
Type field.String
|
||||||
|
ApplicationId field.Uint
|
||||||
|
Application userLikeBelongsToApplication
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@ -59,9 +67,10 @@ func (u userLike) As(alias string) *userLike {
|
|||||||
|
|
||||||
func (u *userLike) updateTableName(table string) *userLike {
|
func (u *userLike) updateTableName(table string) *userLike {
|
||||||
u.ALL = field.NewAsterisk(table)
|
u.ALL = field.NewAsterisk(table)
|
||||||
u.UserId = field.NewString(table, "user_id")
|
u.ExternalUserId = field.NewUint(table, "external_user_id")
|
||||||
u.PostId = field.NewUint(table, "post_id")
|
u.PostId = field.NewUint(table, "post_id")
|
||||||
u.Type = field.NewString(table, "type")
|
u.Type = field.NewString(table, "type")
|
||||||
|
u.ApplicationId = field.NewUint(table, "application_id")
|
||||||
|
|
||||||
u.fillFieldMap()
|
u.fillFieldMap()
|
||||||
|
|
||||||
@ -78,10 +87,12 @@ func (u *userLike) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *userLike) fillFieldMap() {
|
func (u *userLike) fillFieldMap() {
|
||||||
u.fieldMap = make(map[string]field.Expr, 3)
|
u.fieldMap = make(map[string]field.Expr, 5)
|
||||||
u.fieldMap["user_id"] = u.UserId
|
u.fieldMap["external_user_id"] = u.ExternalUserId
|
||||||
u.fieldMap["post_id"] = u.PostId
|
u.fieldMap["post_id"] = u.PostId
|
||||||
u.fieldMap["type"] = u.Type
|
u.fieldMap["type"] = u.Type
|
||||||
|
u.fieldMap["application_id"] = u.ApplicationId
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u userLike) clone(db *gorm.DB) userLike {
|
func (u userLike) clone(db *gorm.DB) userLike {
|
||||||
@ -94,6 +105,77 @@ func (u userLike) replaceDB(db *gorm.DB) userLike {
|
|||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type userLikeBelongsToApplication struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplication) Where(conds ...field.Expr) *userLikeBelongsToApplication {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplication) WithContext(ctx context.Context) *userLikeBelongsToApplication {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplication) Session(session *gorm.Session) *userLikeBelongsToApplication {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplication) Model(m *entity.UserLike) *userLikeBelongsToApplicationTx {
|
||||||
|
return &userLikeBelongsToApplicationTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
type userLikeBelongsToApplicationTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplicationTx) Find() (result *entity.Application, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplicationTx) Append(values ...*entity.Application) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplicationTx) Replace(values ...*entity.Application) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplicationTx) Delete(values ...*entity.Application) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplicationTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userLikeBelongsToApplicationTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
type userLikeDo struct{ gen.DO }
|
type userLikeDo struct{ gen.DO }
|
||||||
|
|
||||||
type IUserLikeDo interface {
|
type IUserLikeDo interface {
|
||||||
|
@ -27,9 +27,10 @@ func newUserTagScore(db *gorm.DB, opts ...gen.DOOption) userTagScore {
|
|||||||
|
|
||||||
tableName := _userTagScore.userTagScoreDo.TableName()
|
tableName := _userTagScore.userTagScoreDo.TableName()
|
||||||
_userTagScore.ALL = field.NewAsterisk(tableName)
|
_userTagScore.ALL = field.NewAsterisk(tableName)
|
||||||
_userTagScore.UserId = field.NewString(tableName, "user_id")
|
_userTagScore.ExternalUserId = field.NewUint(tableName, "external_user_id")
|
||||||
_userTagScore.TagId = field.NewUint(tableName, "tag_id")
|
_userTagScore.TagId = field.NewUint(tableName, "tag_id")
|
||||||
_userTagScore.Score = field.NewInt(tableName, "score")
|
_userTagScore.Score = field.NewInt(tableName, "score")
|
||||||
|
_userTagScore.ApplicationId = field.NewUint(tableName, "application_id")
|
||||||
_userTagScore.Tag = userTagScoreBelongsToTag{
|
_userTagScore.Tag = userTagScoreBelongsToTag{
|
||||||
db: db.Session(&gorm.Session{}),
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
@ -41,6 +42,12 @@ func newUserTagScore(db *gorm.DB, opts ...gen.DOOption) userTagScore {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_userTagScore.Application = userTagScoreBelongsToApplication{
|
||||||
|
db: db.Session(&gorm.Session{}),
|
||||||
|
|
||||||
|
RelationField: field.NewRelation("Application", "entity.Application"),
|
||||||
|
}
|
||||||
|
|
||||||
_userTagScore.fillFieldMap()
|
_userTagScore.fillFieldMap()
|
||||||
|
|
||||||
return _userTagScore
|
return _userTagScore
|
||||||
@ -49,11 +56,14 @@ func newUserTagScore(db *gorm.DB, opts ...gen.DOOption) userTagScore {
|
|||||||
type userTagScore struct {
|
type userTagScore struct {
|
||||||
userTagScoreDo
|
userTagScoreDo
|
||||||
|
|
||||||
ALL field.Asterisk
|
ALL field.Asterisk
|
||||||
UserId field.String
|
ExternalUserId field.Uint
|
||||||
TagId field.Uint
|
TagId field.Uint
|
||||||
Score field.Int
|
Score field.Int
|
||||||
Tag userTagScoreBelongsToTag
|
ApplicationId field.Uint
|
||||||
|
Tag userTagScoreBelongsToTag
|
||||||
|
|
||||||
|
Application userTagScoreBelongsToApplication
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@ -70,9 +80,10 @@ func (u userTagScore) As(alias string) *userTagScore {
|
|||||||
|
|
||||||
func (u *userTagScore) updateTableName(table string) *userTagScore {
|
func (u *userTagScore) updateTableName(table string) *userTagScore {
|
||||||
u.ALL = field.NewAsterisk(table)
|
u.ALL = field.NewAsterisk(table)
|
||||||
u.UserId = field.NewString(table, "user_id")
|
u.ExternalUserId = field.NewUint(table, "external_user_id")
|
||||||
u.TagId = field.NewUint(table, "tag_id")
|
u.TagId = field.NewUint(table, "tag_id")
|
||||||
u.Score = field.NewInt(table, "score")
|
u.Score = field.NewInt(table, "score")
|
||||||
|
u.ApplicationId = field.NewUint(table, "application_id")
|
||||||
|
|
||||||
u.fillFieldMap()
|
u.fillFieldMap()
|
||||||
|
|
||||||
@ -89,10 +100,11 @@ func (u *userTagScore) GetFieldByName(fieldName string) (field.OrderExpr, bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *userTagScore) fillFieldMap() {
|
func (u *userTagScore) fillFieldMap() {
|
||||||
u.fieldMap = make(map[string]field.Expr, 4)
|
u.fieldMap = make(map[string]field.Expr, 6)
|
||||||
u.fieldMap["user_id"] = u.UserId
|
u.fieldMap["external_user_id"] = u.ExternalUserId
|
||||||
u.fieldMap["tag_id"] = u.TagId
|
u.fieldMap["tag_id"] = u.TagId
|
||||||
u.fieldMap["score"] = u.Score
|
u.fieldMap["score"] = u.Score
|
||||||
|
u.fieldMap["application_id"] = u.ApplicationId
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +193,77 @@ func (a userTagScoreBelongsToTagTx) Count() int64 {
|
|||||||
return a.tx.Count()
|
return a.tx.Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type userTagScoreBelongsToApplication struct {
|
||||||
|
db *gorm.DB
|
||||||
|
|
||||||
|
field.RelationField
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplication) Where(conds ...field.Expr) *userTagScoreBelongsToApplication {
|
||||||
|
if len(conds) == 0 {
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := make([]clause.Expression, 0, len(conds))
|
||||||
|
for _, cond := range conds {
|
||||||
|
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||||
|
}
|
||||||
|
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplication) WithContext(ctx context.Context) *userTagScoreBelongsToApplication {
|
||||||
|
a.db = a.db.WithContext(ctx)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplication) Session(session *gorm.Session) *userTagScoreBelongsToApplication {
|
||||||
|
a.db = a.db.Session(session)
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplication) Model(m *entity.UserTagScore) *userTagScoreBelongsToApplicationTx {
|
||||||
|
return &userTagScoreBelongsToApplicationTx{a.db.Model(m).Association(a.Name())}
|
||||||
|
}
|
||||||
|
|
||||||
|
type userTagScoreBelongsToApplicationTx struct{ tx *gorm.Association }
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplicationTx) Find() (result *entity.Application, err error) {
|
||||||
|
return result, a.tx.Find(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplicationTx) Append(values ...*entity.Application) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Append(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplicationTx) Replace(values ...*entity.Application) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Replace(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplicationTx) Delete(values ...*entity.Application) (err error) {
|
||||||
|
targetValues := make([]interface{}, len(values))
|
||||||
|
for i, v := range values {
|
||||||
|
targetValues[i] = v
|
||||||
|
}
|
||||||
|
return a.tx.Delete(targetValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplicationTx) Clear() error {
|
||||||
|
return a.tx.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a userTagScoreBelongsToApplicationTx) Count() int64 {
|
||||||
|
return a.tx.Count()
|
||||||
|
}
|
||||||
|
|
||||||
type userTagScoreDo struct{ gen.DO }
|
type userTagScoreDo struct{ gen.DO }
|
||||||
|
|
||||||
type IUserTagScoreDo interface {
|
type IUserTagScoreDo interface {
|
||||||
|
@ -11,10 +11,27 @@ func (u *User) TableName() string {
|
|||||||
return "users"
|
return "users"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ExternalUser struct {
|
||||||
|
Model
|
||||||
|
Id schema.EntityId `gorm:"primarykey" json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
ExternalId string `json:"external_id"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
ApplicationId schema.EntityId `json:"application_id"`
|
||||||
|
Application *Application
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ExternalUser) TableName() string {
|
||||||
|
return "external_users"
|
||||||
|
}
|
||||||
|
|
||||||
type UserLike struct {
|
type UserLike struct {
|
||||||
UserId schema.UserId `gorm:"primarykey" json:"user_id"`
|
ExternalUserId schema.EntityId `gorm:"primarykey" json:"external_user_id"`
|
||||||
PostId schema.EntityId `gorm:"primarykey" json:"post_id"`
|
PostId schema.EntityId `gorm:"primarykey" json:"post_id"`
|
||||||
Type schema.UserLikeType `json:"type"`
|
Type schema.UserLikeType `json:"type"`
|
||||||
|
Application *Application
|
||||||
|
ApplicationId schema.EntityId `json:"application_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserLike) TableName() string {
|
func (u *UserLike) TableName() string {
|
||||||
@ -22,10 +39,12 @@ func (u *UserLike) TableName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UserTagScore struct {
|
type UserTagScore struct {
|
||||||
UserId schema.UserId `gorm:"primarykey" json:"user_id"`
|
ExternalUserId schema.EntityId `gorm:"primarykey" json:"external_user_id"`
|
||||||
TagId schema.EntityId `gorm:"primarykey" json:"tag_id"`
|
TagId schema.EntityId `gorm:"primarykey" json:"tag_id"`
|
||||||
Tag *Tag
|
Tag *Tag
|
||||||
Score int `json:"score"`
|
Score int `json:"score"`
|
||||||
|
Application *Application
|
||||||
|
ApplicationId schema.EntityId `json:"application_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserTagScore) TableName() string {
|
func (u *UserTagScore) TableName() string {
|
||||||
|
199
internal/handler/http/controller/application_v1/users.go
Normal file
199
internal/handler/http/controller/application_v1/users.go
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
package application_v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/base/logger"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/base/redis"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/handler/http/request"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/handler/http/response"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/service/application"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/service/auth"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/service/post"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/service/user"
|
||||||
|
"leafdev.top/Ecosystem/recommender/pkg/consts"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const TaskProcessing = "user_likes"
|
||||||
|
|
||||||
|
var LockTTL = time.Minute * 10
|
||||||
|
|
||||||
|
type UserController struct {
|
||||||
|
authService *auth.Service
|
||||||
|
applicationService *application.Service
|
||||||
|
userService *user.Service
|
||||||
|
postService *post.Service
|
||||||
|
logger *logger.Logger
|
||||||
|
redis *redis.Redis
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserController(
|
||||||
|
authService *auth.Service,
|
||||||
|
applicationService *application.Service,
|
||||||
|
userService *user.Service,
|
||||||
|
postService *post.Service,
|
||||||
|
logger *logger.Logger,
|
||||||
|
redis *redis.Redis,
|
||||||
|
|
||||||
|
) *UserController {
|
||||||
|
return &UserController{
|
||||||
|
authService: authService,
|
||||||
|
applicationService: applicationService,
|
||||||
|
userService: userService,
|
||||||
|
postService: postService,
|
||||||
|
logger: logger,
|
||||||
|
redis: redis,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Like godoc
|
||||||
|
// @Summary Like
|
||||||
|
// @Description 将标签附加到用户名
|
||||||
|
// @Tags application_api
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param UserLikePost body request.UserLikePost true "UserLikePost"
|
||||||
|
// @Success 200 {object} response.ResponseBody{data=entity.Category}
|
||||||
|
// @Failure 400 {object} response.ResponseBody
|
||||||
|
// @Router /applications/v1/users/_like [post]
|
||||||
|
func (uc *UserController) Like(c *gin.Context) {
|
||||||
|
app, err := uc.authService.GetApplication(c)
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusBadRequest).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var userLikePostRequest = &request.UserLikePost{}
|
||||||
|
|
||||||
|
if err := c.ShouldBindJSON(userLikePostRequest); err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusBadRequest).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
externalUser, err := uc.userService.GetOrCreateExternalUser(c, userLikePostRequest.ExternalUserId, app)
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// posts
|
||||||
|
postEntity, err := uc.postService.GetPostById(c, userLikePostRequest.PostId)
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if postEntity.ApplicationId != app.Id {
|
||||||
|
response.Ctx(c).Status(http.StatusNotFound).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测是否有
|
||||||
|
var cacheKey = uc.redis.Prefix(TaskProcessing + ":" + userLikePostRequest.PostId.String())
|
||||||
|
// if exists
|
||||||
|
exists, err := uc.redis.Client.Exists(c, cacheKey).Result()
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists > 0 {
|
||||||
|
response.Ctx(c).Status(http.StatusTooEarly).Error(consts.ErrAnotherOperationInProgress).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = uc.redis.Client.Set(c, cacheKey, userLikePostRequest.ExternalUserId, LockTTL).Result()
|
||||||
|
|
||||||
|
go func(prefix string) {
|
||||||
|
err = uc.userService.LikePost(c, externalUser, app, postEntity)
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := uc.redis.Client.Del(c, prefix).Result()
|
||||||
|
if err != nil {
|
||||||
|
uc.logger.Sugar.Error(err)
|
||||||
|
}
|
||||||
|
}(cacheKey)
|
||||||
|
|
||||||
|
response.Ctx(c).Status(http.StatusNoContent).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dislike godoc
|
||||||
|
// @Summary Dislike
|
||||||
|
// @Description 从用户的标签喜好中移除内容
|
||||||
|
// @Tags application_api
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Param UserLikePost body request.UserLikePost true "UserLikePost"
|
||||||
|
// @Success 200 {object} response.ResponseBody{data=entity.Category}
|
||||||
|
// @Failure 400 {object} response.ResponseBody
|
||||||
|
// @Router /applications/v1/users/_dislike [post]
|
||||||
|
func (uc *UserController) Dislike(c *gin.Context) {
|
||||||
|
app, err := uc.authService.GetApplication(c)
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusBadRequest).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var userDislikePostRequest = &request.UserDislikePost{}
|
||||||
|
|
||||||
|
if err := c.ShouldBindJSON(userDislikePostRequest); err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusBadRequest).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
externalUser, err := uc.userService.GetOrCreateExternalUser(c, userDislikePostRequest.ExternalUserId, app)
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// posts
|
||||||
|
postEntity, err := uc.postService.GetPostById(c, userDislikePostRequest.PostId)
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if postEntity.ApplicationId != app.Id {
|
||||||
|
response.Ctx(c).Status(http.StatusNotFound).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测是否有
|
||||||
|
var cacheKey = uc.redis.Prefix(TaskProcessing + ":" + userDislikePostRequest.PostId.String())
|
||||||
|
exists, err := uc.redis.Client.Exists(c, cacheKey).Result()
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists > 0 {
|
||||||
|
response.Ctx(c).Status(http.StatusTooEarly).Error(consts.ErrAnotherOperationInProgress).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = uc.redis.Client.Set(c, cacheKey, userDislikePostRequest.ExternalUserId, LockTTL).Result()
|
||||||
|
|
||||||
|
go func(prefix string) {
|
||||||
|
err = uc.userService.DislikePost(c, externalUser, app, postEntity)
|
||||||
|
if err != nil {
|
||||||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := uc.redis.Client.Del(c, prefix).Result()
|
||||||
|
if err != nil {
|
||||||
|
uc.logger.Sugar.Error(err)
|
||||||
|
}
|
||||||
|
}(cacheKey)
|
||||||
|
|
||||||
|
response.Ctx(c).Status(http.StatusNoContent).Send()
|
||||||
|
return
|
||||||
|
}
|
@ -17,6 +17,7 @@ var ProviderSet = wire.NewSet(
|
|||||||
application_v1.NewApplicationController,
|
application_v1.NewApplicationController,
|
||||||
application_v1.NewPostController,
|
application_v1.NewPostController,
|
||||||
application_v1.NewCategoryController,
|
application_v1.NewCategoryController,
|
||||||
|
application_v1.NewUserController,
|
||||||
NewHandler,
|
NewHandler,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ type Handlers struct {
|
|||||||
ApplicationApi *application_v1.ApplicationController
|
ApplicationApi *application_v1.ApplicationController
|
||||||
ApplicationPostApi *application_v1.PostController
|
ApplicationPostApi *application_v1.PostController
|
||||||
ApplicationCategoryApi *application_v1.CategoryController
|
ApplicationCategoryApi *application_v1.CategoryController
|
||||||
|
ApplicationUserApi *application_v1.UserController
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(
|
func NewHandler(
|
||||||
@ -53,11 +55,14 @@ func NewHandler(
|
|||||||
applicationApiController *application_v1.ApplicationController,
|
applicationApiController *application_v1.ApplicationController,
|
||||||
applicationPostApi *application_v1.PostController,
|
applicationPostApi *application_v1.PostController,
|
||||||
applicationCategoryApi *application_v1.CategoryController,
|
applicationCategoryApi *application_v1.CategoryController,
|
||||||
|
applicationUserApi *application_v1.UserController,
|
||||||
|
|
||||||
) *Handlers {
|
) *Handlers {
|
||||||
return &Handlers{
|
return &Handlers{
|
||||||
ApplicationController: applicationController,
|
ApplicationController: applicationController,
|
||||||
ApplicationApi: applicationApiController,
|
ApplicationApi: applicationApiController,
|
||||||
ApplicationPostApi: applicationPostApi,
|
ApplicationPostApi: applicationPostApi,
|
||||||
ApplicationCategoryApi: applicationCategoryApi,
|
ApplicationCategoryApi: applicationCategoryApi,
|
||||||
|
ApplicationUserApi: applicationUserApi,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,3 +9,13 @@ type ApplicationId struct {
|
|||||||
type ApplicationCreateRequest struct {
|
type ApplicationCreateRequest struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserLikePost struct {
|
||||||
|
PostId schema.EntityId `json:"post_id" uri:"post_id"`
|
||||||
|
ExternalUserId string `json:"external_user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserDislikePost struct {
|
||||||
|
PostId schema.EntityId `json:"post_id" uri:"post_id"`
|
||||||
|
ExternalUserId string `json:"external_user_id"`
|
||||||
|
}
|
||||||
|
@ -23,6 +23,22 @@ CREATE TABLE `application_tokens`
|
|||||||
foreign key (application_id) references applications (id) on delete cascade
|
foreign key (application_id) references applications (id) on delete cascade
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `external_users`
|
||||||
|
(
|
||||||
|
id serial NOT NULL,
|
||||||
|
name varchar(255) DEFAULT NULL,
|
||||||
|
email varchar(255) DEFAULT NULL,
|
||||||
|
external_id varchar(255) NOT NULL,
|
||||||
|
summary varchar(255) DEFAULT NULL,
|
||||||
|
application_id bigint unsigned NOT NULL,
|
||||||
|
created_at timestamp DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at timestamp DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
primary key (id),
|
||||||
|
index (external_id),
|
||||||
|
foreign key (application_id) references applications (id) on delete cascade
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE `categories`
|
CREATE TABLE `categories`
|
||||||
(
|
(
|
||||||
id serial NOT NULL,
|
id serial NOT NULL,
|
||||||
@ -88,27 +104,29 @@ CREATE TABLE `post_tags`
|
|||||||
-- user tag scores
|
-- user tag scores
|
||||||
CREATE TABLE `user_tag_scores`
|
CREATE TABLE `user_tag_scores`
|
||||||
(
|
(
|
||||||
user_id varchar(255) NOT NULL,
|
external_user_id bigint unsigned NOT NULL,
|
||||||
tag_id bigint unsigned NOT NULL,
|
tag_id bigint unsigned NOT NULL,
|
||||||
score int NOT NULL,
|
score int NOT NULL,
|
||||||
application_id bigint unsigned NOT NULL,
|
application_id bigint unsigned NOT NULL,
|
||||||
primary key (user_id, tag_id),
|
primary key (external_user_id, tag_id),
|
||||||
index (score, application_id),
|
index (score, application_id),
|
||||||
foreign key (tag_id) references tags (id) on delete cascade,
|
foreign key (tag_id) references tags (id) on delete cascade,
|
||||||
foreign key (application_id) references applications (id) on delete cascade
|
foreign key (application_id) references applications (id) on delete cascade,
|
||||||
|
foreign key (external_user_id) references external_users (id) on delete cascade
|
||||||
);
|
);
|
||||||
|
|
||||||
-- user likes
|
-- user likes
|
||||||
CREATE TABLE `user_likes`
|
CREATE TABLE `user_likes`
|
||||||
(
|
(
|
||||||
user_id varchar(255) NOT NULL,
|
external_user_id bigint unsigned NOT NULL,
|
||||||
post_id bigint unsigned NOT NULL,
|
post_id bigint unsigned NOT NULL,
|
||||||
type enum ('like', 'dislike') NOT NULL,
|
type enum ('like', 'dislike') NOT NULL,
|
||||||
application_id bigint unsigned NOT NULL,
|
application_id bigint unsigned NOT NULL,
|
||||||
primary key (user_id, post_id),
|
primary key (external_user_id, post_id),
|
||||||
index (type, application_id),
|
index (type, application_id),
|
||||||
foreign key (post_id) references posts (id) on delete cascade,
|
foreign key (post_id) references posts (id) on delete cascade,
|
||||||
foreign key (application_id) references applications (id) on delete cascade
|
foreign key (application_id) references applications (id) on delete cascade,
|
||||||
|
foreign key (external_user_id) references external_users (id) on delete cascade
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -122,3 +140,4 @@ DROP TABLE IF EXISTS `tags`;
|
|||||||
DROP TABLE IF EXISTS `categories`;
|
DROP TABLE IF EXISTS `categories`;
|
||||||
DROP TABLE IF EXISTS `application_tokens`;
|
DROP TABLE IF EXISTS `application_tokens`;
|
||||||
DROP TABLE IF EXISTS `applications`;
|
DROP TABLE IF EXISTS `applications`;
|
||||||
|
DROP TABLE IF EXISTS `external_users`;
|
||||||
|
@ -45,4 +45,7 @@ func (a *Api) InitApplicationApi(r *gin.RouterGroup) {
|
|||||||
r.POST("/categories", a.h.ApplicationCategoryApi.Save)
|
r.POST("/categories", a.h.ApplicationCategoryApi.Save)
|
||||||
r.GET("/categories/:category_id", a.h.ApplicationCategoryApi.Get)
|
r.GET("/categories/:category_id", a.h.ApplicationCategoryApi.Get)
|
||||||
r.DELETE("/categories/:category_id", a.h.ApplicationCategoryApi.Delete)
|
r.DELETE("/categories/:category_id", a.h.ApplicationCategoryApi.Delete)
|
||||||
|
|
||||||
|
r.POST("/users/_like", a.h.ApplicationUserApi.Like)
|
||||||
|
r.POST("/users/_dislike", a.h.ApplicationUserApi.Dislike)
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ type User struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UserId string
|
type UserId string
|
||||||
|
type ExternalUserId uint
|
||||||
|
|
||||||
func (u UserId) String() string {
|
func (u UserId) String() string {
|
||||||
return string(u)
|
return string(u)
|
||||||
|
@ -51,3 +51,20 @@ func (s *Service) DeletePost(c context.Context, post *entity.Post) error {
|
|||||||
func (s *Service) GetPostById(c context.Context, postId schema.EntityId) (*entity.Post, error) {
|
func (s *Service) GetPostById(c context.Context, postId schema.EntityId) (*entity.Post, error) {
|
||||||
return s.dao.WithContext(c).Post.Preload(s.dao.Post.Application).Where(s.dao.Post.Id.Eq(postId.Uint())).First()
|
return s.dao.WithContext(c).Post.Preload(s.dao.Post.Application).Where(s.dao.Post.Id.Eq(postId.Uint())).First()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetPostTags(c context.Context, postEntity *entity.Post) ([]*entity.Tag, error) {
|
||||||
|
postTags, err := s.dao.WithContext(c).PostTag.Preload(s.dao.PostTag.Tag).
|
||||||
|
Where(s.dao.PostTag.PostId.Eq(postEntity.Id.Uint())).Find()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tags []*entity.Tag
|
||||||
|
|
||||||
|
for _, postTag := range postTags {
|
||||||
|
tags = append(tags, postTag.Tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags, err
|
||||||
|
}
|
||||||
|
@ -28,7 +28,6 @@ func (s *Service) GetTag(c context.Context, name string, applicationEntity *enti
|
|||||||
FirstOrCreate()
|
FirstOrCreate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has Bind
|
|
||||||
func (s *Service) HasBindTag(c context.Context, post *entity.Post, tagName string) (bool, error) {
|
func (s *Service) HasBindTag(c context.Context, post *entity.Post, tagName string) (bool, error) {
|
||||||
tag, err := s.GetTag(c, tagName, post.Application)
|
tag, err := s.GetTag(c, tagName, post.Application)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -46,12 +45,15 @@ func (s *Service) HasBindTag(c context.Context, post *entity.Post, tagName strin
|
|||||||
|
|
||||||
func (s *Service) BindTag(c context.Context, post *entity.Post, tagName string) error {
|
func (s *Service) BindTag(c context.Context, post *entity.Post, tagName string) error {
|
||||||
tag, err := s.GetTag(c, tagName, post.Application)
|
tag, err := s.GetTag(c, tagName, post.Application)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
bind, err := s.HasBindTag(c, post, tag.Name)
|
bind, err := s.HasBindTag(c, post, tag.Name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if !bind {
|
if !bind {
|
||||||
err = s.dao.WithContext(c).PostTag.Create(&entity.PostTag{
|
err = s.dao.WithContext(c).PostTag.Create(&entity.PostTag{
|
||||||
PostId: &post.Id,
|
PostId: &post.Id,
|
||||||
@ -59,7 +61,7 @@ func (s *Service) BindTag(c context.Context, post *entity.Post, tagName string)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) MarkAsProcessed(c context.Context, post *entity.Post) error {
|
func (s *Service) MarkAsProcessed(c context.Context, post *entity.Post) error {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"leafdev.top/Ecosystem/recommender/internal/service/jwks"
|
"leafdev.top/Ecosystem/recommender/internal/service/jwks"
|
||||||
"leafdev.top/Ecosystem/recommender/internal/service/post"
|
"leafdev.top/Ecosystem/recommender/internal/service/post"
|
||||||
"leafdev.top/Ecosystem/recommender/internal/service/stream"
|
"leafdev.top/Ecosystem/recommender/internal/service/stream"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/service/user"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
)
|
)
|
||||||
@ -20,6 +21,7 @@ type Service struct {
|
|||||||
Application *application.Service
|
Application *application.Service
|
||||||
Post *post.Service
|
Post *post.Service
|
||||||
Category *category.Service
|
Category *category.Service
|
||||||
|
User *user.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
var Provider = wire.NewSet(
|
var Provider = wire.NewSet(
|
||||||
@ -29,6 +31,7 @@ var Provider = wire.NewSet(
|
|||||||
application.NewService,
|
application.NewService,
|
||||||
post.NewService,
|
post.NewService,
|
||||||
category.NewService,
|
category.NewService,
|
||||||
|
user.NewService,
|
||||||
NewService,
|
NewService,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,6 +43,7 @@ func NewService(
|
|||||||
application *application.Service,
|
application *application.Service,
|
||||||
post *post.Service,
|
post *post.Service,
|
||||||
category *category.Service,
|
category *category.Service,
|
||||||
|
user *user.Service,
|
||||||
) *Service {
|
) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
logger,
|
logger,
|
||||||
@ -49,5 +53,6 @@ func NewService(
|
|||||||
application,
|
application,
|
||||||
post,
|
post,
|
||||||
category,
|
category,
|
||||||
|
user,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
internal/service/user/external.go
Normal file
35
internal/service/user/external.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/entity"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) GetOrCreateExternalUser(c context.Context, externalUserId string, applicationEntity *entity.Application) (*entity.ExternalUser, error) {
|
||||||
|
//Where(s.dao.UserTagScore.ExternalUserId.Eq(externalUserEntity.Id.Uint())).
|
||||||
|
count, err := s.dao.WithContext(c).ExternalUser.
|
||||||
|
Where(s.dao.ExternalUser.ApplicationId.Eq(applicationEntity.Id.Uint())).
|
||||||
|
Where(s.dao.ExternalUser.ExternalId.Eq(externalUserId)).Count()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if count > 0 {
|
||||||
|
eu, err := s.dao.WithContext(c).ExternalUser.
|
||||||
|
Where(s.dao.ExternalUser.ApplicationId.Eq(applicationEntity.Id.Uint())).
|
||||||
|
Where(s.dao.ExternalUser.ExternalId.Eq(externalUserId)).First()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return eu, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
eu := &entity.ExternalUser{
|
||||||
|
ApplicationId: applicationEntity.Id,
|
||||||
|
ExternalId: externalUserId,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.dao.WithContext(c).ExternalUser.Create(eu)
|
||||||
|
|
||||||
|
return eu, err
|
||||||
|
}
|
148
internal/service/user/posts.go
Normal file
148
internal/service/user/posts.go
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/entity"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/schema"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const TaskProcessing = "user_likes"
|
||||||
|
|
||||||
|
var LockTTL = time.Minute * 10
|
||||||
|
|
||||||
|
func (s *Service) HasLiked(c context.Context, externalUserEntity *entity.ExternalUser, applicationEntity *entity.Application, postEntity *entity.Post) (bool, error) {
|
||||||
|
count, err := s.dao.WithContext(c).UserLike.Where(s.dao.UserLike.ExternalUserId.Eq(externalUserEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserLike.PostId.Eq(postEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserLike.ApplicationId.Eq(applicationEntity.Id.Uint())).Count()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return count > 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) UpdateLike(c context.Context, externalUserEntity *entity.ExternalUser, applicationEntity *entity.Application, postEntity *entity.Post, likeType schema.UserLikeType) error {
|
||||||
|
count, err := s.dao.WithContext(c).UserLike.Where(s.dao.UserLike.ExternalUserId.Eq(externalUserEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserLike.PostId.Eq(postEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserLike.ApplicationId.Eq(applicationEntity.Id.Uint())).Count()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if count > 0 {
|
||||||
|
// update
|
||||||
|
_, err = s.dao.WithContext(c).UserLike.Where(s.dao.UserLike.ExternalUserId.Eq(externalUserEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserLike.PostId.Eq(postEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserLike.ApplicationId.Eq(applicationEntity.Id.Uint())).
|
||||||
|
Update(s.dao.UserLike.Type, likeType)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var userLike = &entity.UserLike{
|
||||||
|
ApplicationId: applicationEntity.Id,
|
||||||
|
ExternalUserId: externalUserEntity.Id,
|
||||||
|
PostId: postEntity.Id,
|
||||||
|
Type: likeType,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.dao.WithContext(c).UserLike.Create(userLike)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) LikePost(c context.Context, externalUserEntity *entity.ExternalUser, applicationEntity *entity.Application, postEntity *entity.Post) error {
|
||||||
|
//// 检测是否有
|
||||||
|
//var cacheKey = s.redis.Prefix(TaskProcessing)
|
||||||
|
//lock, err := s.redis.Locker.Obtain(c, cacheKey, LockTTL, nil)
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
|
//defer func(lock *redislock.Lock, ctx context.Context) {
|
||||||
|
// err := lock.Release(ctx)
|
||||||
|
// if err != nil {
|
||||||
|
// s.logger.Sugar.Error(err)
|
||||||
|
// }
|
||||||
|
//}(lock, c)
|
||||||
|
|
||||||
|
// get tags
|
||||||
|
postTags, err := s.postService.GetPostTags(c, postEntity)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hasLike, err := s.HasLiked(c, externalUserEntity, applicationEntity, postEntity)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasLike {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.UpdateLike(c, externalUserEntity, applicationEntity, postEntity, schema.UserLikeTypeLike)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.BindTags(context.Background(), externalUserEntity, applicationEntity, postTags)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Sugar.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) DislikePost(c context.Context, externalUserEntity *entity.ExternalUser, applicationEntity *entity.Application, postEntity *entity.Post) error {
|
||||||
|
// 检测是否有
|
||||||
|
//var cacheKey = s.redis.Prefix(TaskProcessing)
|
||||||
|
//lock, err := s.redis.Locker.Obtain(c, cacheKey, LockTTL, nil)
|
||||||
|
//if err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//defer func(lock *redislock.Lock, ctx context.Context) {
|
||||||
|
// err := lock.Release(ctx)
|
||||||
|
// if err != nil {
|
||||||
|
// s.logger.Sugar.Error(err)
|
||||||
|
// }
|
||||||
|
//}(lock, c)
|
||||||
|
|
||||||
|
// get tags
|
||||||
|
postTags, err := s.postService.GetPostTags(c, postEntity)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hasLike, err := s.HasLiked(c, externalUserEntity, applicationEntity, postEntity)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasLike {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.UpdateLike(c, externalUserEntity, applicationEntity, postEntity, schema.UserLikeTypeDislike)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = s.dao.WithContext(c).UserLike.Where(s.dao.UserLike.ExternalUserId.Eq(externalUserEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserLike.PostId.Eq(postEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserLike.ApplicationId.Eq(applicationEntity.Id.Uint())).Count()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.RemoveTags(context.Background(), externalUserEntity, applicationEntity, postTags)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Sugar.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
25
internal/service/user/provider.go
Normal file
25
internal/service/user/provider.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/base/logger"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/dao"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/service/post"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
dao *dao.Query
|
||||||
|
postService *post.Service
|
||||||
|
logger *logger.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(
|
||||||
|
dao *dao.Query,
|
||||||
|
postService *post.Service,
|
||||||
|
logger *logger.Logger,
|
||||||
|
) *Service {
|
||||||
|
return &Service{
|
||||||
|
dao: dao,
|
||||||
|
postService: postService,
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
}
|
114
internal/service/user/tags.go
Normal file
114
internal/service/user/tags.go
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"leafdev.top/Ecosystem/recommender/internal/entity"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) HasBindTag(c context.Context, externalUserEntity *entity.ExternalUser, applicationEntity *entity.Application, tagEntity *entity.Tag) (bool, error) {
|
||||||
|
count, err := s.dao.WithContext(c).UserTagScore.
|
||||||
|
Where(s.dao.UserTagScore.ExternalUserId.Eq(externalUserEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserTagScore.TagId.Eq(tagEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserTagScore.ApplicationId.Eq(applicationEntity.Id.Uint())).Count()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return count > 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) BindTags(c context.Context, externalUserEntity *entity.ExternalUser, applicationEntity *entity.Application, tags []*entity.Tag) error {
|
||||||
|
// 检测用户是否绑定 Tag,如果绑定则更新,否则创建
|
||||||
|
for _, tag := range tags {
|
||||||
|
var uts *entity.UserTagScore
|
||||||
|
|
||||||
|
hasBind, err := s.HasBindTag(c, externalUserEntity, applicationEntity, tag)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if hasBind {
|
||||||
|
// score + 1
|
||||||
|
uts, err = s.dao.WithContext(c).UserTagScore.
|
||||||
|
Where(s.dao.UserTagScore.ExternalUserId.Eq(externalUserEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserTagScore.TagId.Eq(tag.Id.Uint())).
|
||||||
|
Where(s.dao.UserTagScore.ApplicationId.Eq(applicationEntity.Id.Uint())).First()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
uts.Score += 1
|
||||||
|
|
||||||
|
err = s.dao.WithContext(c).UserTagScore.Save(uts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
uts = &entity.UserTagScore{
|
||||||
|
ApplicationId: applicationEntity.Id,
|
||||||
|
TagId: tag.Id,
|
||||||
|
ExternalUserId: externalUserEntity.Id,
|
||||||
|
Score: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.dao.WithContext(c).UserTagScore.Create(uts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) RemoveTags(c context.Context, externalUserEntity *entity.ExternalUser, applicationEntity *entity.Application, tags []*entity.Tag) error {
|
||||||
|
for _, tag := range tags {
|
||||||
|
var uts *entity.UserTagScore
|
||||||
|
|
||||||
|
hasBind, err := s.HasBindTag(c, externalUserEntity, applicationEntity, tag)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if hasBind {
|
||||||
|
// score - 1
|
||||||
|
uts, err = s.dao.WithContext(c).UserTagScore.
|
||||||
|
Where(s.dao.UserTagScore.ExternalUserId.Eq(externalUserEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserTagScore.TagId.Eq(tag.Id.Uint())).
|
||||||
|
Where(s.dao.UserTagScore.ApplicationId.Eq(applicationEntity.Id.Uint())).First()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//if uts.Score-1 < 0 {
|
||||||
|
// continue
|
||||||
|
//}
|
||||||
|
|
||||||
|
uts.Score -= 1
|
||||||
|
|
||||||
|
_, err = s.dao.WithContext(c).UserTagScore.
|
||||||
|
Where(s.dao.UserTagScore.ExternalUserId.Eq(externalUserEntity.Id.Uint())).
|
||||||
|
Where(s.dao.UserTagScore.TagId.Eq(tag.Id.Uint())).
|
||||||
|
Where(s.dao.UserTagScore.ApplicationId.Eq(applicationEntity.Id.Uint())).Update(s.dao.UserTagScore.Score, uts.Score)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
uts = &entity.UserTagScore{
|
||||||
|
ApplicationId: applicationEntity.Id,
|
||||||
|
TagId: tag.Id,
|
||||||
|
ExternalUserId: externalUserEntity.Id,
|
||||||
|
Score: -1,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.dao.WithContext(c).UserTagScore.Create(uts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
7
pkg/consts/posts.go
Normal file
7
pkg/consts/posts.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package consts
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrAnotherOperationInProgress = errors.New("another operation in progress")
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user