feat: create kyc

This commit is contained in:
王性驊 2025-03-31 21:24:40 +08:00
parent eafd691dab
commit bf8d532c6e
15 changed files with 2210 additions and 345 deletions

View File

@ -35,5 +35,8 @@ build-docker:
.PHONY: mock-gen
mock-gen: # 建立 mock 資料
#mockgen -source=./pkg/domain/repository/token.go -destination=./pkg/mock/repository/token.go -package=mock
mockgen -source=./pkg/domain/repository/product.go -destination=./pkg/mock/repository/product.go -package=mock
mockgen -source=./pkg/domain/repository/product_item.go -destination=./pkg/mock/repository/product_item.go -package=mock
mockgen -source=./pkg/domain/repository/product_statistics.go -destination=./pkg/mock/repository/product_statistics.go -package=mock
mockgen -source=./pkg/domain/repository/tags.go -destination=./pkg/mock/repository/tags.go -package=mock
@echo "Generate mock files successfully"

31
pkg/domain/entity/kyc.go Normal file
View File

@ -0,0 +1,31 @@
package entity
import "go.mongodb.org/mongo-driver/bson/primitive"
type KYC struct {
ID primitive.ObjectID `bson:"_id,omitempty"`
UID string `bson:"uid"` // 驗證人 UID
CountryRegion string `bson:"country_region"` // 地區(例如 "TW", "JP", "US"...
Name string `bson:"name"` // 真實姓名
Identification string `bson:"identification"` // 身分證字號 or 護照號碼
IdentificationType string `bson:"identification_type"` // ID 類型ID_CARD, PASSPORT, RESIDENT_CERT
Address string `bson:"address"` // 戶籍地址(或居住地址)
PostalCode string `bson:"postal_code"` // 郵遞區號(海外使用)
// 上傳文件網址(可為 object storage 的 URL
IDFrontImage string `bson:"id_front_image"` // 身分證/護照 正面
IDBackImage string `bson:"id_back_image"` // 身分證/居留證 反面
BankStatementImg string `bson:"bank_statement_img"` // 銀行存摺封面照
BankCode string `bson:"bank_code"` // 銀行代碼(可為 SWIFT
BankName string `bson:"bank_name"` // 銀行名稱(顯示用)
BranchCode string `bson:"branch_code"` // 分行代碼
BranchName string `bson:"branch_name"` // 分行名稱(顯示用)
BankAccount string `bson:"bank_account"` // 銀行帳號
Status string `bson:"status"` // 審核狀態PENDING, APPROVED, REJECTED
RejectReason string `bson:"reject_reason"` // 若被駁回,原因描述
UpdatedAt int64 `bson:"updated_at,omitempty"`
CreatedAt int64 `bson:"created_at,omitempty"`
}
func (p *KYC) CollectionName() string {
return "kyc"
}

View File

@ -0,0 +1,50 @@
package repository
import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"context"
)
// KYCKnow Your Customer
type KYCRepository interface {
// Create 建立 KYC 資料
Create(ctx context.Context, kyc *entity.KYC) error
// FindLatestByUID 根據使用者 UID 取得最新 KYC 紀錄
FindLatestByUID(ctx context.Context, uid string) (*entity.KYC, error)
// FindByID 根據 KYC ID 查詢
FindByID(ctx context.Context, id string) (*entity.KYC, error)
// List 分頁查詢(後台審核列表用)
List(ctx context.Context, params KYCQueryParams) ([]*entity.KYC, int64, error)
// UpdateStatus 更新 KYC 狀態與審核原因(審核用)
UpdateStatus(ctx context.Context, id string, status string, reason string) error
// UpdateKYCInfo 更新使用者的 KYC限於尚未審核的
UpdateKYCInfo(ctx context.Context, id string, update *KYCUpdateParams) error
}
type KYCQueryParams struct {
UID *string
Country *string
Status *string // PENDING, APPROVED, REJECTED
PageSize int64
PageIndex int64
SortByDate bool // 是否依申請時間倒序
}
type KYCUpdateParams struct {
Name *string
Identification *string
IdentificationType *string
Address *string
PostalCode *string
DateOfBirth *string
Gender *string
IDFrontImage *string
IDBackImage *string
BankStatementImg *string
BankCode *string
BankName *string
BranchCode *string
BranchName *string
BankAccount *string
}

View File

@ -0,0 +1 @@
package usecase

View File

@ -0,0 +1 @@
package usecase

View File

@ -0,0 +1 @@
package usecase

View File

@ -0,0 +1,207 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ./pkg/domain/repository/product.go
//
// Generated by this command:
//
// mockgen -source=./pkg/domain/repository/product.go -destination=./pkg/mock/repository/product.go -package=mock
//
// Package mock is a generated GoMock package.
package mock
import (
context "context"
reflect "reflect"
entity "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
repository "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
mongo "go.mongodb.org/mongo-driver/mongo"
options "go.mongodb.org/mongo-driver/mongo/options"
gomock "go.uber.org/mock/gomock"
)
// MockProductRepository is a mock of ProductRepository interface.
type MockProductRepository struct {
ctrl *gomock.Controller
recorder *MockProductRepositoryMockRecorder
isgomock struct{}
}
// MockProductRepositoryMockRecorder is the mock recorder for MockProductRepository.
type MockProductRepositoryMockRecorder struct {
mock *MockProductRepository
}
// NewMockProductRepository creates a new mock instance.
func NewMockProductRepository(ctrl *gomock.Controller) *MockProductRepository {
mock := &MockProductRepository{ctrl: ctrl}
mock.recorder = &MockProductRepositoryMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockProductRepository) EXPECT() *MockProductRepositoryMockRecorder {
return m.recorder
}
// Delete mocks base method.
func (m *MockProductRepository) Delete(ctx context.Context, id string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delete", ctx, id)
ret0, _ := ret[0].(error)
return ret0
}
// Delete indicates an expected call of Delete.
func (mr *MockProductRepositoryMockRecorder) Delete(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockProductRepository)(nil).Delete), ctx, id)
}
// FindOneByID mocks base method.
func (m *MockProductRepository) FindOneByID(ctx context.Context, id string) (*entity.Product, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FindOneByID", ctx, id)
ret0, _ := ret[0].(*entity.Product)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FindOneByID indicates an expected call of FindOneByID.
func (mr *MockProductRepositoryMockRecorder) FindOneByID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneByID", reflect.TypeOf((*MockProductRepository)(nil).FindOneByID), ctx, id)
}
// FindOneBySlug mocks base method.
func (m *MockProductRepository) FindOneBySlug(ctx context.Context, slug string) (*entity.Product, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FindOneBySlug", ctx, slug)
ret0, _ := ret[0].(*entity.Product)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FindOneBySlug indicates an expected call of FindOneBySlug.
func (mr *MockProductRepositoryMockRecorder) FindOneBySlug(ctx, slug any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOneBySlug", reflect.TypeOf((*MockProductRepository)(nil).FindOneBySlug), ctx, slug)
}
// Index20250317001UP mocks base method.
func (m *MockProductRepository) Index20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Index20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Index20250317001UP indicates an expected call of Index20250317001UP.
func (mr *MockProductRepositoryMockRecorder) Index20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index20250317001UP", reflect.TypeOf((*MockProductRepository)(nil).Index20250317001UP), ctx)
}
// Insert mocks base method.
func (m *MockProductRepository) Insert(ctx context.Context, data *entity.Product) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Insert", ctx, data)
ret0, _ := ret[0].(error)
return ret0
}
// Insert indicates an expected call of Insert.
func (mr *MockProductRepositoryMockRecorder) Insert(ctx, data any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Insert", reflect.TypeOf((*MockProductRepository)(nil).Insert), ctx, data)
}
// ListProduct mocks base method.
func (m *MockProductRepository) ListProduct(ctx context.Context, params *repository.ProductQueryParams) ([]*entity.Product, int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListProduct", ctx, params)
ret0, _ := ret[0].([]*entity.Product)
ret1, _ := ret[1].(int64)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// ListProduct indicates an expected call of ListProduct.
func (mr *MockProductRepositoryMockRecorder) ListProduct(ctx, params any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListProduct", reflect.TypeOf((*MockProductRepository)(nil).ListProduct), ctx, params)
}
// Transaction mocks base method.
func (m *MockProductRepository) Transaction(ctx context.Context, fn func(mongo.SessionContext) (any, error), opts ...*options.TransactionOptions) error {
m.ctrl.T.Helper()
varargs := []any{ctx, fn}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Transaction", varargs...)
ret0, _ := ret[0].(error)
return ret0
}
// Transaction indicates an expected call of Transaction.
func (mr *MockProductRepositoryMockRecorder) Transaction(ctx, fn any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, fn}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Transaction", reflect.TypeOf((*MockProductRepository)(nil).Transaction), varargs...)
}
// Update mocks base method.
func (m *MockProductRepository) Update(ctx context.Context, productID string, data *repository.ProductUpdateParams) (*mongo.UpdateResult, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Update", ctx, productID, data)
ret0, _ := ret[0].(*mongo.UpdateResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Update indicates an expected call of Update.
func (mr *MockProductRepositoryMockRecorder) Update(ctx, productID, data any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockProductRepository)(nil).Update), ctx, productID, data)
}
// MockProductIndex is a mock of ProductIndex interface.
type MockProductIndex struct {
ctrl *gomock.Controller
recorder *MockProductIndexMockRecorder
isgomock struct{}
}
// MockProductIndexMockRecorder is the mock recorder for MockProductIndex.
type MockProductIndexMockRecorder struct {
mock *MockProductIndex
}
// NewMockProductIndex creates a new mock instance.
func NewMockProductIndex(ctrl *gomock.Controller) *MockProductIndex {
mock := &MockProductIndex{ctrl: ctrl}
mock.recorder = &MockProductIndexMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockProductIndex) EXPECT() *MockProductIndexMockRecorder {
return m.recorder
}
// Index20250317001UP mocks base method.
func (m *MockProductIndex) Index20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Index20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Index20250317001UP indicates an expected call of Index20250317001UP.
func (mr *MockProductIndexMockRecorder) Index20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index20250317001UP", reflect.TypeOf((*MockProductIndex)(nil).Index20250317001UP), ctx)
}

View File

