feat: 修改当前点赞逻辑
This commit is contained in:
parent
1ee151630d
commit
02598db333
@ -191,14 +191,17 @@ const (
|
|||||||
// ========== 点赞记录表模型 ==========
|
// ========== 点赞记录表模型 ==========
|
||||||
|
|
||||||
// AssetLike 点赞记录表模型
|
// AssetLike 点赞记录表模型
|
||||||
|
// 唯一约束:(asset_id, user_id, exhibition_id) - 每次展览每个用户只能点赞一次
|
||||||
|
// 注意:exhibition_id 不设置外键约束,因为迁移时现有数据没有有效的 exhibition_id
|
||||||
type AssetLike struct {
|
type AssetLike struct {
|
||||||
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
||||||
AssetID int64 `gorm:"not null;uniqueIndex:uk_asset_likes_user_asset;index:idx_asset_likes_asset;column:asset_id"`
|
AssetID int64 `gorm:"not null;uniqueIndex:uk_asset_likes_user_exhibition;index:idx_asset_likes_asset;column:asset_id"`
|
||||||
UserID int64 `gorm:"not null;uniqueIndex:uk_asset_likes_user_asset;index:idx_asset_likes_user_star;column:user_id"`
|
UserID int64 `gorm:"not null;uniqueIndex:uk_asset_likes_user_exhibition;index:idx_asset_likes_user_star;column:user_id"`
|
||||||
StarID int64 `gorm:"not null;index:idx_asset_likes_user_star;column:star_id"` // 用于数据隔离和查询优化
|
StarID int64 `gorm:"not null;uniqueIndex:uk_asset_likes_user_exhibition;index:idx_asset_likes_user_star;column:star_id"` // 用于数据隔离和查询优化
|
||||||
CreatedAt int64 `gorm:"not null;index:idx_asset_likes_user_star,sort:desc;index:idx_asset_likes_asset,sort:desc;column:created_at"`
|
ExhibitionID int64 `gorm:"not null;uniqueIndex:uk_asset_likes_user_exhibition;index:idx_asset_likes_exhibition;column:exhibition_id"` // 关联展览,同一展览只能点赞一次
|
||||||
|
CreatedAt int64 `gorm:"not null;index:idx_asset_likes_user_star,sort:desc;index:idx_asset_likes_asset,sort:desc;column:created_at"`
|
||||||
|
|
||||||
// 关联关系
|
// 关联关系(不设置外键约束,避免迁移问题)
|
||||||
Asset Asset `gorm:"foreignKey:AssetID;references:ID;constraint:OnDelete:CASCADE"`
|
Asset Asset `gorm:"foreignKey:AssetID;references:ID;constraint:OnDelete:CASCADE"`
|
||||||
User User `gorm:"foreignKey:UserID;references:ID;constraint:OnDelete:CASCADE"`
|
User User `gorm:"foreignKey:UserID;references:ID;constraint:OnDelete:CASCADE"`
|
||||||
Star Star `gorm:"foreignKey:StarID;references:StarID;constraint:OnDelete:CASCADE"`
|
Star Star `gorm:"foreignKey:StarID;references:StarID;constraint:OnDelete:CASCADE"`
|
||||||
|
|||||||
@ -13,10 +13,10 @@ type AssetLikeRepository interface {
|
|||||||
Create(like *models.AssetLike) error
|
Create(like *models.AssetLike) error
|
||||||
|
|
||||||
// Delete 删除点赞记录
|
// Delete 删除点赞记录
|
||||||
Delete(assetID, userID, starID int64) error
|
Delete(assetID, userID, starID, exhibitionID int64) error
|
||||||
|
|
||||||
// Exists 检查点赞记录是否存在
|
// Exists 检查点赞记录是否存在(按 asset_id, user_id, exhibition_id)
|
||||||
Exists(assetID, userID, starID int64) (bool, error)
|
Exists(assetID, userID, starID, exhibitionID int64) (bool, error)
|
||||||
|
|
||||||
// GetByAsset 获取资产的点赞记录列表(分页)
|
// GetByAsset 获取资产的点赞记录列表(分页)
|
||||||
GetByAsset(assetID int64, limit, offset int) ([]*models.AssetLike, error)
|
GetByAsset(assetID int64, limit, offset int) ([]*models.AssetLike, error)
|
||||||
@ -61,8 +61,8 @@ func (r *assetLikeRepository) Create(like *models.AssetLike) error {
|
|||||||
return errors.New("star_id must be greater than 0")
|
return errors.New("star_id must be greater than 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否已存在
|
// 检查是否已存在(同一展览同用户只能点赞一次)
|
||||||
exists, err := r.Exists(like.AssetID, like.UserID, like.StarID)
|
exists, err := r.Exists(like.AssetID, like.UserID, like.StarID, like.ExhibitionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ func (r *assetLikeRepository) Create(like *models.AssetLike) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete 删除点赞记录
|
// Delete 删除点赞记录
|
||||||
func (r *assetLikeRepository) Delete(assetID, userID, starID int64) error {
|
func (r *assetLikeRepository) Delete(assetID, userID, starID, exhibitionID int64) error {
|
||||||
if assetID <= 0 {
|
if assetID <= 0 {
|
||||||
return errors.New("asset_id must be greater than 0")
|
return errors.New("asset_id must be greater than 0")
|
||||||
}
|
}
|
||||||
@ -91,7 +91,11 @@ func (r *assetLikeRepository) Delete(assetID, userID, starID int64) error {
|
|||||||
return errors.New("star_id must be greater than 0")
|
return errors.New("star_id must be greater than 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
result := r.db.Where("asset_id = ? AND user_id = ? AND star_id = ?", assetID, userID, starID).
|
if exhibitionID <= 0 {
|
||||||
|
return errors.New("exhibition_id must be greater than 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
result := r.db.Where("asset_id = ? AND user_id = ? AND star_id = ? AND exhibition_id = ?", assetID, userID, starID, exhibitionID).
|
||||||
Delete(&models.AssetLike{})
|
Delete(&models.AssetLike{})
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
@ -105,8 +109,8 @@ func (r *assetLikeRepository) Delete(assetID, userID, starID int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exists 检查点赞记录是否存在
|
// Exists 检查点赞记录是否存在(按 asset_id, user_id, exhibition_id)
|
||||||
func (r *assetLikeRepository) Exists(assetID, userID, starID int64) (bool, error) {
|
func (r *assetLikeRepository) Exists(assetID, userID, starID, exhibitionID int64) (bool, error) {
|
||||||
if assetID <= 0 {
|
if assetID <= 0 {
|
||||||
return false, errors.New("asset_id must be greater than 0")
|
return false, errors.New("asset_id must be greater than 0")
|
||||||
}
|
}
|
||||||
@ -119,9 +123,13 @@ func (r *assetLikeRepository) Exists(assetID, userID, starID int64) (bool, error
|
|||||||
return false, errors.New("star_id must be greater than 0")
|
return false, errors.New("star_id must be greater than 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if exhibitionID <= 0 {
|
||||||
|
return false, errors.New("exhibition_id must be greater than 0")
|
||||||
|
}
|
||||||
|
|
||||||
var count int64
|
var count int64
|
||||||
err := r.db.Model(&models.AssetLike{}).
|
err := r.db.Model(&models.AssetLike{}).
|
||||||
Where("asset_id = ? AND user_id = ? AND star_id = ?", assetID, userID, starID).
|
Where("asset_id = ? AND user_id = ? AND star_id = ? AND exhibition_id = ?", assetID, userID, starID, exhibitionID).
|
||||||
Count(&count).Error
|
Count(&count).Error
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -1,329 +0,0 @@
|
|||||||
package repository
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/topfans/backend/pkg/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestAssetLikeRepository_Create 测试创建点赞记录
|
|
||||||
func TestAssetLikeRepository_Create(t *testing.T) {
|
|
||||||
db := setupTestDB(t)
|
|
||||||
defer cleanupTestDB(t, db)
|
|
||||||
|
|
||||||
repo := NewAssetLikeRepository(db)
|
|
||||||
|
|
||||||
// 创建测试数据
|
|
||||||
star := createTestStar(t, db, "test_like_create")
|
|
||||||
user := createTestUser(t, db, "19900200001")
|
|
||||||
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户")
|
|
||||||
asset := createTestAsset(t, db, user.ID, star.StarID, "测试资产")
|
|
||||||
|
|
||||||
// 测试创建点赞
|
|
||||||
like := &models.AssetLike{
|
|
||||||
AssetID: asset.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
StarID: star.StarID,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := repo.Create(like)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.NotZero(t, like.ID)
|
|
||||||
assert.NotZero(t, like.CreatedAt)
|
|
||||||
|
|
||||||
// 测试重复点赞
|
|
||||||
duplicateLike := &models.AssetLike{
|
|
||||||
AssetID: asset.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
StarID: star.StarID,
|
|
||||||
}
|
|
||||||
err = repo.Create(duplicateLike)
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Contains(t, err.Error(), "already liked")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestAssetLikeRepository_Delete 测试删除点赞记录
|
|
||||||
func TestAssetLikeRepository_Delete(t *testing.T) {
|
|
||||||
db := setupTestDB(t)
|
|
||||||
defer cleanupTestDB(t, db)
|
|
||||||
|
|
||||||
repo := NewAssetLikeRepository(db)
|
|
||||||
|
|
||||||
// 创建测试数据
|
|
||||||
star := createTestStar(t, db, "test_like_delete")
|
|
||||||
user := createTestUser(t, db, "19900200002")
|
|
||||||
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户")
|
|
||||||
asset := createTestAsset(t, db, user.ID, star.StarID, "测试资产")
|
|
||||||
|
|
||||||
// 先创建点赞
|
|
||||||
like := &models.AssetLike{
|
|
||||||
AssetID: asset.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
StarID: star.StarID,
|
|
||||||
}
|
|
||||||
err := repo.Create(like)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// 删除点赞
|
|
||||||
err = repo.Delete(asset.ID, user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// 验证已删除
|
|
||||||
exists, err := repo.Exists(asset.ID, user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, exists)
|
|
||||||
|
|
||||||
// 测试删除不存在的记录
|
|
||||||
err = repo.Delete(asset.ID, user.ID, star.StarID)
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Contains(t, err.Error(), "not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestAssetLikeRepository_Exists 测试检查点赞是否存在
|
|
||||||
func TestAssetLikeRepository_Exists(t *testing.T) {
|
|
||||||
db := setupTestDB(t)
|
|
||||||
defer cleanupTestDB(t, db)
|
|
||||||
|
|
||||||
repo := NewAssetLikeRepository(db)
|
|
||||||
|
|
||||||
// 创建测试数据
|
|
||||||
star := createTestStar(t, db, "test_like_exists")
|
|
||||||
user := createTestUser(t, db, "19900200003")
|
|
||||||
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户")
|
|
||||||
asset := createTestAsset(t, db, user.ID, star.StarID, "测试资产")
|
|
||||||
|
|
||||||
// 初始状态不存在
|
|
||||||
exists, err := repo.Exists(asset.ID, user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, exists)
|
|
||||||
|
|
||||||
// 创建点赞后存在
|
|
||||||
like := &models.AssetLike{
|
|
||||||
AssetID: asset.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
StarID: star.StarID,
|
|
||||||
}
|
|
||||||
err = repo.Create(like)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
exists, err = repo.Exists(asset.ID, user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, exists)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestAssetLikeRepository_GetByAsset 测试获取资产的点赞列表
|
|
||||||
func TestAssetLikeRepository_GetByAsset(t *testing.T) {
|
|
||||||
db := setupTestDB(t)
|
|
||||||
defer cleanupTestDB(t, db)
|
|
||||||
|
|
||||||
repo := NewAssetLikeRepository(db)
|
|
||||||
|
|
||||||
// 创建测试数据
|
|
||||||
star := createTestStar(t, db, "test_like_by_asset")
|
|
||||||
// 创建资产的所有者
|
|
||||||
assetOwner := createTestUser(t, db, "19900200004")
|
|
||||||
createTestFanProfile(t, db, assetOwner.ID, star.StarID, "资产所有者")
|
|
||||||
asset := createTestAsset(t, db, assetOwner.ID, star.StarID, "测试资产")
|
|
||||||
|
|
||||||
// 创建多个用户点赞
|
|
||||||
for i := 1; i <= 5; i++ {
|
|
||||||
mobile := "1990020000" + string(rune('4'+i))
|
|
||||||
user := createTestUser(t, db, mobile)
|
|
||||||
createTestFanProfile(t, db, user.ID, star.StarID, fmt.Sprintf("用户%d", i))
|
|
||||||
|
|
||||||
like := &models.AssetLike{
|
|
||||||
AssetID: asset.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
StarID: star.StarID,
|
|
||||||
}
|
|
||||||
err := repo.Create(like)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取点赞列表
|
|
||||||
likes, err := repo.GetByAsset(asset.ID, 3, 0)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Len(t, likes, 3)
|
|
||||||
|
|
||||||
// 获取第二页
|
|
||||||
likes, err = repo.GetByAsset(asset.ID, 3, 3)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Len(t, likes, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestAssetLikeRepository_GetByUser 测试获取用户的点赞列表
|
|
||||||
func TestAssetLikeRepository_GetByUser(t *testing.T) {
|
|
||||||
db := setupTestDB(t)
|
|
||||||
defer cleanupTestDB(t, db)
|
|
||||||
|
|
||||||
repo := NewAssetLikeRepository(db)
|
|
||||||
|
|
||||||
// 创建测试数据
|
|
||||||
star := createTestStar(t, db, "test_like_by_user")
|
|
||||||
user := createTestUser(t, db, "19900200009")
|
|
||||||
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户")
|
|
||||||
|
|
||||||
// 创建多个资产并点赞
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
asset := createTestAsset(t, db, user.ID, star.StarID, "资产")
|
|
||||||
|
|
||||||
like := &models.AssetLike{
|
|
||||||
AssetID: asset.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
StarID: star.StarID,
|
|
||||||
}
|
|
||||||
err := repo.Create(like)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取点赞列表
|
|
||||||
likes, err := repo.GetByUser(user.ID, star.StarID, 3, 0)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Len(t, likes, 3)
|
|
||||||
|
|
||||||
// 获取第二页
|
|
||||||
likes, err = repo.GetByUser(user.ID, star.StarID, 3, 3)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Len(t, likes, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestAssetLikeRepository_CountByAsset 测试统计资产的点赞数
|
|
||||||
func TestAssetLikeRepository_CountByAsset(t *testing.T) {
|
|
||||||
db := setupTestDB(t)
|
|
||||||
defer cleanupTestDB(t, db)
|
|
||||||
|
|
||||||
repo := NewAssetLikeRepository(db)
|
|
||||||
|
|
||||||
// 创建测试数据
|
|
||||||
star := createTestStar(t, db, "test_like_count_asset")
|
|
||||||
// 创建资产的所有者
|
|
||||||
assetOwner := createTestUser(t, db, "19900200010")
|
|
||||||
createTestFanProfile(t, db, assetOwner.ID, star.StarID, "资产所有者")
|
|
||||||
asset := createTestAsset(t, db, assetOwner.ID, star.StarID, "测试资产")
|
|
||||||
|
|
||||||
// 初始点赞数为0
|
|
||||||
count, err := repo.CountByAsset(asset.ID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int64(0), count)
|
|
||||||
|
|
||||||
// 创建3个点赞
|
|
||||||
for i := 1; i <= 3; i++ {
|
|
||||||
mobile := "1990020001" + string(rune('0'+i))
|
|
||||||
user := createTestUser(t, db, mobile)
|
|
||||||
createTestFanProfile(t, db, user.ID, star.StarID, fmt.Sprintf("用户%d", i))
|
|
||||||
|
|
||||||
like := &models.AssetLike{
|
|
||||||
AssetID: asset.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
StarID: star.StarID,
|
|
||||||
}
|
|
||||||
err := repo.Create(like)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证点赞数
|
|
||||||
count, err = repo.CountByAsset(asset.ID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int64(3), count)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestAssetLikeRepository_CountByUser 测试统计用户的点赞数
|
|
||||||
func TestAssetLikeRepository_CountByUser(t *testing.T) {
|
|
||||||
db := setupTestDB(t)
|
|
||||||
defer cleanupTestDB(t, db)
|
|
||||||
|
|
||||||
repo := NewAssetLikeRepository(db)
|
|
||||||
|
|
||||||
// 创建测试数据
|
|
||||||
star := createTestStar(t, db, "test_like_count_user")
|
|
||||||
user := createTestUser(t, db, "19900200014")
|
|
||||||
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户")
|
|
||||||
|
|
||||||
// 初始点赞数为0
|
|
||||||
count, err := repo.CountByUser(user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int64(0), count)
|
|
||||||
|
|
||||||
// 创建3个点赞
|
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
asset := createTestAsset(t, db, user.ID, star.StarID, "资产")
|
|
||||||
|
|
||||||
like := &models.AssetLike{
|
|
||||||
AssetID: asset.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
StarID: star.StarID,
|
|
||||||
}
|
|
||||||
err := repo.Create(like)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证点赞数
|
|
||||||
count, err = repo.CountByUser(user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int64(3), count)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestAssetLikeRepository_LikeUnlikeFlow 测试点赞-取消点赞流程
|
|
||||||
func TestAssetLikeRepository_LikeUnlikeFlow(t *testing.T) {
|
|
||||||
db := setupTestDB(t)
|
|
||||||
defer cleanupTestDB(t, db)
|
|
||||||
|
|
||||||
assetLikeRepo := NewAssetLikeRepository(db)
|
|
||||||
assetRepo := NewAssetRepository(db)
|
|
||||||
|
|
||||||
// 创建测试数据
|
|
||||||
star := createTestStar(t, db, "test_like_flow")
|
|
||||||
user := createTestUser(t, db, "19900200015")
|
|
||||||
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户")
|
|
||||||
asset := createTestAsset(t, db, user.ID, star.StarID, "测试资产")
|
|
||||||
|
|
||||||
// 1. 初始状态
|
|
||||||
exists, err := assetLikeRepo.Exists(asset.ID, user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, exists)
|
|
||||||
|
|
||||||
assetData, err := assetRepo.GetByID(asset.ID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int32(0), assetData.LikeCount)
|
|
||||||
|
|
||||||
// 2. 点赞
|
|
||||||
like := &models.AssetLike{
|
|
||||||
AssetID: asset.ID,
|
|
||||||
UserID: user.ID,
|
|
||||||
StarID: star.StarID,
|
|
||||||
}
|
|
||||||
err = assetLikeRepo.Create(like)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// 增加资产点赞数
|
|
||||||
err = assetRepo.IncrementLikeCount(asset.ID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// 验证点赞状态
|
|
||||||
exists, err = assetLikeRepo.Exists(asset.ID, user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, exists)
|
|
||||||
|
|
||||||
assetData, err = assetRepo.GetByID(asset.ID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int32(1), assetData.LikeCount)
|
|
||||||
|
|
||||||
// 3. 取消点赞
|
|
||||||
err = assetLikeRepo.Delete(asset.ID, user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// 减少资产点赞数
|
|
||||||
err = assetRepo.DecrementLikeCount(asset.ID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// 验证取消点赞状态
|
|
||||||
exists, err = assetLikeRepo.Exists(asset.ID, user.ID, star.StarID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, exists)
|
|
||||||
|
|
||||||
assetData, err = assetRepo.GetByID(asset.ID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, int32(0), assetData.LikeCount)
|
|
||||||
}
|
|
||||||
@ -54,6 +54,9 @@ type AssetRepository interface {
|
|||||||
// IsExhibiting 检查资产是否正在展出中
|
// IsExhibiting 检查资产是否正在展出中
|
||||||
IsExhibiting(assetID int64) (bool, error)
|
IsExhibiting(assetID int64) (bool, error)
|
||||||
|
|
||||||
|
// GetExhibitingID 获取正在展出的展览ID(如果正在展出),返回0表示未展出
|
||||||
|
GetExhibitingID(assetID int64) (int64, error)
|
||||||
|
|
||||||
// GetExhibitionStartTime 获取资产展出开始时间(如果正在展出)
|
// GetExhibitionStartTime 获取资产展出开始时间(如果正在展出)
|
||||||
GetExhibitionStartTime(assetID int64) (int64, error)
|
GetExhibitionStartTime(assetID int64) (int64, error)
|
||||||
|
|
||||||
@ -367,6 +370,30 @@ func (r *assetRepository) IsExhibiting(assetID int64) (bool, error) {
|
|||||||
return count > 0, nil
|
return count > 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetExhibitingID 获取正在展出的展览ID(如果正在展出),返回0表示未展出
|
||||||
|
func (r *assetRepository) GetExhibitingID(assetID int64) (int64, error) {
|
||||||
|
if assetID <= 0 {
|
||||||
|
return 0, errors.New("asset_id must be greater than 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
var exhibition struct {
|
||||||
|
ID int64
|
||||||
|
}
|
||||||
|
err := r.db.Model(&models.Exhibition{}).
|
||||||
|
Select("id").
|
||||||
|
Where("asset_id = ? AND expire_at > ?", assetID, time.Now().UnixMilli()).
|
||||||
|
First(&exhibition).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return 0, nil // 未展出
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return exhibition.ID, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetExhibitionStartTime 获取资产展出开始时间(如果正在展出)
|
// GetExhibitionStartTime 获取资产展出开始时间(如果正在展出)
|
||||||
func (r *assetRepository) GetExhibitionStartTime(assetID int64) (int64, error) {
|
func (r *assetRepository) GetExhibitionStartTime(assetID int64) (int64, error) {
|
||||||
if assetID <= 0 {
|
if assetID <= 0 {
|
||||||
|
|||||||
@ -33,17 +33,20 @@ func NewAssetLikeService(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isAssetExhibiting 检查资产当前是否在展出中
|
// isAssetExhibiting 检查资产当前是否在展出中,返回 exhibition_id
|
||||||
func (s *AssetLikeService) isAssetExhibiting(assetID int64) (bool, error) {
|
func (s *AssetLikeService) isAssetExhibiting(assetID int64) (int64, error) {
|
||||||
nowMs := time.Now().UnixMilli()
|
nowMs := time.Now().UnixMilli()
|
||||||
var count int64
|
var exhibition struct {
|
||||||
err := s.db.Table("exhibitions").
|
ID int64
|
||||||
Where("asset_id = ? AND expire_at > ?", assetID, nowMs).
|
|
||||||
Count(&count).Error
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("failed to check exhibition status: %w", err)
|
|
||||||
}
|
}
|
||||||
return count > 0, nil
|
err := s.db.Table("exhibitions").
|
||||||
|
Select("id").
|
||||||
|
Where("asset_id = ? AND expire_at > ?", assetID, nowMs).
|
||||||
|
First(&exhibition).Error
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to check exhibition status: %w", err)
|
||||||
|
}
|
||||||
|
return exhibition.ID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUniqueConstraintViolation 检查错误是否为唯一约束冲突(PostgreSQL error code 23505)
|
// isUniqueConstraintViolation 检查错误是否为唯一约束冲突(PostgreSQL error code 23505)
|
||||||
@ -116,8 +119,8 @@ func (s *AssetLikeService) LikeAsset(ctx context.Context, assetID, userID, starI
|
|||||||
return 0, fmt.Errorf("asset not found: %w", err)
|
return 0, fmt.Errorf("asset not found: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.5 检查资产是否当前在展出中
|
// 1.5 检查资产是否当前在展出中,获取 exhibition_id
|
||||||
exhibiting, err := s.isAssetExhibiting(assetID)
|
exhibitionID, err := s.isAssetExhibiting(assetID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Logger.Error("Failed to check exhibition status",
|
logger.Logger.Error("Failed to check exhibition status",
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
@ -125,12 +128,12 @@ func (s *AssetLikeService) LikeAsset(ctx context.Context, assetID, userID, starI
|
|||||||
)
|
)
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if !exhibiting {
|
if exhibitionID == 0 {
|
||||||
return 0, fmt.Errorf("资产未在展示中,无法点赞")
|
return 0, fmt.Errorf("资产未在展示中,无法点赞")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查是否已点赞
|
// 2. 检查是否已点赞(同一展览同用户只能点赞一次)
|
||||||
exists, err := s.assetLikeRepo.Exists(assetID, userID, starID)
|
exists, err := s.assetLikeRepo.Exists(assetID, userID, starID, exhibitionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Logger.Error("Failed to check if already liked",
|
logger.Logger.Error("Failed to check if already liked",
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
@ -229,8 +232,8 @@ func (s *AssetLikeService) UnlikeAsset(ctx context.Context, assetID, userID, sta
|
|||||||
zap.Int64("star_id", starID),
|
zap.Int64("star_id", starID),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 0. 检查资产是否当前在展出中(展出结束后不允许取消点赞)
|
// 0. 检查资产是否当前在展出中,获取 exhibition_id(展出结束后不允许取消点赞)
|
||||||
exhibiting, err := s.isAssetExhibiting(assetID)
|
exhibitionID, err := s.isAssetExhibiting(assetID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Logger.Error("Failed to check exhibition status",
|
logger.Logger.Error("Failed to check exhibition status",
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
@ -238,12 +241,12 @@ func (s *AssetLikeService) UnlikeAsset(ctx context.Context, assetID, userID, sta
|
|||||||
)
|
)
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if !exhibiting {
|
if exhibitionID == 0 {
|
||||||
return 0, fmt.Errorf("资产未在展示中,无法取消点赞")
|
return 0, fmt.Errorf("资产未在展示中,无法取消点赞")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. 检查是否已点赞
|
// 1. 检查是否已点赞(同一展览同用户只能点赞一次)
|
||||||
exists, err := s.assetLikeRepo.Exists(assetID, userID, starID)
|
exists, err := s.assetLikeRepo.Exists(assetID, userID, starID, exhibitionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Logger.Error("Failed to check if liked",
|
logger.Logger.Error("Failed to check if liked",
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
@ -262,8 +265,8 @@ func (s *AssetLikeService) UnlikeAsset(ctx context.Context, assetID, userID, sta
|
|||||||
|
|
||||||
// 2. 开启事务
|
// 2. 开启事务
|
||||||
err = s.db.Transaction(func(tx *gorm.DB) error {
|
err = s.db.Transaction(func(tx *gorm.DB) error {
|
||||||
// 2.1 删除点赞记录
|
// 2.1 删除点赞记录(按 exhibition_id 删除)
|
||||||
if err := tx.Where("asset_id = ? AND user_id = ? AND star_id = ?", assetID, userID, starID).
|
if err := tx.Where("asset_id = ? AND user_id = ? AND star_id = ? AND exhibition_id = ?", assetID, userID, starID, exhibitionID).
|
||||||
Delete(&models.AssetLike{}).Error; err != nil {
|
Delete(&models.AssetLike{}).Error; err != nil {
|
||||||
logger.Logger.Error("Failed to delete like record",
|
logger.Logger.Error("Failed to delete like record",
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
@ -336,7 +339,7 @@ func (s *AssetLikeService) UnlikeAsset(ctx context.Context, assetID, userID, sta
|
|||||||
return asset.LikeCount, nil
|
return asset.LikeCount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckAssetLike 检查是否已点赞
|
// CheckAssetLike 检查是否已点赞(在当前展出中)
|
||||||
func (s *AssetLikeService) CheckAssetLike(ctx context.Context, assetID, userID, starID int64) (bool, error) {
|
func (s *AssetLikeService) CheckAssetLike(ctx context.Context, assetID, userID, starID int64) (bool, error) {
|
||||||
logger.Logger.Debug("AssetLikeService.CheckAssetLike called",
|
logger.Logger.Debug("AssetLikeService.CheckAssetLike called",
|
||||||
zap.Int64("asset_id", assetID),
|
zap.Int64("asset_id", assetID),
|
||||||
@ -344,7 +347,22 @@ func (s *AssetLikeService) CheckAssetLike(ctx context.Context, assetID, userID,
|
|||||||
zap.Int64("star_id", starID),
|
zap.Int64("star_id", starID),
|
||||||
)
|
)
|
||||||
|
|
||||||
exists, err := s.assetLikeRepo.Exists(assetID, userID, starID)
|
// 获取当前展出中的 exhibition_id
|
||||||
|
exhibitionID, err := s.isAssetExhibiting(assetID)
|
||||||
|
if err != nil {
|
||||||
|
logger.Logger.Error("Failed to check exhibition status",
|
||||||
|
zap.Error(err),
|
||||||
|
zap.Int64("asset_id", assetID),
|
||||||
|
)
|
||||||
|
return false, fmt.Errorf("failed to check exhibition status: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if exhibitionID == 0 {
|
||||||
|
// 资产不在展出中,视为未点赞
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
exists, err := s.assetLikeRepo.Exists(assetID, userID, starID, exhibitionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Logger.Error("Failed to check like status",
|
logger.Logger.Error("Failed to check like status",
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
|
|||||||
@ -452,17 +452,21 @@ func (s *assetService) GetAsset(req *pb.GetAssetRequest, userID, starID int64) (
|
|||||||
ownerNickname = profile.Nickname
|
ownerNickname = profile.Nickname
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 检查当前用户是否已点赞
|
// 4. 检查当前用户是否已点赞(需要获取当前展出中的 exhibition_id)
|
||||||
isLiked, err := s.assetLikeRepo.Exists(asset.ID, userID, starID)
|
exhibitionID, _ := s.assetRepo.GetExhibitingID(asset.ID)
|
||||||
if err != nil {
|
isLiked := false
|
||||||
logger.Logger.Warn("Failed to check like status, will return is_liked as false",
|
if exhibitionID > 0 {
|
||||||
zap.Int64("asset_id", asset.ID),
|
isLiked, err = s.assetLikeRepo.Exists(asset.ID, userID, starID, exhibitionID)
|
||||||
zap.Int64("user_id", userID),
|
if err != nil {
|
||||||
zap.Int64("star_id", starID),
|
logger.Logger.Warn("Failed to check like status, will return is_liked as false",
|
||||||
zap.Error(err),
|
zap.Int64("asset_id", asset.ID),
|
||||||
)
|
zap.Int64("user_id", userID),
|
||||||
// 检查失败时,默认为未点赞
|
zap.Int64("star_id", starID),
|
||||||
isLiked = false
|
zap.Error(err),
|
||||||
|
)
|
||||||
|
// 检查失败时,默认为未点赞
|
||||||
|
isLiked = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 从 asset_registry 表获取 display_status
|
// 5. 从 asset_registry 表获取 display_status
|
||||||
|
|||||||
@ -156,17 +156,8 @@ func (w *CleanupWorker) cleanupExpiredExhibitions(now int64) {
|
|||||||
log.Printf("展品已到期并生成领取记录: ExhibitionID=%d, AssetID=%d, SlotID=%d, OccupierUID=%d, Revenue=%d",
|
log.Printf("展品已到期并生成领取记录: ExhibitionID=%d, AssetID=%d, SlotID=%d, OccupierUID=%d, Revenue=%d",
|
||||||
e.ID, e.AssetID, e.SlotID, e.OccupierUID, revenue)
|
e.ID, e.AssetID, e.SlotID, e.OccupierUID, revenue)
|
||||||
|
|
||||||
// 5. 清除该资产的点赞记录(不阻断主流程),允许用户在下次展出时再次点赞
|
// 5. 保留点赞记录,允许用户在下次展出时再次点赞(每次展览可点赞一次)
|
||||||
assetID := e.AssetID
|
// 注意:点赞记录现在按 (asset_id, user_id, exhibition_id) 去重,不会与历史点赞冲突
|
||||||
go func() {
|
|
||||||
if w.assetClient != nil {
|
|
||||||
if err := w.assetClient.ClearAssetLikeRecords(assetID); err != nil {
|
|
||||||
logger.Logger.Error("清除过期展品点赞记录失败",
|
|
||||||
zap.Int64("asset_id", assetID),
|
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("过期展品清理完成: 成功 %d 个, 失败 %d 个", successCount, failedCount)
|
log.Printf("过期展品清理完成: 成功 %d 个, 失败 %d 个", successCount, failedCount)
|
||||||
|
|||||||
@ -593,9 +593,10 @@ func (r *socialRepositoryImpl) GetMyLikedAssets(userID, starID int64, page, page
|
|||||||
// 计数查询(使用 DISTINCT 因为一个资产可能在多个展位展出)
|
// 计数查询(使用 DISTINCT 因为一个资产可能在多个展位展出)
|
||||||
// 显示:展品未下架(deleted_at IS NULL),无论是否过期
|
// 显示:展品未下架(deleted_at IS NULL),无论是否过期
|
||||||
// 不显示:已领取下架的(deleted_at IS NOT NULL)或从未展出过的
|
// 不显示:已领取下架的(deleted_at IS NOT NULL)或从未展出过的
|
||||||
|
// 使用 asset_likes.exhibition_id 关联,确保只返回有效展览的点赞记录
|
||||||
countQuery := r.db.Model(&models.AssetLike{}).
|
countQuery := r.db.Model(&models.AssetLike{}).
|
||||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||||
Joins("JOIN exhibitions e ON e.asset_id = a.id AND e.deleted_at IS NULL").
|
Joins("JOIN exhibitions e ON e.id = asset_likes.exhibition_id AND e.deleted_at IS NULL").
|
||||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true)
|
Where("a.deleted_at IS NULL AND a.is_active = ?", true)
|
||||||
|
|
||||||
@ -604,13 +605,14 @@ func (r *socialRepositoryImpl) GetMyLikedAssets(userID, starID int64, page, page
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 数据查询:只过滤已下架的,不过滤过期(用户领取收益后才下架)
|
// 数据查询:只过滤已下架的,不过滤过期(用户领取收益后才下架)
|
||||||
|
// 使用 asset_likes.exhibition_id 关联,确保只返回当前有效展览的点赞记录
|
||||||
offset := (page - 1) * pageSize
|
offset := (page - 1) * pageSize
|
||||||
err := r.db.Model(&models.AssetLike{}).
|
err := r.db.Model(&models.AssetLike{}).
|
||||||
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
||||||
asset_likes.created_at as liked_at,
|
asset_likes.created_at as liked_at,
|
||||||
(a.tags @> '["craft:lenticular"]') as is_lenticular`).
|
(a.tags @> '["craft:lenticular"]') as is_lenticular`).
|
||||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||||
Joins("JOIN exhibitions e ON e.asset_id = a.id AND e.deleted_at IS NULL").
|
Joins("JOIN exhibitions e ON e.id = asset_likes.exhibition_id AND e.deleted_at IS NULL").
|
||||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||||
Group("asset_likes.asset_id, a.name, a.cover_url, a.like_count, asset_likes.created_at, is_lenticular").
|
Group("asset_likes.asset_id, a.name, a.cover_url, a.like_count, asset_likes.created_at, is_lenticular").
|
||||||
@ -692,7 +694,7 @@ func (r *socialRepositoryImpl) GetMyTodayLikedAssets(userID, starID int64, page,
|
|||||||
|
|
||||||
countQuery := r.db.Model(&models.AssetLike{}).
|
countQuery := r.db.Model(&models.AssetLike{}).
|
||||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
Joins("JOIN exhibitions e ON e.id = asset_likes.exhibition_id").
|
||||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||||
Where("asset_likes.created_at >= ?", startOfDay).
|
Where("asset_likes.created_at >= ?", startOfDay).
|
||||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||||
@ -707,7 +709,7 @@ func (r *socialRepositoryImpl) GetMyTodayLikedAssets(userID, starID int64, page,
|
|||||||
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
||||||
asset_likes.created_at as liked_at`).
|
asset_likes.created_at as liked_at`).
|
||||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
Joins("JOIN exhibitions e ON e.id = asset_likes.exhibition_id").
|
||||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||||
Where("asset_likes.created_at >= ?", startOfDay).
|
Where("asset_likes.created_at >= ?", startOfDay).
|
||||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||||
@ -752,7 +754,7 @@ func (r *socialRepositoryImpl) GetMyWeekLikedAssets(userID, starID int64, page,
|
|||||||
|
|
||||||
countQuery := r.db.Model(&models.AssetLike{}).
|
countQuery := r.db.Model(&models.AssetLike{}).
|
||||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
Joins("JOIN exhibitions e ON e.id = asset_likes.exhibition_id").
|
||||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||||
Where("asset_likes.created_at >= ?", startOfWeekMillis).
|
Where("asset_likes.created_at >= ?", startOfWeekMillis).
|
||||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||||
@ -767,7 +769,7 @@ func (r *socialRepositoryImpl) GetMyWeekLikedAssets(userID, starID int64, page,
|
|||||||
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
||||||
asset_likes.created_at as liked_at`).
|
asset_likes.created_at as liked_at`).
|
||||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
Joins("JOIN exhibitions e ON e.id = asset_likes.exhibition_id").
|
||||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||||
Where("asset_likes.created_at >= ?", startOfWeekMillis).
|
Where("asset_likes.created_at >= ?", startOfWeekMillis).
|
||||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||||
@ -805,7 +807,7 @@ func (r *socialRepositoryImpl) GetUserLikedAssets(userID, starID int64, page, pa
|
|||||||
|
|
||||||
countQuery := r.db.Model(&models.AssetLike{}).
|
countQuery := r.db.Model(&models.AssetLike{}).
|
||||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
Joins("JOIN exhibitions e ON e.id = asset_likes.exhibition_id").
|
||||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||||
Where("e.deleted_at IS NULL AND e.expire_at > ?", now)
|
Where("e.deleted_at IS NULL AND e.expire_at > ?", now)
|
||||||
@ -819,7 +821,7 @@ func (r *socialRepositoryImpl) GetUserLikedAssets(userID, starID int64, page, pa
|
|||||||
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count,
|
||||||
asset_likes.created_at as liked_at`).
|
asset_likes.created_at as liked_at`).
|
||||||
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
Joins("JOIN assets a ON a.id = asset_likes.asset_id").
|
||||||
Joins("JOIN exhibitions e ON e.asset_id = a.id").
|
Joins("JOIN exhibitions e ON e.id = asset_likes.exhibition_id").
|
||||||
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID).
|
||||||
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
Where("a.deleted_at IS NULL AND a.is_active = ?", true).
|
||||||
Where("e.deleted_at IS NULL AND e.expire_at > ?", now).
|
Where("e.deleted_at IS NULL AND e.expire_at > ?", now).
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user