核心改造: 1. Wallet模块DTO层全部改为*Cent int64字段 2. Wallet.Entry结构从Amount float64改为AmountCent int64 3. Repository层applyEntry函数使用整数加减,无需浮点运算 4. Withdrawal模块DTO/Request全部改为*Cent字段 5. 所有wallet.AppendEntries调用点改为AmountCent 6. 提现手续费计算改为分单位 技术细节: - 删除了roundWalletMoney函数(不再需要) - toAccountDTO/toLedgerDTO使用*Cent字段 - 最小提现金额:10元=1000分 - 最大提现金额:5000元=500000分 - 编译验证通过 ✅ Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
108 lines
2.8 KiB
Go
108 lines
2.8 KiB
Go
package withdrawal
|
||
|
||
import "errors"
|
||
|
||
var (
|
||
ErrDependencyUnavailable = errors.New("dependency unavailable")
|
||
ErrWithdrawalNotFound = errors.New("withdrawal not found")
|
||
ErrInvalidAmount = errors.New("invalid amount")
|
||
ErrInsufficientBalance = errors.New("insufficient balance")
|
||
ErrMinWithdrawalAmount = errors.New("amount below minimum withdrawal")
|
||
ErrMaxWithdrawalAmount = errors.New("amount exceeds maximum withdrawal")
|
||
ErrWithdrawalLocked = errors.New("withdrawal status locked")
|
||
ErrUnauthorized = errors.New("unauthorized")
|
||
)
|
||
|
||
const (
|
||
MinWithdrawalAmountCent = 1000 // 最低提现金额:10元 = 1000分
|
||
MaxWithdrawalAmountCent = 500000 // 单笔最高提现金额:5000元 = 500000分
|
||
WithdrawalFeeRate = 0.0 // 手续费率(暂时0%)
|
||
)
|
||
|
||
type Service struct {
|
||
repo *Repository
|
||
}
|
||
|
||
func NewService(repo *Repository) *Service {
|
||
return &Service{repo: repo}
|
||
}
|
||
|
||
// 用户端方法
|
||
func (s *Service) Create(userID uint64, req CreateWithdrawalRequest) (*WithdrawalDTO, error) {
|
||
if s.repo == nil {
|
||
return nil, ErrDependencyUnavailable
|
||
}
|
||
|
||
// 验证金额
|
||
if req.AmountCent < MinWithdrawalAmountCent {
|
||
return nil, ErrMinWithdrawalAmount
|
||
}
|
||
if req.AmountCent > MaxWithdrawalAmountCent {
|
||
return nil, ErrMaxWithdrawalAmount
|
||
}
|
||
|
||
return s.repo.Create(userID, req)
|
||
}
|
||
|
||
func (s *Service) List(userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
||
if s.repo == nil {
|
||
return nil, ErrDependencyUnavailable
|
||
}
|
||
if page < 1 {
|
||
page = 1
|
||
}
|
||
if pageSize < 1 || pageSize > 100 {
|
||
pageSize = 20
|
||
}
|
||
return s.repo.List(userID, page, pageSize)
|
||
}
|
||
|
||
func (s *Service) FindByID(userID, id uint64) (*WithdrawalDTO, error) {
|
||
if s.repo == nil {
|
||
return nil, ErrDependencyUnavailable
|
||
}
|
||
return s.repo.FindByID(userID, id)
|
||
}
|
||
|
||
func (s *Service) Cancel(userID, id uint64) error {
|
||
if s.repo == nil {
|
||
return ErrDependencyUnavailable
|
||
}
|
||
return s.repo.Cancel(userID, id)
|
||
}
|
||
|
||
// 管理员端方法
|
||
func (s *Service) AdminList(query AdminListQuery) (*AdminPaginatedResult, error) {
|
||
if s.repo == nil {
|
||
return nil, ErrDependencyUnavailable
|
||
}
|
||
if query.Page < 1 {
|
||
query.Page = 1
|
||
}
|
||
if query.Size < 1 || query.Size > 100 {
|
||
query.Size = 20
|
||
}
|
||
return s.repo.AdminList(query)
|
||
}
|
||
|
||
func (s *Service) AdminFindByID(id uint64) (*WithdrawalDetailDTO, error) {
|
||
if s.repo == nil {
|
||
return nil, ErrDependencyUnavailable
|
||
}
|
||
return s.repo.AdminFindByID(id)
|
||
}
|
||
|
||
func (s *Service) Review(adminID, id uint64, req ReviewWithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||
if s.repo == nil {
|
||
return nil, ErrDependencyUnavailable
|
||
}
|
||
return s.repo.Review(adminID, id, req)
|
||
}
|
||
|
||
func (s *Service) ConfirmPayment(adminID, id uint64, req ConfirmPaymentRequest) (*WithdrawalDetailDTO, error) {
|
||
if s.repo == nil {
|
||
return nil, ErrDependencyUnavailable
|
||
}
|
||
return s.repo.ConfirmPayment(adminID, id, req)
|
||
}
|