@ -0,0 +1,435 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ./pkg/domain/repository/product_item.go
//
// Generated by this command:
//
// mockgen -source=./pkg/domain/repository/product_item.go -destination=./pkg/mock/repository/product_item.go -package=mock
//
// Package mock is a generated GoMock package.
package mock
import (
context "context"
reflect "reflect"
entity "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
product "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
repository "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
mongo "go.mongodb.org/mongo-driver/mongo"
gomock "go.uber.org/mock/gomock"
)
// MockProductItemRepository is a mock of ProductItemRepository interface.
type MockProductItemRepository struct {
ctrl *gomock.Controller
recorder *MockProductItemRepositoryMockRecorder
isgomock struct{}
}
// MockProductItemRepositoryMockRecorder is the mock recorder for MockProductItemRepository.
type MockProductItemRepositoryMockRecorder struct {
mock *MockProductItemRepository
}
// NewMockProductItemRepository creates a new mock instance.
func NewMockProductItemRepository(ctrl *gomock.Controller) *MockProductItemRepository {
mock := &MockProductItemRepository{ctrl: ctrl}
mock.recorder = &MockProductItemRepositoryMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockProductItemRepository) EXPECT() *MockProductItemRepositoryMockRecorder {
return m.recorder
}
// DecSalesCount mocks base method.
func (m *MockProductItemRepository) DecSalesCount(ctx context.Context, id string, count int64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DecSalesCount", ctx, id, count)
ret0, _ := ret[0].(error)
return ret0
}
// DecSalesCount indicates an expected call of DecSalesCount.
func (mr *MockProductItemRepositoryMockRecorder) DecSalesCount(ctx, id, count any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecSalesCount", reflect.TypeOf((*MockProductItemRepository)(nil).DecSalesCount), ctx, id, count)
}
// Delete mocks base method.
func (m *MockProductItemRepository) Delete(ctx context.Context, ids []string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delete", ctx, ids)
ret0, _ := ret[0].(error)
return ret0
}
// Delete indicates an expected call of Delete.
func (mr *MockProductItemRepositoryMockRecorder) Delete(ctx, ids any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockProductItemRepository)(nil).Delete), ctx, ids)
}
// DeleteByReferenceID mocks base method.
func (m *MockProductItemRepository) DeleteByReferenceID(ctx context.Context, id string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteByReferenceID", ctx, id)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteByReferenceID indicates an expected call of DeleteByReferenceID.
func (mr *MockProductItemRepositoryMockRecorder) DeleteByReferenceID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByReferenceID", reflect.TypeOf((*MockProductItemRepository)(nil).DeleteByReferenceID), ctx, id)
}
// FindByID mocks base method.
func (m *MockProductItemRepository) FindByID(ctx context.Context, id string) (*entity.ProductItems, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FindByID", ctx, id)
ret0, _ := ret[0].(*entity.ProductItems)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FindByID indicates an expected call of FindByID.
func (mr *MockProductItemRepositoryMockRecorder) FindByID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByID", reflect.TypeOf((*MockProductItemRepository)(nil).FindByID), ctx, id)
}
// GetSalesCount mocks base method.
func (m *MockProductItemRepository) GetSalesCount(ctx context.Context, ids []string) ([]repository.ProductItemSalesCount, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSalesCount", ctx, ids)
ret0, _ := ret[0].([]repository.ProductItemSalesCount)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSalesCount indicates an expected call of GetSalesCount.
func (mr *MockProductItemRepositoryMockRecorder) GetSalesCount(ctx, ids any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSalesCount", reflect.TypeOf((*MockProductItemRepository)(nil).GetSalesCount), ctx, ids)
}
// IncSalesCount mocks base method.
func (m *MockProductItemRepository) IncSalesCount(ctx context.Context, id string, count int64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IncSalesCount", ctx, id, count)
ret0, _ := ret[0].(error)
return ret0
}
// IncSalesCount indicates an expected call of IncSalesCount.
func (mr *MockProductItemRepositoryMockRecorder) IncSalesCount(ctx, id, count any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IncSalesCount", reflect.TypeOf((*MockProductItemRepository)(nil).IncSalesCount), ctx, id, count)
}
// Index20250317001UP mocks base method.
func (m *MockProductItemRepository) Index20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Index20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Index20250317001UP indicates an expected call of Index20250317001UP.
func (mr *MockProductItemRepositoryMockRecorder) Index20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index20250317001UP", reflect.TypeOf((*MockProductItemRepository)(nil).Index20250317001UP), ctx)
}
// Insert mocks base method.
func (m *MockProductItemRepository) Insert(ctx context.Context, item []entity.ProductItems) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Insert", ctx, item)
ret0, _ := ret[0].(error)
return ret0
}
// Insert indicates an expected call of Insert.
func (mr *MockProductItemRepositoryMockRecorder) Insert(ctx, item any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Insert", reflect.TypeOf((*MockProductItemRepository)(nil).Insert), ctx, item)
}
// ListProductItem mocks base method.
func (m *MockProductItemRepository) ListProductItem(ctx context.Context, param repository.ProductItemQueryParams) ([]entity.ProductItems, int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListProductItem", ctx, param)
ret0, _ := ret[0].([]entity.ProductItems)
ret1, _ := ret[1].(int64)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// ListProductItem indicates an expected call of ListProductItem.
func (mr *MockProductItemRepositoryMockRecorder) ListProductItem(ctx, param any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListProductItem", reflect.TypeOf((*MockProductItemRepository)(nil).ListProductItem), ctx, param)
}
// Update mocks base method.
func (m *MockProductItemRepository) Update(ctx context.Context, id string, param *repository.ProductUpdateItem) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Update", ctx, id, param)
ret0, _ := ret[0].(error)
return ret0
}
// Update indicates an expected call of Update.
func (mr *MockProductItemRepositoryMockRecorder) Update(ctx, id, param any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockProductItemRepository)(nil).Update), ctx, id, param)
}
// UpdateStatus mocks base method.
func (m *MockProductItemRepository) UpdateStatus(ctx context.Context, id string, status product.ItemStatus) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateStatus", ctx, id, status)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateStatus indicates an expected call of UpdateStatus.
func (mr *MockProductItemRepositoryMockRecorder) UpdateStatus(ctx, id, status any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStatus", reflect.TypeOf((*MockProductItemRepository)(nil).UpdateStatus), ctx, id, status)
}
// MockProductItemIndex is a mock of ProductItemIndex interface.
type MockProductItemIndex struct {
ctrl *gomock.Controller
recorder *MockProductItemIndexMockRecorder
isgomock struct{}
}
// MockProductItemIndexMockRecorder is the mock recorder for MockProductItemIndex.
type MockProductItemIndexMockRecorder struct {
mock *MockProductItemIndex
}
// NewMockProductItemIndex creates a new mock instance.
func NewMockProductItemIndex(ctrl *gomock.Controller) *MockProductItemIndex {
mock := &MockProductItemIndex{ctrl: ctrl}
mock.recorder = &MockProductItemIndexMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockProductItemIndex) EXPECT() *MockProductItemIndexMockRecorder {
return m.recorder
}
// Index20250317001UP mocks base method.
func (m *MockProductItemIndex) Index20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Index20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Index20250317001UP indicates an expected call of Index20250317001UP.
func (mr *MockProductItemIndexMockRecorder) Index20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index20250317001UP", reflect.TypeOf((*MockProductItemIndex)(nil).Index20250317001UP), ctx)
}
// MockProductItemBasic is a mock of ProductItemBasic interface.
type MockProductItemBasic struct {
ctrl *gomock.Controller
recorder *MockProductItemBasicMockRecorder
isgomock struct{}
}
// MockProductItemBasicMockRecorder is the mock recorder for MockProductItemBasic.
type MockProductItemBasicMockRecorder struct {
mock *MockProductItemBasic
}
// NewMockProductItemBasic creates a new mock instance.
func NewMockProductItemBasic(ctrl *gomock.Controller) *MockProductItemBasic {
mock := &MockProductItemBasic{ctrl: ctrl}
mock.recorder = &MockProductItemBasicMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockProductItemBasic) EXPECT() *MockProductItemBasicMockRecorder {
return m.recorder
}
// Delete mocks base method.
func (m *MockProductItemBasic) Delete(ctx context.Context, ids []string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delete", ctx, ids)
ret0, _ := ret[0].(error)
return ret0
}
// Delete indicates an expected call of Delete.
func (mr *MockProductItemBasicMockRecorder) Delete(ctx, ids any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockProductItemBasic)(nil).Delete), ctx, ids)
}
// DeleteByReferenceID mocks base method.
func (m *MockProductItemBasic) DeleteByReferenceID(ctx context.Context, id string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteByReferenceID", ctx, id)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteByReferenceID indicates an expected call of DeleteByReferenceID.
func (mr *MockProductItemBasicMockRecorder) DeleteByReferenceID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByReferenceID", reflect.TypeOf((*MockProductItemBasic)(nil).DeleteByReferenceID), ctx, id)
}
// FindByID mocks base method.
func (m *MockProductItemBasic) FindByID(ctx context.Context, id string) (*entity.ProductItems, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FindByID", ctx, id)
ret0, _ := ret[0].(*entity.ProductItems)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FindByID indicates an expected call of FindByID.
func (mr *MockProductItemBasicMockRecorder) FindByID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindByID", reflect.TypeOf((*MockProductItemBasic)(nil).FindByID), ctx, id)
}
// Insert mocks base method.
func (m *MockProductItemBasic) Insert(ctx context.Context, item []entity.ProductItems) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Insert", ctx, item)
ret0, _ := ret[0].(error)
return ret0
}
// Insert indicates an expected call of Insert.
func (mr *MockProductItemBasicMockRecorder) Insert(ctx, item any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Insert", reflect.TypeOf((*MockProductItemBasic)(nil).Insert), ctx, item)
}
// ListProductItem mocks base method.
func (m *MockProductItemBasic) ListProductItem(ctx context.Context, param repository.ProductItemQueryParams) ([]entity.ProductItems, int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListProductItem", ctx, param)
ret0, _ := ret[0].([]entity.ProductItems)
ret1, _ := ret[1].(int64)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// ListProductItem indicates an expected call of ListProductItem.
func (mr *MockProductItemBasicMockRecorder) ListProductItem(ctx, param any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListProductItem", reflect.TypeOf((*MockProductItemBasic)(nil).ListProductItem), ctx, param)
}
// Update mocks base method.
func (m *MockProductItemBasic) Update(ctx context.Context, id string, param *repository.ProductUpdateItem) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Update", ctx, id, param)
ret0, _ := ret[0].(error)
return ret0
}
// Update indicates an expected call of Update.
func (mr *MockProductItemBasicMockRecorder) Update(ctx, id, param any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockProductItemBasic)(nil).Update), ctx, id, param)
}
// UpdateStatus mocks base method.
func (m *MockProductItemBasic) UpdateStatus(ctx context.Context, id string, status product.ItemStatus) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateStatus", ctx, id, status)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateStatus indicates an expected call of UpdateStatus.
func (mr *MockProductItemBasicMockRecorder) UpdateStatus(ctx, id, status any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStatus", reflect.TypeOf((*MockProductItemBasic)(nil).UpdateStatus), ctx, id, status)
}
// MockProductItemStatistics is a mock of ProductItemStatistics interface.
type MockProductItemStatistics struct {
ctrl *gomock.Controller
recorder *MockProductItemStatisticsMockRecorder
isgomock struct{}
}
// MockProductItemStatisticsMockRecorder is the mock recorder for MockProductItemStatistics.
type MockProductItemStatisticsMockRecorder struct {
mock *MockProductItemStatistics
}
// NewMockProductItemStatistics creates a new mock instance.
func NewMockProductItemStatistics(ctrl *gomock.Controller) *MockProductItemStatistics {
mock := &MockProductItemStatistics{ctrl: ctrl}
mock.recorder = &MockProductItemStatisticsMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockProductItemStatistics) EXPECT() *MockProductItemStatisticsMockRecorder {
return m.recorder
}
// DecSalesCount mocks base method.
func (m *MockProductItemStatistics) DecSalesCount(ctx context.Context, id string, count int64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DecSalesCount", ctx, id, count)
ret0, _ := ret[0].(error)
return ret0
}
// DecSalesCount indicates an expected call of DecSalesCount.
func (mr *MockProductItemStatisticsMockRecorder) DecSalesCount(ctx, id, count any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecSalesCount", reflect.TypeOf((*MockProductItemStatistics)(nil).DecSalesCount), ctx, id, count)
}
// GetSalesCount mocks base method.
func (m *MockProductItemStatistics) GetSalesCount(ctx context.Context, ids []string) ([]repository.ProductItemSalesCount, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSalesCount", ctx, ids)
ret0, _ := ret[0].([]repository.ProductItemSalesCount)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSalesCount indicates an expected call of GetSalesCount.
func (mr *MockProductItemStatisticsMockRecorder) GetSalesCount(ctx, ids any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSalesCount", reflect.TypeOf((*MockProductItemStatistics)(nil).GetSalesCount), ctx, ids)
}
// IncSalesCount mocks base method.
func (m *MockProductItemStatistics) IncSalesCount(ctx context.Context, id string, count int64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IncSalesCount", ctx, id, count)
ret0, _ := ret[0].(error)
return ret0
}
// IncSalesCount indicates an expected call of IncSalesCount.
func (mr *MockProductItemStatisticsMockRecorder) IncSalesCount(ctx, id, count any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IncSalesCount", reflect.TypeOf((*MockProductItemStatistics)(nil).IncSalesCount), ctx, id, count)
}

View File

@ -0,0 +1,225 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ./pkg/domain/repository/product_statistics.go
//
// Generated by this command:
//
// mockgen -source=./pkg/domain/repository/product_statistics.go -destination=./pkg/mock/repository/product_statistics.go -package=mock
//
// Package mock is a generated GoMock package.
package mock
import (
context "context"
reflect "reflect"
entity "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
mongo "go.mongodb.org/mongo-driver/mongo"
gomock "go.uber.org/mock/gomock"
)
// MockProductStatisticsRepo is a mock of ProductStatisticsRepo interface.
type MockProductStatisticsRepo struct {
ctrl *gomock.Controller
recorder *MockProductStatisticsRepoMockRecorder
isgomock struct{}
}
// MockProductStatisticsRepoMockRecorder is the mock recorder for MockProductStatisticsRepo.
type MockProductStatisticsRepoMockRecorder struct {
mock *MockProductStatisticsRepo
}
// NewMockProductStatisticsRepo creates a new mock instance.
func NewMockProductStatisticsRepo(ctrl *gomock.Controller) *MockProductStatisticsRepo {
mock := &MockProductStatisticsRepo{ctrl: ctrl}
mock.recorder = &MockProductStatisticsRepoMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockProductStatisticsRepo) EXPECT() *MockProductStatisticsRepoMockRecorder {
return m.recorder
}
// Create mocks base method.
func (m *MockProductStatisticsRepo) Create(ctx context.Context, stats *entity.ProductStatistics) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Create", ctx, stats)
ret0, _ := ret[0].(error)
return ret0
}
// Create indicates an expected call of Create.
func (mr *MockProductStatisticsRepoMockRecorder) Create(ctx, stats any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockProductStatisticsRepo)(nil).Create), ctx, stats)
}
// DecFansCount mocks base method.
func (m *MockProductStatisticsRepo) DecFansCount(ctx context.Context, productID string, fansCount uint64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DecFansCount", ctx, productID, fansCount)
ret0, _ := ret[0].(error)
return ret0
}
// DecFansCount indicates an expected call of DecFansCount.
func (mr *MockProductStatisticsRepoMockRecorder) DecFansCount(ctx, productID, fansCount any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecFansCount", reflect.TypeOf((*MockProductStatisticsRepo)(nil).DecFansCount), ctx, productID, fansCount)
}
// DecOrders mocks base method.
func (m *MockProductStatisticsRepo) DecOrders(ctx context.Context, productID string, count int64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DecOrders", ctx, productID, count)
ret0, _ := ret[0].(error)
return ret0
}
// DecOrders indicates an expected call of DecOrders.
func (mr *MockProductStatisticsRepoMockRecorder) DecOrders(ctx, productID, count any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecOrders", reflect.TypeOf((*MockProductStatisticsRepo)(nil).DecOrders), ctx, productID, count)
}
// Delete mocks base method.
func (m *MockProductStatisticsRepo) Delete(ctx context.Context, id string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delete", ctx, id)
ret0, _ := ret[0].(error)
return ret0
}
// Delete indicates an expected call of Delete.
func (mr *MockProductStatisticsRepoMockRecorder) Delete(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockProductStatisticsRepo)(nil).Delete), ctx, id)
}
// GetByID mocks base method.
func (m *MockProductStatisticsRepo) GetByID(ctx context.Context, id string) (*entity.ProductStatistics, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetByID", ctx, id)
ret0, _ := ret[0].(*entity.ProductStatistics)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetByID indicates an expected call of GetByID.
func (mr *MockProductStatisticsRepoMockRecorder) GetByID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockProductStatisticsRepo)(nil).GetByID), ctx, id)
}
// GetByProductID mocks base method.
func (m *MockProductStatisticsRepo) GetByProductID(ctx context.Context, productID string) (*entity.ProductStatistics, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetByProductID", ctx, productID)
ret0, _ := ret[0].(*entity.ProductStatistics)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetByProductID indicates an expected call of GetByProductID.
func (mr *MockProductStatisticsRepoMockRecorder) GetByProductID(ctx, productID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByProductID", reflect.TypeOf((*MockProductStatisticsRepo)(nil).GetByProductID), ctx, productID)
}
// IncFansCount mocks base method.
func (m *MockProductStatisticsRepo) IncFansCount(ctx context.Context, productID string, fansCount uint64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IncFansCount", ctx, productID, fansCount)
ret0, _ := ret[0].(error)
return ret0
}
// IncFansCount indicates an expected call of IncFansCount.
func (mr *MockProductStatisticsRepoMockRecorder) IncFansCount(ctx, productID, fansCount any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IncFansCount", reflect.TypeOf((*MockProductStatisticsRepo)(nil).IncFansCount), ctx, productID, fansCount)
}
// IncOrders mocks base method.
func (m *MockProductStatisticsRepo) IncOrders(ctx context.Context, productID string, count int64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IncOrders", ctx, productID, count)
ret0, _ := ret[0].(error)
return ret0
}
// IncOrders indicates an expected call of IncOrders.
func (mr *MockProductStatisticsRepoMockRecorder) IncOrders(ctx, productID, count any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IncOrders", reflect.TypeOf((*MockProductStatisticsRepo)(nil).IncOrders), ctx, productID, count)
}
// Index20250317001UP mocks base method.
func (m *MockProductStatisticsRepo) Index20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Index20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Index20250317001UP indicates an expected call of Index20250317001UP.
func (mr *MockProductStatisticsRepoMockRecorder) Index20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index20250317001UP", reflect.TypeOf((*MockProductStatisticsRepo)(nil).Index20250317001UP), ctx)
}
// UpdateAverageRating mocks base method.
func (m *MockProductStatisticsRepo) UpdateAverageRating(ctx context.Context, productID string, averageRating float64) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateAverageRating", ctx, productID, averageRating)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateAverageRating indicates an expected call of UpdateAverageRating.
func (mr *MockProductStatisticsRepoMockRecorder) UpdateAverageRating(ctx, productID, averageRating any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAverageRating", reflect.TypeOf((*MockProductStatisticsRepo)(nil).UpdateAverageRating), ctx, productID, averageRating)
}
// MockProductStatisticsIndex is a mock of ProductStatisticsIndex interface.
type MockProductStatisticsIndex struct {
ctrl *gomock.Controller
recorder *MockProductStatisticsIndexMockRecorder
isgomock struct{}
}
// MockProductStatisticsIndexMockRecorder is the mock recorder for MockProductStatisticsIndex.
type MockProductStatisticsIndexMockRecorder struct {
mock *MockProductStatisticsIndex
}
// NewMockProductStatisticsIndex creates a new mock instance.
func NewMockProductStatisticsIndex(ctrl *gomock.Controller) *MockProductStatisticsIndex {
mock := &MockProductStatisticsIndex{ctrl: ctrl}
mock.recorder = &MockProductStatisticsIndexMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockProductStatisticsIndex) EXPECT() *MockProductStatisticsIndexMockRecorder {
return m.recorder
}
// Index20250317001UP mocks base method.
func (m *MockProductStatisticsIndex) Index20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Index20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Index20250317001UP indicates an expected call of Index20250317001UP.
func (mr *MockProductStatisticsIndexMockRecorder) Index20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index20250317001UP", reflect.TypeOf((*MockProductStatisticsIndex)(nil).Index20250317001UP), ctx)
}

