feat: go lint

This commit is contained in:
王性驊 2025-04-06 10:08:46 +08:00
parent c4617956e5
commit 7951f4b98a
24 changed files with 151 additions and 70 deletions

View File

@ -3,4 +3,18 @@ syntax = "proto3";
package product;
option go_package="./product";
service Product {}
// OKResp
message OKResp {}
// NoneReq
message NoneReq {}
message CreateCategoryReq {
string name = 1;
}
service Product {
// CreateCategory product
rpc CreateCategory(CreateCategoryReq) returns(OKResp);
}

View File

@ -1,9 +1,10 @@
package repository
import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"context"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"go.mongodb.org/mongo-driver/mongo"
)

View File

@ -1,8 +1,9 @@
package repository
import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"context"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
)
// KYCKnow Your Customer

View File

@ -1,8 +1,9 @@
package usecase
import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"context"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
)
type CategoryUseCase interface {

View File

@ -1,8 +1,9 @@
package usecase
import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"context"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
)
type KYCUseCase interface {

View File

@ -1,16 +1,13 @@
package usecase
import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
"context"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
)
type ProductUseCase interface {
Create(ctx context.Context, product *Product) error
Update(ctx context.Context, id string, product *Product) error
Delete(ctx context.Context, id string) error
Get(ctx context.Context, id string) (*ProductResp, error)
List(ctx context.Context, data ProductQueryParams) ([]*ProductResp, int64, error)
Base
// IncOrders 新增訂單數
IncOrders(ctx context.Context, productID string, count int64) error
// DecOrders 減少訂單數。-> 退貨時專用
@ -30,6 +27,13 @@ type ProductUseCase interface {
// ListTagBinding 根據查詢條件取得 tag binding 的資料列表
ListTagBinding(ctx context.Context, params TagBindingQueryParams) ([]TagsBindingTableResp, int64, error)
}
type Base interface {
Create(ctx context.Context, product *Product) error
Update(ctx context.Context, id string, product *Product) error
Delete(ctx context.Context, id string) error
Get(ctx context.Context, id string) (*ProductResp, error)
List(ctx context.Context, data ProductQueryParams) ([]*ProductResp, int64, error)
}
type Product struct {
UID *string // 專案擁有者 UID

View File

@ -1,8 +1,9 @@
package usecase
import (
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
"context"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
)
type ProductItemUseCase interface {

View File

@ -1,9 +1,10 @@
package usecase
import (
"context"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
"context"
)
type ProductBaseTags interface {

View File

@ -1,12 +1,13 @@
package repository
import (
"context"
"errors"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain"
"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"
"errors"
"time"

View File

@ -1,19 +1,20 @@
package repository
import (
"context"
"fmt"
"testing"
"time"
"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"
"fmt"
"github.com/alicebob/miniredis/v2"
"github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/mon"
"github.com/zeromicro/go-zero/core/stores/redis"
"go.mongodb.org/mongo-driver/bson/primitive"
"testing"
"time"
)
func SetupTestCategoryRepository(db string) (repository.CategoryRepository, func(), error) {

View File

@ -1,18 +1,19 @@
package repository
import (
"context"
"errors"
"time"
"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"
"errors"
"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"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
type KYCRepositoryParam struct {
@ -60,15 +61,17 @@ func (repo *KYCRepository) Create(ctx context.Context, data *entity.KYC) error {
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 加入排序
opts := options.FindOne().SetSort(bson.D{{Key: "created_at", Value: -1}}) // 用 SetSort 加入排序
err := repo.DB.GetClient().FindOne(ctx, &result, filter, opts)
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
return nil, ErrNotFound
}
return nil, err
}
return &result, nil
}
@ -83,6 +86,7 @@ func (repo *KYCRepository) FindByID(ctx context.Context, id string) (*entity.KYC
if err != nil {
return nil, err
}
return &result, nil
}
@ -97,15 +101,14 @@ func (repo *KYCRepository) List(ctx context.Context, params repository.KYCQueryP
if params.Status != nil {
filter["status"] = *params.Status
}
sort := bson.D{}
if params.SortByDate {
sort = append(sort, bson.E{Key: "created_at", Value: -1})
}
// 設置排序選項
opts := options.Find().SetSkip((params.PageIndex - 1) * params.PageSize).SetLimit(params.PageSize)
opts.SetSort(bson.D{{Key: "updated_at", Value: -1}})
if params.SortByDate {
opts.SetSort(bson.E{Key: "created_at", Value: -1})
} else {
opts.SetSort(bson.D{{Key: "updated_at", Value: -1}})
}
// 查詢符合條件的總數
total, err := repo.DB.GetClient().CountDocuments(ctx, filter)
if err != nil {
@ -136,6 +139,7 @@ func (repo *KYCRepository) UpdateStatus(ctx context.Context, id string, status s
},
}
_, err = repo.DB.GetClient().UpdateOne(ctx, filter, update)
return err
}
@ -194,5 +198,6 @@ func (repo *KYCRepository) UpdateKYCInfo(ctx context.Context, id string, update
filter := bson.M{"_id": oid, "status": "PENDING"} // 僅允許更新尚未審核的
updateDoc := bson.M{"$set": setFields}
_, err = repo.DB.GetClient().UpdateOne(ctx, filter, updateDoc)
return err
}

View File

@ -1,20 +1,21 @@
package repository
import (
"context"
"fmt"
"testing"
"time"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/kyc"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
mgo "code.30cm.net/digimon/library-go/mongo"
"context"
"fmt"
"github.com/alicebob/miniredis/v2"
"github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/mon"
"github.com/zeromicro/go-zero/core/stores/redis"
"go.mongodb.org/mongo-driver/bson/primitive"
"testing"
"time"
)
func SetupTestKYCRepository(db string) (repository.KYCRepository, func(), error) {

View File

@ -1,13 +1,16 @@
package repository
import (
"context"
"errors"
"fmt"
"testing"
"time"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
mgo "code.30cm.net/digimon/library-go/mongo"
"context"
"errors"
"fmt"
"github.com/alicebob/miniredis/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -15,8 +18,6 @@ import (
"github.com/zeromicro/go-zero/core/stores/mon"
"github.com/zeromicro/go-zero/core/stores/redis"
"go.mongodb.org/mongo-driver/bson/primitive"
"testing"
"time"
)
func SetupTestProductTagsRepo(db string) (repository.TagRepo, func(), error) {

View File

@ -1,12 +1,13 @@
package usecase
import (
"context"
"errors"
"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"
"code.30cm.net/digimon/library-go/errs"
"context"
"errors"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/mon"
)

View File

@ -1,18 +1,19 @@
package usecase
import (
"context"
"errors"
"testing"
"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"
"code.30cm.net/digimon/library-go/errs"
"context"
"errors"
"github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/mon"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.uber.org/mock/gomock"
"testing"
mockRepository "code.30cm.net/digimon/app-cloudep-product-service/pkg/mock/repository"
)

View File

@ -1,15 +1,16 @@
package usecase
import (
"context"
"errors"
"fmt"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/kyc"
"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/library-go/errs"
"context"
"errors"
"fmt"
"github.com/zeromicro/go-zero/core/logx"
)

View File

@ -1,6 +1,11 @@
package usecase
import (
"context"
"errors"
"fmt"
"testing"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/kyc"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
@ -8,15 +13,11 @@ import (
mockRepository "code.30cm.net/digimon/app-cloudep-product-service/pkg/mock/repository"
repo "code.30cm.net/digimon/app-cloudep-product-service/pkg/repository"
"code.30cm.net/digimon/library-go/errs"
"context"
"errors"
"fmt"
"github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/core/logx"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.uber.org/mock/gomock"
"google.golang.org/protobuf/proto"
"testing"
)
func TestKYCUseCase_Create(t *testing.T) {

View File

@ -1,14 +1,15 @@
package usecase
import (
"context"
"errors"
"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"
@ -36,6 +37,7 @@ func (use *ProductUseCase) Create(ctx context.Context, product *usecase.Product)
insert := convertUseCaseToEntity(product)
// Transaction 設定:只做必要寫入
opts := options.Transaction().SetReadConcern(readconcern.Local())
//nolint:contextcheck
err := use.ProductRepo.Transaction(ctx, func(sessCtx mongo.SessionContext) (any, error) {
if err := use.ProductRepo.Insert(sessCtx, insert); err != nil {
return nil, logDBError(ctx, "ProductRepo.Insert", []logx.LogField{{Key: "req", Value: product}}, err, "failed to create product")
@ -58,7 +60,7 @@ func (use *ProductUseCase) Create(ctx context.Context, product *usecase.Product)
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
return struct{}{}, nil
}, opts)
if err != nil {
@ -73,18 +75,21 @@ func (use *ProductUseCase) Update(ctx context.Context, id string, product *useca
tagsBinding := buildTagsBinding(id, product.Tags)
opts := options.Transaction().SetReadConcern(readconcern.Local())
err := use.ProductRepo.Transaction(ctx, func(sessCtx mongo.SessionContext) (any, error) {
//nolint:contextcheck
_, err := use.ProductRepo.Update(sessCtx, id, update)
if err != nil {
return nil, logDBError(ctx, "ProductRepo.Update", []logx.LogField{{Key: "req", Value: product}}, err, "failed to update product")
}
//nolint:contextcheck
if err := use.TagBinding.UnbindTagByReferenceID(sessCtx, id); err != nil {
return nil, logDBError(ctx, "TagBinding.UnbindTagByReferenceID", []logx.LogField{{Key: "ReferenceID", Value: id}}, err, "failed to unbind tags")
}
//nolint:contextcheck
if err := use.TagBinding.BindTags(sessCtx, tagsBinding); err != nil {
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
return struct{}{}, nil
}, opts)
return err
@ -94,6 +99,7 @@ func (use *ProductUseCase) Delete(ctx context.Context, id string) error {
// Transaction 設定:只做必要寫入
opts := options.Transaction().SetReadConcern(readconcern.Local())
err := use.ProductRepo.Transaction(ctx, func(sessCtx mongo.SessionContext) (any, error) {
//nolint:contextcheck
err := use.ProductRepo.Delete(sessCtx, id)
if err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
@ -105,7 +111,7 @@ func (use *ProductUseCase) Delete(ctx context.Context, id string) error {
return nil, e
}
//nolint:contextcheck
err = use.TagRepo.UnbindTagByReferenceID(sessCtx, id)
if err != nil {
e := errs.DBErrorL(logx.WithContext(ctx),
@ -118,7 +124,7 @@ func (use *ProductUseCase) Delete(ctx context.Context, id string) error {
return nil, e
}
return nil, nil
return struct{}{}, nil
}, opts)
if err != nil {
return err
@ -465,6 +471,7 @@ func buildTagsBinding(referenceID string, tags []string) []*entity.TagsBindingTa
TagID: tag,
})
}
return binding
}
@ -571,6 +578,7 @@ func convertUseCaseToUpdateParams(product *usecase.Product) *repository.ProductU
}
update.CustomFields = cf
}
return update
}

View File

@ -1,13 +1,15 @@
package usecase
import (
"context"
"math"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/usecase"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/utils"
"code.30cm.net/digimon/library-go/errs"
"context"
"github.com/shopspring/decimal"
"github.com/zeromicro/go-zero/core/logx"
)
@ -36,6 +38,7 @@ func toEntity(u *usecase.ProductItems) (entity.ProductItems, error) {
if err != nil {
return entity.ProductItems{}, err
}
return entity.ProductItems{
// ID 在新增時通常由資料庫自動產生
ReferenceID: u.ReferenceID,
@ -89,6 +92,7 @@ func convertMediaToEntity(meds []usecase.Media) []entity.Media {
URL: m.URL,
}
}
return res
}
@ -102,6 +106,7 @@ func convertEntityMedia(meds []entity.Media) []usecase.Media {
URL: m.URL,
}
}
return res
}
@ -114,6 +119,7 @@ func convertCustomFieldsToEntity(cfs []usecase.CustomFields) []entity.CustomFiel
Value: cf.Value,
}
}
return res
}
@ -126,6 +132,7 @@ func convertEntityCustomFields(cfs []entity.CustomFields) []usecase.CustomFields
Value: cf.Value,
}
}
return res
}
@ -166,6 +173,7 @@ func (use *ProductItemUseCase) Get(ctx context.Context, id string) (*usecase.Pro
{Key: "err", Value: err.Error()},
}, "failed to create product items")
}
return fromEntity(ent), nil
}
@ -188,6 +196,13 @@ func (use *ProductItemUseCase) Update(ctx context.Context, id string, data *usec
update.IsFree = data.IsFree
}
if data.Stock != nil {
if *data.Stock > math.MaxInt64 {
return errs.InvalidFormatL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "id", Value: id},
{Key: "data.Stock ", Value: *data.Stock},
}, "data.Stock too large to convert to int64")
}
// data.Stock 為 *uint64需先解引用再轉換為 int64
s := int64(*data.Stock)
update.Stock = &s
@ -245,6 +260,13 @@ func (use *ProductItemUseCase) UpdateStatus(ctx context.Context, id string, stat
}
func (use *ProductItemUseCase) IncSalesCount(ctx context.Context, id string, saleCount uint64) error {
if saleCount > math.MaxInt64 {
return errs.InvalidFormatL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "id", Value: id},
{Key: "saleCount", Value: saleCount},
}, "saleCount too large to convert to int64")
}
// repository 方法使用 int64故需轉型
if err := use.ProductItemUseCaseParam.ProductItems.IncSalesCount(ctx, id, int64(saleCount)); err != nil {
return errs.DBErrorL(logx.WithContext(ctx),
@ -260,7 +282,14 @@ func (use *ProductItemUseCase) IncSalesCount(ctx context.Context, id string, sal
}
func (use *ProductItemUseCase) DecSalesCount(ctx context.Context, id string, saleCount uint64) error {
// repository 方法使用 int64故需轉型
if saleCount > math.MaxInt64 {
return errs.InvalidFormatL(logx.WithContext(ctx),
[]logx.LogField{
{Key: "id", Value: id},
{Key: "saleCount", Value: saleCount},
}, "saleCount too large to convert to int64")
}
if err := use.ProductItemUseCaseParam.ProductItems.DecSalesCount(ctx, id, int64(saleCount)); err != nil {
return errs.DBErrorL(logx.WithContext(ctx),
[]logx.LogField{
@ -306,10 +335,11 @@ func (use *ProductItemUseCase) List(ctx context.Context, filter usecase.QueryPro
{Key: "err", Value: err.Error()},
}, "failed to list product item")
}
var result []*usecase.ProductItems
result := make([]*usecase.ProductItems, 0, len(entities))
for i := range entities {
// 逐筆轉換 entity -> usecase 型別
result = append(result, fromEntity(&entities[i]))
}
return result, total, nil
}

View File

@ -1,18 +1,19 @@
package usecase
import (
"context"
"errors"
"testing"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/usecase"
mockRepository "code.30cm.net/digimon/app-cloudep-product-service/pkg/mock/repository"
"context"
"errors"
"github.com/shopspring/decimal"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.uber.org/mock/gomock"
"testing"
)
func TestProductItemUseCase_Create(t *testing.T) {

View File

@ -1,20 +1,21 @@
package usecase
import (
"context"
"errors"
"testing"
"time"
"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"
mockRepository "code.30cm.net/digimon/app-cloudep-product-service/pkg/mock/repository"
repo "code.30cm.net/digimon/app-cloudep-product-service/pkg/repository"
"context"
"errors"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.uber.org/mock/gomock"
"testing"
"time"
)
func TestProductUseCase_Create(t *testing.T) {

View File

@ -1,11 +1,12 @@
package usecase
import (
"context"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
repo "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/usecase"
"code.30cm.net/digimon/library-go/errs"
"context"
"github.com/zeromicro/go-zero/core/logx"
)

View File

@ -1,17 +1,18 @@
package usecase
import (
"context"
"errors"
"testing"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/product"
repo "code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/repository"
"code.30cm.net/digimon/app-cloudep-product-service/pkg/domain/usecase"
mockRepository "code.30cm.net/digimon/app-cloudep-product-service/pkg/mock/repository"
"context"
"errors"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.uber.org/mock/gomock"
"testing"
)
func TestTagsUseCase_Create(t *testing.T) {

View File

@ -22,7 +22,9 @@ func Rfc3339ToUnix(rfc3339 string) int64 {
func ToValue[T any](ptr *T) T {
if ptr == nil {
var zero T
return zero
}
return *ptr
}