This commit is contained in:
parent
367db36c7a
commit
735aad8cc1
@ -15,7 +15,9 @@ type ItemController struct {
|
|||||||
func (c *ItemController) BeforeActivation(b mvc.BeforeActivation) {
|
func (c *ItemController) BeforeActivation(b mvc.BeforeActivation) {
|
||||||
b.Handle("GET", "/detail/{id:uint}", "Detail")
|
b.Handle("GET", "/detail/{id:uint}", "Detail")
|
||||||
|
|
||||||
b.Handle("PUT", "/history/{id:uint}", "PutHistory")
|
b.Handle("PUT", "/history/{id:uint}", "PutHistory", middleware.JwtMiddleware.Serve)
|
||||||
|
|
||||||
|
b.Handle("GET", "/recommend", "GetRecommend", middleware.JwtMiddleware.Serve)
|
||||||
|
|
||||||
b.Handle("GET", "/list/type/{ttype:int}", "GetListByType")
|
b.Handle("GET", "/list/type/{ttype:int}", "GetListByType")
|
||||||
b.Handle("GET", "/search", "Search")
|
b.Handle("GET", "/search", "Search")
|
||||||
@ -60,12 +62,33 @@ func (c *ItemController) Detail(id uint) mvc.Result {
|
|||||||
// @Success 200 {object} map[string]interface{} "{"msg": "历史记录统计成功"}"
|
// @Success 200 {object} map[string]interface{} "{"msg": "历史记录统计成功"}"
|
||||||
// @Failure 400 {object} map[string]interface{} "{"msg": "错误信息","code":0}"
|
// @Failure 400 {object} map[string]interface{} "{"msg": "错误信息","code":0}"
|
||||||
// @Router /api/item/history/{id} [put]
|
// @Router /api/item/history/{id} [put]
|
||||||
func (c *ItemController) DetailHistory(id uint) mvc.Result {
|
func (c *ItemController) PutHistory(id uint) mvc.Result {
|
||||||
uid := GetUidFromCtx(c.Ctx)
|
uid := GetUidFromCtx(c.Ctx)
|
||||||
e := c.Service.Item.PutHistory(uid, id)
|
e := c.Service.Item.PutHistory(uid, id)
|
||||||
return e.Response()
|
return e.Response()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Summary get recommend item api
|
||||||
|
// @Description 获取推荐商品列表(首页使用,每次返回十个)
|
||||||
|
// @Description 算法模型:用户浏览记录,用户购买记录,商品类型,商品热度
|
||||||
|
// @Description 该接口为 BETA 接口,正在测试中,调用请谨慎
|
||||||
|
// @Tags item api
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} []model.ItemModel "{["id":1],["id":2]}"
|
||||||
|
// @Failure 400 {object} map[string]interface{} "{"msg": "错误信息","code":0}"
|
||||||
|
// @Router /api/item/recommend [get]
|
||||||
|
func (c *ItemController) GetRecommend() mvc.Result {
|
||||||
|
uid := GetUidFromCtx(c.Ctx)
|
||||||
|
itemHot, e := c.Service.Recomment.GetPersonalHotItems(uid)
|
||||||
|
if e.Error() {
|
||||||
|
return e.Response()
|
||||||
|
}
|
||||||
|
return mvc.Response{
|
||||||
|
Object: itemHot,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// @Summary get item list api
|
// @Summary get item list api
|
||||||
// @Description 通过类型获取相关商品列表
|
// @Description 通过类型获取相关商品列表
|
||||||
// @Tags item api
|
// @Tags item api
|
||||||
|
73
docs/docs.go
73
docs/docs.go
@ -304,6 +304,46 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/item/history/{id}": {
|
||||||
|
"put": {
|
||||||
|
"description": "上传用户浏览历史记录",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"item api"
|
||||||
|
],
|
||||||
|
"summary": "上传用户浏览历史记录",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "商品ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "{\"msg\": \"历史记录统计成功\"}",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "{\"msg\": \"错误信息\",\"code\":0}",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/item/list/type/{type}": {
|
"/api/item/list/type/{type}": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "通过类型获取相关商品列表",
|
"description": "通过类型获取相关商品列表",
|
||||||
@ -447,6 +487,39 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/item/recommend": {
|
||||||
|
"get": {
|
||||||
|
"description": "获取推荐商品列表(首页使用,每次返回十个)\n算法模型:用户浏览记录,用户购买记录,商品类型,商品热度\n该接口为 BETA 接口,正在测试中,调用请谨慎",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"item api"
|
||||||
|
],
|
||||||
|
"summary": "get recommend item api",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "{[\"id\":1],[\"id\":2]}",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/model.ItemModel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "{\"msg\": \"错误信息\",\"code\":0}",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/item/search": {
|
"/api/item/search": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "搜索商品",
|
"description": "搜索商品",
|
||||||
|
@ -298,6 +298,46 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/item/history/{id}": {
|
||||||
|
"put": {
|
||||||
|
"description": "上传用户浏览历史记录",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"item api"
|
||||||
|
],
|
||||||
|
"summary": "上传用户浏览历史记录",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "商品ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "{\"msg\": \"历史记录统计成功\"}",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "{\"msg\": \"错误信息\",\"code\":0}",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/item/list/type/{type}": {
|
"/api/item/list/type/{type}": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "通过类型获取相关商品列表",
|
"description": "通过类型获取相关商品列表",
|
||||||
@ -441,6 +481,39 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/item/recommend": {
|
||||||
|
"get": {
|
||||||
|
"description": "获取推荐商品列表(首页使用,每次返回十个)\n算法模型:用户浏览记录,用户购买记录,商品类型,商品热度\n该接口为 BETA 接口,正在测试中,调用请谨慎",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"item api"
|
||||||
|
],
|
||||||
|
"summary": "get recommend item api",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "{[\"id\":1],[\"id\":2]}",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/model.ItemModel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "{\"msg\": \"错误信息\",\"code\":0}",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/item/search": {
|
"/api/item/search": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "搜索商品",
|
"description": "搜索商品",
|
||||||
|
@ -360,6 +360,33 @@ paths:
|
|||||||
summary: get item api
|
summary: get item api
|
||||||
tags:
|
tags:
|
||||||
- item api
|
- item api
|
||||||
|
/api/item/history/{id}:
|
||||||
|
put:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 上传用户浏览历史记录
|
||||||
|
parameters:
|
||||||
|
- description: 商品ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: '{"msg": "历史记录统计成功"}'
|
||||||
|
schema:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: '{"msg": "错误信息","code":0}'
|
||||||
|
schema:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
summary: 上传用户浏览历史记录
|
||||||
|
tags:
|
||||||
|
- item api
|
||||||
/api/item/list/type/{type}:
|
/api/item/list/type/{type}:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@ -457,6 +484,31 @@ paths:
|
|||||||
summary: 删除商品
|
summary: 删除商品
|
||||||
tags:
|
tags:
|
||||||
- item api
|
- item api
|
||||||
|
/api/item/recommend:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: |-
|
||||||
|
获取推荐商品列表(首页使用,每次返回十个)
|
||||||
|
算法模型:用户浏览记录,用户购买记录,商品类型,商品热度
|
||||||
|
该接口为 BETA 接口,正在测试中,调用请谨慎
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: '{["id":1],["id":2]}'
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/model.ItemModel'
|
||||||
|
type: array
|
||||||
|
"400":
|
||||||
|
description: '{"msg": "错误信息","code":0}'
|
||||||
|
schema:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
summary: get recommend item api
|
||||||
|
tags:
|
||||||
|
- item api
|
||||||
/api/item/search:
|
/api/item/search:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
|
15
model/buyment_model.go
Normal file
15
model/buyment_model.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type BuymentModel struct {
|
||||||
|
BaseModel
|
||||||
|
ItemId uint
|
||||||
|
UserId uint
|
||||||
|
Price int
|
||||||
|
|
||||||
|
User UserModel `gorm:"foreignKey:UserId"`
|
||||||
|
Item ItemModel `gorm:"foreignKey:ItemId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (BuymentModel) TableName() string {
|
||||||
|
return "buyment"
|
||||||
|
}
|
@ -5,4 +5,11 @@ type HistoryModel struct {
|
|||||||
UserId uint
|
UserId uint
|
||||||
ItemId uint
|
ItemId uint
|
||||||
Count int
|
Count int
|
||||||
|
|
||||||
|
User UserModel `gorm:"foreignKey:UserId"`
|
||||||
|
Item ItemModel `gorm:"foreignKey:ItemId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (HistoryModel) TableName() string {
|
||||||
|
return "history"
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,18 @@ func ConnectToDb(dsn string) *gorm.DB {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
err = DB.AutoMigrate(&CaptchaModel{}, &UserModel{}, &ItemModel{}, &LoginLogModel{}, &FileModel{}, &TypeModel{})
|
err = DB.AutoMigrate(&CaptchaModel{},
|
||||||
|
&UserModel{},
|
||||||
|
&ItemModel{},
|
||||||
|
&LoginLogModel{},
|
||||||
|
&FileModel{},
|
||||||
|
&TypeModel{},
|
||||||
|
&HistoryModel{},
|
||||||
|
&BuymentModel{},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return DB
|
return DB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
@ -25,8 +27,22 @@ func RedisRemember(key string, timeout int, funct func() interface{}) string {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
if RDB.Exists(ctx, key).Val() == 0 {
|
if RDB.Exists(ctx, key).Val() == 0 {
|
||||||
data := funct()
|
data := funct()
|
||||||
RDB.Set(ctx, key, data, time.Duration(timeout)*time.Second)
|
b, _ := json.Marshal(data)
|
||||||
|
s := RDB.Set(ctx, key, string(b), time.Duration(timeout)*time.Second)
|
||||||
|
if s.Err() != nil {
|
||||||
|
fmt.Printf("s.Err(): %v\n", s.Err())
|
||||||
|
}
|
||||||
return RDB.Get(ctx, key).Val()
|
return RDB.Get(ctx, key).Val()
|
||||||
}
|
}
|
||||||
return RDB.Get(ctx, key).Val()
|
return RDB.Get(ctx, key).Val()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RedisForget(key string) {
|
||||||
|
ctx := context.Background()
|
||||||
|
RDB.Del(ctx, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RedisRememberRet(key string, timeout int, funct func() interface{}, ret interface{}) {
|
||||||
|
s := RedisRemember(key, timeout, funct)
|
||||||
|
json.Unmarshal([]byte(s), ret)
|
||||||
|
}
|
||||||
|
@ -67,7 +67,7 @@ func (s *ItemService) PutHistory(uid uint, item_id uint) *ecode.Ecode {
|
|||||||
h := new(model.HistoryModel)
|
h := new(model.HistoryModel)
|
||||||
// 查看以前共有几条纪录
|
// 查看以前共有几条纪录
|
||||||
var c int64
|
var c int64
|
||||||
model.DB.Model(h).Where("uid=? and item_id=?", uid, item_id).Count(&c)
|
model.DB.Model(h).Where("user_id=? and item_id=?", uid, item_id).Count(&c)
|
||||||
h.UserId = uid
|
h.UserId = uid
|
||||||
h.ItemId = item_id
|
h.ItemId = item_id
|
||||||
h.Count = int(c) + 1
|
h.Count = int(c) + 1
|
||||||
|
157
service/recomment_service.go
Normal file
157
service/recomment_service.go
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"yitao/ecode"
|
||||||
|
"yitao/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RecommentService struct{}
|
||||||
|
|
||||||
|
// 推荐算法模块
|
||||||
|
/*********************************************************************************/
|
||||||
|
|
||||||
|
// 获取用户个人推荐商品
|
||||||
|
func (s *RecommentService) GetPersonalHotItems(uid uint) (items []model.ItemModel, e *ecode.Ecode) {
|
||||||
|
e = ecode.OK()
|
||||||
|
|
||||||
|
// 在算法中处理的都是“类型”,而最后返回的是“商品”
|
||||||
|
|
||||||
|
// 类型总体热度 = 该类商品在过去30天的浏览量*0.5 + 该类商品的总被购买量*0.5
|
||||||
|
// 用户喜爱程度 = 用户对该类商品的浏览量*0.4 + 用户对该类商品的购买量*0.6
|
||||||
|
// 时间指数:为解决商品冷启动问题:Wtime = 1/(1+e^(-x))
|
||||||
|
// 类型推荐程度 = (类型总体热度*0.4 + 用户喜爱程度*0.6) * Wtime
|
||||||
|
// 将类型推荐程度进行拟合,得到一个商品符合类型多的商品
|
||||||
|
// 然后在对所有商品对于所有用户的浏览量进行排序,采用类型拟合优先,类型完全一致的商品采用浏览量排序
|
||||||
|
|
||||||
|
// 因为用户会一直刷新列表
|
||||||
|
// 在前15名中随机选取5个商品,在15-27随机选取4个商品,在27-30中随机选取1个商品
|
||||||
|
// 维持三轮,如果用户三轮都不满意,那么判定用户是来找茬的,建议前端直接跳个鬼图
|
||||||
|
// 这样做可以也可以保证热门商品可能被重复推荐,让用户狠狠购买!
|
||||||
|
|
||||||
|
// 该算法运行过程中计算与数据库负荷较大,用户喜爱程度缓存60秒,商品总体热度缓存600秒,单一商品浏览量缓存60秒
|
||||||
|
// @TODO: 采用布隆过滤器,降低推荐过的商品的概率
|
||||||
|
|
||||||
|
//缓存机制,每次用户的记录都会隔60秒更新
|
||||||
|
// userHotTypes := model.RedisRemember(strconv.FormatUint(uint64(uid), 10)+"_hot_types", 60, func() interface{} {
|
||||||
|
// return s.LoadUserHotTypes(uid)
|
||||||
|
// })
|
||||||
|
// allHotTypes := model.RedisRemember("all_hot_types", 600, func() interface{} {
|
||||||
|
// return s.LoadAllHotTypes()
|
||||||
|
// })
|
||||||
|
|
||||||
|
userHotTypes := new(map[int]int)
|
||||||
|
model.RedisRememberRet(strconv.FormatUint(uint64(uid), 10)+"_hot_types", 60, func() interface{} {
|
||||||
|
return s.LoadUserHotTypes(uid)
|
||||||
|
}, &userHotTypes)
|
||||||
|
allHotTypes := new(map[int]int)
|
||||||
|
model.RedisRememberRet("all_hot_types", 600, func() interface{} {
|
||||||
|
return s.LoadAllHotTypes()
|
||||||
|
}, &allHotTypes)
|
||||||
|
|
||||||
|
// 整合
|
||||||
|
allTypes := make(map[int]int)
|
||||||
|
for k, v := range *userHotTypes {
|
||||||
|
allTypes[k] += v
|
||||||
|
}
|
||||||
|
for k, v := range *allHotTypes {
|
||||||
|
allTypes[k] += v
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在所有商品中匹配符合类型多的
|
||||||
|
// 1. 获取所有商品
|
||||||
|
var allItems []model.ItemModel
|
||||||
|
model.DB.Find(&allItems)
|
||||||
|
// 2. 计算商品的类型匹配度
|
||||||
|
var itemMatch = make(map[uint]int)
|
||||||
|
for _, item := range allItems {
|
||||||
|
for _, t := range item.Types {
|
||||||
|
itemMatch[item.ID] += allTypes[t]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 对商品进行排序
|
||||||
|
type kv struct {
|
||||||
|
Key uint
|
||||||
|
Value int
|
||||||
|
}
|
||||||
|
|
||||||
|
var sortedItems []kv
|
||||||
|
for k, v := range itemMatch {
|
||||||
|
sortedItems = append(sortedItems, kv{k, v})
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(sortedItems, func(i, j int) bool {
|
||||||
|
return sortedItems[i].Value > sortedItems[j].Value
|
||||||
|
})
|
||||||
|
|
||||||
|
// 4. 根据排序结果获取商品
|
||||||
|
for _, kv := range sortedItems {
|
||||||
|
var item model.ItemModel
|
||||||
|
model.DB.First(&item, kv.Key)
|
||||||
|
items = append(items, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 随机选取商品
|
||||||
|
var result []model.ItemModel
|
||||||
|
if len(items) > 30 {
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
result = append(result, items[i])
|
||||||
|
}
|
||||||
|
for i := 15; i < 27; i++ {
|
||||||
|
result = append(result, items[i])
|
||||||
|
}
|
||||||
|
result = append(result, items[29])
|
||||||
|
} else {
|
||||||
|
result = items
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RecommentService) LoadUserHotTypes(uid uint) map[int]int {
|
||||||
|
// 1. 获取用户的历史记录
|
||||||
|
var history []model.HistoryModel
|
||||||
|
model.DB.Preload("Item").Where("user_id=?", uid).Find(&history)
|
||||||
|
// 提取对每种商品的类型
|
||||||
|
var allTypes = make(map[int]int)
|
||||||
|
for _, h := range history {
|
||||||
|
for _, t := range h.Item.Types {
|
||||||
|
allTypes[t] += 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取用户的购买记录
|
||||||
|
var buyments []model.BuymentModel
|
||||||
|
model.DB.Preload("Item").Preload("User").Where("user_id=?", uid).Find(&buyments)
|
||||||
|
for _, b := range buyments {
|
||||||
|
for _, t := range b.Item.Types {
|
||||||
|
allTypes[t] += 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RecommentService) LoadAllHotTypes() map[int]int {
|
||||||
|
// 获取全部的商品浏览记录
|
||||||
|
var history []model.HistoryModel
|
||||||
|
model.DB.Preload("Item").Find(&history)
|
||||||
|
// 提取对每种商品的类型
|
||||||
|
var allTypes = make(map[int]int)
|
||||||
|
for _, h := range history {
|
||||||
|
for _, t := range h.Item.Types {
|
||||||
|
allTypes[t] += 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取全部的商品购买记录
|
||||||
|
var buyments []model.BuymentModel
|
||||||
|
model.DB.Preload("Item").Preload("User").Find(&buyments)
|
||||||
|
for _, b := range buyments {
|
||||||
|
for _, t := range b.Item.Types {
|
||||||
|
allTypes[t] += 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allTypes
|
||||||
|
}
|
@ -7,6 +7,7 @@ type Service struct {
|
|||||||
Common *CommonService
|
Common *CommonService
|
||||||
Item *ItemService
|
Item *ItemService
|
||||||
File *FileService
|
File *FileService
|
||||||
|
Recomment *RecommentService
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitService() *Service {
|
func InitService() *Service {
|
||||||
@ -18,6 +19,7 @@ func InitService() *Service {
|
|||||||
s.Common = new(CommonService)
|
s.Common = new(CommonService)
|
||||||
s.Item = new(ItemService)
|
s.Item = new(ItemService)
|
||||||
s.File = new(FileService)
|
s.File = new(FileService)
|
||||||
|
s.Recomment = new(RecommentService)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user