498
pkg/mock/repository/tags.go Normal file
View File

@ -0,0 +1,498 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ./pkg/domain/repository/tags.go
//
// Generated by this command:
//
// mockgen -source=./pkg/domain/repository/tags.go -destination=./pkg/mock/repository/tags.go -package=mock
//
// Package mock is a generated GoMock package.
package mock
import (
context "context"
reflect "reflect"
entity "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
repository "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
mongo "go.mongodb.org/mongo-driver/mongo"
gomock "go.uber.org/mock/gomock"
)
// MockTagRepo is a mock of TagRepo interface.
type MockTagRepo struct {
ctrl *gomock.Controller
recorder *MockTagRepoMockRecorder
isgomock struct{}
}
// MockTagRepoMockRecorder is the mock recorder for MockTagRepo.
type MockTagRepoMockRecorder struct {
mock *MockTagRepo
}
// NewMockTagRepo creates a new mock instance.
func NewMockTagRepo(ctrl *gomock.Controller) *MockTagRepo {
mock := &MockTagRepo{ctrl: ctrl}
mock.recorder = &MockTagRepoMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockTagRepo) EXPECT() *MockTagRepoMockRecorder {
return m.recorder
}
// BindTags mocks base method.
func (m *MockTagRepo) BindTags(ctx context.Context, binding []*entity.TagsBindingTable) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BindTags", ctx, binding)
ret0, _ := ret[0].(error)
return ret0
}
// BindTags indicates an expected call of BindTags.
func (mr *MockTagRepoMockRecorder) BindTags(ctx, binding any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BindTags", reflect.TypeOf((*MockTagRepo)(nil).BindTags), ctx, binding)
}
// Create mocks base method.
func (m *MockTagRepo) Create(ctx context.Context, tag *entity.Tags) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Create", ctx, tag)
ret0, _ := ret[0].(error)
return ret0
}
// Create indicates an expected call of Create.
func (mr *MockTagRepoMockRecorder) Create(ctx, tag any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockTagRepo)(nil).Create), ctx, tag)
}
// Delete mocks base method.
func (m *MockTagRepo) Delete(ctx context.Context, id string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delete", ctx, id)
ret0, _ := ret[0].(error)
return ret0
}
// Delete indicates an expected call of Delete.
func (mr *MockTagRepoMockRecorder) Delete(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockTagRepo)(nil).Delete), ctx, id)
}
// GetBindingsByReference mocks base method.
func (m *MockTagRepo) GetBindingsByReference(ctx context.Context, referenceID string) ([]*entity.TagsBindingTable, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBindingsByReference", ctx, referenceID)
ret0, _ := ret[0].([]*entity.TagsBindingTable)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBindingsByReference indicates an expected call of GetBindingsByReference.
func (mr *MockTagRepoMockRecorder) GetBindingsByReference(ctx, referenceID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBindingsByReference", reflect.TypeOf((*MockTagRepo)(nil).GetBindingsByReference), ctx, referenceID)
}
// GetByID mocks base method.
func (m *MockTagRepo) GetByID(ctx context.Context, id string) (*entity.Tags, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetByID", ctx, id)
ret0, _ := ret[0].(*entity.Tags)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetByID indicates an expected call of GetByID.
func (mr *MockTagRepoMockRecorder) GetByID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockTagRepo)(nil).GetByID), ctx, id)
}
// GetByIDs mocks base method.
func (m *MockTagRepo) GetByIDs(ctx context.Context, ids []string) ([]*entity.Tags, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetByIDs", ctx, ids)
ret0, _ := ret[0].([]*entity.Tags)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetByIDs indicates an expected call of GetByIDs.
func (mr *MockTagRepoMockRecorder) GetByIDs(ctx, ids any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByIDs", reflect.TypeOf((*MockTagRepo)(nil).GetByIDs), ctx, ids)
}
// IndexTags20250317001UP mocks base method.
func (m *MockTagRepo) IndexTags20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IndexTags20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// IndexTags20250317001UP indicates an expected call of IndexTags20250317001UP.
func (mr *MockTagRepoMockRecorder) IndexTags20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IndexTags20250317001UP", reflect.TypeOf((*MockTagRepo)(nil).IndexTags20250317001UP), ctx)
}
// IndexTagsBinding20250317001UP mocks base method.
func (m *MockTagRepo) IndexTagsBinding20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IndexTagsBinding20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// IndexTagsBinding20250317001UP indicates an expected call of IndexTagsBinding20250317001UP.
func (mr *MockTagRepoMockRecorder) IndexTagsBinding20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IndexTagsBinding20250317001UP", reflect.TypeOf((*MockTagRepo)(nil).IndexTagsBinding20250317001UP), ctx)
}
// List mocks base method.
func (m *MockTagRepo) List(ctx context.Context, params repository.TagQueryParams) ([]*entity.Tags, int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "List", ctx, params)
ret0, _ := ret[0].([]*entity.Tags)
ret1, _ := ret[1].(int64)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// List indicates an expected call of List.
func (mr *MockTagRepoMockRecorder) List(ctx, params any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockTagRepo)(nil).List), ctx, params)
}
// ListTagBinding mocks base method.
func (m *MockTagRepo) ListTagBinding(ctx context.Context, params repository.TagBindingQueryParams) ([]*entity.TagsBindingTable, int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListTagBinding", ctx, params)
ret0, _ := ret[0].([]*entity.TagsBindingTable)
ret1, _ := ret[1].(int64)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// ListTagBinding indicates an expected call of ListTagBinding.
func (mr *MockTagRepoMockRecorder) ListTagBinding(ctx, params any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTagBinding", reflect.TypeOf((*MockTagRepo)(nil).ListTagBinding), ctx, params)
}
// UnbindTag mocks base method.
func (m *MockTagRepo) UnbindTag(ctx context.Context, tagID, referenceID string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UnbindTag", ctx, tagID, referenceID)
ret0, _ := ret[0].(error)
return ret0
}
// UnbindTag indicates an expected call of UnbindTag.
func (mr *MockTagRepoMockRecorder) UnbindTag(ctx, tagID, referenceID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnbindTag", reflect.TypeOf((*MockTagRepo)(nil).UnbindTag), ctx, tagID, referenceID)
}
// UnbindTagByReferenceID mocks base method.
func (m *MockTagRepo) UnbindTagByReferenceID(ctx context.Context, referenceID string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UnbindTagByReferenceID", ctx, referenceID)
ret0, _ := ret[0].(error)
return ret0
}
// UnbindTagByReferenceID indicates an expected call of UnbindTagByReferenceID.
func (mr *MockTagRepoMockRecorder) UnbindTagByReferenceID(ctx, referenceID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnbindTagByReferenceID", reflect.TypeOf((*MockTagRepo)(nil).UnbindTagByReferenceID), ctx, referenceID)
}
// Update mocks base method.
func (m *MockTagRepo) Update(ctx context.Context, id string, tag repository.TagModifyParams) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Update", ctx, id, tag)
ret0, _ := ret[0].(error)
return ret0
}
// Update indicates an expected call of Update.
func (mr *MockTagRepoMockRecorder) Update(ctx, id, tag any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockTagRepo)(nil).Update), ctx, id, tag)
}
// MockBase is a mock of Base interface.
type MockBase struct {
ctrl *gomock.Controller
recorder *MockBaseMockRecorder
isgomock struct{}
}
// MockBaseMockRecorder is the mock recorder for MockBase.
type MockBaseMockRecorder struct {
mock *MockBase
}
// NewMockBase creates a new mock instance.
func NewMockBase(ctrl *gomock.Controller) *MockBase {
mock := &MockBase{ctrl: ctrl}
mock.recorder = &MockBaseMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBase) EXPECT() *MockBaseMockRecorder {
return m.recorder
}
// Create mocks base method.
func (m *MockBase) Create(ctx context.Context, tag *entity.Tags) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Create", ctx, tag)
ret0, _ := ret[0].(error)
return ret0
}
// Create indicates an expected call of Create.
func (mr *MockBaseMockRecorder) Create(ctx, tag any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockBase)(nil).Create), ctx, tag)
}
// Delete mocks base method.
func (m *MockBase) Delete(ctx context.Context, id string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delete", ctx, id)
ret0, _ := ret[0].(error)
return ret0
}
// Delete indicates an expected call of Delete.
func (mr *MockBaseMockRecorder) Delete(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockBase)(nil).Delete), ctx, id)
}
// GetByID mocks base method.
func (m *MockBase) GetByID(ctx context.Context, id string) (*entity.Tags, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetByID", ctx, id)
ret0, _ := ret[0].(*entity.Tags)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetByID indicates an expected call of GetByID.
func (mr *MockBaseMockRecorder) GetByID(ctx, id any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockBase)(nil).GetByID), ctx, id)
}
// GetByIDs mocks base method.
func (m *MockBase) GetByIDs(ctx context.Context, ids []string) ([]*entity.Tags, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetByIDs", ctx, ids)
ret0, _ := ret[0].([]*entity.Tags)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetByIDs indicates an expected call of GetByIDs.
func (mr *MockBaseMockRecorder) GetByIDs(ctx, ids any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByIDs", reflect.TypeOf((*MockBase)(nil).GetByIDs), ctx, ids)
}
// List mocks base method.
func (m *MockBase) List(ctx context.Context, params repository.TagQueryParams) ([]*entity.Tags, int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "List", ctx, params)
ret0, _ := ret[0].([]*entity.Tags)
ret1, _ := ret[1].(int64)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// List indicates an expected call of List.
func (mr *MockBaseMockRecorder) List(ctx, params any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockBase)(nil).List), ctx, params)
}
// Update mocks base method.
func (m *MockBase) Update(ctx context.Context, id string, tag repository.TagModifyParams) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Update", ctx, id, tag)
ret0, _ := ret[0].(error)
return ret0
}
// Update indicates an expected call of Update.
func (mr *MockBaseMockRecorder) Update(ctx, id, tag any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockBase)(nil).Update), ctx, id, tag)
}
// MockTagBindingRepo is a mock of TagBindingRepo interface.
type MockTagBindingRepo struct {
ctrl *gomock.Controller
recorder *MockTagBindingRepoMockRecorder
isgomock struct{}
}
// MockTagBindingRepoMockRecorder is the mock recorder for MockTagBindingRepo.
type MockTagBindingRepoMockRecorder struct {
mock *MockTagBindingRepo
}
// NewMockTagBindingRepo creates a new mock instance.
func NewMockTagBindingRepo(ctrl *gomock.Controller) *MockTagBindingRepo {
mock := &MockTagBindingRepo{ctrl: ctrl}
mock.recorder = &MockTagBindingRepoMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockTagBindingRepo) EXPECT() *MockTagBindingRepoMockRecorder {
return m.recorder
}
// BindTags mocks base method.
func (m *MockTagBindingRepo) BindTags(ctx context.Context, binding []*entity.TagsBindingTable) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BindTags", ctx, binding)
ret0, _ := ret[0].(error)
return ret0
}
// BindTags indicates an expected call of BindTags.
func (mr *MockTagBindingRepoMockRecorder) BindTags(ctx, binding any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BindTags", reflect.TypeOf((*MockTagBindingRepo)(nil).BindTags), ctx, binding)
}
// GetBindingsByReference mocks base method.
func (m *MockTagBindingRepo) GetBindingsByReference(ctx context.Context, referenceID string) ([]*entity.TagsBindingTable, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBindingsByReference", ctx, referenceID)
ret0, _ := ret[0].([]*entity.TagsBindingTable)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetBindingsByReference indicates an expected call of GetBindingsByReference.
func (mr *MockTagBindingRepoMockRecorder) GetBindingsByReference(ctx, referenceID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBindingsByReference", reflect.TypeOf((*MockTagBindingRepo)(nil).GetBindingsByReference), ctx, referenceID)
}
// ListTagBinding mocks base method.
func (m *MockTagBindingRepo) ListTagBinding(ctx context.Context, params repository.TagBindingQueryParams) ([]*entity.TagsBindingTable, int64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListTagBinding", ctx, params)
ret0, _ := ret[0].([]*entity.TagsBindingTable)
ret1, _ := ret[1].(int64)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// ListTagBinding indicates an expected call of ListTagBinding.
func (mr *MockTagBindingRepoMockRecorder) ListTagBinding(ctx, params any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTagBinding", reflect.TypeOf((*MockTagBindingRepo)(nil).ListTagBinding), ctx, params)
}
// UnbindTag mocks base method.
func (m *MockTagBindingRepo) UnbindTag(ctx context.Context, tagID, referenceID string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UnbindTag", ctx, tagID, referenceID)
ret0, _ := ret[0].(error)
return ret0
}
// UnbindTag indicates an expected call of UnbindTag.
func (mr *MockTagBindingRepoMockRecorder) UnbindTag(ctx, tagID, referenceID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnbindTag", reflect.TypeOf((*MockTagBindingRepo)(nil).UnbindTag), ctx, tagID, referenceID)
}
// UnbindTagByReferenceID mocks base method.
func (m *MockTagBindingRepo) UnbindTagByReferenceID(ctx context.Context, referenceID string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UnbindTagByReferenceID", ctx, referenceID)
ret0, _ := ret[0].(error)
return ret0
}
// UnbindTagByReferenceID indicates an expected call of UnbindTagByReferenceID.
func (mr *MockTagBindingRepoMockRecorder) UnbindTagByReferenceID(ctx, referenceID any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnbindTagByReferenceID", reflect.TypeOf((*MockTagBindingRepo)(nil).UnbindTagByReferenceID), ctx, referenceID)
}
// MockIndex is a mock of Index interface.
type MockIndex struct {
ctrl *gomock.Controller
recorder *MockIndexMockRecorder
isgomock struct{}
}
// MockIndexMockRecorder is the mock recorder for MockIndex.
type MockIndexMockRecorder struct {
mock *MockIndex
}
// NewMockIndex creates a new mock instance.
func NewMockIndex(ctrl *gomock.Controller) *MockIndex {
mock := &MockIndex{ctrl: ctrl}
mock.recorder = &MockIndexMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockIndex) EXPECT() *MockIndexMockRecorder {
return m.recorder
}
// IndexTags20250317001UP mocks base method.
func (m *MockIndex) IndexTags20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IndexTags20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// IndexTags20250317001UP indicates an expected call of IndexTags20250317001UP.
func (mr *MockIndexMockRecorder) IndexTags20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IndexTags20250317001UP", reflect.TypeOf((*MockIndex)(nil).IndexTags20250317001UP), ctx)
}
// IndexTagsBinding20250317001UP mocks base method.
func (m *MockIndex) IndexTagsBinding20250317001UP(ctx context.Context) (*mongo.Cursor, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IndexTagsBinding20250317001UP", ctx)
ret0, _ := ret[0].(*mongo.Cursor)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// IndexTagsBinding20250317001UP indicates an expected call of IndexTagsBinding20250317001UP.
func (mr *MockIndexMockRecorder) IndexTagsBinding20250317001UP(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IndexTagsBinding20250317001UP", reflect.TypeOf((*MockIndex)(nil).IndexTagsBinding20250317001UP), ctx)
}

181
pkg/repository/kyc.go Normal file
View File

@ -0,0 +1,181 @@
package repository
import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
mgo "code.30cm.net/digimon/library-go/mongo"
"context"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/mon"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
type KYCRepositoryParam struct {
Conf *mgo.Conf
CacheConf cache.CacheConf
DBOpts []mon.Option
CacheOpts []cache.Option
}
type KYCRepository struct {
DB mgo.DocumentDBWithCacheUseCase
}
func NewKYCRepository(param KYCRepositoryParam) repository.KYCRepository {
e := entity.KYC{}
documentDB, err := mgo.MustDocumentDBWithCache(
param.Conf,
e.CollectionName(),
param.CacheConf,
param.DBOpts,
param.CacheOpts,
)
if err != nil {
panic(err)
}
return &KYCRepository{
DB: documentDB,
}
}
func (repo *KYCRepository) Create(ctx context.Context, data *entity.KYC) error {
if data.ID.IsZero() {
now := time.Now().UTC().UnixNano()
data.ID = primitive.NewObjectID()
data.CreatedAt = now
data.UpdatedAt = now
}
_, err := repo.DB.GetClient().InsertOne(ctx, data)
return err
}
func (repo *KYCRepository) FindLatestByUID(ctx context.Context, uid string) (*entity.KYC, error) {
filter := bson.M{"uid": uid}
var result entity.KYC
opts := options.FindOne().SetSort(bson.D{{"created_at", -1}}) // 用 SetSort 加入排序
err := repo.DB.GetClient().FindOne(ctx, &result, filter, opts)
if err != nil {
return nil, err
}
return &result, nil
}
func (repo *KYCRepository) FindByID(ctx context.Context, id string) (*entity.KYC, error) {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return nil, err
}
filter := bson.M{"_id": oid}
var result entity.KYC
err = repo.DB.GetClient().FindOne(ctx, &result, filter)
if err != nil {
return nil, err
}
return &result, nil
}
func (repo *KYCRepository) List(ctx context.Context, params repository.KYCQueryParams) ([]*entity.KYC, int64, error) {
filter := bson.M{}
if params.UID != nil {
filter["uid"] = *params.UID
}
if params.Country != nil {
filter["country_region"] = *params.Country
}
if params.Status != nil {
filter["status"] = *params.Status
}
sort := bson.D{}
if params.SortByDate {
sort = append(sort, bson.E{Key: "created_at", Value: -1})
}
var results []*entity.KYC
total, err := repo.DB.GetClient().FindManyWithTotal(ctx, &results, filter, params.PageIndex, params.PageSize, WithSort(sort))
if err != nil {
return nil, 0, err
}
return results, total, nil
}
func (repo *KYCRepository) UpdateStatus(ctx context.Context, id string, status string, reason string) error {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return err
}
filter := bson.M{"_id": oid}
update := bson.M{
"$set": bson.M{
"status": status,
"reject_reason": reason,
"updated_at": time.Now().UTC().UnixNano(),
},
}
_, err = repo.DB.GetClient().UpdateOne(ctx, filter, update)
return err
}
func (repo *KYCRepository) UpdateKYCInfo(ctx context.Context, id string, update *repository.KYCUpdateParams) error {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return err
}
setFields := bson.M{"updated_at": time.Now().UTC().UnixNano()}
if update.Name != nil {
setFields["name"] = *update.Name
}
if update.Identification != nil {
setFields["identification"] = *update.Identification
}
if update.IdentificationType != nil {
setFields["identification_type"] = *update.IdentificationType
}
if update.Address != nil {
setFields["address"] = *update.Address
}
if update.PostalCode != nil {
setFields["postal_code"] = *update.PostalCode
}
if update.DateOfBirth != nil {
setFields["date_of_birth"] = *update.DateOfBirth
}
if update.Gender != nil {
setFields["gender"] = *update.Gender
}
if update.IDFrontImage != nil {
setFields["id_front_image"] = *update.IDFrontImage
}
if update.IDBackImage != nil {
setFields["id_back_image"] = *update.IDBackImage
}
if update.BankStatementImg != nil {
setFields["bank_statement_img"] = *update.BankStatementImg
}
if update.BankCode != nil {
setFields["bank_code"] = *update.BankCode
}
if update.BankName != nil {
setFields["bank_name"] = *update.BankName
}
if update.BranchCode != nil {
setFields["branch_code"] = *update.BranchCode
}
if update.BranchName != nil {
setFields["branch_name"] = *update.BranchName
}
if update.BankAccount != nil {
setFields["bank_account"] = *update.BankAccount
}
filter := bson.M{"_id": oid, "status": "PENDING"} // 僅允許更新尚未審核的
updateDoc := bson.M{"$set": setFields}
_, err = repo.DB.GetClient().UpdateOne(ctx, filter, updateDoc)
return err
}

