feat(员工代收款): 新增员工代收款账单闭环
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m20s

- 新增 6 张表与成对迁移 000212,扩展企业微信审批场景业务类型白名单
- 后台线下套餐订单与两条代理线下充值入账路径在来源成功事务内建账,来源唯一键幂等
- 核销申请、审批尝试记录、账单分摊预占与驳回重提,审批业务类型 employee_collection_approval
- 企业微信终态消费幂等:通过转已核销、驳回释放预占、通过后撤销不回滚并转异常终态
- 退款成功事务内按 bill_id+refund_id 幂等冲销账单或仅写退款关联提示
- 线下收款方式字典、账单查询/统计/关闭、申请查询与代办权限,均写入事务内审计

OpenSpec Change: add-employee-collection-bills
This commit is contained in:
2026-09-10 18:24:05 +08:00
parent dc4e0d4103
commit ce24d5612e
54 changed files with 5975 additions and 465 deletions

View File

@@ -9,6 +9,7 @@ import (
"gorm.io/gorm/clause"
approvalapp "github.com/break/junhong_cmp_fiber/internal/application/approval"
employeecollectionapp "github.com/break/junhong_cmp_fiber/internal/application/employeecollection"
"github.com/break/junhong_cmp_fiber/internal/infrastructure/commissiondelivery"
"github.com/break/junhong_cmp_fiber/internal/infrastructure/messaging/outbox"
"github.com/break/junhong_cmp_fiber/internal/model"
@@ -101,6 +102,16 @@ func (s *Service) applyApprovedDecision(ctx context.Context, event approvalapp.T
if err := s.refundWalletPayment(ctx, tx, &refund, &order, approvedAmount, event.SubmitterAccountID); err != nil {
return err
}
// 员工代收款冲销:接入点只在既有退款成功事务内,以 bill_id+refund_id 唯一事实幂等,
// 不依赖下方 changed 门;来源订单未建账时直接跳过,不阻断退款。
if s.refundOffset == nil {
return errors.New(errors.CodeInternalError, "员工代收款退款冲销能力未配置")
}
if err := s.refundOffset.ApplyInTx(ctx, tx, employeecollectionapp.RefundOffsetSource{
RefundID: refund.ID, OrderID: order.ID, RefundAmount: approvedAmount,
}); err != nil {
return err
}
if err := s.appendCompletedNotification(ctx, tx, &refund); err != nil {
return err
}

View File

@@ -15,6 +15,7 @@ import (
"gorm.io/gorm"
"gorm.io/gorm/clause"
employeecollectionapp "github.com/break/junhong_cmp_fiber/internal/application/employeecollection"
merchantpayment "github.com/break/junhong_cmp_fiber/internal/application/merchantpayment"
notificationapp "github.com/break/junhong_cmp_fiber/internal/application/notification"
refundapprovalapp "github.com/break/junhong_cmp_fiber/internal/application/refundapproval"
@@ -58,6 +59,12 @@ type Service struct {
auditWriter *audit.Writer
logger *zap.Logger
paymentMerchantRuntime *merchantpayment.RuntimeLoader
refundOffset *employeecollectionapp.RefundOffsetService
}
// SetEmployeeCollectionRefundOffset 注入员工代收款账单退款冲销用例。
func (s *Service) SetEmployeeCollectionRefundOffset(offset *employeecollectionapp.RefundOffsetService) {
s.refundOffset = offset
}
// New 创建退款业务服务实例