关于绑定的问题
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled

This commit is contained in:
2026-06-22 12:08:41 +09:00
parent 5f960daf78
commit ba435dd6a6
13 changed files with 1306 additions and 210 deletions

View File

@@ -10,6 +10,7 @@ import (
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
customerBinding "github.com/break/junhong_cmp_fiber/internal/service/customer_binding"
"github.com/break/junhong_cmp_fiber/internal/service/verification"
wechatConfigSvc "github.com/break/junhong_cmp_fiber/internal/service/wechat_config"
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
@@ -41,7 +42,6 @@ type Service struct {
db *gorm.DB
openidStore *postgres.PersonalCustomerOpenIDStore
customerStore *postgres.PersonalCustomerStore
deviceBindStore *postgres.PersonalCustomerDeviceStore
phoneStore *postgres.PersonalCustomerPhoneStore
iotCardStore *postgres.IotCardStore
deviceStore *postgres.DeviceStore
@@ -51,6 +51,7 @@ type Service struct {
redis *redis.Client
logger *zap.Logger
wechatCache kernel.CacheInterface
customerBinding *customerBinding.Service
}
// New 创建 C 端认证服务实例
@@ -58,7 +59,6 @@ func New(
db *gorm.DB,
openidStore *postgres.PersonalCustomerOpenIDStore,
customerStore *postgres.PersonalCustomerStore,
deviceBindStore *postgres.PersonalCustomerDeviceStore,
phoneStore *postgres.PersonalCustomerPhoneStore,
iotCardStore *postgres.IotCardStore,
deviceStore *postgres.DeviceStore,
@@ -67,12 +67,12 @@ func New(
jwtManager *auth.JWTManager,
redisClient *redis.Client,
logger *zap.Logger,
binding *customerBinding.Service,
) *Service {
return &Service{
db: db,
openidStore: openidStore,
customerStore: customerStore,
deviceBindStore: deviceBindStore,
phoneStore: phoneStore,
iotCardStore: iotCardStore,
deviceStore: deviceStore,
@@ -82,6 +82,7 @@ func New(
redis: redisClient,
logger: logger,
wechatCache: wechat.NewRedisCache(redisClient),
customerBinding: binding,
}
}
@@ -630,99 +631,9 @@ func (s *Service) checkCardBoundToDevice(ctx context.Context, cardID uint) (bool
return !card.IsStandalone || card.DeviceVirtualNo != "", nil
}
// bindAsset 绑定客户与资产关系
// bindAsset 委托 CustomerBinding 模块处理客户与资产的绑定关系
func (s *Service) bindAsset(ctx context.Context, tx *gorm.DB, customerID uint, assetType string, assetID uint) error {
assetKey, err := s.resolveAssetBindingKey(ctx, tx, assetType, assetID)
if err != nil {
return err
}
var bindCount int64
if err := tx.WithContext(ctx).
Model(&model.PersonalCustomerDevice{}).
Where("virtual_no = ?", assetKey).
Count(&bindCount).Error; err != nil {
return errors.Wrap(errors.CodeInternalError, err, "查询资产绑定关系失败")
}
firstEverBind := bindCount == 0
bindStore := postgres.NewPersonalCustomerDeviceStore(tx)
exists, err := bindStore.ExistsByCustomerAndDevice(ctx, customerID, assetKey)
if err != nil {
return errors.Wrap(errors.CodeInternalError, err, "查询客户资产绑定关系失败")
}
if !exists {
record := &model.PersonalCustomerDevice{
CustomerID: customerID,
VirtualNo: assetKey,
Status: 1,
}
if err := bindStore.Create(ctx, record); err != nil {
return errors.Wrap(errors.CodeInternalError, err, "创建资产绑定关系失败")
}
}
if firstEverBind {
if err := s.markAssetAsSold(ctx, tx, assetType, assetID); err != nil {
return err
}
}
return nil
}
func (s *Service) resolveAssetBindingKey(ctx context.Context, tx *gorm.DB, assetType string, assetID uint) (string, error) {
if assetType == assetTypeIotCard {
var card model.IotCard
if err := tx.WithContext(ctx).First(&card, assetID).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return "", errors.New(errors.CodeAssetNotFound)
}
return "", errors.Wrap(errors.CodeInternalError, err, "查询卡资产失败")
}
return card.VirtualNo, nil
}
if assetType == assetTypeDevice {
var device model.Device
if err := tx.WithContext(ctx).First(&device, assetID).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return "", errors.New(errors.CodeAssetNotFound)
}
return "", errors.Wrap(errors.CodeInternalError, err, "查询设备资产失败")
}
if device.VirtualNo != "" {
return device.VirtualNo, nil
}
return device.IMEI, nil
}
return "", errors.New(errors.CodeInvalidParam)
}
func (s *Service) markAssetAsSold(ctx context.Context, tx *gorm.DB, assetType string, assetID uint) error {
if assetType == assetTypeIotCard {
if err := tx.WithContext(ctx).
Model(&model.IotCard{}).
Where("id = ? AND asset_status = ?", assetID, 1).
Update("asset_status", 2).Error; err != nil {
return errors.Wrap(errors.CodeInternalError, err, "更新卡资产状态失败")
}
return nil
}
if assetType == assetTypeDevice {
if err := tx.WithContext(ctx).
Model(&model.Device{}).
Where("id = ? AND asset_status = ?", assetID, 1).
Update("asset_status", 2).Error; err != nil {
return errors.Wrap(errors.CodeInternalError, err, "更新设备资产状态失败")
}
return nil
}
return errors.New(errors.CodeInvalidParam)
return s.customerBinding.Bind(ctx, tx, customerID, assetType, assetID)
}
func (s *Service) issueLoginToken(ctx context.Context, customerID uint, assetType string, assetID uint) (string, bool, error) {