补充退款列表应当让本店铺的人看见
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m30s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m30s
This commit is contained in:
@@ -3,6 +3,7 @@ package retention
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -55,17 +56,17 @@ func Load(ctx context.Context, db *gorm.DB, sources ...Source) (Info, error) {
|
||||
}
|
||||
|
||||
func sourceBoundary(ctx context.Context, db *gorm.DB, source Source, location *time.Location) (time.Time, bool, error) {
|
||||
var cleanedEnd *time.Time
|
||||
var cleanedEnd sql.NullTime
|
||||
if err := db.WithContext(ctx).Model(&model.LogArchiveRun{}).
|
||||
Where("source = ? AND cleaned_at IS NOT NULL", source).
|
||||
Select("MAX(range_end)").Scan(&cleanedEnd).Error; err != nil {
|
||||
return time.Time{}, false, errors.Wrap(errors.CodeDatabaseError, err, "查询审计留存清理边界失败")
|
||||
}
|
||||
if cleanedEnd != nil {
|
||||
return cleanedEnd.In(location), true, nil
|
||||
if cleanedEnd.Valid {
|
||||
return cleanedEnd.Time.In(location), true, nil
|
||||
}
|
||||
|
||||
var earliest *time.Time
|
||||
var earliest sql.NullTime
|
||||
table, column := "tb_audit_event", "occurred_at"
|
||||
if source == SourceIntegration {
|
||||
table, column = "tb_integration_log", "created_at"
|
||||
@@ -73,8 +74,8 @@ func sourceBoundary(ctx context.Context, db *gorm.DB, source Source, location *t
|
||||
if err := db.WithContext(ctx).Table(table).Select("MIN(" + column + ")").Scan(&earliest).Error; err != nil {
|
||||
return time.Time{}, false, errors.Wrap(errors.CodeDatabaseError, err, "查询审计在线数据边界失败")
|
||||
}
|
||||
if earliest != nil {
|
||||
return earliest.In(location), false, nil
|
||||
if earliest.Valid {
|
||||
return earliest.Time.In(location), false, nil
|
||||
}
|
||||
now := time.Now().In(location)
|
||||
return time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, location), false, nil
|
||||
|
||||
@@ -268,7 +268,7 @@ func (s *Service) Approve(ctx context.Context, id uint, req *dto.ApproveRefundRe
|
||||
return err
|
||||
}
|
||||
|
||||
refund, err := s.refundStore.GetByID(ctx, id)
|
||||
refund, err := s.refundStore.GetByIDForOperation(ctx, id)
|
||||
if err != nil {
|
||||
return errors.New(errors.CodeNotFound, "退款申请不存在")
|
||||
}
|
||||
@@ -690,7 +690,7 @@ func (s *Service) Resubmit(ctx context.Context, id uint, req *dto.ResubmitRefund
|
||||
return errors.New(errors.CodeUnauthorized, "未授权访问")
|
||||
}
|
||||
|
||||
refund, err := s.refundStore.GetByID(ctx, id)
|
||||
refund, err := s.refundStore.GetByIDForOperation(ctx, id)
|
||||
if err != nil {
|
||||
return errors.New(errors.CodeInvalidStatus, "仅已退回状态可重新提交")
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func (s *RefundStore) Create(ctx context.Context, req *model.RefundRequest) erro
|
||||
return s.db.WithContext(ctx).Create(req).Error
|
||||
}
|
||||
|
||||
// GetByID 根据 ID 查询退款申请(含数据权限过滤)
|
||||
// GetByID 根据 ID 查询退款申请详情(含读取数据权限过滤)。
|
||||
func (s *RefundStore) GetByID(ctx context.Context, id uint) (*model.RefundRequest, error) {
|
||||
var req model.RefundRequest
|
||||
query := s.db.WithContext(ctx).
|
||||
@@ -41,7 +41,22 @@ func (s *RefundStore) GetByID(ctx context.Context, id uint) (*model.RefundReques
|
||||
Select("tb_refund_request.*, tb_shop.shop_name AS shop_name").
|
||||
Joins("LEFT JOIN tb_shop ON tb_shop.id = tb_refund_request.shop_id AND tb_shop.deleted_at IS NULL").
|
||||
Where("tb_refund_request.id = ?", id)
|
||||
query = applyRefundScope(ctx, query)
|
||||
query = applyRefundReadScope(ctx, query)
|
||||
if err := query.First(&req).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &req, nil
|
||||
}
|
||||
|
||||
// GetByIDForOperation 根据 ID 查询退款申请(含写操作数据权限过滤)。
|
||||
func (s *RefundStore) GetByIDForOperation(ctx context.Context, id uint) (*model.RefundRequest, error) {
|
||||
var req model.RefundRequest
|
||||
query := s.db.WithContext(ctx).
|
||||
Model(&model.RefundRequest{}).
|
||||
Select("tb_refund_request.*, tb_shop.shop_name AS shop_name").
|
||||
Joins("LEFT JOIN tb_shop ON tb_shop.id = tb_refund_request.shop_id AND tb_shop.deleted_at IS NULL").
|
||||
Where("tb_refund_request.id = ?", id)
|
||||
query = applyRefundOperationScope(ctx, query)
|
||||
if err := query.First(&req).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -70,7 +85,7 @@ func (s *RefundStore) List(ctx context.Context, opts *store.QueryOptions, filter
|
||||
Model(&model.RefundRequest{}).
|
||||
Select("tb_refund_request.*, tb_shop.shop_name AS shop_name").
|
||||
Joins("LEFT JOIN tb_shop ON tb_shop.id = tb_refund_request.shop_id AND tb_shop.deleted_at IS NULL")
|
||||
query = applyRefundScope(ctx, query)
|
||||
query = applyRefundReadScope(ctx, query)
|
||||
|
||||
if filters != nil {
|
||||
if filters.Status != nil {
|
||||
@@ -113,9 +128,25 @@ func (s *RefundStore) List(ctx context.Context, opts *store.QueryOptions, filter
|
||||
return requests, total, nil
|
||||
}
|
||||
|
||||
// applyRefundScope 应用退款单专属数据权限。
|
||||
// 退款申请对代理按创建人隔离,避免上级代理通过店铺层级看到下级申请。
|
||||
func applyRefundScope(ctx context.Context, query *gorm.DB) *gorm.DB {
|
||||
// applyRefundReadScope 应用退款单读取数据权限。
|
||||
// 代理仅可查看直接所属店铺的申请,不包含下级代理店铺。
|
||||
func applyRefundReadScope(ctx context.Context, query *gorm.DB) *gorm.DB {
|
||||
switch middleware.GetUserTypeFromContext(ctx) {
|
||||
case constants.UserTypeSuperAdmin, constants.UserTypePlatform:
|
||||
return query
|
||||
case constants.UserTypeAgent:
|
||||
shopID := middleware.GetShopIDFromContext(ctx)
|
||||
if shopID == 0 {
|
||||
return query.Where("1 = 0")
|
||||
}
|
||||
return query.Where("tb_refund_request.shop_id = ?", shopID)
|
||||
default:
|
||||
return query.Where("1 = 0")
|
||||
}
|
||||
}
|
||||
|
||||
// applyRefundOperationScope 应用退款单写操作数据权限。
|
||||
func applyRefundOperationScope(ctx context.Context, query *gorm.DB) *gorm.DB {
|
||||
switch middleware.GetUserTypeFromContext(ctx) {
|
||||
case constants.UserTypeSuperAdmin, constants.UserTypePlatform:
|
||||
return query
|
||||
|
||||
Reference in New Issue
Block a user