feat(t226): add Go ERP session login

This commit is contained in:
QiuSW
2026-07-29 09:51:41 +08:00
parent c2f340d067
commit a5a61c05d0
23 changed files with 1633 additions and 33 deletions
@@ -7,6 +7,7 @@ import (
"strings"
"cmroubao/backend-api/internal/domain"
"cmroubao/backend-api/internal/platform/shunyunbao"
"cmroubao/backend-api/internal/transport/authcommon"
"cmroubao/backend-api/internal/usecase"
)
@@ -19,6 +20,7 @@ type UsecaseAdapter struct {
authorizations *usecase.OrderAuthorizationService
freight *usecase.FreightService
procurement *usecase.ProcurementService
erp *shunyunbao.SessionManager
}
func (adapter *UsecaseAdapter) SetProcurement(
@@ -27,6 +29,65 @@ func (adapter *UsecaseAdapter) SetProcurement(
adapter.procurement = procurement
}
func (adapter *UsecaseAdapter) SetERPConnection(
manager *shunyunbao.SessionManager,
) {
adapter.erp = manager
}
func (adapter *UsecaseAdapter) ERPConnectionStatus(
context.Context,
) (ERPConnectionStatus, error) {
if adapter.erp == nil {
return ERPConnectionStatus{}, ErrUnavailable
}
return erpConnectionStatusFrom(adapter.erp.Status()), nil
}
func (adapter *UsecaseAdapter) RequestERPCaptcha(
ctx context.Context,
) (ERPConnectionStatus, error) {
if adapter.erp == nil {
return ERPConnectionStatus{}, ErrUnavailable
}
status, err := adapter.erp.FetchCaptcha(ctx)
if err != nil {
return erpConnectionStatusFrom(status), mapERPError(err)
}
return erpConnectionStatusFrom(status), nil
}
func (adapter *UsecaseAdapter) OpenERPCaptcha(
_ context.Context,
ticket string,
) (ERPCaptchaImage, error) {
if adapter.erp == nil {
return ERPCaptchaImage{}, ErrUnavailable
}
image, err := adapter.erp.OpenCaptcha(ticket)
if err != nil {
return ERPCaptchaImage{}, mapERPError(err)
}
return ERPCaptchaImage{
Content: image.Content,
ContentType: image.ContentType,
}, nil
}
func (adapter *UsecaseAdapter) LoginERP(
ctx context.Context,
input ERPLoginInput,
) (ERPConnectionStatus, error) {
if adapter.erp == nil {
return ERPConnectionStatus{}, ErrUnavailable
}
status, err := adapter.erp.Login(ctx, input.CaptchaTicket, input.CaptchaCode)
if err != nil {
return erpConnectionStatusFrom(status), mapERPError(err)
}
return erpConnectionStatusFrom(status), nil
}
func NewUsecaseAdapter(
tasks *usecase.TaskService,
assets *usecase.AssetService,
@@ -840,6 +901,38 @@ func mapUsecaseError(err error) error {
}
}
func mapERPError(err error) error {
var public error
switch {
case errors.Is(err, domain.ErrFreightSourceNotConfigured):
public = ErrERPNotConfigured
case errors.Is(err, domain.ErrFreightSourceSessionNeeded):
public = ErrERPSessionNeeded
case errors.Is(err, shunyunbao.ErrCaptchaTicketInvalid):
public = ErrERPCaptchaInvalid
case errors.Is(err, shunyunbao.ErrLoginRejected):
public = ErrERPLoginRejected
case errors.Is(err, domain.ErrFreightSourceProtocol):
public = ErrERPProtocol
case errors.Is(err, domain.ErrFreightSourceUnavailable):
public = ErrUnavailable
default:
return err
}
return &adapterError{public: public, cause: err}
}
func erpConnectionStatusFrom(
status shunyunbao.SessionStatus,
) ERPConnectionStatus {
return ERPConnectionStatus{
Configured: status.Configured,
Authenticated: status.Authenticated,
CaptchaReady: status.CaptchaReady,
CaptchaTicket: status.CaptchaTicket,
}
}
type adapterError struct {
public error
cause error
@@ -856,3 +949,4 @@ func (err *adapterError) Unwrap() []error {
var _ Service = (*UsecaseAdapter)(nil)
var _ FreightService = (*UsecaseAdapter)(nil)
var _ ProcurementService = (*UsecaseAdapter)(nil)
var _ ERPConnectionService = (*UsecaseAdapter)(nil)