View File

@ -97,7 +97,14 @@ func (repo *ProductStatisticsRepository) GetByProductID(ctx context.Context, pro
func (repo *ProductStatisticsRepository) IncOrders(ctx context.Context, productID string, count int64) error {
filter := bson.M{"product_id": productID}
update := bson.M{"$inc": bson.M{"total_orders": count}}
now := time.Now().UTC().UnixNano()
update := bson.M{
"$inc": bson.M{"total_orders": count},
"$set": bson.M{
"total_orders_update_time": now,
"updated_at": now,
},
}
rk := domain.GetProductStatisticsRK(productID)
_, err := repo.DB.UpdateOne(ctx, rk, filter, update)
@ -117,7 +124,14 @@ func (repo *ProductStatisticsRepository) IncOrders(ctx context.Context, productI
func (repo *ProductStatisticsRepository) DecOrders(ctx context.Context, productID string, count int64) error {
filter := bson.M{"product_id": productID, "total_orders": bson.M{"$gte": count}}
update := bson.M{"$inc": bson.M{"total_orders": -count}}
now := time.Now().UTC().UnixNano()
update := bson.M{
"$inc": bson.M{"total_orders": -count},
"$set": bson.M{
"total_orders_update_time": now,
"updated_at": now,
},
}
rk := domain.GetProductStatisticsRK(productID)
_, err := repo.DB.UpdateOne(ctx, rk, filter, update)
@ -137,7 +151,7 @@ func (repo *ProductStatisticsRepository) DecOrders(ctx context.Context, productI
func (repo *ProductStatisticsRepository) UpdateAverageRating(ctx context.Context, productID string, averageRating float64) error {
filter := bson.M{"product_id": productID}
now := time.Now().UnixNano()
now := time.Now().UTC().UnixNano()
update := bson.M{
"$set": bson.M{
"average_rating": averageRating,
@ -163,7 +177,7 @@ func (repo *ProductStatisticsRepository) UpdateAverageRating(ctx context.Context
func (repo *ProductStatisticsRepository) IncFansCount(ctx context.Context, productID string, fansCount uint64) error {
filter := bson.M{"product_id": productID}
now := time.Now().UnixNano()
now := time.Now().UTC().UnixNano()
update := bson.M{
"$inc": bson.M{"fans_count": fansCount},
"$set": bson.M{
@ -191,7 +205,7 @@ func (repo *ProductStatisticsRepository) IncFansCount(ctx context.Context, produ
func (repo *ProductStatisticsRepository) DecFansCount(ctx context.Context, productID string, fansCount uint64) error {
// 只允許在 fans_count 大於或等於欲扣減值時進行扣減
filter := bson.M{"product_id": productID, "fans_count": bson.M{"$gte": fansCount}}
now := time.Now().UnixNano()
now := time.Now().UTC().UnixNano()
// 在更新之前先檢查 fansCount 是否過大
if fansCount > uint64(math.MaxInt64) {

View File

@ -801,3 +801,115 @@ func TestUnbindTag(t *testing.T) {
})
}
}
func TestGetByIDs(t *testing.T) {
repo, tearDown, err := SetupTestProductTagsRepo("testDB_get_by_ids")
require.NoError(t, err)
defer tearDown()
ctx := context.Background()
now := time.Now().Unix()
tag1 := &entity.Tags{
ID: primitive.NewObjectID(),
Name: "Tag1",
Types: product.ItemTypeProduct,
ShowType: product.ShowTypeNormal,
CreatedAt: now,
UpdatedAt: now,
}
tag2 := &entity.Tags{
ID: primitive.NewObjectID(),
Name: "Tag2",
Types: product.ItemTypeSkill,
ShowType: product.ShowTypeNormal,
CreatedAt: now,
UpdatedAt: now,
}
// 寫入測試資料
require.NoError(t, repo.Create(ctx, tag1))
require.NoError(t, repo.Create(ctx, tag2))
t.Run("return matching tags", func(t *testing.T) {
results, err := repo.GetByIDs(ctx, []string{tag1.ID.Hex(), tag2.ID.Hex()})
require.NoError(t, err)
require.Len(t, results, 2)
gotIDs := map[primitive.ObjectID]bool{}
for _, tag := range results {
gotIDs[tag.ID] = true
}
assert.True(t, gotIDs[tag1.ID])
assert.True(t, gotIDs[tag2.ID])
})
t.Run("skip invalid object ids", func(t *testing.T) {
results, err := repo.GetByIDs(ctx, []string{"invalid_id", tag1.ID.Hex()})
require.NoError(t, err)
require.Len(t, results, 1)
assert.Equal(t, tag1.ID, results[0].ID)
})
t.Run("return empty if all ids invalid", func(t *testing.T) {
results, err := repo.GetByIDs(ctx, []string{"invalid1", "wrong!"})
require.NoError(t, err)
assert.Empty(t, results)
})
}
func TestUnbindTagByReferenceID(t *testing.T) {
repo, tearDown, err := SetupTestProductTagsRepo("testDB_get_by_ids")
require.NoError(t, err)
defer tearDown()
ctx := context.Background()
now := time.Now().Unix()
referenceID := "ref123"
// 建立測試資料
binding1 := &entity.TagsBindingTable{
ID: primitive.NewObjectID(),
ReferenceID: referenceID,
TagID: "tag1",
CreatedAt: now,
UpdatedAt: now,
}
binding2 := &entity.TagsBindingTable{
ID: primitive.NewObjectID(),
ReferenceID: referenceID,
TagID: "tag2",
CreatedAt: now,
UpdatedAt: now,
}
bindingOther := &entity.TagsBindingTable{
ID: primitive.NewObjectID(),
ReferenceID: "ref999",
TagID: "tag999",
CreatedAt: now,
UpdatedAt: now,
}
require.NoError(t, repo.BindTags(ctx, []*entity.TagsBindingTable{binding1, binding2, bindingOther}))
t.Run("should delete bindings by referenceID", func(t *testing.T) {
err := repo.UnbindTagByReferenceID(ctx, referenceID)
require.NoError(t, err)
// 確認 ref123 的都被刪了ref999 還在
result, err := repo.GetBindingsByReference(ctx, referenceID)
require.NoError(t, err)
assert.Len(t, result, 0)
// 檢查其他 reference 還在
resultOthers, err := repo.GetBindingsByReference(ctx, "ref999")
require.NoError(t, err)
assert.Len(t, resultOthers, 1)
assert.Equal(t, "tag999", resultOthers[0].TagID)
})
t.Run("should not fail if no matching data", func(t *testing.T) {
err := repo.UnbindTagByReferenceID(ctx, "nonexistent-ref")
require.NoError(t, err)
})
}

View File

@ -68,7 +68,6 @@ func SetupTestProductRepository(db string) (repository.ProductRepository, func()
func TestListProduct(t *testing.T) {
model, tearDown, err := SetupTestProductRepository("testDB")
defer tearDown()
fmt.Println("ddddddddddddddddddddd", err.Error())
assert.NoError(t, err)
now := time.Now()

View File

@ -4,9 +4,11 @@ import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/usecase"
repo "code.30cm.net/digimon/app-cloudep-product-service/pkg/repository"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/utils"
"code.30cm.net/digimon/library-go/errs"
"context"
"errors"
"github.com/zeromicro/go-zero/core/logx"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
@ -31,92 +33,14 @@ func MustProductUseCase(param ProductUseCaseParam) usecase.ProductUseCase {
}
func (use *ProductUseCase) Create(ctx context.Context, product *usecase.Product) error {
// 資料前處理:準備 entity.Product 實體
insert := &entity.Product{}
if product.UID != nil {
insert.UID = *product.UID
}
if product.Title != nil {
insert.Title = *product.Title
}
if product.IsPublished != nil {
insert.IsPublished = *product.IsPublished
}
if product.Category != nil {
insert.Category = *product.Category
}
if product.ShortTitle != nil {
insert.ShortTitle = product.ShortTitle
}
if product.Details != nil {
insert.Details = product.Details
}
if product.ShortDescription != nil {
insert.ShortDescription = *product.ShortDescription
}
if product.Slug != nil {
insert.Slug = product.Slug
}
if product.Amount != 0 {
insert.Amount = product.Amount
}
if product.StartTime != nil {
st := utils.Rfc3339ToUnix(utils.ToValue(product.StartTime))
insert.StartTime = &st
}
if product.EndTime != nil {
et := utils.Rfc3339ToUnix(utils.ToValue(product.EndTime))
insert.EndTime = &et
}
if len(product.Media) > 0 {
medias := make([]entity.Media, 0, len(product.Media))
for _, m := range product.Media {
medias = append(medias, entity.Media{
Sort: m.Sort,
URL: m.URL,
Type: m.Type,
})
}
insert.Media = medias
}
if len(product.CustomFields) > 0 {
cf := make([]entity.CustomFields, 0, len(product.CustomFields))
for _, field := range product.CustomFields {
cf = append(cf, entity.CustomFields{
Key: field.Key,
Value: field.Value,
})
}
insert.CustomFields = cf
}
// 綁定 Tags
tagsBinding := make([]*entity.TagsBindingTable, 0, len(product.Tags))
for _, tag := range product.Tags {
tagsBinding = append(tagsBinding, &entity.TagsBindingTable{
ReferenceID: insert.ID.Hex(),
TagID: tag,
})
}
insert := convertUseCaseToEntity(product)
// Transaction 設定:只做必要寫入
opts := options.Transaction().SetReadConcern(readconcern.Local())
err := use.ProductRepo.Transaction(ctx, func(sessCtx mongo.SessionContext) (any, error) {
// 插入 Product
if err := use.ProductRepo.Insert(sessCtx, insert); err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "req", Value: product},
{Key: "func", Value: "ProductRepo.Insert"},
{Key: "err", Value: err.Error()},
},
"failed to create product")
return nil, e
return nil, logDBError(ctx, "ProductRepo.Insert", []logx.LogField{{Key: "req", Value: product}}, err, "failed to create product")
}
// 插入 Product 統計資料
if err := use.ProductStatisticsRepo.Create(sessCtx, &entity.ProductStatistics{
ProductID: insert.ID.Hex(),
Orders: 0,
@ -126,27 +50,12 @@ func (use *ProductUseCase) Create(ctx context.Context, product *usecase.Product)
FansCount: 0,
FansCountUpdateTime: 0,
}); err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "ProductID", Value: insert.ID.Hex()},
{Key: "func", Value: "ProductStatisticsRepo.Create"},
{Key: "err", Value: err.Error()},
},
"failed to create product statistics")
return nil, e
return nil, logDBError(ctx, "ProductStatisticsRepo.Create", []logx.LogField{{Key: "ProductID", Value: insert.ID.Hex()}}, err, "failed to create product statistics")
}
tagsBinding := buildTagsBinding(insert.ID.Hex(), product.Tags)
if err := use.TagBinding.BindTags(sessCtx, tagsBinding); err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "ReferenceID", Value: insert.ID.Hex()},
{Key: "tags", Value: product.Tags},
{Key: "func", Value: "TagBinding.BindTag"},
{Key: "err", Value: err.Error()},
}, "failed to binding product tags")
return nil, e
return nil, logDBError(ctx, "TagBinding.BindTags", []logx.LogField{{Key: "ReferenceID", Value: insert.ID.Hex()}, {Key: "tags", Value: product.Tags}}, err, "failed to bind product tags")
}
return nil, nil
@ -160,118 +69,25 @@ func (use *ProductUseCase) Create(ctx context.Context, product *usecase.Product)
}
func (use *ProductUseCase) Update(ctx context.Context, id string, product *usecase.Product) error {
// 資料前處理:準備 entity.Product 實體
update := &repository.ProductUpdateParams{}
if product.Title != nil {
update.Title = product.Title
}
if product.IsPublished != nil {
update.IsPublished = product.IsPublished
}
if product.Category != nil {
update.Category = product.Category
}
if product.ShortTitle != nil {
update.ShortTitle = product.ShortTitle
}
if product.Details != nil {
update.Details = product.Details
}
if product.ShortDescription != nil {
update.ShortDescription = *product.ShortDescription
}
if product.Slug != nil {
update.Slug = product.Slug
}
if product.Amount != 0 {
update.Amount = &product.Amount
}
if product.StartTime != nil {
st := utils.Rfc3339ToUnix(utils.ToValue(product.StartTime))
update.StartTime = &st
}
if product.EndTime != nil {
et := utils.Rfc3339ToUnix(utils.ToValue(product.EndTime))
update.EndTime = &et
}
if len(product.Media) > 0 {
medias := make([]entity.Media, 0, len(product.Media))
for _, m := range product.Media {
medias = append(medias, entity.Media{
Sort: m.Sort,
URL: m.URL,
Type: m.Type,
})
}
update.Media = medias
}
if len(product.CustomFields) > 0 {
cf := make([]entity.CustomFields, 0, len(product.CustomFields))
for _, field := range product.CustomFields {
cf = append(cf, entity.CustomFields{
Key: field.Key,
Value: field.Value,
})
}
update.CustomFields = cf
}
// 綁定 Tags
tagsBinding := make([]*entity.TagsBindingTable, 0, len(product.Tags))
for _, tag := range product.Tags {
tagsBinding = append(tagsBinding, &entity.TagsBindingTable{
ReferenceID: id,
TagID: tag,
})
}
// Transaction 設定:只做必要寫入
update := convertUseCaseToUpdateParams(product)
tagsBinding := buildTagsBinding(id, product.Tags)
opts := options.Transaction().SetReadConcern(readconcern.Local())
err := use.ProductRepo.Transaction(ctx, func(sessCtx mongo.SessionContext) (any, error) {
_, err := use.ProductRepo.Update(sessCtx, id, update)
if err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "req", Value: product},
{Key: "func", Value: "ProductRepo.Update"},
{Key: "err", Value: err.Error()},
},
"failed to update product")
return nil, e
return nil, logDBError(ctx, "ProductRepo.Update", []logx.LogField{{Key: "req", Value: product}}, err, "failed to update product")
}
if err := use.TagBinding.UnbindTagByReferenceID(sessCtx, id); err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "ReferenceID", Value: id},
{Key: "func", Value: "TagBinding.UnbindTagByReferenceID"},
{Key: "err", Value: err.Error()},
}, "failed to unbind tags")
return nil, e
return nil, logDBError(ctx, "TagBinding.UnbindTagByReferenceID", []logx.LogField{{Key: "ReferenceID", Value: id}}, err, "failed to unbind tags")
}
if err := use.TagBinding.BindTags(sessCtx, tagsBinding); err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "ReferenceID", Value: id},
{Key: "tags", Value: product.Tags},
{Key: "func", Value: "TagBinding.BindTags"},
{Key: "err", Value: err.Error()},
}, "failed to binding product tags")
return nil, e
return nil, logDBError(ctx, "TagBinding.BindTags", []logx.LogField{{Key: "ReferenceID", Value: id}, {Key: "tags", Value: product.Tags}}, err, "failed to bind tags")
}
return nil, nil
}, opts)
if err != nil {
return err
}
return nil
return err
}
func (use *ProductUseCase) Delete(ctx context.Context, id string) error {
@ -314,135 +130,29 @@ func (use *ProductUseCase) Delete(ctx context.Context, id string) error {
func (use *ProductUseCase) Get(ctx context.Context, id string) (*usecase.ProductResp, error) {
product, err := use.ProductRepo.FindOneByID(ctx, id)
if err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "product_id", Value: id},
{Key: "func", Value: "ProductRepo.FindOneByID"},
{Key: "err", Value: err.Error()},
}, "failed to find product")
return nil, e
return nil, logDBError(ctx, "ProductRepo.FindOneByID", []logx.LogField{{Key: "product_id", Value: id}}, err, "failed to find product")
}
productStatistics, err := use.ProductStatisticsRepo.GetByID(ctx, id)
stats, err := use.ProductStatisticsRepo.GetByID(ctx, id)
if err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "product_id", Value: id},
{Key: "func", Value: "ProductStatisticsRepo.GetByID"},
{Key: "err", Value: err.Error()},
}, "failed to get product statistics")
return nil, e
return nil, logDBError(ctx, "ProductStatisticsRepo.GetByID", []logx.LogField{{Key: "product_id", Value: id}}, err, "failed to get product statistics")
}
tags, err := use.TagRepo.GetBindingsByReference(ctx, id)
bindings, err := use.TagRepo.GetBindingsByReference(ctx, id)
if err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "product_id", Value: id},
{Key: "func", Value: "TagRepo.GetBindingsByReference"},
{Key: "err", Value: err.Error()},
}, "failed to get tags")
return nil, e
return nil, logDBError(ctx, "TagRepo.GetBindingsByReference", []logx.LogField{{Key: "product_id", Value: id}}, err, "failed to get tag bindings")
}
t := make([]string, 0, len(tags))
for _, item := range tags {
t = append(t, item.TagID)
tagIDs := make([]string, 0, len(bindings))
for _, item := range bindings {
tagIDs = append(tagIDs, item.TagID)
}
tagsInfo, err := use.TagRepo.GetByIDs(ctx, t)
tags, err := use.TagRepo.GetByIDs(ctx, tagIDs)
if err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "product_id", Value: id},
{Key: "func", Value: "TagRepo.GetByIDs"},
{Key: "err", Value: err.Error()},
}, "failed to get tags")
return nil, e
}
// 組合資料
result := &usecase.ProductResp{
ID: product.ID.Hex(),
UID: product.UID,
Title: product.Title,
ShortDescription: product.ShortDescription,
IsPublished: product.IsPublished,
Amount: product.Amount,
Category: product.Category,
Orders: productStatistics.Orders,
AverageRating: productStatistics.AverageRating,
FansCount: productStatistics.FansCount,
UpdatedAt: utils.UnixToRfc3339(product.UpdatedAt),
CreatedAt: utils.UnixToRfc3339(product.CreatedAt),
return nil, logDBError(ctx, "TagRepo.GetByIDs", []logx.LogField{{Key: "product_id", Value: id}}, err, "failed to get tags")
}
for _, tag := range tagsInfo {
item := usecase.Tags{
ID: tag.ID.Hex(),
Types: tag.Types,
Name: tag.Name,
ShowType: tag.ShowType,
UpdatedAt: utils.UnixToRfc3339(tag.UpdatedAt),
CreatedAt: utils.UnixToRfc3339(tag.CreatedAt),
}
if tag.Cover != nil {
item.Cover = *tag.Cover
}
result.Tags = append(result.Tags, item)
return convertEntityToResp(product, stats, tags), nil
}
if len(product.Media) > 0 {
medias := make([]usecase.Media, 0, len(product.Media))
for _, m := range product.Media {
medias = append(medias, usecase.Media{
Sort: m.Sort,
URL: m.URL,
Type: m.Type,
})
}
result.Media = medias
}
if len(product.CustomFields) > 0 {
cf := make([]usecase.CustomFields, 0, len(product.CustomFields))
for _, field := range product.CustomFields {
cf = append(cf, usecase.CustomFields{
Key: field.Key,
Value: field.Value,
})
}
result.CustomFields = cf
}
if product.Slug != nil {
result.Slug = *product.Slug
}
if product.ShortTitle != nil {
result.ShortTitle = *product.ShortTitle
}
if product.Details != nil {
result.Details = *product.Details
}
if product.StartTime != nil {
result.StartTime = utils.UnixToRfc3339(*product.StartTime)
}
if product.EndTime != nil {
result.EndTime = utils.UnixToRfc3339(*product.EndTime)
}
if productStatistics.OrdersUpdateTime > 0 {
result.OrdersUpdateTime = utils.UnixToRfc3339(productStatistics.OrdersUpdateTime)
}
if productStatistics.FansCountUpdateTime > 0 {
result.FansCountUpdateTime = utils.UnixToRfc3339(productStatistics.FansCountUpdateTime)
}
if productStatistics.AverageRatingUpdateTime > 0 {
result.AverageRatingUpdateTime = utils.UnixToRfc3339(productStatistics.AverageRatingUpdateTime)
}
return result, nil
}
// TODO 效能有問題這邊優先改List 會有N + 1 問題
func (use *ProductUseCase) List(ctx context.Context, data usecase.ProductQueryParams) ([]*usecase.ProductResp, int64, error) {
query := &repository.ProductQueryParams{
@ -465,58 +175,455 @@ func (use *ProductUseCase) List(ctx context.Context, data usecase.ProductQueryPa
if data.StartTime != nil {
query.StartTime = data.StartTime
}
if data.EndTime != nil {
query.EndTime = data.EndTime
}
EndTime * int64 // 結束時間Unix 時間戳)
Slug * string // URL 後綴
product, i, err := use.ProductRepo.ListProduct(ctx, &repository.ProductQueryParams{})
products, total, err := use.ProductRepo.ListProduct(ctx, query)
if err != nil {
return nil, 0, err
}
result := make([]*usecase.ProductResp, 0, len(products))
for _, p := range products {
// 查詢統計資料
stats, _ := use.ProductStatisticsRepo.GetByID(ctx, p.ID.Hex())
// 查詢 Tag 資訊
tags, _ := use.TagRepo.GetBindingsByReference(ctx, p.ID.Hex())
tagIDs := make([]string, 0, len(tags))
for _, t := range tags {
tagIDs = append(tagIDs, t.TagID)
}
tagsInfo, _ := use.TagRepo.GetByIDs(ctx, tagIDs)
// 組合 Tags 回應
respTags := make([]usecase.Tags, 0, len(tagsInfo))
for _, tag := range tagsInfo {
item := usecase.Tags{
ID: tag.ID.Hex(),
Types: tag.Types,
Name: tag.Name,
ShowType: tag.ShowType,
UpdatedAt: utils.UnixToRfc3339(tag.UpdatedAt),
CreatedAt: utils.UnixToRfc3339(tag.CreatedAt),
}
if tag.Cover != nil {
item.Cover = *tag.Cover
}
respTags = append(respTags, item)
}
// Media & CustomFields
media := make([]usecase.Media, 0, len(p.Media))
for _, m := range p.Media {
media = append(media, usecase.Media{
Sort: m.Sort,
URL: m.URL,
Type: m.Type,
})
}
customFields := make([]usecase.CustomFields, 0, len(p.CustomFields))
for _, f := range p.CustomFields {
customFields = append(customFields, usecase.CustomFields{
Key: f.Key,
Value: f.Value,
})
}
resp := &usecase.ProductResp{
ID: p.ID.Hex(),
UID: p.UID,
Title: p.Title,
ShortTitle: utils.ToValue(p.ShortTitle),
Details: utils.ToValue(p.Details),
ShortDescription: p.ShortDescription,
Media: media,
Slug: utils.ToValue(p.Slug),
IsPublished: p.IsPublished,
Amount: p.Amount,
StartTime: utils.UnixToRfc3339(utils.ToValue(p.StartTime)),
EndTime: utils.UnixToRfc3339(utils.ToValue(p.EndTime)),
Category: p.Category,
CustomFields: customFields,
Tags: respTags,
Orders: stats.Orders,
OrdersUpdateTime: utils.UnixToRfc3339(stats.OrdersUpdateTime),
AverageRating: stats.AverageRating,
AverageRatingUpdateTime: utils.UnixToRfc3339(stats.AverageRatingUpdateTime),
FansCount: stats.FansCount,
FansCountUpdateTime: utils.UnixToRfc3339(stats.FansCountUpdateTime),
UpdatedAt: utils.UnixToRfc3339(p.UpdatedAt),
CreatedAt: utils.UnixToRfc3339(p.CreatedAt),
}
result = append(result, resp)
}
return result, total, nil
}
func (use *ProductUseCase) IncOrders(ctx context.Context, productID string, count int64) error {
//TODO implement me
panic("implement me")
err := use.ProductStatisticsRepo.IncOrders(ctx, productID, count)
if err != nil {
return errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "product_id", Value: productID},
{Key: "func", Value: "ProductStatisticsRepo.IncOrders"},
{Key: "err", Value: err.Error()},
}, "failed to inc order")
}
return nil
}
func (use *ProductUseCase) DecOrders(ctx context.Context, productID string, count int64) error {
//TODO implement me
panic("implement me")
err := use.ProductStatisticsRepo.DecOrders(ctx, productID, count)
if err != nil {
return errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "product_id", Value: productID},
{Key: "func", Value: "ProductStatisticsRepo.DecOrders"},
{Key: "err", Value: err.Error()},
}, "failed to dec order")
}
return nil
}
func (use *ProductUseCase) UpdateAverageRating(ctx context.Context, productID string, averageRating float64) error {
//TODO implement me
panic("implement me")
err := use.ProductStatisticsRepo.UpdateAverageRating(ctx, productID, averageRating)
if err != nil {
return errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "product_id", Value: productID},
{Key: "func", Value: "ProductStatisticsRepo.UpdateAverageRating"},
{Key: "err", Value: err.Error()},
}, "failed to update average rating")
}
return nil
}
func (use *ProductUseCase) IncFansCount(ctx context.Context, productID string, fansCount uint64) error {
//TODO implement me
panic("implement me")
err := use.ProductStatisticsRepo.IncFansCount(ctx, productID, fansCount)
if err != nil {
return errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "product_id", Value: productID},
{Key: "func", Value: "ProductStatisticsRepo.IncFansCount"},
{Key: "err", Value: err.Error()},
}, "failed to inc fans count")
}
return nil
}
func (use *ProductUseCase) DecFansCount(ctx context.Context, productID string, fansCount uint64) error {
//TODO implement me
panic("implement me")
err := use.ProductStatisticsRepo.DecFansCount(ctx, productID, fansCount)
if err != nil {
return errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "product_id", Value: productID},
{Key: "func", Value: "ProductStatisticsRepo.DecFansCount"},
{Key: "err", Value: err.Error()},
}, "failed to dec fans count")
}
return nil
}
func (use *ProductUseCase) BindTag(ctx context.Context, binding usecase.TagsBindingTable) error {
//TODO implement me
panic("implement me")
_, err := use.TagRepo.GetByID(ctx, binding.TagID)
if err != nil {
if errors.Is(err, repo.ErrNotFound) {
return errs.ResourceNotFound("failed to get tags")
}
return err
}
_, err = use.ProductRepo.FindOneByID(ctx, binding.ReferenceID)
if err != nil {
if errors.Is(err, repo.ErrNotFound) {
return errs.ResourceNotFound("failed to get tags")
}
return err
}
err = use.TagBinding.BindTags(ctx, []*entity.TagsBindingTable{{ReferenceID: binding.ReferenceID, TagID: binding.TagID}})
if err != nil {
return errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "binding", Value: binding},
{Key: "func", Value: "TagBinding.BindTags"},
{Key: "err", Value: err.Error()},
}, "failed to bind tags")
}
return nil
}
func (use *ProductUseCase) UnbindTag(ctx context.Context, binding usecase.TagsBindingTable) error {
//TODO implement me
panic("implement me")
_, err := use.TagRepo.GetByID(ctx, binding.TagID)
if err != nil {
if errors.Is(err, repo.ErrNotFound) {
return errs.ResourceNotFound("failed to get tags")
}
return err
}
_, err = use.ProductRepo.FindOneByID(ctx, binding.ReferenceID)
if err != nil {
if errors.Is(err, repo.ErrNotFound) {
return errs.ResourceNotFound("failed to get tags")
}
return err
}
err = use.TagBinding.UnbindTag(ctx, binding.TagID, binding.ReferenceID)
if err != nil {
return errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "binding", Value: binding},
{Key: "func", Value: "TagBinding.UnbindTag"},
{Key: "err", Value: err.Error()},
}, "failed to unbind tags")
}
return nil
}
func (use *ProductUseCase) GetBindingsByReference(ctx context.Context, referenceID string) ([]usecase.TagsBindingTableResp, error) {
//TODO implement me
panic("implement me")
ref, err := use.TagBinding.GetBindingsByReference(ctx, referenceID)
if err != nil {
return nil, errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "referenceID", Value: referenceID},
{Key: "func", Value: "TagBinding.GetBindingsByReference"},
{Key: "err", Value: err.Error()},
}, "failed to get bindings by reference")
}
result := make([]usecase.TagsBindingTableResp, 0, len(ref))
for _, bind := range ref {
result = append(result, usecase.TagsBindingTableResp{
ID: bind.ID.Hex(),
ReferenceID: bind.ReferenceID,
TagID: bind.TagID,
CreatedAt: utils.UnixToRfc3339(bind.CreatedAt),
UpdatedAt: utils.UnixToRfc3339(bind.UpdatedAt),
})
}
return result, nil
}
func (use *ProductUseCase) ListTagBinding(ctx context.Context, params usecase.TagBindingQueryParams) ([]usecase.TagsBindingTableResp, int64, error) {
//TODO implement me
panic("implement me")
ref, total, err := use.TagBinding.ListTagBinding(ctx, repository.TagBindingQueryParams{
ReferenceID: params.ReferenceID,
TagID: params.TagID,
PageIndex: params.PageIndex,
PageSize: params.PageSize,
})
if err != nil {
return nil, 0, errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "params", Value: params},
{Key: "func", Value: "TagBinding.ListTagBinding"},
{Key: "err", Value: err.Error()},
}, "failed to list tags")
}
result := make([]usecase.TagsBindingTableResp, 0, len(ref))
for _, bind := range ref {
result = append(result, usecase.TagsBindingTableResp{
ID: bind.ID.Hex(),
ReferenceID: bind.ReferenceID,
TagID: bind.TagID,
CreatedAt: utils.UnixToRfc3339(bind.CreatedAt),
UpdatedAt: utils.UnixToRfc3339(bind.UpdatedAt),
})
}
return result, total, nil
}
func logDBError(ctx context.Context, funcName string, fields []logx.LogField, err error, msg string) error {
return errs.DBErrorL(logx.WithContext(ctx), append(fields, logx.Field("func", funcName), logx.Field("err", err.Error())), msg)
}
func buildTagsBinding(referenceID string, tags []string) []*entity.TagsBindingTable {
binding := make([]*entity.TagsBindingTable, 0, len(tags))
for _, tag := range tags {
binding = append(binding, &entity.TagsBindingTable{
ReferenceID: referenceID,
TagID: tag,
})
}
return binding
}
func convertUseCaseToEntity(product *usecase.Product) *entity.Product {
insert := &entity.Product{}
if product.UID != nil {
insert.UID = *product.UID
}
if product.Title != nil {
insert.Title = *product.Title
}
if product.IsPublished != nil {
insert.IsPublished = *product.IsPublished
}
if product.Category != nil {
insert.Category = *product.Category
}
if product.ShortTitle != nil {
insert.ShortTitle = product.ShortTitle
}
if product.Details != nil {
insert.Details = product.Details
}
if product.ShortDescription != nil {
insert.ShortDescription = *product.ShortDescription
}
if product.Slug != nil {
insert.Slug = product.Slug
}
if product.Amount != 0 {
insert.Amount = product.Amount
}
if product.StartTime != nil {
st := utils.Rfc3339ToUnix(utils.ToValue(product.StartTime))
insert.StartTime = &st
}
if product.EndTime != nil {
et := utils.Rfc3339ToUnix(utils.ToValue(product.EndTime))
insert.EndTime = &et
}
if len(product.Media) > 0 {
medias := make([]entity.Media, 0, len(product.Media))
for _, m := range product.Media {
medias = append(medias, entity.Media{Sort: m.Sort, URL: m.URL, Type: m.Type})
}
insert.Media = medias
}
if len(product.CustomFields) > 0 {
cf := make([]entity.CustomFields, 0, len(product.CustomFields))
for _, field := range product.CustomFields {
cf = append(cf, entity.CustomFields{Key: field.Key, Value: field.Value})
}
insert.CustomFields = cf
}
return insert
}
func convertUseCaseToUpdateParams(product *usecase.Product) *repository.ProductUpdateParams {
update := &repository.ProductUpdateParams{}
if product.Title != nil {
update.Title = product.Title
}
if product.IsPublished != nil {
update.IsPublished = product.IsPublished
}
if product.Category != nil {
update.Category = product.Category
}
if product.ShortTitle != nil {
update.ShortTitle = product.ShortTitle
}
if product.Details != nil {
update.Details = product.Details
}
if product.ShortDescription != nil {
update.ShortDescription = *product.ShortDescription
}
if product.Slug != nil {
update.Slug = product.Slug
}
if product.Amount != 0 {
update.Amount = &product.Amount
}
if product.StartTime != nil {
st := utils.Rfc3339ToUnix(utils.ToValue(product.StartTime))
update.StartTime = &st
}
if product.EndTime != nil {
et := utils.Rfc3339ToUnix(utils.ToValue(product.EndTime))
update.EndTime = &et
}
if len(product.Media) > 0 {
medias := make([]entity.Media, 0, len(product.Media))
for _, m := range product.Media {
medias = append(medias, entity.Media{Sort: m.Sort, URL: m.URL, Type: m.Type})
}
update.Media = medias
}
if len(product.CustomFields) > 0 {
cf := make([]entity.CustomFields, 0, len(product.CustomFields))
for _, field := range product.CustomFields {
cf = append(cf, entity.CustomFields{Key: field.Key, Value: field.Value})
}
update.CustomFields = cf
}
return update
}
func convertEntityToResp(p *entity.Product, stats *entity.ProductStatistics, tags []*entity.Tags) *usecase.ProductResp {
tagsResp := make([]usecase.Tags, 0, len(tags))
for _, tag := range tags {
item := usecase.Tags{
ID: tag.ID.Hex(),
Types: tag.Types,
Name: tag.Name,
ShowType: tag.ShowType,
UpdatedAt: utils.UnixToRfc3339(tag.UpdatedAt),
CreatedAt: utils.UnixToRfc3339(tag.CreatedAt),
}
if tag.Cover != nil {
item.Cover = *tag.Cover
}
tagsResp = append(tagsResp, item)
}
media := make([]usecase.Media, 0, len(p.Media))
for _, m := range p.Media {
media = append(media, usecase.Media{Sort: m.Sort, URL: m.URL, Type: m.Type})
}
cf := make([]usecase.CustomFields, 0, len(p.CustomFields))
for _, field := range p.CustomFields {
cf = append(cf, usecase.CustomFields{Key: field.Key, Value: field.Value})
}
return &usecase.ProductResp{
ID: p.ID.Hex(),
UID: p.UID,
Title: p.Title,
ShortTitle: utils.ToValue(p.ShortTitle),
Details: utils.ToValue(p.Details),
ShortDescription: p.ShortDescription,
Slug: utils.ToValue(p.Slug),
IsPublished: p.IsPublished,
Amount: p.Amount,
StartTime: utils.UnixToRfc3339(utils.ToValue(p.StartTime)),
EndTime: utils.UnixToRfc3339(utils.ToValue(p.EndTime)),
Category: p.Category,
Media: media,
CustomFields: cf,
Tags: tagsResp,
Orders: stats.Orders,
OrdersUpdateTime: utils.UnixToRfc3339(stats.OrdersUpdateTime),
AverageRating: stats.AverageRating,
AverageRatingUpdateTime: utils.UnixToRfc3339(stats.AverageRatingUpdateTime),
FansCount: stats.FansCount,
FansCountUpdateTime: utils.UnixToRfc3339(stats.FansCountUpdateTime),
UpdatedAt: utils.UnixToRfc3339(p.UpdatedAt),
CreatedAt: utils.UnixToRfc3339(p.CreatedAt),
}
}