mirror of https://github.com/rocboss/paopao-ce
parent
6c923207bf
commit
fcba697a55
@ -0,0 +1,39 @@
|
||||
// Copyright 2022 ROC. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
|
||||
)
|
||||
|
||||
// EmojiService 表情包服务接口
|
||||
type EmojiService interface {
|
||||
// 上传表情包
|
||||
UploadEmoji(userID int64, name, url string, width, height int, size int64, emojiType string) (*dbr.Emoji, error)
|
||||
|
||||
// 获取表情包列表
|
||||
GetEmojiList(offset, limit int) ([]*dbr.Emoji, error)
|
||||
|
||||
// 获取用户上传的表情包列表
|
||||
GetUserEmojiList(userID int64, offset, limit int) ([]*dbr.Emoji, error)
|
||||
|
||||
// 获取用户收藏的表情包列表
|
||||
GetUserCollectedEmojiList(userID int64, offset, limit int) ([]*dbr.Emoji, error)
|
||||
|
||||
// 收藏表情包
|
||||
CollectEmoji(userID, emojiID int64) error
|
||||
|
||||
// 取消收藏表情包
|
||||
UncollectEmoji(userID, emojiID int64) error
|
||||
|
||||
// 检查表情包是否被用户收藏
|
||||
IsEmojiCollected(userID, emojiID int64) (bool, error)
|
||||
|
||||
// 获取表情包详情
|
||||
GetEmojiByID(emojiID int64) (*dbr.Emoji, error)
|
||||
|
||||
// 删除表情包
|
||||
DeleteEmoji(userID, emojiID int64) error
|
||||
}
|
||||
@ -0,0 +1,170 @@
|
||||
// Copyright 2022 ROC. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package dbr
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Emoji 表情包模型
|
||||
type Emoji struct {
|
||||
*Model
|
||||
UserID int64 `json:"user_id"`
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
Size int64 `json:"size"`
|
||||
Type string `json:"type"`
|
||||
CollectionCount int64 `json:"collection_count"`
|
||||
}
|
||||
|
||||
// UserEmoji 用户表情包收藏模型
|
||||
type UserEmoji struct {
|
||||
*Model
|
||||
UserID int64 `json:"user_id"`
|
||||
EmojiID int64 `json:"emoji_id"`
|
||||
}
|
||||
|
||||
// EmojiFormated 格式化的表情包信息
|
||||
type EmojiFormated struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID int64 `json:"user_id"`
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
Size int64 `json:"size"`
|
||||
Type string `json:"type"`
|
||||
CollectionCount int64 `json:"collection_count"`
|
||||
IsCollected bool `json:"is_collected"`
|
||||
CreatedOn int64 `json:"created_on"`
|
||||
}
|
||||
|
||||
// Format 格式化表情包信息
|
||||
func (e *Emoji) Format() *EmojiFormated {
|
||||
if e.Model != nil {
|
||||
return &EmojiFormated{
|
||||
ID: e.ID,
|
||||
UserID: e.UserID,
|
||||
Name: e.Name,
|
||||
URL: e.URL,
|
||||
Width: e.Width,
|
||||
Height: e.Height,
|
||||
Size: e.Size,
|
||||
Type: e.Type,
|
||||
CollectionCount: e.CollectionCount,
|
||||
IsCollected: false,
|
||||
CreatedOn: e.CreatedOn,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get 获取单个表情包
|
||||
func (e *Emoji) Get(db *gorm.DB) (*Emoji, error) {
|
||||
var emoji Emoji
|
||||
if e.Model != nil && e.Model.ID > 0 {
|
||||
db = db.Where("id = ? AND is_del = ?", e.Model.ID, 0)
|
||||
} else {
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
err := db.First(&emoji).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &emoji, nil
|
||||
}
|
||||
|
||||
// List 获取表情包列表
|
||||
func (e *Emoji) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*Emoji, error) {
|
||||
var emojis []*Emoji
|
||||
var err error
|
||||
|
||||
if offset >= 0 && limit > 0 {
|
||||
db = db.Offset(offset).Limit(limit)
|
||||
}
|
||||
|
||||
for k, v := range *conditions {
|
||||
if k == "ORDER" {
|
||||
db = db.Order(v)
|
||||
} else {
|
||||
db = db.Where(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
if err = db.Where("is_del = ?", 0).Find(&emojis).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return emojis, nil
|
||||
}
|
||||
|
||||
// Create 创建表情包
|
||||
func (e *Emoji) Create(db *gorm.DB) (*Emoji, error) {
|
||||
err := db.Create(&e).Error
|
||||
return e, err
|
||||
}
|
||||
|
||||
// Update 更新表情包
|
||||
func (e *Emoji) Update(db *gorm.DB) error {
|
||||
return db.Model(&Emoji{}).Where("id = ? AND is_del = ?", e.Model.ID, 0).Save(e).Error
|
||||
}
|
||||
|
||||
// Delete 删除表情包
|
||||
func (e *Emoji) Delete(db *gorm.DB) error {
|
||||
return db.Delete(&e).Error
|
||||
}
|
||||
|
||||
// IncrementCollectionCount 增加收藏数
|
||||
func (e *Emoji) IncrementCollectionCount(db *gorm.DB) error {
|
||||
return db.Model(&Emoji{}).Where("id = ? AND is_del = ?", e.Model.ID, 0).Update("collection_count", gorm.Expr("collection_count + ?", 1)).Error
|
||||
}
|
||||
|
||||
// DecrementCollectionCount 减少收藏数
|
||||
func (e *Emoji) DecrementCollectionCount(db *gorm.DB) error {
|
||||
return db.Model(&Emoji{}).Where("id = ? AND is_del = ? AND collection_count > 0", e.Model.ID, 0).Update("collection_count", gorm.Expr("collection_count - ?", 1)).Error
|
||||
}
|
||||
|
||||
// GetUserEmoji 获取用户的表情包收藏
|
||||
func (ue *UserEmoji) GetUserEmoji(db *gorm.DB) (*UserEmoji, error) {
|
||||
var userEmoji UserEmoji
|
||||
err := db.Where("user_id = ? AND emoji_id = ? AND is_del = ?", ue.UserID, ue.EmojiID, 0).First(&userEmoji).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &userEmoji, nil
|
||||
}
|
||||
|
||||
// ListUserEmojis 获取用户的表情包收藏列表
|
||||
func (ue *UserEmoji) ListUserEmojis(db *gorm.DB, userID int64, offset, limit int) ([]*Emoji, error) {
|
||||
var emojis []*Emoji
|
||||
|
||||
query := db.Table("p_emoji").Select("p_emoji.*").Joins("JOIN p_user_emoji ON p_emoji.id = p_user_emoji.emoji_id").Where("p_user_emoji.user_id = ? AND p_user_emoji.is_del = ? AND p_emoji.is_del = ?", userID, 0, 0)
|
||||
|
||||
if offset >= 0 && limit > 0 {
|
||||
query = query.Offset(offset).Limit(limit)
|
||||
}
|
||||
|
||||
err := query.Order("p_user_emoji.created_on DESC").Find(&emojis).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return emojis, nil
|
||||
}
|
||||
|
||||
// Create 创建用户表情包收藏
|
||||
func (ue *UserEmoji) Create(db *gorm.DB) (*UserEmoji, error) {
|
||||
err := db.Create(&ue).Error
|
||||
return ue, err
|
||||
}
|
||||
|
||||
// Delete 删除用户表情包收藏
|
||||
func (ue *UserEmoji) Delete(db *gorm.DB) error {
|
||||
return db.Where("user_id = ? AND emoji_id = ? AND is_del = ?", ue.UserID, ue.EmojiID, 0).Delete(&UserEmoji{}).Error
|
||||
}
|
||||
@ -0,0 +1,193 @@
|
||||
// Copyright 2022 ROC. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package jinzhu
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/rocboss/paopao-ce/internal/core"
|
||||
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
_ core.EmojiService = (*emojiSrv)(nil)
|
||||
)
|
||||
|
||||
const (
|
||||
_emoji_ = "p_emoji"
|
||||
_user_emoji_ = "p_user_emoji"
|
||||
)
|
||||
|
||||
type emojiSrv struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func newEmojiService(db *gorm.DB) core.EmojiService {
|
||||
return &emojiSrv{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// UploadEmoji 上传表情包
|
||||
func (s *emojiSrv) UploadEmoji(userID int64, name, url string, width, height int, size int64, emojiType string) (*dbr.Emoji, error) {
|
||||
emoji := &dbr.Emoji{
|
||||
Model: &dbr.Model{},
|
||||
UserID: userID,
|
||||
Name: name,
|
||||
URL: url,
|
||||
Width: width,
|
||||
Height: height,
|
||||
Size: size,
|
||||
Type: emojiType,
|
||||
CollectionCount: 0,
|
||||
}
|
||||
|
||||
return emoji.Create(s.db)
|
||||
}
|
||||
|
||||
// GetEmojiList 获取表情包列表
|
||||
func (s *emojiSrv) GetEmojiList(offset, limit int) ([]*dbr.Emoji, error) {
|
||||
emoji := &dbr.Emoji{}
|
||||
conditions := &dbr.ConditionsT{
|
||||
"ORDER": "collection_count DESC, created_on DESC",
|
||||
}
|
||||
|
||||
return emoji.List(s.db, conditions, offset, limit)
|
||||
}
|
||||
|
||||
// GetUserEmojiList 获取用户上传的表情包列表
|
||||
func (s *emojiSrv) GetUserEmojiList(userID int64, offset, limit int) ([]*dbr.Emoji, error) {
|
||||
emoji := &dbr.Emoji{}
|
||||
conditions := &dbr.ConditionsT{
|
||||
"user_id = ?": userID,
|
||||
"ORDER": "created_on DESC",
|
||||
}
|
||||
|
||||
return emoji.List(s.db, conditions, offset, limit)
|
||||
}
|
||||
|
||||
// GetUserCollectedEmojiList 获取用户收藏的表情包列表
|
||||
func (s *emojiSrv) GetUserCollectedEmojiList(userID int64, offset, limit int) ([]*dbr.Emoji, error) {
|
||||
userEmoji := &dbr.UserEmoji{}
|
||||
return userEmoji.ListUserEmojis(s.db, userID, offset, limit)
|
||||
}
|
||||
|
||||
// CollectEmoji 收藏表情包
|
||||
func (s *emojiSrv) CollectEmoji(userID, emojiID int64) error {
|
||||
// 检查表情包是否存在
|
||||
emoji := &dbr.Emoji{
|
||||
Model: &dbr.Model{
|
||||
ID: emojiID,
|
||||
},
|
||||
}
|
||||
_, err := emoji.Get(s.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查是否已经收藏
|
||||
userEmoji := &dbr.UserEmoji{
|
||||
UserID: userID,
|
||||
EmojiID: emojiID,
|
||||
}
|
||||
_, err = userEmoji.GetUserEmoji(s.db)
|
||||
if err == nil {
|
||||
return errors.New("emoji already collected")
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建收藏记录
|
||||
userEmoji = &dbr.UserEmoji{
|
||||
Model: &dbr.Model{},
|
||||
UserID: userID,
|
||||
EmojiID: emojiID,
|
||||
}
|
||||
_, err = userEmoji.Create(s.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 增加表情包收藏数
|
||||
return emoji.IncrementCollectionCount(s.db)
|
||||
}
|
||||
|
||||
// UncollectEmoji 取消收藏表情包
|
||||
func (s *emojiSrv) UncollectEmoji(userID, emojiID int64) error {
|
||||
// 检查是否已经收藏
|
||||
userEmoji := &dbr.UserEmoji{
|
||||
UserID: userID,
|
||||
EmojiID: emojiID,
|
||||
}
|
||||
_, err := userEmoji.GetUserEmoji(s.db)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errors.New("emoji not collected")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除收藏记录
|
||||
err = userEmoji.Delete(s.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 减少表情包收藏数
|
||||
emoji := &dbr.Emoji{
|
||||
Model: &dbr.Model{
|
||||
ID: emojiID,
|
||||
},
|
||||
}
|
||||
return emoji.DecrementCollectionCount(s.db)
|
||||
}
|
||||
|
||||
// IsEmojiCollected 检查表情包是否被用户收藏
|
||||
func (s *emojiSrv) IsEmojiCollected(userID, emojiID int64) (bool, error) {
|
||||
userEmoji := &dbr.UserEmoji{
|
||||
UserID: userID,
|
||||
EmojiID: emojiID,
|
||||
}
|
||||
_, err := userEmoji.GetUserEmoji(s.db)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// GetEmojiByID 获取表情包详情
|
||||
func (s *emojiSrv) GetEmojiByID(emojiID int64) (*dbr.Emoji, error) {
|
||||
emoji := &dbr.Emoji{
|
||||
Model: &dbr.Model{
|
||||
ID: emojiID,
|
||||
},
|
||||
}
|
||||
return emoji.Get(s.db)
|
||||
}
|
||||
|
||||
// DeleteEmoji 删除表情包
|
||||
func (s *emojiSrv) DeleteEmoji(userID, emojiID int64) error {
|
||||
// 检查表情包是否存在且属于该用户
|
||||
emoji := &dbr.Emoji{
|
||||
Model: &dbr.Model{
|
||||
ID: emojiID,
|
||||
},
|
||||
}
|
||||
emoji, err := emoji.Get(s.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if emoji.UserID != userID {
|
||||
return errors.New("permission denied")
|
||||
}
|
||||
|
||||
// 删除表情包
|
||||
return emoji.Delete(s.db)
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
DROP TABLE IF EXISTS `p_user_emoji`;
|
||||
DROP TABLE IF EXISTS `p_emoji`;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
@ -0,0 +1,36 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
CREATE TABLE `p_emoji` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '表情包ID',
|
||||
`user_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '上传用户ID',
|
||||
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '表情包名称',
|
||||
`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '表情包URL',
|
||||
`width` int unsigned NOT NULL DEFAULT '0' COMMENT '宽度',
|
||||
`height` int unsigned NOT NULL DEFAULT '0' COMMENT '高度',
|
||||
`size` bigint unsigned NOT NULL DEFAULT '0' COMMENT '文件大小',
|
||||
`type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '文件类型',
|
||||
`collection_count` bigint unsigned NOT NULL DEFAULT '0' COMMENT '收藏数',
|
||||
`created_on` bigint unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
`modified_on` bigint unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
|
||||
`deleted_on` bigint unsigned NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
`is_del` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否删除 0 为未删除、1 为已删除',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_user` (`user_id`) USING BTREE,
|
||||
KEY `idx_collection` (`collection_count`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='表情包';
|
||||
|
||||
CREATE TABLE `p_user_emoji` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '记录ID',
|
||||
`user_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
|
||||
`emoji_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '表情包ID',
|
||||
`created_on` bigint unsigned NOT NULL DEFAULT '0' COMMENT '收藏时间',
|
||||
`modified_on` bigint unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
|
||||
`deleted_on` bigint unsigned NOT NULL DEFAULT '0' COMMENT '删除时间',
|
||||
`is_del` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否删除 0 为未删除、1 为已删除',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `idx_user_emoji` (`user_id`,`emoji_id`) USING BTREE,
|
||||
KEY `idx_emoji` (`emoji_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表情包收藏';
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
@ -0,0 +1,2 @@
|
||||
DROP TABLE IF EXISTS p_user_emoji;
|
||||
DROP TABLE IF EXISTS p_emoji;
|
||||
@ -0,0 +1,31 @@
|
||||
CREATE TABLE IF NOT EXISTS p_emoji (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL DEFAULT 0,
|
||||
name VARCHAR(64) NOT NULL DEFAULT '',
|
||||
url VARCHAR(255) NOT NULL DEFAULT '',
|
||||
width INTEGER NOT NULL DEFAULT 0,
|
||||
height INTEGER NOT NULL DEFAULT 0,
|
||||
size BIGINT NOT NULL DEFAULT 0,
|
||||
type VARCHAR(32) NOT NULL DEFAULT '',
|
||||
collection_count BIGINT NOT NULL DEFAULT 0,
|
||||
created_on BIGINT NOT NULL DEFAULT 0,
|
||||
modified_on BIGINT NOT NULL DEFAULT 0,
|
||||
deleted_on BIGINT NOT NULL DEFAULT 0,
|
||||
is_del SMALLINT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_emoji_user ON p_emoji(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_emoji_collection ON p_emoji(collection_count);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS p_user_emoji (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL DEFAULT 0,
|
||||
emoji_id BIGINT NOT NULL DEFAULT 0,
|
||||
created_on BIGINT NOT NULL DEFAULT 0,
|
||||
modified_on BIGINT NOT NULL DEFAULT 0,
|
||||
deleted_on BIGINT NOT NULL DEFAULT 0,
|
||||
is_del SMALLINT NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_user_emoji ON p_user_emoji(user_id, emoji_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_user_emoji_emoji ON p_user_emoji(emoji_id);
|
||||
@ -0,0 +1,2 @@
|
||||
DROP TABLE IF EXISTS p_user_emoji;
|
||||
DROP TABLE IF EXISTS p_emoji;
|
||||
@ -0,0 +1,31 @@
|
||||
CREATE TABLE IF NOT EXISTS p_emoji (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL DEFAULT 0,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
url TEXT NOT NULL DEFAULT '',
|
||||
width INTEGER NOT NULL DEFAULT 0,
|
||||
height INTEGER NOT NULL DEFAULT 0,
|
||||
size INTEGER NOT NULL DEFAULT 0,
|
||||
type TEXT NOT NULL DEFAULT '',
|
||||
collection_count INTEGER NOT NULL DEFAULT 0,
|
||||
created_on INTEGER NOT NULL DEFAULT 0,
|
||||
modified_on INTEGER NOT NULL DEFAULT 0,
|
||||
deleted_on INTEGER NOT NULL DEFAULT 0,
|
||||
is_del INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_emoji_user ON p_emoji(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_emoji_collection ON p_emoji(collection_count);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS p_user_emoji (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL DEFAULT 0,
|
||||
emoji_id INTEGER NOT NULL DEFAULT 0,
|
||||
created_on INTEGER NOT NULL DEFAULT 0,
|
||||
modified_on INTEGER NOT NULL DEFAULT 0,
|
||||
deleted_on INTEGER NOT NULL DEFAULT 0,
|
||||
is_del INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_user_emoji ON p_user_emoji(user_id, emoji_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_user_emoji_emoji ON p_user_emoji(emoji_id);
|
||||
Loading…
Reference in new issue