package dao import ( "context" "customer-server/model/dto" "customer-server/model/entity" "gitea.com/red-future/common/beans" "gitea.com/red-future/common/db/mongo" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" "go.mongodb.org/mongo-driver/v2/bson" ) var Product = new(product) type product struct{} // Insert 插入产品 // 注意:mongo.DB().Insert不会自动将生成的ID回写到原始对象 // 必须手动从返回的InsertedIDs中提取并赋值给data.Id,否则后续访问data.Id会触发空指针异常 func (d *product) Insert(ctx context.Context, data *entity.Product) (id bson.ObjectID, err error) { ids, err := mongo.DB().Insert(ctx, []interface{}{data}, entity.ProductCollection) if err != nil { return } // 从返回的ID列表中提取ObjectID并回写到data.Id if len(ids) > 0 { if oid, ok := ids[0].(bson.ObjectID); ok { id = oid data.Id = &oid // 回写ID到原始对象,防止后续访问时空指针异常 } } return } // Update 更新产品 func (d *product) Update(ctx context.Context, req *dto.UpdateProductReq) (err error) { objectId, err := bson.ObjectIDFromHex(req.Id) if err != nil { return } filter := bson.M{"_id": objectId, "isDeleted": false} updateFields := bson.M{} if !g.IsEmpty(req.Name) { updateFields["name"] = req.Name } if !g.IsEmpty(req.Description) { updateFields["description"] = req.Description } // 自动更新时间为当前时间 updateFields["updatedAt"] = gtime.Now().Time if len(updateFields) > 0 { _, err = mongo.DB().Update(ctx, filter, bson.M{"$set": updateFields}, entity.ProductCollection) } return } // Delete 软删除产品(设置 IsDeleted=true) func (d *product) Delete(ctx context.Context, req *dto.DeleteProductReq) (err error) { objectId, err := bson.ObjectIDFromHex(req.Id) if err != nil { return } filter := bson.M{"_id": objectId, "isDeleted": false} update := bson.M{"$set": bson.M{"isDeleted": true, "updatedAt": gtime.Now().Time}} _, err = mongo.DB().Update(ctx, filter, update, entity.ProductCollection) if err != nil { return gerror.Wrap(err, "删除产品失败") } return } // buildListFilter 构建列表查询的过滤条件 func (d *product) buildListFilter(req *dto.ListProductReq) bson.M { filter := bson.M{"isDeleted": false} if !g.IsEmpty(req.Name) { filter["name"] = bson.M{"$regex": req.Name} } return filter } // checkTotalCount 检查总数 func (d *product) checkTotalCount(ctx context.Context, filter bson.M) (total int64, err error) { total, err = mongo.DB().Count(ctx, filter, entity.ProductCollection) return } // FindByName 根据名称查询产品(用于去重检查) func (d *product) FindByName(ctx context.Context, name string) (product *entity.Product, err error) { filter := bson.M{ "name": name, "isDeleted": false, } err = mongo.DB().FindOne(ctx, filter, &product, entity.ProductCollection) if err != nil { if err.Error() == "mongo: no documents in result" { return nil, nil } return nil, err } return } // List 获取产品列表(排除已删除) func (d *product) List(ctx context.Context, req *dto.ListProductReq) (list []*entity.Product, total int64, err error) { // 构建查询过滤条件 filter := d.buildListFilter(req) // 检查总数 total, err = d.checkTotalCount(ctx, filter) if err != nil { return } // 分页参数处理 pageNum := req.PageNum if pageNum <= 0 { pageNum = 1 } pageSize := req.PageSize if pageSize <= 0 { pageSize = 20 } // 使用统一的mongo.DB().Find方法(支持分页和排序) page := &beans.Page{ PageNum: int64(pageNum), PageSize: int64(pageSize), } orderBy := []beans.OrderBy{ {Field: "createdAt", Order: beans.Desc}, // 按创建时间倒序 } _, err = mongo.DB().Find(ctx, filter, &list, entity.ProductCollection, page, orderBy) return } // GetById 根据ID获取产品 func (d *product) GetById(ctx context.Context, id string) (product *entity.Product, err error) { objectId, err := bson.ObjectIDFromHex(id) if err != nil { return } filter := bson.M{"_id": objectId, "isDeleted": false} err = mongo.DB().FindOne(ctx, filter, &product, entity.ProductCollection) return } // FindAllForExport 查询所有产品用于导出(不分页) func (d *product) FindAllForExport(ctx context.Context, name string) (list []*entity.Product, err error) { filter := bson.M{} if !g.IsEmpty(name) { filter["name"] = bson.M{"$regex": name, "$options": "i"} // 模糊查询,忽略大小写 } // 使用 mongo.DB().Find(会自动过滤租户和已删除数据) // 导出场景:不分页,设置足够大的PageSize page := &beans.Page{ PageNum: 1, PageSize: 100000, // 导出场景:设置足够大的PageSize } orderBy := []beans.OrderBy{ {Field: "createdAt", Order: beans.Desc}, // 按创建时间倒序 } _, err = mongo.DB().Find(ctx, filter, &list, entity.ProductCollection, page, orderBy) return } // UpdateEntity 更新产品实体(用于绑定/解绑/同步等场景) func (d *product) UpdateEntity(ctx context.Context, product *entity.Product) (err error) { filter := bson.M{"_id": product.Id, "isDeleted": false} // 将实体转换为bson.M updateDoc := bson.M{} data, _ := bson.Marshal(product) bson.Unmarshal(data, &updateDoc) _, err = mongo.DB().Update(ctx, filter, bson.M{"$set": updateDoc}, entity.ProductCollection) return }