Files
chat-deploy/pkg/common/db/model/chat/attribute.go
kim.dev.6789 b7f8db7d08 复制项目
2026-01-14 22:35:45 +08:00

248 lines
8.1 KiB
Go
Raw 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 chat
import (
"context"
"time"
"github.com/openimsdk/tools/db/mongoutil"
"github.com/openimsdk/tools/db/pagination"
"github.com/openimsdk/tools/errs"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"git.imall.cloud/openim/chat/pkg/common/db/table/chat"
)
func NewAttribute(db *mongo.Database) (chat.AttributeInterface, error) {
coll := db.Collection("attribute")
_, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{
{
Keys: bson.D{
{Key: "user_id", Value: 1},
},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{
{Key: "account", Value: 1},
},
},
{
Keys: bson.D{
{Key: "email", Value: 1},
},
},
{
Keys: bson.D{
{Key: "area_code", Value: 1},
{Key: "phone_number", Value: 1},
},
},
})
if err != nil {
return nil, errs.Wrap(err)
}
return &Attribute{coll: coll}, nil
}
type Attribute struct {
coll *mongo.Collection
}
func (o *Attribute) Create(ctx context.Context, attribute ...*chat.Attribute) error {
return mongoutil.InsertMany(ctx, o.coll, attribute)
}
func (o *Attribute) Update(ctx context.Context, userID string, data map[string]any) error {
if len(data) == 0 {
return nil
}
return mongoutil.UpdateOne(ctx, o.coll, bson.M{"user_id": userID}, bson.M{"$set": data}, false)
}
func (o *Attribute) Find(ctx context.Context, userIds []string) ([]*chat.Attribute, error) {
return mongoutil.Find[*chat.Attribute](ctx, o.coll, bson.M{"user_id": bson.M{"$in": userIds}})
}
func (o *Attribute) FindAccount(ctx context.Context, accounts []string) ([]*chat.Attribute, error) {
return mongoutil.Find[*chat.Attribute](ctx, o.coll, bson.M{"account": bson.M{"$in": accounts}})
}
func (o *Attribute) FindPhone(ctx context.Context, phoneNumbers []string) ([]*chat.Attribute, error) {
return mongoutil.Find[*chat.Attribute](ctx, o.coll, bson.M{"phone_number": bson.M{"$in": phoneNumbers}})
}
func (o *Attribute) Search(ctx context.Context, keyword string, genders []int32, pagination pagination.Pagination) (int64, []*chat.Attribute, error) {
filter := bson.M{}
if len(genders) > 0 {
filter["gender"] = bson.M{
"$in": genders,
}
}
if keyword != "" {
filter["$or"] = []bson.M{
{"user_id": bson.M{"$regex": keyword, "$options": "i"}},
{"account": bson.M{"$regex": keyword, "$options": "i"}},
{"nickname": bson.M{"$regex": keyword, "$options": "i"}},
{"phone_number": bson.M{"$regex": keyword, "$options": "i"}},
}
}
return mongoutil.FindPage[*chat.Attribute](ctx, o.coll, filter, pagination)
}
func (o *Attribute) TakePhone(ctx context.Context, areaCode string, phoneNumber string) (*chat.Attribute, error) {
return mongoutil.FindOne[*chat.Attribute](ctx, o.coll, bson.M{"area_code": areaCode, "phone_number": phoneNumber})
}
func (o *Attribute) TakeEmail(ctx context.Context, email string) (*chat.Attribute, error) {
return mongoutil.FindOne[*chat.Attribute](ctx, o.coll, bson.M{"email": email})
}
func (o *Attribute) TakeAccount(ctx context.Context, account string) (*chat.Attribute, error) {
return mongoutil.FindOne[*chat.Attribute](ctx, o.coll, bson.M{"account": account})
}
func (o *Attribute) Take(ctx context.Context, userID string) (*chat.Attribute, error) {
return mongoutil.FindOne[*chat.Attribute](ctx, o.coll, bson.M{"user_id": userID})
}
func (o *Attribute) SearchNormalUser(ctx context.Context, keyword string, forbiddenIDs []string, gender int32, startTime, endTime *time.Time, pagination pagination.Pagination) (int64, []*chat.Attribute, error) {
filter := bson.M{}
if gender == 0 {
filter["gender"] = bson.M{
"$in": []int32{0, 1, 2},
}
} else {
filter["gender"] = gender
}
if len(forbiddenIDs) > 0 {
filter["user_id"] = bson.M{
"$nin": forbiddenIDs,
}
}
if keyword != "" {
filter["$or"] = []bson.M{
{"user_id": bson.M{"$regex": keyword, "$options": "i"}},
{"account": bson.M{"$regex": keyword, "$options": "i"}},
{"nickname": bson.M{"$regex": keyword, "$options": "i"}},
{"phone_number": bson.M{"$regex": keyword, "$options": "i"}},
{"email": bson.M{"$regex": keyword, "$options": "i"}},
}
}
// 注册时间范围查询
if startTime != nil || endTime != nil {
timeFilter := bson.M{}
if startTime != nil {
timeFilter["$gte"] = *startTime
}
if endTime != nil {
// 使用 $lt小于而不是 $lte确保不包含结束时间当天的数据
// 例如endTime="2025-11-02 00:00:00" 应该查询到 2025-11-01 23:59:59不包含 11月2日的数据
timeFilter["$lt"] = *endTime
}
if len(timeFilter) > 0 {
filter["create_time"] = timeFilter
}
}
return mongoutil.FindPage[*chat.Attribute](ctx, o.coll, filter, pagination, options.Find().SetSort(bson.D{{Key: "create_time", Value: -1}}))
}
// SearchNormalUserWithUserIDs 按条件搜索用户支持额外的userIDs过滤
func (o *Attribute) SearchNormalUserWithUserIDs(ctx context.Context, keyword string, forbiddenIDs []string, gender int32, startTime, endTime *time.Time, userIDs []string, pagination pagination.Pagination) (int64, []*chat.Attribute, error) {
filter := bson.M{}
if gender == 0 {
filter["gender"] = bson.M{
"$in": []int32{0, 1, 2},
}
} else {
filter["gender"] = gender
}
// 构建user_id过滤条件需要同时满足在userIDs中且不在forbiddenIDs中
userIDConditions := []bson.M{}
if len(userIDs) > 0 {
userIDConditions = append(userIDConditions, bson.M{"user_id": bson.M{"$in": userIDs}})
}
if len(forbiddenIDs) > 0 {
userIDConditions = append(userIDConditions, bson.M{"user_id": bson.M{"$nin": forbiddenIDs}})
}
if len(userIDConditions) > 0 {
if len(userIDConditions) == 1 {
filter["user_id"] = userIDConditions[0]["user_id"]
} else {
// 需要同时满足多个条件,使用 $and
filter["$and"] = userIDConditions
}
}
if keyword != "" {
filter["$or"] = []bson.M{
{"user_id": bson.M{"$regex": keyword, "$options": "i"}},
{"account": bson.M{"$regex": keyword, "$options": "i"}},
{"nickname": bson.M{"$regex": keyword, "$options": "i"}},
{"phone_number": bson.M{"$regex": keyword, "$options": "i"}},
{"email": bson.M{"$regex": keyword, "$options": "i"}},
}
}
// 注册时间范围查询
if startTime != nil || endTime != nil {
timeFilter := bson.M{}
if startTime != nil {
timeFilter["$gte"] = *startTime
}
if endTime != nil {
timeFilter["$lt"] = *endTime
}
if len(timeFilter) > 0 {
filter["create_time"] = timeFilter
}
}
return mongoutil.FindPage[*chat.Attribute](ctx, o.coll, filter, pagination, options.Find().SetSort(bson.D{{Key: "create_time", Value: -1}}))
}
func (o *Attribute) SearchUser(ctx context.Context, keyword string, userIDs []string, genders []int32, pagination pagination.Pagination) (int64, []*chat.Attribute, error) {
filter := bson.M{}
if len(genders) > 0 {
filter["gender"] = bson.M{
"$in": genders,
}
}
if len(userIDs) > 0 {
filter["user_id"] = bson.M{
"$in": userIDs,
}
}
if keyword != "" {
filter["$or"] = []bson.M{
{"user_id": bson.M{"$regex": keyword, "$options": "i"}},
{"account": bson.M{"$regex": keyword, "$options": "i"}},
{"nickname": bson.M{"$regex": keyword, "$options": "i"}},
{"phone_number": bson.M{"$regex": keyword, "$options": "i"}},
{"email": bson.M{"$regex": keyword, "$options": "i"}},
}
}
return mongoutil.FindPage[*chat.Attribute](ctx, o.coll, filter, pagination)
}
func (o *Attribute) Delete(ctx context.Context, userIDs []string) error {
if len(userIDs) == 0 {
return nil
}
return mongoutil.DeleteMany(ctx, o.coll, bson.M{"user_id": bson.M{"$in": userIDs}})
}