优化结构
This commit is contained in:
parent
279692375b
commit
e997d9718e
|
|
@ -388,12 +388,8 @@ func NewPaymentUsecase(repo PaymentRepo, orders PaymentOrderRepo, hooks PaymentH
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfiguredPaymentUsecase(repo PaymentRepo, orders PaymentOrderRepo, hooks PaymentHooks, sources *PaymentOrderSourceRegistry, fulfillments *PaymentFulfillmentRegistry, appLogger *slog.Logger) (*PaymentUsecase, error) {
|
func NewConfiguredPaymentUsecase(repo PaymentRepo, orders PaymentOrderRepo, hooks PaymentHooks, sources *PaymentOrderSourceRegistry, fulfillments *PaymentFulfillmentRegistry, appLogger *slog.Logger) (*PaymentUsecase, error) {
|
||||||
if sources == nil || sources.Len() == 0 {
|
// Business modules are optional in the template. Missing modules are
|
||||||
return nil, errors.New("支付业务订单来源未注册,无法启动支付服务")
|
// reported when the corresponding payment operation is invoked.
|
||||||
}
|
|
||||||
if fulfillments == nil || fulfillments.Len() == 0 {
|
|
||||||
return nil, errors.New("支付发货 handler 未注册,无法启动支付服务")
|
|
||||||
}
|
|
||||||
return NewPaymentUsecase(repo, orders, hooks, sources, fulfillments, appLogger), nil
|
return NewPaymentUsecase(repo, orders, hooks, sources, fulfillments, appLogger), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -924,8 +920,6 @@ func (uc *PaymentUsecase) refundWithOrder(ctx context.Context, provider, tradeNo
|
||||||
message := ""
|
message := ""
|
||||||
if providerErr != nil {
|
if providerErr != nil {
|
||||||
message = providerErr.Error()
|
message = providerErr.Error()
|
||||||
} else if !accepted {
|
|
||||||
message = "支付平台未接受退款请求"
|
|
||||||
}
|
}
|
||||||
order, err = uc.orders.CompletePaymentRefundRequest(ctx, provider, tradeNo, token, accepted, message)
|
order, err = uc.orders.CompletePaymentRefundRequest(ctx, provider, tradeNo, token, accepted, message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,6 @@ type ErrorRecord struct {
|
||||||
type AuditRecordRepo interface {
|
type AuditRecordRepo interface {
|
||||||
RecordOperation(context.Context, *OperationRecord) error
|
RecordOperation(context.Context, *OperationRecord) error
|
||||||
RecordLogin(context.Context, *LoginLog) error
|
RecordLogin(context.Context, *LoginLog) error
|
||||||
RecordDataAccess(context.Context, *DataAccessLog) error
|
|
||||||
CreateError(context.Context, *ErrorRecord) error
|
CreateError(context.Context, *ErrorRecord) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,10 @@ func (uc *MediaUsecase) CompleteUpload(ctx context.Context, userID, uploadID uin
|
||||||
return nil, value
|
return nil, value
|
||||||
}
|
}
|
||||||
chunks, err := uc.ListChunks(ctx, uploadID)
|
chunks, err := uc.ListChunks(ctx, uploadID)
|
||||||
if err != nil || len(chunks) != session.ChunkTotal {
|
if err != nil {
|
||||||
|
return fail(err)
|
||||||
|
}
|
||||||
|
if len(chunks) != session.ChunkTotal {
|
||||||
return fail(fmt.Errorf("分片不全: %d/%d", len(chunks), session.ChunkTotal))
|
return fail(fmt.Errorf("分片不全: %d/%d", len(chunks), session.ChunkTotal))
|
||||||
}
|
}
|
||||||
sort.Slice(chunks, func(i, j int) bool { return chunks[i].Index < chunks[j].Index })
|
sort.Slice(chunks, func(i, j int) bool { return chunks[i].Index < chunks[j].Index })
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,22 @@ func MergeRuntimeConfig(current, next *Config) *Config {
|
||||||
}
|
}
|
||||||
if merged.Data == nil {
|
if merged.Data == nil {
|
||||||
merged.Data = cloneData(current.Data)
|
merged.Data = cloneData(current.Data)
|
||||||
|
} else if current.Data != nil {
|
||||||
|
if merged.Data.Database == nil {
|
||||||
|
merged.Data.Database = clonePtr(current.Data.Database)
|
||||||
|
}
|
||||||
|
if merged.Data.Redis == nil {
|
||||||
|
merged.Data.Redis = cloneRedis(current.Data.Redis)
|
||||||
|
}
|
||||||
|
if merged.Data.Mongo == nil {
|
||||||
|
merged.Data.Mongo = cloneMongo(current.Data.Mongo)
|
||||||
|
}
|
||||||
|
if merged.Data.DatabaseList == nil {
|
||||||
|
merged.Data.DatabaseList = cloneSlice(current.Data.DatabaseList, clonePtr)
|
||||||
|
}
|
||||||
|
if merged.Data.RedisList == nil {
|
||||||
|
merged.Data.RedisList = cloneSlice(current.Data.RedisList, cloneRedis)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if merged.Admin == nil {
|
if merged.Admin == nil {
|
||||||
merged.Admin = cloneAdmin(current.Admin)
|
merged.Admin = cloneAdmin(current.Admin)
|
||||||
|
|
|
||||||
|
|
@ -168,3 +168,12 @@ func TestMergeRuntimeConfigPreservesOmittedSections(t *testing.T) {
|
||||||
t.Fatal("MergeRuntimeConfig leaked mutable storage state into current config")
|
t.Fatal("MergeRuntimeConfig leaked mutable storage state into current config")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMergeRuntimeConfigPreservesOmittedNestedDataSections(t *testing.T) {
|
||||||
|
current := &Config{Data: &Data{Database: &Database{Source: "current-dsn"}}}
|
||||||
|
next := &Config{Data: &Data{}}
|
||||||
|
merged := MergeRuntimeConfig(current, next)
|
||||||
|
if merged.Data == nil || merged.Data.Database == nil || merged.Data.Database.Source != "current-dsn" {
|
||||||
|
t.Fatalf("nested database section was not preserved: %#v", merged.Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ package integration
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"kra/internal/integration/runtimeconfig"
|
"kra/internal/integration/runtimeconfig"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Provider is the minimal database/runtime seam for integration configuration.
|
// Provider is the minimal database/runtime seam for integration configuration.
|
||||||
|
|
@ -10,3 +12,5 @@ type Provider interface {
|
||||||
DB() *gorm.DB
|
DB() *gorm.DB
|
||||||
IntegrationRuntime() *runtimeconfig.Store
|
IntegrationRuntime() *runtimeconfig.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ProviderSet = wire.NewSet(NewIntegrationConfigRepo, NewPaymentConfigReader)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package integration
|
|
||||||
|
|
||||||
import "github.com/google/wire"
|
|
||||||
|
|
||||||
var ProviderSet = wire.NewSet(NewIntegrationConfigRepo, NewPaymentConfigReader)
|
|
||||||
|
|
@ -424,15 +424,15 @@ func paymentCreateRequiresNotifyURL(provider string, extra, config map[string]an
|
||||||
normalized := strings.NewReplacer(".", "_", "-", "_", " ", "_").Replace(strings.ToLower(strings.TrimSpace(value)))
|
normalized := strings.NewReplacer(".", "_", "-", "_", " ", "_").Replace(strings.ToLower(strings.TrimSpace(value)))
|
||||||
switch provider {
|
switch provider {
|
||||||
case bizpayment.PaymentAlipay, bizpayment.PaymentAlipayV3:
|
case bizpayment.PaymentAlipay, bizpayment.PaymentAlipayV3:
|
||||||
return !contains([]string{"pay", "trade_pay", "alipay_trade_pay", "barcode", "barcode_pay", "micropay", "face_to_face"}, normalized)
|
return !paymentkit.ContainsFold([]string{"pay", "trade_pay", "alipay_trade_pay", "barcode", "barcode_pay", "micropay", "face_to_face"}, normalized)
|
||||||
case bizpayment.PaymentWechatV2:
|
case bizpayment.PaymentWechatV2:
|
||||||
return !contains([]string{"micropay", "micro_pay", "barcode", "barcode_pay", "pay_code", "payment_code"}, normalized)
|
return !paymentkit.ContainsFold([]string{"micropay", "micro_pay", "barcode", "barcode_pay", "pay_code", "payment_code"}, normalized)
|
||||||
case bizpayment.PaymentWechatV3:
|
case bizpayment.PaymentWechatV3:
|
||||||
return !contains([]string{"micropay", "micro_pay", "codepay", "code_pay", "barcode", "barcode_pay", "facepay", "face_pay"}, normalized)
|
return !paymentkit.ContainsFold([]string{"micropay", "micro_pay", "codepay", "code_pay", "barcode", "barcode_pay", "facepay", "face_pay"}, normalized)
|
||||||
case bizpayment.PaymentQQ:
|
case bizpayment.PaymentQQ:
|
||||||
return !contains([]string{"micropay", "micro_pay", "barcode", "barcode_pay"}, normalized)
|
return !paymentkit.ContainsFold([]string{"micropay", "micro_pay", "barcode", "barcode_pay"}, normalized)
|
||||||
case bizpayment.PaymentLakala:
|
case bizpayment.PaymentLakala:
|
||||||
return !contains([]string{"retail", "retail_pay", "micropay", "barcode"}, normalized)
|
return !paymentkit.ContainsFold([]string{"retail", "retail_pay", "micropay", "barcode"}, normalized)
|
||||||
default:
|
default:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -516,12 +516,3 @@ func paymentCallbackAck(provider string, values map[string]any, success bool) bi
|
||||||
}
|
}
|
||||||
return ack
|
return ack
|
||||||
}
|
}
|
||||||
|
|
||||||
func contains(values []string, value string) bool {
|
|
||||||
for _, item := range values {
|
|
||||||
if item == value {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,16 @@
|
||||||
package payment
|
package payment
|
||||||
|
|
||||||
import "gorm.io/gorm"
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
// Provider is the narrow persistence seam required by payment repositories.
|
// Provider is the narrow persistence seam required by payment repositories.
|
||||||
// Keeping it here lets payment remain an independent data module.
|
// Keeping it here lets payment remain an independent data module.
|
||||||
type Provider interface {
|
type Provider interface {
|
||||||
DB() *gorm.DB
|
DB() *gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProviderSet wires payment persistence repositories.
|
||||||
|
var ProviderSet = wire.NewSet(NewPaymentRepo, NewPaymentOrderRepo)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package payment
|
|
||||||
|
|
||||||
import "github.com/google/wire"
|
|
||||||
|
|
||||||
// ProviderSet wires payment persistence repositories.
|
|
||||||
var ProviderSet = wire.NewSet(NewPaymentRepo, NewPaymentOrderRepo)
|
|
||||||
|
|
@ -71,7 +71,7 @@ func (r *announcementRepo) List(ctx context.Context, filter system.AnnouncementF
|
||||||
if filter.StartCreatedAt != nil && filter.EndCreatedAt != nil {
|
if filter.StartCreatedAt != nil && filter.EndCreatedAt != nil {
|
||||||
db = db.Where("created_at BETWEEN ? AND ?", filter.StartCreatedAt, filter.EndCreatedAt)
|
db = db.Where("created_at BETWEEN ? AND ?", filter.StartCreatedAt, filter.EndCreatedAt)
|
||||||
}
|
}
|
||||||
return listRows(db, filter.Page, filter.PageSize, filter.PageSize > 0, func(po announcementPO) *system.Announcement {
|
return listRows(db.Order("id desc"), filter.Page, filter.PageSize, filter.PageSize > 0, func(po announcementPO) *system.Announcement {
|
||||||
return announcementToBiz(po)
|
return announcementToBiz(po)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,10 @@ type DataAccessLogPO struct {
|
||||||
|
|
||||||
func (DataAccessLogPO) TableName() string { return "sys_data_access_logs" }
|
func (DataAccessLogPO) TableName() string { return "sys_data_access_logs" }
|
||||||
|
|
||||||
func (r *auditRecorderRepo) RecordDataAccess(ctx context.Context, v *system.DataAccessLog) error {
|
|
||||||
return r.data.DB().WithContext(ctx).Create(&DataAccessLogPO{EventType: v.EventType, TargetTable: v.TargetTable, Operation: v.Operation, UserID: v.UserID, AuthorityID: v.AuthorityID, Scope: v.Scope, RequestID: v.RequestID, Method: v.Method, Path: v.Path, Detail: v.Detail}).Error
|
|
||||||
}
|
|
||||||
func dataAccessFromPO(v DataAccessLogPO) *system.DataAccessLog {
|
func dataAccessFromPO(v DataAccessLogPO) *system.DataAccessLog {
|
||||||
return &system.DataAccessLog{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, EventType: v.EventType, TargetTable: v.TargetTable, Operation: v.Operation, UserID: v.UserID, AuthorityID: v.AuthorityID, Scope: v.Scope, RequestID: v.RequestID, Method: v.Method, Path: v.Path, Detail: v.Detail}
|
return &system.DataAccessLog{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, EventType: v.EventType, TargetTable: v.TargetTable, Operation: v.Operation, UserID: v.UserID, AuthorityID: v.AuthorityID, Scope: v.Scope, RequestID: v.RequestID, Method: v.Method, Path: v.Path, Detail: v.Detail}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *auditQueryRepo) ListDataAccess(ctx context.Context, page, size int, q *system.DataAccessLog) ([]*system.DataAccessLog, int64, error) {
|
func (r *auditQueryRepo) ListDataAccess(ctx context.Context, page, size int, q *system.DataAccessLog) ([]*system.DataAccessLog, int64, error) {
|
||||||
db := r.data.DB().WithContext(ctx).Model(&DataAccessLogPO{})
|
db := r.data.DB().WithContext(ctx).Model(&DataAccessLogPO{})
|
||||||
if q != nil {
|
if q != nil {
|
||||||
|
|
@ -47,6 +45,7 @@ func (r *auditQueryRepo) ListDataAccess(ctx context.Context, page, size int, q *
|
||||||
}
|
}
|
||||||
return out, total, nil
|
return out, total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *auditQueryRepo) DeleteDataAccess(ctx context.Context, ids []uint) error {
|
func (r *auditQueryRepo) DeleteDataAccess(ctx context.Context, ids []uint) error {
|
||||||
return r.data.DB().WithContext(ctx).Delete(&DataAccessLogPO{}, "id IN ?", ids).Error
|
return r.data.DB().WithContext(ctx).Delete(&DataAccessLogPO{}, "id IN ?", ids).Error
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ func (r *parameterRepo) ListParameters(ctx context.Context, page, size int, q *s
|
||||||
db = db.Where(clause.Like{Column: clause.Column{Name: "key"}, Value: "%" + q.Key + "%"})
|
db = db.Where(clause.Like{Column: clause.Column{Name: "key"}, Value: "%" + q.Key + "%"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return listRows(db, page, size, true, func(po parameterPO) *system.SystemParameter {
|
return listRows(db.Order("id desc"), page, size, true, func(po parameterPO) *system.SystemParameter {
|
||||||
return parameterFromPO(po)
|
return parameterFromPO(po)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package system
|
||||||
import (
|
import (
|
||||||
"kra/internal/config"
|
"kra/internal/config"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -14,3 +15,28 @@ type Provider interface {
|
||||||
DatabaseReady() bool
|
DatabaseReady() bool
|
||||||
Runtime() *config.Store
|
Runtime() *config.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProviderSet wires system repositories and their runtime-backed adapters.
|
||||||
|
var ProviderSet = wire.NewSet(
|
||||||
|
NewRuntimeSettings,
|
||||||
|
NewTokenIssuer,
|
||||||
|
NewUserRepo,
|
||||||
|
NewAuthorityAccessRepo,
|
||||||
|
NewAPIRepo,
|
||||||
|
NewPermissionRepo,
|
||||||
|
NewMenuRepo,
|
||||||
|
NewDepartmentRepo,
|
||||||
|
NewPositionRepo,
|
||||||
|
NewDictionaryRepo,
|
||||||
|
NewParameterRepo,
|
||||||
|
NewAPITokenRepo,
|
||||||
|
NewSecurityRepo,
|
||||||
|
NewVersionRepo,
|
||||||
|
NewExportRepo,
|
||||||
|
NewAuditRepo,
|
||||||
|
NewAuditRecorderRepo,
|
||||||
|
NewLogFileRepo,
|
||||||
|
NewMediaRepo,
|
||||||
|
NewAnnouncementRepo,
|
||||||
|
NewMaintenanceRepo,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package system
|
|
||||||
|
|
||||||
import "github.com/google/wire"
|
|
||||||
|
|
||||||
// ProviderSet wires system repositories and their runtime-backed adapters.
|
|
||||||
var ProviderSet = wire.NewSet(
|
|
||||||
NewRuntimeSettings,
|
|
||||||
NewTokenIssuer,
|
|
||||||
NewUserRepo,
|
|
||||||
NewAuthorityAccessRepo,
|
|
||||||
NewAPIRepo,
|
|
||||||
NewPermissionRepo,
|
|
||||||
NewMenuRepo,
|
|
||||||
NewDepartmentRepo,
|
|
||||||
NewPositionRepo,
|
|
||||||
NewDictionaryRepo,
|
|
||||||
NewParameterRepo,
|
|
||||||
NewAPITokenRepo,
|
|
||||||
NewSecurityRepo,
|
|
||||||
NewVersionRepo,
|
|
||||||
NewExportRepo,
|
|
||||||
NewAuditRepo,
|
|
||||||
NewAuditRecorderRepo,
|
|
||||||
NewLogFileRepo,
|
|
||||||
NewMediaRepo,
|
|
||||||
NewAnnouncementRepo,
|
|
||||||
NewMaintenanceRepo,
|
|
||||||
)
|
|
||||||
|
|
@ -59,6 +59,7 @@ func (r *versionRepo) ListVersions(ctx context.Context, page, size int, name, co
|
||||||
if code != "" {
|
if code != "" {
|
||||||
db = db.Where("version_code = ?", code)
|
db = db.Where("version_code = ?", code)
|
||||||
}
|
}
|
||||||
|
db = db.Order("id desc")
|
||||||
var total int64
|
var total int64
|
||||||
if err := db.Count(&total).Error; err != nil {
|
if err := db.Count(&total).Error; err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
package task
|
package task
|
||||||
|
|
||||||
import dataprovider "kra/internal/data/provider"
|
import (
|
||||||
|
dataprovider "kra/internal/data/provider"
|
||||||
|
|
||||||
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
// Provider is the minimal database seam required by the task tables.
|
// Provider is the minimal database seam required by the task tables.
|
||||||
// Task persistence must not depend on the full data runtime or system repos.
|
// Task persistence must not depend on the full data runtime or system repos.
|
||||||
type Provider = dataprovider.Database
|
type Provider = dataprovider.Database
|
||||||
|
|
||||||
|
var ProviderSet = wire.NewSet(NewTaskRepo)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package task
|
|
||||||
|
|
||||||
import "github.com/google/wire"
|
|
||||||
|
|
||||||
var ProviderSet = wire.NewSet(NewTaskRepo)
|
|
||||||
|
|
@ -70,7 +70,7 @@ func skipStackFile(filename string) bool {
|
||||||
"/go/pkg/mod/",
|
"/go/pkg/mod/",
|
||||||
"/go.uber.org/",
|
"/go.uber.org/",
|
||||||
"/gorm.io/",
|
"/gorm.io/",
|
||||||
"/pkg/logging/",
|
"/internal/logging/",
|
||||||
"/internal/transport/middleware/",
|
"/internal/transport/middleware/",
|
||||||
"/internal/transport/router/",
|
"/internal/transport/router/",
|
||||||
"/internal/server/handler/",
|
"/internal/server/handler/",
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ type Options struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorEntry is the storage-neutral representation of an Error-level log.
|
// ErrorEntry is the storage-neutral representation of an Error-level log.
|
||||||
// Keeping it in pkg/logging lets the log core report failures without taking a
|
// Keeping it in internal/logging lets the log core report failures without taking a
|
||||||
// dependency on the application service or persistence layers.
|
// dependency on the application service or persistence layers.
|
||||||
type ErrorEntry struct {
|
type ErrorEntry struct {
|
||||||
Form, Info, Level, RequestID, TraceID string
|
Form, Info, Level, RequestID, TraceID string
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ func NormalizeStatus(value, fallback string) string {
|
||||||
return "success"
|
return "success"
|
||||||
case "WAIT_BUYER_PAY", "USERPAYING", "NOTPAY", "PROCESSING", "PENDING", "CREATED", "CLIENT_PENDING", "ACCEPT", "ACCEPTED", "PAYING":
|
case "WAIT_BUYER_PAY", "USERPAYING", "NOTPAY", "PROCESSING", "PENDING", "CREATED", "CLIENT_PENDING", "ACCEPT", "ACCEPTED", "PAYING":
|
||||||
return "pending"
|
return "pending"
|
||||||
case "CLOSED", "TRADE_CLOSED", "CANCELLED", "CANCELED", "REVOKED", "REFUND", "FAILED", "FAIL", "REJECTED", "DENIED", "DECLINED", "ERROR", "PAYERROR":
|
case "CLOSED", "TRADE_CLOSED", "CANCELLED", "CANCELED", "REVOKED", "FAILED", "FAIL", "REJECTED", "DENIED", "DECLINED", "ERROR", "PAYERROR":
|
||||||
return "failed"
|
return "failed"
|
||||||
default:
|
default:
|
||||||
return fallback
|
return fallback
|
||||||
|
|
@ -22,7 +22,7 @@ func NormalizeStatus(value, fallback string) string {
|
||||||
|
|
||||||
func NormalizeRefundStatus(value, fallback string) string {
|
func NormalizeRefundStatus(value, fallback string) string {
|
||||||
switch strings.ToUpper(strings.TrimSpace(value)) {
|
switch strings.ToUpper(strings.TrimSpace(value)) {
|
||||||
case "SUCCESS", "OK", "PAID", "REFUND_SUCCESS", "REFUNDED", "COMPLETED", "FINISHED":
|
case "SUCCESS", "OK", "PAID", "REFUND_SUCCESS", "REFUNDED", "COMPLETED", "FINISHED", "TRADE_SUCCESS":
|
||||||
return "success"
|
return "success"
|
||||||
case "WAIT_BUYER_PAY", "USERPAYING", "NOTPAY", "PROCESSING", "PENDING", "CREATED", "ACCEPT", "ACCEPTED", "PAYING":
|
case "WAIT_BUYER_PAY", "USERPAYING", "NOTPAY", "PROCESSING", "PENDING", "CREATED", "ACCEPT", "ACCEPTED", "PAYING":
|
||||||
return "pending"
|
return "pending"
|
||||||
|
|
|
||||||
|
|
@ -24,3 +24,15 @@ func TestNormalizeStatusSeparatesRefundStates(t *testing.T) {
|
||||||
t.Fatalf("refund status = %q, want success", got)
|
t.Fatalf("refund status = %q, want success", got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNormalizeStatusDoesNotTreatRefundAsPaymentFailure(t *testing.T) {
|
||||||
|
if got := NormalizeStatus("REFUND", "unknown"); got != "unknown" {
|
||||||
|
t.Fatalf("NormalizeStatus(REFUND) = %q, want fallback", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNormalizeRefundStatusAcceptsTradeSuccess(t *testing.T) {
|
||||||
|
if got := NormalizeRefundStatus("TRADE_SUCCESS", "unknown"); got != "success" {
|
||||||
|
t.Fatalf("NormalizeRefundStatus(TRADE_SUCCESS) = %q, want success", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,7 @@ func requestUsesHTTPS(request *http.Request) bool {
|
||||||
return strings.EqualFold(strings.TrimSpace(forwarded), "https")
|
return strings.EqualFold(strings.TrimSpace(forwarded), "https")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTokenCookie is the shared transport-level cookie policy. It has no KRA
|
// SetTokenCookie is the shared transport-level cookie policy for the admin API.
|
||||||
// business dependency, so handlers and middleware can use pkg/httpx directly.
|
|
||||||
func SetTokenCookie(c *gin.Context, value string, maxAge int) {
|
func SetTokenCookie(c *gin.Context, value string, maxAge int) {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
package dto
|
package dto
|
||||||
|
|
||||||
type GetAuthorityButtonsRequest struct {
|
type GetAuthorityButtonsRequest struct {
|
||||||
MenuID uint `json:"menuID"`
|
MenuID uint `json:"menuID"`
|
||||||
AuthorityID uint `json:"authorityId"`
|
AuthorityID uint `json:"authorityId"`
|
||||||
Selected []uint `json:"selected"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SetAuthorityButtonsRequest struct {
|
type SetAuthorityButtonsRequest struct {
|
||||||
|
|
|
||||||
|
|
@ -16,21 +16,7 @@ func (s *PaymentService) Order(ctx context.Context, provider, tradeNo string) (*
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &dto.PaymentOrderResponse{
|
return paymentOrderResponse(order)
|
||||||
ID: order.ID,
|
|
||||||
Provider: order.Provider, TradeNo: order.TradeNo, ProviderTradeNo: order.ProviderTradeNo,
|
|
||||||
BusinessType: order.BusinessType, BusinessID: order.BusinessID, Subject: order.Subject,
|
|
||||||
PaymentMode: order.PaymentMode, OriginalAmount: order.OriginalAmount,
|
|
||||||
Amount: order.Amount, PaidAmount: order.PaidAmount, PayerPaidAmount: order.PayerPaidAmount,
|
|
||||||
CashPaidAmount: order.CashPaidAmount, PointPaidAmount: order.PointPaidAmount,
|
|
||||||
DiscountAmount: order.DiscountAmount, ProviderDiscountAmount: order.ProviderDiscountAmount,
|
|
||||||
MerchantDiscountAmount: order.MerchantDiscountAmount, SettlementAmount: order.SettlementAmount,
|
|
||||||
Currency: order.Currency, PayerCurrency: order.PayerCurrency, AmountBreakdownKnown: order.AmountBreakdownKnown,
|
|
||||||
PaymentStatus: order.PaymentStatus, ProviderStatus: order.ProviderStatus, FulfillmentStatus: order.FulfillmentStatus,
|
|
||||||
RefundStatus: order.RefundStatus, RefundedAmount: order.RefundedAmount, RefundRequestedAmount: order.RefundRequestedAmount, RefundNo: order.RefundNo, LastError: order.LastError,
|
|
||||||
CreatedAt: order.CreatedAt, UpdatedAt: order.UpdatedAt, PaidAt: order.PaidAt,
|
|
||||||
FulfilledAt: order.FulfilledAt, RefundedAt: order.RefundedAt,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PaymentService) Orders(ctx context.Context, req *dto.PaymentOrderListRequest) ([]*dto.PaymentOrderResponse, int64, int, int, error) {
|
func (s *PaymentService) Orders(ctx context.Context, req *dto.PaymentOrderListRequest) ([]*dto.PaymentOrderResponse, int64, int, int, error) {
|
||||||
|
|
|
||||||
|
|
@ -14,34 +14,10 @@ func NewSecurityService(uc *system.SecurityUsecase) *SecurityService {
|
||||||
return &SecurityService{uc: uc}
|
return &SecurityService{uc: uc}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SecurityService) ActiveToken(ctx context.Context, username string) (string, error) {
|
|
||||||
return s.uc.ActiveToken(ctx, username)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SecurityService) LoginLocked(ctx context.Context, username string) (bool, error) {
|
|
||||||
return s.uc.LoginLocked(ctx, username)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SecurityService) IncrementLoginFailure(ctx context.Context, username string, expiration time.Duration) (int64, error) {
|
|
||||||
return s.uc.IncrementLoginFailure(ctx, username, expiration)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SecurityService) LockLogin(ctx context.Context, username string, expiration time.Duration) error {
|
|
||||||
return s.uc.LockLogin(ctx, username, expiration)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SecurityService) ClearLoginState(ctx context.Context, username string) {
|
|
||||||
s.uc.ClearLoginState(ctx, username)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SecurityService) EnsureLoginIPCounter(ctx context.Context, ip string, expiration time.Duration) (int, error) {
|
func (s *SecurityService) EnsureLoginIPCounter(ctx context.Context, ip string, expiration time.Duration) (int, error) {
|
||||||
return s.uc.EnsureLoginIPCounter(ctx, ip, expiration)
|
return s.uc.EnsureLoginIPCounter(ctx, ip, expiration)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SecurityService) IncrementLoginIP(ctx context.Context, ip string, expiration time.Duration) (int64, error) {
|
|
||||||
return s.uc.IncrementLoginIP(ctx, ip, expiration)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SecurityService) IncrementRateLimit(ctx context.Context, key string, expiration time.Duration) (int64, error) {
|
func (s *SecurityService) IncrementRateLimit(ctx context.Context, key string, expiration time.Duration) (int64, error) {
|
||||||
return s.uc.IncrementRateLimit(ctx, key, expiration)
|
return s.uc.IncrementRateLimit(ctx, key, expiration)
|
||||||
}
|
}
|
||||||
|
|
@ -58,12 +34,6 @@ func (s *SecurityService) DeleteCaptcha(ctx context.Context, id string) error {
|
||||||
return s.uc.DeleteCaptcha(ctx, id)
|
return s.uc.DeleteCaptcha(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SecurityService) UseMultipoint() bool { return s.uc.UseMultipoint() }
|
|
||||||
|
|
||||||
func (s *SecurityService) CaptchaSettings() system.CaptchaSettings {
|
func (s *SecurityService) CaptchaSettings() system.CaptchaSettings {
|
||||||
return s.uc.CaptchaRuntimeSettings()
|
return s.uc.CaptchaRuntimeSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SecurityService) RotateActiveToken(ctx context.Context, username, oldToken, newToken string, expiration time.Duration) error {
|
|
||||||
return s.uc.RotateActiveToken(ctx, username, oldToken, newToken, expiration)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue