Files
kim.dev.6789 b7f8db7d08 复制项目
2026-01-14 22:35:45 +08:00

868 lines
41 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright © 2023 OpenIM open source community. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package database
import (
"context"
"time"
"github.com/openimsdk/tools/db/mongoutil"
"github.com/openimsdk/tools/db/pagination"
"github.com/openimsdk/tools/db/tx"
"github.com/redis/go-redis/v9"
"git.imall.cloud/openim/chat/pkg/common/constant"
"git.imall.cloud/openim/chat/pkg/common/db/cache"
admindb "git.imall.cloud/openim/chat/pkg/common/db/model/admin"
"git.imall.cloud/openim/chat/pkg/common/db/model/chat"
"git.imall.cloud/openim/chat/pkg/common/db/table/admin"
chatdb "git.imall.cloud/openim/chat/pkg/common/db/table/chat"
)
type ChatDatabaseInterface interface {
GetUser(ctx context.Context, userID string) (account *chatdb.Account, err error)
UpdateUseInfo(ctx context.Context, userID string, attribute map[string]any, updateCred, delCred []*chatdb.Credential) (err error)
FindAttribute(ctx context.Context, userIDs []string) ([]*chatdb.Attribute, error)
FindAttributeByAccount(ctx context.Context, accounts []string) ([]*chatdb.Attribute, error)
TakeAttributeByPhone(ctx context.Context, areaCode string, phoneNumber string) (*chatdb.Attribute, error)
TakeAttributeByEmail(ctx context.Context, Email string) (*chatdb.Attribute, error)
TakeAttributeByAccount(ctx context.Context, account string) (*chatdb.Attribute, error)
TakeAttributeByUserID(ctx context.Context, userID string) (*chatdb.Attribute, error)
TakeAccount(ctx context.Context, userID string) (*chatdb.Account, error)
TakeCredentialByAccount(ctx context.Context, account string) (*chatdb.Credential, error)
TakeCredentialsByUserID(ctx context.Context, userID string) ([]*chatdb.Credential, error)
TakeLastVerifyCode(ctx context.Context, account string) (*chatdb.VerifyCode, error)
Search(ctx context.Context, normalUser int32, keyword string, genders int32, startTime, endTime *time.Time, pagination pagination.Pagination) (int64, []*chatdb.Attribute, error)
SearchWithRealNameAuth(ctx context.Context, normalUser int32, keyword string, genders int32, startTime, endTime *time.Time, realNameKeyword string, idCardKeyword string, pagination pagination.Pagination) (total int64, attributes []*chatdb.Attribute, err error) // 搜索用户(支持实名信息搜索)
SearchUser(ctx context.Context, keyword string, userIDs []string, genders []int32, pagination pagination.Pagination) (int64, []*chatdb.Attribute, error)
CountVerifyCodeRange(ctx context.Context, account string, start time.Time, end time.Time) (int64, error)
AddVerifyCode(ctx context.Context, verifyCode *chatdb.VerifyCode, fn func() error) error
UpdateVerifyCodeIncrCount(ctx context.Context, id string) error
DelVerifyCode(ctx context.Context, id string) error
RegisterUser(ctx context.Context, register *chatdb.Register, account *chatdb.Account, attribute *chatdb.Attribute, credentials []*chatdb.Credential) error
LoginRecord(ctx context.Context, record *chatdb.UserLoginRecord, verifyCodeID *string) error
UpdatePassword(ctx context.Context, userID string, password string) error
UpdatePasswordAndDeleteVerifyCode(ctx context.Context, userID string, password string, codeID string) error
NewUserCountTotal(ctx context.Context, before *time.Time) (int64, error)
UserLoginCountTotal(ctx context.Context, before *time.Time) (int64, error)
UserLoginCountRangeEverydayTotal(ctx context.Context, start *time.Time, end *time.Time) (map[string]int64, int64, error)
CountTodayRegisteredUsers(ctx context.Context) (int64, error)
CountTodayActiveUsers(ctx context.Context) (int64, error)
GetLatestLoginIP(ctx context.Context, userID string) (string, error) // 获取用户最新登录IP
SearchUserLoginRecords(ctx context.Context, userID, ip string, pagination pagination.Pagination) (int64, []*chatdb.UserLoginRecord, error) // 查询用户登录记录支持按用户ID或IP查询
DelUserAccount(ctx context.Context, userIDs []string) error
// 敏感词相关方法
GetSensitiveWords(ctx context.Context) ([]*chatdb.SensitiveWord, error)
CheckSensitiveWords(ctx context.Context, content string) ([]*chatdb.SensitiveWord, bool, error)
FilterContent(ctx context.Context, content string) (string, []*chatdb.SensitiveWord, bool, error)
GetSensitiveWordConfig(ctx context.Context) (*chatdb.SensitiveWordConfig, error)
// 敏感词管理相关方法
CreateSensitiveWord(ctx context.Context, word *chatdb.SensitiveWord) error
UpdateSensitiveWord(ctx context.Context, id string, data map[string]any) error
DeleteSensitiveWord(ctx context.Context, ids []string) error
GetSensitiveWord(ctx context.Context, id string) (*chatdb.SensitiveWord, error)
SearchSensitiveWords(ctx context.Context, keyword string, action int32, status int32, pagination pagination.Pagination) (int64, []*chatdb.SensitiveWord, error)
BatchAddSensitiveWords(ctx context.Context, words []*chatdb.SensitiveWord) error
BatchUpdateSensitiveWords(ctx context.Context, updates map[string]map[string]any) error
BatchDeleteSensitiveWords(ctx context.Context, ids []string) error
// 敏感词分组管理
CreateSensitiveWordGroup(ctx context.Context, group *chatdb.SensitiveWordGroup) error
UpdateSensitiveWordGroup(ctx context.Context, id string, data map[string]any) error
DeleteSensitiveWordGroup(ctx context.Context, ids []string) error
GetSensitiveWordGroup(ctx context.Context, id string) (*chatdb.SensitiveWordGroup, error)
GetAllSensitiveWordGroups(ctx context.Context) ([]*chatdb.SensitiveWordGroup, error)
// 敏感词配置管理
UpdateSensitiveWordConfig(ctx context.Context, config *chatdb.SensitiveWordConfig) error
// 敏感词日志管理
GetSensitiveWordLogs(ctx context.Context, userID, groupID string, pagination pagination.Pagination) (int64, []*chatdb.SensitiveWordLog, error)
DeleteSensitiveWordLogs(ctx context.Context, ids []string) error
// 敏感词统计
GetSensitiveWordStats(ctx context.Context) (map[string]int64, error)
GetSensitiveWordLogStats(ctx context.Context, startTime, endTime time.Time) (map[string]int64, error)
// 收藏相关方法
CreateFavorite(ctx context.Context, favorite *chatdb.Favorite) error
GetFavorite(ctx context.Context, favoriteID string) (*chatdb.Favorite, error)
GetFavoritesByUserID(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.Favorite, error)
GetFavoritesByUserIDAndType(ctx context.Context, userID string, favoriteType int32, pagination pagination.Pagination) (int64, []*chatdb.Favorite, error)
SearchFavoritesByKeyword(ctx context.Context, userID string, keyword string, pagination pagination.Pagination) (int64, []*chatdb.Favorite, error)
UpdateFavorite(ctx context.Context, favoriteID string, data map[string]any) error
DeleteFavorite(ctx context.Context, favoriteIDs []string) error
DeleteFavoritesByUserID(ctx context.Context, userID string) error
CountFavoritesByUserID(ctx context.Context, userID string) (int64, error)
GetFavoritesByTags(ctx context.Context, userID string, tags []string, pagination pagination.Pagination) (int64, []*chatdb.Favorite, error)
// 定时任务相关方法
CreateScheduledTask(ctx context.Context, task *chatdb.ScheduledTask) error
GetScheduledTask(ctx context.Context, taskID string) (*chatdb.ScheduledTask, error)
GetScheduledTasksByUserID(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.ScheduledTask, error)
GetAllScheduledTasks(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.ScheduledTask, error)
UpdateScheduledTask(ctx context.Context, taskID string, data map[string]any) error
DeleteScheduledTask(ctx context.Context, taskIDs []string) error
// 系统配置相关方法
CreateSystemConfig(ctx context.Context, config *chatdb.SystemConfig) error
GetSystemConfig(ctx context.Context, key string) (*chatdb.SystemConfig, error)
GetSystemConfigsByKeys(ctx context.Context, keys []string) ([]*chatdb.SystemConfig, error)
GetAllSystemConfigs(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.SystemConfig, error)
UpdateSystemConfig(ctx context.Context, key string, data map[string]any) error
UpdateSystemConfigValue(ctx context.Context, key string, value string) error
UpdateSystemConfigEnabled(ctx context.Context, key string, enabled bool) error
DeleteSystemConfig(ctx context.Context, keys []string) error
GetEnabledSystemConfigs(ctx context.Context) ([]*chatdb.SystemConfig, error)
GetAppSystemConfigs(ctx context.Context) ([]*chatdb.SystemConfig, error) // 获取所有 show_in_app=true 且 enabled=true 的配置
// 钱包相关方法
GetWallet(ctx context.Context, userID string) (*chatdb.Wallet, error) // 获取钱包信息
GetWalletsByUserIDs(ctx context.Context, userIDs []string) ([]*chatdb.Wallet, error) // 根据用户ID列表批量获取钱包
GetWalletsPage(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.Wallet, error) // 分页获取钱包列表
GetWalletsPageByRealNameAuthAuditStatus(ctx context.Context, auditStatus int32, userID string, pagination pagination.Pagination) (int64, []*chatdb.Wallet, error) // 按实名认证审核状态分页查询钱包支持用户ID搜索
CreateWallet(ctx context.Context, wallet *chatdb.Wallet) error // 创建钱包
UpdateWalletBalance(ctx context.Context, userID string, balance int64) error // 更新钱包余额
IncrementWalletBalance(ctx context.Context, userID string, amount int64) (beforeBalance int64, afterBalance int64, err error) // 原子更新余额,返回更新前后的余额
UpdateWalletPaymentPassword(ctx context.Context, userID string, paymentPassword string) error // 更新支付密码
UpdateWalletWithdrawAccount(ctx context.Context, userID string, withdrawAccount string) error // 更新提款账号(兼容旧接口)
UpdateWalletWithdrawAccountWithType(ctx context.Context, userID string, withdrawAccount string, accountType int32) error // 更新提款账号(带类型)
UpdateWalletRealNameAuth(ctx context.Context, userID string, realNameAuth chatdb.RealNameAuth) error // 更新实名认证信息
GetWalletBalanceRecords(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.WalletBalanceRecord, error) // 获取钱包余额变动记录
GetWalletBalanceRecordsByUserIDAndType(ctx context.Context, userID string, recordType int32, pagination pagination.Pagination) (int64, []*chatdb.WalletBalanceRecord, error) // 根据类型获取钱包余额变动记录
CreateWalletBalanceRecord(ctx context.Context, record *chatdb.WalletBalanceRecord) error // 创建余额变动记录
// 提现相关方法
CreateWithdraw(ctx context.Context, withdraw *chatdb.Withdraw) error // 创建提现记录
GetWithdraw(ctx context.Context, withdrawID string) (*chatdb.Withdraw, error) // 获取提现记录
GetWithdrawsByUserID(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.Withdraw, error) // 获取用户的提现记录列表
GetWithdrawsByStatus(ctx context.Context, status int32, pagination pagination.Pagination) (int64, []*chatdb.Withdraw, error) // 根据状态获取提现记录列表
UpdateWithdrawStatus(ctx context.Context, withdrawID string, status int32, auditorID string, auditRemark string) error // 更新提现状态(审核)
GetWithdrawsPage(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.Withdraw, error) // 获取提现记录列表(分页)
// 提现申请相关方法
CreateWithdrawApplication(ctx context.Context, application *chatdb.WithdrawApplication) error // 创建提现申请
GetWithdrawApplication(ctx context.Context, applicationID string) (*chatdb.WithdrawApplication, error) // 获取提现申请
GetWithdrawApplicationsByUserID(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.WithdrawApplication, error) // 获取用户的提现申请列表
GetWithdrawApplicationsByStatus(ctx context.Context, status int32, pagination pagination.Pagination) (int64, []*chatdb.WithdrawApplication, error) // 根据状态获取提现申请列表
UpdateWithdrawApplicationStatus(ctx context.Context, applicationID string, status int32, auditorID string, auditRemark string) error // 更新提现申请状态(审核)
GetWithdrawApplicationsPage(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.WithdrawApplication, error) // 获取提现申请列表(分页)
UpdateWithdrawApplication(ctx context.Context, applicationID string, data map[string]any) error // 更新提现申请
}
func NewChatDatabase(cli *mongoutil.Client, rdb redis.UniversalClient) (ChatDatabaseInterface, error) {
register, err := chat.NewRegister(cli.GetDB())
if err != nil {
return nil, err
}
account, err := chat.NewAccount(cli.GetDB())
if err != nil {
return nil, err
}
attribute, err := chat.NewAttribute(cli.GetDB())
if err != nil {
return nil, err
}
credential, err := chat.NewCredential(cli.GetDB())
if err != nil {
return nil, err
}
userLoginRecord, err := chat.NewUserLoginRecord(cli.GetDB())
if err != nil {
return nil, err
}
verifyCode, err := chat.NewVerifyCode(cli.GetDB())
if err != nil {
return nil, err
}
forbiddenAccount, err := admindb.NewForbiddenAccount(cli.GetDB())
if err != nil {
return nil, err
}
sensitiveWord, err := chat.NewSensitiveWord(cli.GetDB())
if err != nil {
return nil, err
}
favorite, err := chat.NewFavorite(cli.GetDB())
if err != nil {
return nil, err
}
scheduledTask, err := chat.NewScheduledTask(cli.GetDB())
if err != nil {
return nil, err
}
systemConfig, err := chat.NewSystemConfig(cli.GetDB())
if err != nil {
return nil, err
}
wallet, err := chat.NewWallet(cli.GetDB())
if err != nil {
return nil, err
}
walletBalanceRecord, err := chat.NewWalletBalanceRecord(cli.GetDB())
if err != nil {
return nil, err
}
withdraw, err := chat.NewWithdraw(cli.GetDB())
if err != nil {
return nil, err
}
withdrawApplication, err := chat.NewWithdrawApplication(cli.GetDB())
if err != nil {
return nil, err
}
var userLoginIPCache cache.UserLoginIPInterface
if rdb != nil {
userLoginIPCache = cache.NewUserLoginIPInterface(rdb)
}
return &ChatDatabase{
tx: cli.GetTx(),
register: register,
account: account,
attribute: attribute,
credential: credential,
userLoginRecord: userLoginRecord,
verifyCode: verifyCode,
forbiddenAccount: forbiddenAccount,
sensitiveWord: sensitiveWord,
favorite: favorite,
scheduledTask: scheduledTask,
systemConfig: systemConfig,
wallet: wallet,
walletBalanceRecord: walletBalanceRecord,
withdraw: withdraw,
withdrawApplication: withdrawApplication,
userLoginIPCache: userLoginIPCache,
}, nil
}
type ChatDatabase struct {
tx tx.Tx
register chatdb.RegisterInterface
account chatdb.AccountInterface
attribute chatdb.AttributeInterface
credential chatdb.CredentialInterface
userLoginRecord chatdb.UserLoginRecordInterface
verifyCode chatdb.VerifyCodeInterface
forbiddenAccount admin.ForbiddenAccountInterface
sensitiveWord chatdb.SensitiveWordInterface
favorite chatdb.FavoriteInterface
scheduledTask chatdb.ScheduledTaskInterface
systemConfig chatdb.SystemConfigInterface
wallet chatdb.WalletInterface
walletBalanceRecord chatdb.WalletBalanceRecordInterface
withdraw chatdb.WithdrawInterface
withdrawApplication chatdb.WithdrawApplicationInterface
userLoginIPCache cache.UserLoginIPInterface // 用户登录IP缓存可选如果为nil则不使用缓存
}
func (o *ChatDatabase) GetUser(ctx context.Context, userID string) (account *chatdb.Account, err error) {
return o.account.Take(ctx, userID)
}
func (o *ChatDatabase) UpdateUseInfo(ctx context.Context, userID string, attribute map[string]any, updateCred, delCred []*chatdb.Credential) (err error) {
return o.tx.Transaction(ctx, func(ctx context.Context) error {
if err = o.attribute.Update(ctx, userID, attribute); err != nil {
return err
}
for _, credential := range updateCred {
if err = o.credential.CreateOrUpdateAccount(ctx, credential); err != nil {
return err
}
}
if err = o.credential.DeleteByUserIDType(ctx, delCred...); err != nil {
return err
}
return nil
})
}
func (o *ChatDatabase) FindAttribute(ctx context.Context, userIDs []string) ([]*chatdb.Attribute, error) {
return o.attribute.Find(ctx, userIDs)
}
func (o *ChatDatabase) FindAttributeByAccount(ctx context.Context, accounts []string) ([]*chatdb.Attribute, error) {
return o.attribute.FindAccount(ctx, accounts)
}
func (o *ChatDatabase) TakeAttributeByPhone(ctx context.Context, areaCode string, phoneNumber string) (*chatdb.Attribute, error) {
return o.attribute.TakePhone(ctx, areaCode, phoneNumber)
}
func (o *ChatDatabase) TakeAttributeByEmail(ctx context.Context, email string) (*chatdb.Attribute, error) {
return o.attribute.TakeEmail(ctx, email)
}
func (o *ChatDatabase) TakeAttributeByAccount(ctx context.Context, account string) (*chatdb.Attribute, error) {
return o.attribute.TakeAccount(ctx, account)
}
func (o *ChatDatabase) TakeAttributeByUserID(ctx context.Context, userID string) (*chatdb.Attribute, error) {
return o.attribute.Take(ctx, userID)
}
func (o *ChatDatabase) TakeLastVerifyCode(ctx context.Context, account string) (*chatdb.VerifyCode, error) {
return o.verifyCode.TakeLast(ctx, account)
}
func (o *ChatDatabase) TakeAccount(ctx context.Context, userID string) (*chatdb.Account, error) {
return o.account.Take(ctx, userID)
}
func (o *ChatDatabase) TakeCredentialByAccount(ctx context.Context, account string) (*chatdb.Credential, error) {
return o.credential.TakeAccount(ctx, account)
}
func (o *ChatDatabase) TakeCredentialsByUserID(ctx context.Context, userID string) ([]*chatdb.Credential, error) {
return o.credential.Find(ctx, userID)
}
func (o *ChatDatabase) Search(ctx context.Context, normalUser int32, keyword string, genders int32, startTime, endTime *time.Time, pagination pagination.Pagination) (total int64, attributes []*chatdb.Attribute, err error) {
var forbiddenIDs []string
if int(normalUser) == constant.NormalUser {
forbiddenIDs, err = o.forbiddenAccount.FindAllIDs(ctx)
if err != nil {
return 0, nil, err
}
}
total, totalUser, err := o.attribute.SearchNormalUser(ctx, keyword, forbiddenIDs, genders, startTime, endTime, pagination)
if err != nil {
return 0, nil, err
}
return total, totalUser, nil
}
// SearchWithRealNameAuth 搜索用户(支持实名信息搜索)
func (o *ChatDatabase) SearchWithRealNameAuth(ctx context.Context, normalUser int32, keyword string, genders int32, startTime, endTime *time.Time, realNameKeyword string, idCardKeyword string, pagination pagination.Pagination) (total int64, attributes []*chatdb.Attribute, err error) {
// 如果提供了实名信息搜索关键词先查询钱包获取userIDs
var realNameAuthUserIDs []string
if realNameKeyword != "" || idCardKeyword != "" {
realNameAuthUserIDs, err = o.wallet.SearchByRealNameAuth(ctx, realNameKeyword, idCardKeyword)
if err != nil {
return 0, nil, err
}
// 如果没有找到匹配的用户,直接返回空结果
if len(realNameAuthUserIDs) == 0 {
return 0, []*chatdb.Attribute{}, nil
}
}
var forbiddenIDs []string
if int(normalUser) == constant.NormalUser {
forbiddenIDs, err = o.forbiddenAccount.FindAllIDs(ctx)
if err != nil {
return 0, nil, err
}
}
// 如果提供了实名信息搜索需要在用户ID列表中过滤
if len(realNameAuthUserIDs) > 0 {
// 修改 SearchNormalUser 方法,支持传入额外的 userIDs 过滤条件
// 或者创建一个新的方法
// 这里我们修改 SearchNormalUser 来支持这个功能
total, totalUser, err := o.attribute.SearchNormalUserWithUserIDs(ctx, keyword, forbiddenIDs, genders, startTime, endTime, realNameAuthUserIDs, pagination)
if err != nil {
return 0, nil, err
}
return total, totalUser, nil
}
// 没有实名信息搜索,使用原来的方法
return o.Search(ctx, normalUser, keyword, genders, startTime, endTime, pagination)
}
func (o *ChatDatabase) SearchUser(ctx context.Context, keyword string, userIDs []string, genders []int32, pagination pagination.Pagination) (int64, []*chatdb.Attribute, error) {
return o.attribute.SearchUser(ctx, keyword, userIDs, genders, pagination)
}
func (o *ChatDatabase) CountVerifyCodeRange(ctx context.Context, account string, start time.Time, end time.Time) (int64, error) {
return o.verifyCode.RangeNum(ctx, account, start, end)
}
func (o *ChatDatabase) AddVerifyCode(ctx context.Context, verifyCode *chatdb.VerifyCode, fn func() error) error {
return o.tx.Transaction(ctx, func(ctx context.Context) error {
if err := o.verifyCode.Add(ctx, []*chatdb.VerifyCode{verifyCode}); err != nil {
return err
}
if fn != nil {
return fn()
}
return nil
})
}
func (o *ChatDatabase) UpdateVerifyCodeIncrCount(ctx context.Context, id string) error {
return o.verifyCode.Incr(ctx, id)
}
func (o *ChatDatabase) DelVerifyCode(ctx context.Context, id string) error {
return o.verifyCode.Delete(ctx, id)
}
func (o *ChatDatabase) RegisterUser(ctx context.Context, register *chatdb.Register, account *chatdb.Account, attribute *chatdb.Attribute, credentials []*chatdb.Credential) error {
return o.tx.Transaction(ctx, func(ctx context.Context) error {
if err := o.register.Create(ctx, register); err != nil {
return err
}
if err := o.account.Create(ctx, account); err != nil {
return err
}
if err := o.attribute.Create(ctx, attribute); err != nil {
return err
}
if err := o.credential.Create(ctx, credentials...); err != nil {
return err
}
return nil
})
}
func (o *ChatDatabase) LoginRecord(ctx context.Context, record *chatdb.UserLoginRecord, verifyCodeID *string) error {
return o.tx.Transaction(ctx, func(ctx context.Context) error {
if err := o.userLoginRecord.Create(ctx, record); err != nil {
return err
}
// 创建登录记录后,更新缓存(保证缓存一致性)
if o.userLoginIPCache != nil && record.UserID != "" {
// 先删除旧缓存,然后设置新缓存
// 使用新IP更新缓存这样下次查询时可以直接从缓存获取
_ = o.userLoginIPCache.SetLatestLoginIP(ctx, record.UserID, record.IP)
}
if verifyCodeID != nil {
if err := o.verifyCode.Delete(ctx, *verifyCodeID); err != nil {
return err
}
}
return nil
})
}
func (o *ChatDatabase) UpdatePassword(ctx context.Context, userID string, password string) error {
return o.account.UpdatePassword(ctx, userID, password)
}
func (o *ChatDatabase) UpdatePasswordAndDeleteVerifyCode(ctx context.Context, userID string, password string, codeID string) error {
return o.tx.Transaction(ctx, func(ctx context.Context) error {
if err := o.account.UpdatePassword(ctx, userID, password); err != nil {
return err
}
if codeID == "" {
return nil
}
if err := o.verifyCode.Delete(ctx, codeID); err != nil {
return err
}
return nil
})
}
func (o *ChatDatabase) NewUserCountTotal(ctx context.Context, before *time.Time) (int64, error) {
return o.register.CountTotal(ctx, before)
}
func (o *ChatDatabase) UserLoginCountTotal(ctx context.Context, before *time.Time) (int64, error) {
return o.userLoginRecord.CountTotal(ctx, before)
}
func (o *ChatDatabase) UserLoginCountRangeEverydayTotal(ctx context.Context, start *time.Time, end *time.Time) (map[string]int64, int64, error) {
return o.userLoginRecord.CountRangeEverydayTotal(ctx, start, end)
}
func (o *ChatDatabase) CountTodayRegisteredUsers(ctx context.Context) (int64, error) {
return o.register.CountToday(ctx)
}
func (o *ChatDatabase) CountTodayActiveUsers(ctx context.Context) (int64, error) {
return o.userLoginRecord.CountTodayActiveUsers(ctx)
}
func (o *ChatDatabase) GetLatestLoginIP(ctx context.Context, userID string) (string, error) {
// 如果启用了缓存,先尝试从缓存获取
if o.userLoginIPCache != nil {
ip, found, err := o.userLoginIPCache.GetLatestLoginIP(ctx, userID)
if err != nil {
// 缓存查询出错,降级到数据库查询
return o.userLoginRecord.GetLatestLoginIP(ctx, userID)
}
// 如果缓存命中直接返回即使IP为空字符串也表示用户确实没有IP
if found {
return ip, nil
}
// 缓存未命中,从数据库查询
ip, err = o.userLoginRecord.GetLatestLoginIP(ctx, userID)
if err != nil {
return "", err
}
// 将查询结果写入缓存(即使为空也缓存,避免频繁查询数据库)
_ = o.userLoginIPCache.SetLatestLoginIP(ctx, userID, ip)
return ip, nil
}
// 未启用缓存,直接从数据库查询
return o.userLoginRecord.GetLatestLoginIP(ctx, userID)
}
func (o *ChatDatabase) SearchUserLoginRecords(ctx context.Context, userID, ip string, pagination pagination.Pagination) (int64, []*chatdb.UserLoginRecord, error) {
return o.userLoginRecord.Search(ctx, userID, ip, pagination)
}
func (o *ChatDatabase) DelUserAccount(ctx context.Context, userIDs []string) error {
return o.tx.Transaction(ctx, func(ctx context.Context) error {
if err := o.register.Delete(ctx, userIDs); err != nil {
return err
}
if err := o.account.Delete(ctx, userIDs); err != nil {
return err
}
if err := o.attribute.Delete(ctx, userIDs); err != nil {
return err
}
return nil
})
}
// ==================== 敏感词相关方法实现 ====================
// GetSensitiveWords 获取所有启用的敏感词
func (o *ChatDatabase) GetSensitiveWords(ctx context.Context) ([]*chatdb.SensitiveWord, error) {
return o.sensitiveWord.GetEnabledSensitiveWords(ctx)
}
// CheckSensitiveWords 检测敏感词
func (o *ChatDatabase) CheckSensitiveWords(ctx context.Context, content string) ([]*chatdb.SensitiveWord, bool, error) {
words, err := o.sensitiveWord.CheckSensitiveWords(ctx, content)
hasSensitive := len(words) > 0
return words, hasSensitive, err
}
// FilterContent 过滤内容
func (o *ChatDatabase) FilterContent(ctx context.Context, content string) (string, []*chatdb.SensitiveWord, bool, error) {
filteredContent, words, err := o.sensitiveWord.FilterContent(ctx, content)
hasSensitive := len(words) > 0
return filteredContent, words, hasSensitive, err
}
// GetSensitiveWordConfig 获取敏感词配置
func (o *ChatDatabase) GetSensitiveWordConfig(ctx context.Context) (*chatdb.SensitiveWordConfig, error) {
return o.sensitiveWord.GetSensitiveWordConfig(ctx)
}
// ==================== 敏感词管理相关方法实现 ====================
func (o *ChatDatabase) CreateSensitiveWord(ctx context.Context, word *chatdb.SensitiveWord) error {
return o.sensitiveWord.CreateSensitiveWord(ctx, word)
}
func (o *ChatDatabase) UpdateSensitiveWord(ctx context.Context, id string, data map[string]any) error {
return o.sensitiveWord.UpdateSensitiveWord(ctx, id, data)
}
func (o *ChatDatabase) DeleteSensitiveWord(ctx context.Context, ids []string) error {
return o.sensitiveWord.DeleteSensitiveWord(ctx, ids)
}
func (o *ChatDatabase) GetSensitiveWord(ctx context.Context, id string) (*chatdb.SensitiveWord, error) {
return o.sensitiveWord.GetSensitiveWord(ctx, id)
}
func (o *ChatDatabase) SearchSensitiveWords(ctx context.Context, keyword string, action int32, status int32, pagination pagination.Pagination) (int64, []*chatdb.SensitiveWord, error) {
return o.sensitiveWord.SearchSensitiveWords(ctx, keyword, action, status, pagination)
}
func (o *ChatDatabase) BatchAddSensitiveWords(ctx context.Context, words []*chatdb.SensitiveWord) error {
return o.sensitiveWord.BatchCreateSensitiveWords(ctx, words)
}
func (o *ChatDatabase) BatchUpdateSensitiveWords(ctx context.Context, updates map[string]map[string]any) error {
return o.sensitiveWord.BatchUpdateSensitiveWords(ctx, updates)
}
func (o *ChatDatabase) BatchDeleteSensitiveWords(ctx context.Context, ids []string) error {
return o.sensitiveWord.BatchDeleteSensitiveWords(ctx, ids)
}
// ==================== 敏感词分组管理实现 ====================
func (o *ChatDatabase) CreateSensitiveWordGroup(ctx context.Context, group *chatdb.SensitiveWordGroup) error {
return o.sensitiveWord.CreateSensitiveWordGroup(ctx, group)
}
func (o *ChatDatabase) UpdateSensitiveWordGroup(ctx context.Context, id string, data map[string]any) error {
return o.sensitiveWord.UpdateSensitiveWordGroup(ctx, id, data)
}
func (o *ChatDatabase) DeleteSensitiveWordGroup(ctx context.Context, ids []string) error {
return o.sensitiveWord.DeleteSensitiveWordGroup(ctx, ids)
}
func (o *ChatDatabase) GetSensitiveWordGroup(ctx context.Context, id string) (*chatdb.SensitiveWordGroup, error) {
return o.sensitiveWord.GetSensitiveWordGroup(ctx, id)
}
func (o *ChatDatabase) GetAllSensitiveWordGroups(ctx context.Context) ([]*chatdb.SensitiveWordGroup, error) {
return o.sensitiveWord.GetAllSensitiveWordGroups(ctx)
}
// ==================== 敏感词配置管理实现 ====================
func (o *ChatDatabase) UpdateSensitiveWordConfig(ctx context.Context, config *chatdb.SensitiveWordConfig) error {
return o.sensitiveWord.UpdateSensitiveWordConfig(ctx, config)
}
// ==================== 敏感词日志管理实现 ====================
func (o *ChatDatabase) GetSensitiveWordLogs(ctx context.Context, userID, groupID string, pagination pagination.Pagination) (int64, []*chatdb.SensitiveWordLog, error) {
return o.sensitiveWord.GetSensitiveWordLogs(ctx, userID, groupID, pagination)
}
func (o *ChatDatabase) DeleteSensitiveWordLogs(ctx context.Context, ids []string) error {
return o.sensitiveWord.DeleteSensitiveWordLogs(ctx, ids)
}
// ==================== 敏感词统计实现 ====================
func (o *ChatDatabase) GetSensitiveWordStats(ctx context.Context) (map[string]int64, error) {
return o.sensitiveWord.GetSensitiveWordStats(ctx)
}
func (o *ChatDatabase) GetSensitiveWordLogStats(ctx context.Context, startTime, endTime time.Time) (map[string]int64, error) {
return o.sensitiveWord.GetSensitiveWordLogStats(ctx, startTime, endTime)
}
// ==================== 收藏相关方法实现 ====================
func (o *ChatDatabase) CreateFavorite(ctx context.Context, favorite *chatdb.Favorite) error {
return o.favorite.Create(ctx, favorite)
}
func (o *ChatDatabase) GetFavorite(ctx context.Context, favoriteID string) (*chatdb.Favorite, error) {
return o.favorite.Take(ctx, favoriteID)
}
func (o *ChatDatabase) GetFavoritesByUserID(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.Favorite, error) {
return o.favorite.FindByUserID(ctx, userID, pagination)
}
func (o *ChatDatabase) GetFavoritesByUserIDAndType(ctx context.Context, userID string, favoriteType int32, pagination pagination.Pagination) (int64, []*chatdb.Favorite, error) {
return o.favorite.FindByUserIDAndType(ctx, userID, favoriteType, pagination)
}
func (o *ChatDatabase) SearchFavoritesByKeyword(ctx context.Context, userID string, keyword string, pagination pagination.Pagination) (int64, []*chatdb.Favorite, error) {
return o.favorite.SearchByKeyword(ctx, userID, keyword, pagination)
}
func (o *ChatDatabase) UpdateFavorite(ctx context.Context, favoriteID string, data map[string]any) error {
return o.favorite.Update(ctx, favoriteID, data)
}
func (o *ChatDatabase) DeleteFavorite(ctx context.Context, favoriteIDs []string) error {
return o.favorite.Delete(ctx, favoriteIDs)
}
func (o *ChatDatabase) DeleteFavoritesByUserID(ctx context.Context, userID string) error {
return o.favorite.DeleteByUserID(ctx, userID)
}
func (o *ChatDatabase) CountFavoritesByUserID(ctx context.Context, userID string) (int64, error) {
return o.favorite.CountByUserID(ctx, userID)
}
func (o *ChatDatabase) GetFavoritesByTags(ctx context.Context, userID string, tags []string, pagination pagination.Pagination) (int64, []*chatdb.Favorite, error) {
return o.favorite.FindByTags(ctx, userID, tags, pagination)
}
// ==================== 定时任务相关方法实现 ====================
func (o *ChatDatabase) CreateScheduledTask(ctx context.Context, task *chatdb.ScheduledTask) error {
return o.scheduledTask.Create(ctx, task)
}
func (o *ChatDatabase) GetScheduledTask(ctx context.Context, taskID string) (*chatdb.ScheduledTask, error) {
return o.scheduledTask.Take(ctx, taskID)
}
func (o *ChatDatabase) GetScheduledTasksByUserID(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.ScheduledTask, error) {
return o.scheduledTask.FindByUserID(ctx, userID, pagination)
}
func (o *ChatDatabase) GetAllScheduledTasks(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.ScheduledTask, error) {
return o.scheduledTask.FindAll(ctx, pagination)
}
func (o *ChatDatabase) UpdateScheduledTask(ctx context.Context, taskID string, data map[string]any) error {
return o.scheduledTask.Update(ctx, taskID, data)
}
func (o *ChatDatabase) DeleteScheduledTask(ctx context.Context, taskIDs []string) error {
return o.scheduledTask.Delete(ctx, taskIDs)
}
// ==================== 系统配置相关方法实现 ====================
func (o *ChatDatabase) CreateSystemConfig(ctx context.Context, config *chatdb.SystemConfig) error {
return o.systemConfig.Create(ctx, config)
}
func (o *ChatDatabase) GetSystemConfig(ctx context.Context, key string) (*chatdb.SystemConfig, error) {
return o.systemConfig.Take(ctx, key)
}
func (o *ChatDatabase) GetSystemConfigsByKeys(ctx context.Context, keys []string) ([]*chatdb.SystemConfig, error) {
return o.systemConfig.FindByKeys(ctx, keys)
}
func (o *ChatDatabase) GetAllSystemConfigs(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.SystemConfig, error) {
return o.systemConfig.FindAll(ctx, pagination)
}
func (o *ChatDatabase) UpdateSystemConfig(ctx context.Context, key string, data map[string]any) error {
return o.systemConfig.Update(ctx, key, data)
}
func (o *ChatDatabase) UpdateSystemConfigValue(ctx context.Context, key string, value string) error {
return o.systemConfig.UpdateValue(ctx, key, value)
}
func (o *ChatDatabase) UpdateSystemConfigEnabled(ctx context.Context, key string, enabled bool) error {
return o.systemConfig.UpdateEnabled(ctx, key, enabled)
}
func (o *ChatDatabase) DeleteSystemConfig(ctx context.Context, keys []string) error {
return o.systemConfig.Delete(ctx, keys)
}
func (o *ChatDatabase) GetEnabledSystemConfigs(ctx context.Context) ([]*chatdb.SystemConfig, error) {
return o.systemConfig.GetEnabledConfigs(ctx)
}
func (o *ChatDatabase) GetAppSystemConfigs(ctx context.Context) ([]*chatdb.SystemConfig, error) {
return o.systemConfig.GetAppConfigs(ctx)
}
func (o *ChatDatabase) GetWallet(ctx context.Context, userID string) (*chatdb.Wallet, error) {
return o.wallet.Take(ctx, userID)
}
func (o *ChatDatabase) GetWalletsByUserIDs(ctx context.Context, userIDs []string) ([]*chatdb.Wallet, error) {
return o.wallet.Find(ctx, userIDs)
}
func (o *ChatDatabase) GetWalletsPage(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.Wallet, error) {
return o.wallet.Page(ctx, pagination)
}
func (o *ChatDatabase) GetWalletsPageByRealNameAuthAuditStatus(ctx context.Context, auditStatus int32, userID string, pagination pagination.Pagination) (int64, []*chatdb.Wallet, error) {
return o.wallet.PageByRealNameAuthAuditStatus(ctx, auditStatus, userID, pagination)
}
func (o *ChatDatabase) UpdateWalletBalance(ctx context.Context, userID string, balance int64) error {
return o.wallet.UpdateBalance(ctx, userID, balance)
}
func (o *ChatDatabase) IncrementWalletBalance(ctx context.Context, userID string, amount int64) (beforeBalance int64, afterBalance int64, err error) {
return o.wallet.IncrementBalance(ctx, userID, amount)
}
func (o *ChatDatabase) UpdateWalletPaymentPassword(ctx context.Context, userID string, paymentPassword string) error {
return o.wallet.UpdatePaymentPassword(ctx, userID, paymentPassword)
}
func (o *ChatDatabase) UpdateWalletWithdrawAccount(ctx context.Context, userID string, withdrawAccount string) error {
return o.wallet.UpdateWithdrawAccount(ctx, userID, withdrawAccount)
}
func (o *ChatDatabase) UpdateWalletWithdrawAccountWithType(ctx context.Context, userID string, withdrawAccount string, accountType int32) error {
return o.wallet.UpdateWithdrawAccountWithType(ctx, userID, withdrawAccount, accountType)
}
func (o *ChatDatabase) UpdateWalletRealNameAuth(ctx context.Context, userID string, realNameAuth chatdb.RealNameAuth) error {
return o.wallet.UpdateRealNameAuth(ctx, userID, realNameAuth)
}
func (o *ChatDatabase) CreateWallet(ctx context.Context, wallet *chatdb.Wallet) error {
return o.wallet.Create(ctx, wallet)
}
func (o *ChatDatabase) GetWalletBalanceRecords(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.WalletBalanceRecord, error) {
return o.walletBalanceRecord.FindByUserID(ctx, userID, pagination)
}
func (o *ChatDatabase) GetWalletBalanceRecordsByUserIDAndType(ctx context.Context, userID string, recordType int32, pagination pagination.Pagination) (int64, []*chatdb.WalletBalanceRecord, error) {
return o.walletBalanceRecord.FindByUserIDAndType(ctx, userID, recordType, pagination)
}
func (o *ChatDatabase) CreateWalletBalanceRecord(ctx context.Context, record *chatdb.WalletBalanceRecord) error {
return o.walletBalanceRecord.Create(ctx, record)
}
// ==================== 提现相关方法 ====================
func (o *ChatDatabase) CreateWithdraw(ctx context.Context, withdraw *chatdb.Withdraw) error {
return o.withdraw.Create(ctx, withdraw)
}
func (o *ChatDatabase) GetWithdraw(ctx context.Context, withdrawID string) (*chatdb.Withdraw, error) {
return o.withdraw.Take(ctx, withdrawID)
}
func (o *ChatDatabase) GetWithdrawsByUserID(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.Withdraw, error) {
return o.withdraw.FindByUserID(ctx, userID, pagination)
}
func (o *ChatDatabase) GetWithdrawsByStatus(ctx context.Context, status int32, pagination pagination.Pagination) (int64, []*chatdb.Withdraw, error) {
return o.withdraw.FindByStatus(ctx, status, pagination)
}
func (o *ChatDatabase) UpdateWithdrawStatus(ctx context.Context, withdrawID string, status int32, auditorID string, auditRemark string) error {
return o.withdraw.UpdateStatus(ctx, withdrawID, status, auditorID, auditRemark)
}
func (o *ChatDatabase) GetWithdrawsPage(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.Withdraw, error) {
return o.withdraw.Page(ctx, pagination)
}
// ==================== 提现申请相关方法 ====================
func (o *ChatDatabase) CreateWithdrawApplication(ctx context.Context, application *chatdb.WithdrawApplication) error {
return o.withdrawApplication.Create(ctx, application)
}
func (o *ChatDatabase) GetWithdrawApplication(ctx context.Context, applicationID string) (*chatdb.WithdrawApplication, error) {
return o.withdrawApplication.Take(ctx, applicationID)
}
func (o *ChatDatabase) GetWithdrawApplicationsByUserID(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*chatdb.WithdrawApplication, error) {
return o.withdrawApplication.FindByUserID(ctx, userID, pagination)
}
func (o *ChatDatabase) GetWithdrawApplicationsByStatus(ctx context.Context, status int32, pagination pagination.Pagination) (int64, []*chatdb.WithdrawApplication, error) {
return o.withdrawApplication.FindByStatus(ctx, status, pagination)
}
func (o *ChatDatabase) UpdateWithdrawApplicationStatus(ctx context.Context, applicationID string, status int32, auditorID string, auditRemark string) error {
return o.withdrawApplication.UpdateStatus(ctx, applicationID, status, auditorID, auditRemark)
}
func (o *ChatDatabase) GetWithdrawApplicationsPage(ctx context.Context, pagination pagination.Pagination) (int64, []*chatdb.WithdrawApplication, error) {
return o.withdrawApplication.Page(ctx, pagination)
}
func (o *ChatDatabase) UpdateWithdrawApplication(ctx context.Context, applicationID string, data map[string]any) error {
return o.withdrawApplication.Update(ctx, applicationID, data)
}