完成剩余模块 Context 超时控制改造
This commit is contained in:
@@ -380,7 +380,7 @@ func seedMockPaymentConfig(t *testing.T, service *paymentconfig.Service, adminID
|
|||||||
|
|
||||||
func createOwnerPaymentAccount(t *testing.T, service *paymentaccount.Service, ownerID uint64) *paymentaccount.PaymentAccountDTO {
|
func createOwnerPaymentAccount(t *testing.T, service *paymentaccount.Service, ownerID uint64) *paymentaccount.PaymentAccountDTO {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
account, err := service.Create(ownerID, paymentaccount.CreatePaymentAccountRequest{
|
account, err := service.Create(t.Context(), ownerID, paymentaccount.CreatePaymentAccountRequest{
|
||||||
AccountType: "alipay",
|
AccountType: "alipay",
|
||||||
AccountName: "张三",
|
AccountName: "张三",
|
||||||
AccountNo: "owner@example.com",
|
AccountNo: "owner@example.com",
|
||||||
@@ -458,7 +458,7 @@ func assertFinanceDashboard(t *testing.T, service *adminfinance.Service, orderNo
|
|||||||
StartDate: now.Add(-time.Hour),
|
StartDate: now.Add(-time.Hour),
|
||||||
EndDate: now.Add(time.Hour),
|
EndDate: now.Add(time.Hour),
|
||||||
}
|
}
|
||||||
dashboard, err := service.Dashboard(query)
|
dashboard, err := service.Dashboard(t.Context(), query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("读取财务看板失败: %v", err)
|
t.Fatalf("读取财务看板失败: %v", err)
|
||||||
}
|
}
|
||||||
@@ -469,7 +469,7 @@ func assertFinanceDashboard(t *testing.T, service *adminfinance.Service, orderNo
|
|||||||
assertEqual(t, "财务号主钱包入账", dashboard.Summary.OwnerWalletIncomeAmountCent, int64(27500))
|
assertEqual(t, "财务号主钱包入账", dashboard.Summary.OwnerWalletIncomeAmountCent, int64(27500))
|
||||||
assertEqual(t, "财务结算订单数", dashboard.Summary.SettledOrderCount, int64(1))
|
assertEqual(t, "财务结算订单数", dashboard.Summary.SettledOrderCount, int64(1))
|
||||||
|
|
||||||
details, err := service.Details(adminfinance.DetailQuery{
|
details, err := service.Details(t.Context(), adminfinance.DetailQuery{
|
||||||
OrderNo: orderNo,
|
OrderNo: orderNo,
|
||||||
DateType: "settled",
|
DateType: "settled",
|
||||||
StartDate: query.StartDate,
|
StartDate: query.StartDate,
|
||||||
@@ -497,7 +497,7 @@ func assertWalletAndWithdrawal(t *testing.T, walletService *wallet.Service, with
|
|||||||
}
|
}
|
||||||
assertEqual(t, "提现前可用余额", accountBefore.AvailableBalanceCent, int64(27500))
|
assertEqual(t, "提现前可用余额", accountBefore.AvailableBalanceCent, int64(27500))
|
||||||
|
|
||||||
req, err := withdrawalService.Create(ownerID, withdrawal.CreateWithdrawalRequest{
|
req, err := withdrawalService.Create(t.Context(), ownerID, withdrawal.CreateWithdrawalRequest{
|
||||||
PaymentAccountID: paymentAccountID,
|
PaymentAccountID: paymentAccountID,
|
||||||
AmountCent: 10000,
|
AmountCent: 10000,
|
||||||
})
|
})
|
||||||
@@ -507,7 +507,7 @@ func assertWalletAndWithdrawal(t *testing.T, walletService *wallet.Service, with
|
|||||||
assertEqual(t, "提现申请金额", req.AmountCent, int64(10000))
|
assertEqual(t, "提现申请金额", req.AmountCent, int64(10000))
|
||||||
assertEqual(t, "提现申请状态", req.Status, "pending")
|
assertEqual(t, "提现申请状态", req.Status, "pending")
|
||||||
|
|
||||||
reviewed, err := withdrawalService.Review(adminID, req.ID, withdrawal.ReviewWithdrawalRequest{
|
reviewed, err := withdrawalService.Review(t.Context(), adminID, req.ID, withdrawal.ReviewWithdrawalRequest{
|
||||||
Approved: true,
|
Approved: true,
|
||||||
Remark: "E2E 审核通过",
|
Remark: "E2E 审核通过",
|
||||||
})
|
})
|
||||||
@@ -516,7 +516,7 @@ func assertWalletAndWithdrawal(t *testing.T, walletService *wallet.Service, with
|
|||||||
}
|
}
|
||||||
assertEqual(t, "提现审核后状态", reviewed.Status, "processing")
|
assertEqual(t, "提现审核后状态", reviewed.Status, "processing")
|
||||||
|
|
||||||
paid, err := withdrawalService.ConfirmPayment(adminID, req.ID, withdrawal.ConfirmPaymentRequest{
|
paid, err := withdrawalService.ConfirmPayment(t.Context(), adminID, req.ID, withdrawal.ConfirmPaymentRequest{
|
||||||
PaymentProofURL: "https://example.com/proof.png",
|
PaymentProofURL: "https://example.com/proof.png",
|
||||||
Remark: "E2E 已打款",
|
Remark: "E2E 已打款",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -53,9 +52,8 @@ func getPermCodes(c *gin.Context, rdb *redis.Client, adminID uint64) ([]string,
|
|||||||
if rdb == nil {
|
if rdb == nil {
|
||||||
return nil, errors.New("redis unavailable")
|
return nil, errors.New("redis unavailable")
|
||||||
}
|
}
|
||||||
ctx := context.Background()
|
|
||||||
key := fmt.Sprintf("admin:perms:%d", adminID)
|
key := fmt.Sprintf("admin:perms:%d", adminID)
|
||||||
raw, err := rdb.Get(ctx, key).Result()
|
raw, err := rdb.Get(c.Request.Context(), key).Result()
|
||||||
if errors.Is(err, redis.Nil) {
|
if errors.Is(err, redis.Nil) {
|
||||||
return nil, nil // 缓存未命中,视为无权限
|
return nil, nil // 缓存未命中,视为无权限
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ func (r *Repository) loadRolesAndPerms(ctx context.Context, dto *AdminDTO) {
|
|||||||
for _, role := range roles {
|
for _, role := range roles {
|
||||||
if role.Code == "super_admin" {
|
if role.Code == "super_admin" {
|
||||||
dto.Permissions = []string{"*"}
|
dto.Permissions = []string{"*"}
|
||||||
cachePermissions(r, dto.ID, dto.Permissions)
|
cachePermissions(ctx, r, dto.ID, dto.Permissions)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,14 +212,13 @@ func (r *Repository) loadRolesAndPerms(ctx context.Context, dto *AdminDTO) {
|
|||||||
dto.Permissions = permCodes
|
dto.Permissions = permCodes
|
||||||
|
|
||||||
// 缓存权限到 Redis
|
// 缓存权限到 Redis
|
||||||
cachePermissions(r, dto.ID, permCodes)
|
cachePermissions(ctx, r, dto.ID, permCodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cachePermissions(r *Repository, adminID uint64, permCodes []string) {
|
func cachePermissions(ctx context.Context, r *Repository, adminID uint64, permCodes []string) {
|
||||||
if r.redis == nil || len(permCodes) == 0 {
|
if r.redis == nil || len(permCodes) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx := context.Background()
|
|
||||||
key := fmt.Sprintf("admin:perms:%d", adminID)
|
key := fmt.Sprintf("admin:perms:%d", adminID)
|
||||||
raw, _ := json.Marshal(permCodes)
|
raw, _ := json.Marshal(permCodes)
|
||||||
r.redis.Set(ctx, key, string(raw), 2*time.Hour)
|
r.redis.Set(ctx, key, string(raw), 2*time.Hour)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func NewHandler(service *Service) *Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) Summary(c *gin.Context) {
|
func (h *Handler) Summary(c *gin.Context) {
|
||||||
item, err := h.service.Summary()
|
item, err := h.service.Summary(c.Request.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeDashboardError(c, err)
|
writeDashboardError(c, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package admindashboard
|
package admindashboard
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hfb_sys/backend/internal/model"
|
"hfb_sys/backend/internal/model"
|
||||||
@@ -16,56 +17,57 @@ func NewRepository(db *gorm.DB) *Repository {
|
|||||||
return &Repository{db: db}
|
return &Repository{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Summary() (*DashboardDTO, error) {
|
func (r *Repository) Summary(ctx context.Context) (*DashboardDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||||
metrics := MetricsDTO{}
|
metrics := MetricsDTO{}
|
||||||
pending := PendingDTO{}
|
pending := PendingDTO{}
|
||||||
|
|
||||||
if err := r.db.Model(&model.User{}).Count(&metrics.TotalUsers).Error; err != nil {
|
if err := db.Model(&model.User{}).Count(&metrics.TotalUsers).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.User{}).Where("realname_status = ?", "verified").Count(&metrics.VerifiedUsers).Error; err != nil {
|
if err := db.Model(&model.User{}).Where("realname_status = ?", "verified").Count(&metrics.VerifiedUsers).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.RentalListing{}).Count(&metrics.TotalListings).Error; err != nil {
|
if err := db.Model(&model.RentalListing{}).Count(&metrics.TotalListings).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.RentalListing{}).Where("status = ? AND review_status = ?", "published", "approved").Count(&metrics.PublishedListings).Error; err != nil {
|
if err := db.Model(&model.RentalListing{}).Where("status = ? AND review_status = ?", "published", "approved").Count(&metrics.PublishedListings).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.RentalOrder{}).Count(&metrics.TotalOrders).Error; err != nil {
|
if err := db.Model(&model.RentalOrder{}).Count(&metrics.TotalOrders).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.RentalOrder{}).Where("status = ?", "renting").Count(&metrics.RentingOrders).Error; err != nil {
|
if err := db.Model(&model.RentalOrder{}).Where("status = ?", "renting").Count(&metrics.RentingOrders).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.RentalOrder{}).Where("created_at >= ?", today).Count(&metrics.TodayOrders).Error; err != nil {
|
if err := db.Model(&model.RentalOrder{}).Where("created_at >= ?", today).Count(&metrics.TodayOrders).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.WalletLedger{}).
|
if err := db.Model(&model.WalletLedger{}).
|
||||||
Select("COALESCE(SUM(amount_cent), 0)").
|
Select("COALESCE(SUM(amount_cent), 0)").
|
||||||
Where("created_at >= ?", today).
|
Where("created_at >= ?", today).
|
||||||
Scan(&metrics.TodayLedgerAmountCent).Error; err != nil {
|
Scan(&metrics.TodayLedgerAmountCent).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.RentalListing{}).Where("review_status = ?", "pending").Count(&pending.ListingReviews).Error; err != nil {
|
if err := db.Model(&model.RentalListing{}).Where("review_status = ?", "pending").Count(&pending.ListingReviews).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.Dispute{}).Where("status IN ?", []string{"open", "processing"}).Count(&pending.Disputes).Error; err != nil {
|
if err := db.Model(&model.Dispute{}).Where("status IN ?", []string{"open", "processing"}).Count(&pending.Disputes).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.RentalOrder{}).Where("status = ? AND handoff_status IN ?", "pending_handoff", []string{"pending_owner", "pending_renter_confirm"}).Count(&pending.PendingHandoffs).Error; err != nil {
|
if err := db.Model(&model.RentalOrder{}).Where("status = ? AND handoff_status IN ?", "pending_handoff", []string{"pending_owner", "pending_renter_confirm"}).Count(&pending.PendingHandoffs).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := r.db.Model(&model.RentalOrder{}).Where("status IN ?", []string{"pending_checkout_confirm", "pending_checkout_accept"}).Count(&pending.PendingReturnConfirms).Error; err != nil {
|
if err := db.Model(&model.RentalOrder{}).Where("status IN ?", []string{"pending_checkout_confirm", "pending_checkout_accept"}).Count(&pending.PendingReturnConfirms).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
recentOrders, err := r.recentOrders()
|
recentOrders, err := r.recentOrders(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
recentDisputes, err := r.recentDisputes()
|
recentDisputes, err := r.recentDisputes(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -78,9 +80,9 @@ func (r *Repository) Summary() (*DashboardDTO, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) recentOrders() ([]RecentOrderDTO, error) {
|
func (r *Repository) recentOrders(ctx context.Context) ([]RecentOrderDTO, error) {
|
||||||
rows := make([]RecentOrderDTO, 0)
|
rows := make([]RecentOrderDTO, 0)
|
||||||
err := r.db.Table("rental_orders AS o").
|
err := r.db.WithContext(ctx).Table("rental_orders AS o").
|
||||||
Select("o.id, o.order_no, a.title, o.renter_id, o.owner_id, o.status, o.rent_amount_cent, o.deposit_amount_cent, o.created_at").
|
Select("o.id, o.order_no, a.title, o.renter_id, o.owner_id, o.status, o.rent_amount_cent, o.deposit_amount_cent, o.created_at").
|
||||||
Joins("JOIN game_accounts AS a ON a.id = o.account_id").
|
Joins("JOIN game_accounts AS a ON a.id = o.account_id").
|
||||||
Order("o.id DESC").
|
Order("o.id DESC").
|
||||||
@@ -89,9 +91,9 @@ func (r *Repository) recentOrders() ([]RecentOrderDTO, error) {
|
|||||||
return rows, err
|
return rows, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) recentDisputes() ([]RecentDisputeDTO, error) {
|
func (r *Repository) recentDisputes(ctx context.Context) ([]RecentDisputeDTO, error) {
|
||||||
rows := make([]RecentDisputeDTO, 0)
|
rows := make([]RecentDisputeDTO, 0)
|
||||||
err := r.db.Table("disputes AS d").
|
err := r.db.WithContext(ctx).Table("disputes AS d").
|
||||||
Select("d.id, d.order_id, o.order_no, a.title, d.type, d.status, d.initiator_id, d.created_at").
|
Select("d.id, d.order_id, o.order_no, a.title, d.type, d.status, d.initiator_id, d.created_at").
|
||||||
Joins("JOIN rental_orders AS o ON o.id = d.order_id").
|
Joins("JOIN rental_orders AS o ON o.id = d.order_id").
|
||||||
Joins("JOIN game_accounts AS a ON a.id = o.account_id").
|
Joins("JOIN game_accounts AS a ON a.id = o.account_id").
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package admindashboard
|
package admindashboard
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
var ErrDependencyUnavailable = errors.New("dependency unavailable")
|
var ErrDependencyUnavailable = errors.New("dependency unavailable")
|
||||||
|
|
||||||
@@ -12,9 +15,9 @@ func NewService(repo *Repository) *Service {
|
|||||||
return &Service{repo: repo}
|
return &Service{repo: repo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Summary() (*DashboardDTO, error) {
|
func (s *Service) Summary(ctx context.Context) (*DashboardDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Summary()
|
return s.repo.Summary(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func (h *Handler) Dashboard(c *gin.Context) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item, err := h.service.Dashboard(query)
|
item, err := h.service.Dashboard(c.Request.Context(), query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeFinanceError(c, err)
|
writeFinanceError(c, err)
|
||||||
return
|
return
|
||||||
@@ -38,7 +38,7 @@ func (h *Handler) Details(c *gin.Context) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
result, err := h.service.Details(query)
|
result, err := h.service.Details(c.Request.Context(), query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeFinanceError(c, err)
|
writeFinanceError(c, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package adminfinance
|
package adminfinance
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hfb_sys/backend/internal/timeutil"
|
"hfb_sys/backend/internal/timeutil"
|
||||||
@@ -16,12 +17,12 @@ func NewRepository(db *gorm.DB) *Repository {
|
|||||||
return &Repository{db: db}
|
return &Repository{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Dashboard(query DashboardQuery) (*DashboardDTO, error) {
|
func (r *Repository) Dashboard(ctx context.Context, query DashboardQuery) (*DashboardDTO, error) {
|
||||||
dailyItems, err := r.dailyItems(query)
|
dailyItems, err := r.dailyItems(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
summary, err := r.summary(query)
|
summary, err := r.summary(ctx, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -32,10 +33,11 @@ func (r *Repository) Dashboard(query DashboardQuery) (*DashboardDTO, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Details(query DetailQuery) (*PaginatedResult, error) {
|
func (r *Repository) Details(ctx context.Context, query DetailQuery) (*PaginatedResult, error) {
|
||||||
db := r.financeDetailBaseQuery(query)
|
baseDB := r.db.WithContext(ctx)
|
||||||
|
db := r.financeDetailBaseQuery(ctx, query)
|
||||||
var total int64
|
var total int64
|
||||||
countDB := r.db.Table("(?) AS finance_rows", db)
|
countDB := baseDB.Table("(?) AS finance_rows", db)
|
||||||
if err := countDB.Count(&total).Error; err != nil {
|
if err := countDB.Count(&total).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -52,9 +54,10 @@ func (r *Repository) Details(query DetailQuery) (*PaginatedResult, error) {
|
|||||||
return &PaginatedResult{Items: items, Total: total, Page: query.Page, PageSize: query.PageSize}, nil
|
return &PaginatedResult{Items: items, Total: total, Page: query.Page, PageSize: query.PageSize}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) summary(query DashboardQuery) (*FinanceSummaryDTO, error) {
|
func (r *Repository) summary(ctx context.Context, query DashboardQuery) (*FinanceSummaryDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var payment paymentSummaryRow
|
var payment paymentSummaryRow
|
||||||
if err := r.db.Table("payment_orders").
|
if err := db.Table("payment_orders").
|
||||||
Select(`COALESCE(SUM(CASE WHEN biz_type IN ('order_pay', 'wallet_recharge') AND status = 'paid' THEN amount_cent ELSE 0 END), 0) AS total_flow_amount_cent,
|
Select(`COALESCE(SUM(CASE WHEN biz_type IN ('order_pay', 'wallet_recharge') AND status = 'paid' THEN amount_cent ELSE 0 END), 0) AS total_flow_amount_cent,
|
||||||
COALESCE(SUM(CASE WHEN biz_type IN ? AND status = 'refunded' THEN amount_cent ELSE 0 END), 0) AS total_refund_amount_cent,
|
COALESCE(SUM(CASE WHEN biz_type IN ? AND status = 'refunded' THEN amount_cent ELSE 0 END), 0) AS total_refund_amount_cent,
|
||||||
COALESCE(SUM(CASE WHEN biz_type IN ? AND status = 'refunding' THEN amount_cent ELSE 0 END), 0) AS pending_refund_amount_cent,
|
COALESCE(SUM(CASE WHEN biz_type IN ? AND status = 'refunding' THEN amount_cent ELSE 0 END), 0) AS pending_refund_amount_cent,
|
||||||
@@ -68,20 +71,20 @@ func (r *Repository) summary(query DashboardQuery) (*FinanceSummaryDTO, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var settlement settlementSummaryRow
|
var settlement settlementSummaryRow
|
||||||
if err := r.db.Table("rental_orders AS ro").
|
if err := db.Table("rental_orders AS ro").
|
||||||
Select(`COALESCE(SUM(oc.platform_fee_cent), 0) AS platform_income_amount_cent,
|
Select(`COALESCE(SUM(oc.platform_fee_cent), 0) AS platform_income_amount_cent,
|
||||||
COALESCE(SUM(oc.owner_income_amount_cent), 0) AS owner_should_income_amount_cent,
|
COALESCE(SUM(oc.owner_income_amount_cent), 0) AS owner_should_income_amount_cent,
|
||||||
COALESCE(SUM(COALESCE(w.owner_wallet_income_amount_cent, 0)), 0) AS owner_wallet_income_amount_cent,
|
COALESCE(SUM(COALESCE(w.owner_wallet_income_amount_cent, 0)), 0) AS owner_wallet_income_amount_cent,
|
||||||
COUNT(ro.id) AS settled_order_count`).
|
COUNT(ro.id) AS settled_order_count`).
|
||||||
Joins("JOIN order_checkouts AS oc ON oc.order_id = ro.id AND oc.status = 'accepted'").
|
Joins("JOIN order_checkouts AS oc ON oc.order_id = ro.id AND oc.status = 'accepted'").
|
||||||
Joins("LEFT JOIN (?) AS w ON w.order_id = ro.id", ownerWalletIncomeSubquery(r.db)).
|
Joins("LEFT JOIN (?) AS w ON w.order_id = ro.id", ownerWalletIncomeSubquery(db)).
|
||||||
Where("ro.settled_at >= ? AND ro.settled_at <= ?", query.StartDate, query.EndDate).
|
Where("ro.settled_at >= ? AND ro.settled_at <= ?", query.StartDate, query.EndDate).
|
||||||
Scan(&settlement).Error; err != nil {
|
Scan(&settlement).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var exceptionCount int64
|
var exceptionCount int64
|
||||||
if err := r.db.Table("(?) AS d", r.financeDetailBaseQuery(DetailQuery{
|
if err := db.Table("(?) AS d", r.financeDetailBaseQuery(ctx, DetailQuery{
|
||||||
DateType: "settled",
|
DateType: "settled",
|
||||||
StartDate: query.StartDate,
|
StartDate: query.StartDate,
|
||||||
EndDate: query.EndDate,
|
EndDate: query.EndDate,
|
||||||
@@ -108,9 +111,10 @@ func (r *Repository) summary(query DashboardQuery) (*FinanceSummaryDTO, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) dailyItems(query DashboardQuery) ([]FinanceDailyDTO, error) {
|
func (r *Repository) dailyItems(ctx context.Context, query DashboardQuery) ([]FinanceDailyDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
payments := make([]dailyPaymentRow, 0)
|
payments := make([]dailyPaymentRow, 0)
|
||||||
if err := r.db.Table("payment_orders").
|
if err := db.Table("payment_orders").
|
||||||
Select(`DATE(created_at) AS date,
|
Select(`DATE(created_at) AS date,
|
||||||
COALESCE(SUM(CASE WHEN biz_type IN ('order_pay', 'wallet_recharge') AND status = 'paid' THEN amount_cent ELSE 0 END), 0) AS total_flow_amount_cent,
|
COALESCE(SUM(CASE WHEN biz_type IN ('order_pay', 'wallet_recharge') AND status = 'paid' THEN amount_cent ELSE 0 END), 0) AS total_flow_amount_cent,
|
||||||
COALESCE(SUM(CASE WHEN biz_type IN ? AND status = 'refunded' THEN amount_cent ELSE 0 END), 0) AS total_refund_amount_cent,
|
COALESCE(SUM(CASE WHEN biz_type IN ? AND status = 'refunded' THEN amount_cent ELSE 0 END), 0) AS total_refund_amount_cent,
|
||||||
@@ -126,14 +130,14 @@ func (r *Repository) dailyItems(query DashboardQuery) ([]FinanceDailyDTO, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
settlements := make([]dailySettlementRow, 0)
|
settlements := make([]dailySettlementRow, 0)
|
||||||
if err := r.db.Table("rental_orders AS ro").
|
if err := db.Table("rental_orders AS ro").
|
||||||
Select(`DATE(ro.settled_at) AS date,
|
Select(`DATE(ro.settled_at) AS date,
|
||||||
COALESCE(SUM(oc.platform_fee_cent), 0) AS platform_income_amount_cent,
|
COALESCE(SUM(oc.platform_fee_cent), 0) AS platform_income_amount_cent,
|
||||||
COALESCE(SUM(oc.owner_income_amount_cent), 0) AS owner_should_income_amount_cent,
|
COALESCE(SUM(oc.owner_income_amount_cent), 0) AS owner_should_income_amount_cent,
|
||||||
COALESCE(SUM(COALESCE(w.owner_wallet_income_amount_cent, 0)), 0) AS owner_wallet_income_amount_cent,
|
COALESCE(SUM(COALESCE(w.owner_wallet_income_amount_cent, 0)), 0) AS owner_wallet_income_amount_cent,
|
||||||
COUNT(ro.id) AS settled_order_count`).
|
COUNT(ro.id) AS settled_order_count`).
|
||||||
Joins("JOIN order_checkouts AS oc ON oc.order_id = ro.id AND oc.status = 'accepted'").
|
Joins("JOIN order_checkouts AS oc ON oc.order_id = ro.id AND oc.status = 'accepted'").
|
||||||
Joins("LEFT JOIN (?) AS w ON w.order_id = ro.id", ownerWalletIncomeSubquery(r.db)).
|
Joins("LEFT JOIN (?) AS w ON w.order_id = ro.id", ownerWalletIncomeSubquery(db)).
|
||||||
Where("ro.settled_at >= ? AND ro.settled_at <= ?", query.StartDate, query.EndDate).
|
Where("ro.settled_at >= ? AND ro.settled_at <= ?", query.StartDate, query.EndDate).
|
||||||
Group("DATE(ro.settled_at)").
|
Group("DATE(ro.settled_at)").
|
||||||
Scan(&settlements).Error; err != nil {
|
Scan(&settlements).Error; err != nil {
|
||||||
@@ -175,8 +179,8 @@ func (r *Repository) dailyItems(query DashboardQuery) ([]FinanceDailyDTO, error)
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) financeDetailBaseQuery(query DetailQuery) *gorm.DB {
|
func (r *Repository) financeDetailBaseQuery(ctx context.Context, query DetailQuery) *gorm.DB {
|
||||||
db := r.db.Table("rental_orders AS ro").
|
db := r.db.WithContext(ctx).Table("rental_orders AS ro").
|
||||||
Select(`ro.id AS order_id, ro.order_no, ro.status AS order_status, ro.settlement_status, ro.refund_status,
|
Select(`ro.id AS order_id, ro.order_no, ro.status AS order_status, ro.settlement_status, ro.refund_status,
|
||||||
ro.renter_id, COALESCE(ru.phone, '') AS renter_phone, COALESCE(ru.nickname, '') AS renter_nickname,
|
ro.renter_id, COALESCE(ru.phone, '') AS renter_phone, COALESCE(ru.nickname, '') AS renter_nickname,
|
||||||
ro.owner_id, COALESCE(ou.phone, '') AS owner_phone, COALESCE(ou.nickname, '') AS owner_nickname,
|
ro.owner_id, COALESCE(ou.phone, '') AS owner_phone, COALESCE(ou.nickname, '') AS owner_nickname,
|
||||||
@@ -202,9 +206,9 @@ func (r *Repository) financeDetailBaseQuery(query DetailQuery) *gorm.DB {
|
|||||||
ro.created_at, ro.settled_at`).
|
ro.created_at, ro.settled_at`).
|
||||||
Joins("LEFT JOIN users AS ru ON ru.id = ro.renter_id").
|
Joins("LEFT JOIN users AS ru ON ru.id = ro.renter_id").
|
||||||
Joins("LEFT JOIN users AS ou ON ou.id = ro.owner_id").
|
Joins("LEFT JOIN users AS ou ON ou.id = ro.owner_id").
|
||||||
Joins("LEFT JOIN (?) AS oc ON oc.order_id = ro.id", acceptedCheckoutSubquery(r.db)).
|
Joins("LEFT JOIN (?) AS oc ON oc.order_id = ro.id", acceptedCheckoutSubquery(r.db.WithContext(ctx))).
|
||||||
Joins("LEFT JOIN (?) AS p ON p.order_id = ro.id", orderPaymentSubquery(r.db)).
|
Joins("LEFT JOIN (?) AS p ON p.order_id = ro.id", orderPaymentSubquery(r.db.WithContext(ctx))).
|
||||||
Joins("LEFT JOIN (?) AS w ON w.order_id = ro.id", ownerWalletIncomeSubquery(r.db))
|
Joins("LEFT JOIN (?) AS w ON w.order_id = ro.id", ownerWalletIncomeSubquery(r.db.WithContext(ctx)))
|
||||||
|
|
||||||
if query.OrderNo != "" {
|
if query.OrderNo != "" {
|
||||||
db = db.Where("ro.order_no = ?", query.OrderNo)
|
db = db.Where("ro.order_no = ?", query.OrderNo)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package adminfinance
|
package adminfinance
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
var ErrDependencyUnavailable = errors.New("dependency unavailable")
|
var ErrDependencyUnavailable = errors.New("dependency unavailable")
|
||||||
|
|
||||||
@@ -12,14 +15,14 @@ func NewService(repo *Repository) *Service {
|
|||||||
return &Service{repo: repo}
|
return &Service{repo: repo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Dashboard(query DashboardQuery) (*DashboardDTO, error) {
|
func (s *Service) Dashboard(ctx context.Context, query DashboardQuery) (*DashboardDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Dashboard(query)
|
return s.repo.Dashboard(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Details(query DetailQuery) (*PaginatedResult, error) {
|
func (s *Service) Details(ctx context.Context, query DetailQuery) (*PaginatedResult, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
@@ -32,5 +35,5 @@ func (s *Service) Details(query DetailQuery) (*PaginatedResult, error) {
|
|||||||
if query.PageSize > 100 {
|
if query.PageSize > 100 {
|
||||||
query.PageSize = 100
|
query.PageSize = 100
|
||||||
}
|
}
|
||||||
return s.repo.Details(query)
|
return s.repo.Details(ctx, query)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func NewHandler(service *Service) *Handler {
|
|||||||
func (h *Handler) List(c *gin.Context) {
|
func (h *Handler) List(c *gin.Context) {
|
||||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||||
result, err := h.service.List(page, pageSize)
|
result, err := h.service.List(c.Request.Context(), page, pageSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -35,7 +35,7 @@ func (h *Handler) FindByID(c *gin.Context) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item, err := h.service.FindByID(id)
|
item, err := h.service.FindByID(c.Request.Context(), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -49,7 +49,7 @@ func (h *Handler) Create(c *gin.Context) {
|
|||||||
response.BadRequest(c, "用户名和密码不能为空")
|
response.BadRequest(c, "用户名和密码不能为空")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item, err := h.service.Create(req)
|
item, err := h.service.Create(c.Request.Context(), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -67,7 +67,7 @@ func (h *Handler) Update(c *gin.Context) {
|
|||||||
response.BadRequest(c, "请求格式不正确")
|
response.BadRequest(c, "请求格式不正确")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item, err := h.service.Update(id, req)
|
item, err := h.service.Update(c.Request.Context(), id, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -81,7 +81,7 @@ func (h *Handler) Delete(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
currentAdminID, _ := c.Get(middleware.ContextAdminID)
|
currentAdminID, _ := c.Get(middleware.ContextAdminID)
|
||||||
if err := h.service.Delete(id, currentAdminID.(uint64)); err != nil {
|
if err := h.service.Delete(c.Request.Context(), id, currentAdminID.(uint64)); err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ func (h *Handler) AssignRoles(c *gin.Context) {
|
|||||||
response.BadRequest(c, "请求格式不正确")
|
response.BadRequest(c, "请求格式不正确")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := h.service.AssignRoles(id, req); err != nil {
|
if err := h.service.AssignRoles(c.Request.Context(), id, req); err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ func (h *Handler) ChangePassword(c *gin.Context) {
|
|||||||
response.BadRequest(c, "密码不能为空")
|
response.BadRequest(c, "密码不能为空")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := h.service.ChangePassword(id, req); err != nil {
|
if err := h.service.ChangePassword(c.Request.Context(), id, req); err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,19 +23,20 @@ func NewRepository(db *gorm.DB, redis *redis.Client) *Repository {
|
|||||||
return &Repository{db: db, redis: redis}
|
return &Repository{db: db, redis: redis}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) List(page, pageSize int) (*PaginatedResult, error) {
|
func (r *Repository) List(ctx context.Context, page, pageSize int) (*PaginatedResult, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var total int64
|
var total int64
|
||||||
if err := r.db.Model(&model.AdminUser{}).Count(&total).Error; err != nil {
|
if err := db.Model(&model.AdminUser{}).Count(&total).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
offset := (page - 1) * pageSize
|
offset := (page - 1) * pageSize
|
||||||
var admins []model.AdminUser
|
var admins []model.AdminUser
|
||||||
if err := r.db.Order("id DESC").Offset(offset).Limit(pageSize).Find(&admins).Error; err != nil {
|
if err := db.Order("id DESC").Offset(offset).Limit(pageSize).Find(&admins).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
items := make([]AdminUserDTO, 0, len(admins))
|
items := make([]AdminUserDTO, 0, len(admins))
|
||||||
for _, admin := range admins {
|
for _, admin := range admins {
|
||||||
roles, _ := r.getAdminRoles(admin.ID)
|
roles, _ := r.getAdminRoles(ctx, admin.ID)
|
||||||
items = append(items, AdminUserDTO{
|
items = append(items, AdminUserDTO{
|
||||||
ID: admin.ID,
|
ID: admin.ID,
|
||||||
Username: admin.Username,
|
Username: admin.Username,
|
||||||
@@ -50,12 +51,12 @@ func (r *Repository) List(page, pageSize int) (*PaginatedResult, error) {
|
|||||||
return &PaginatedResult{Items: items, Total: total, Page: page, PageSize: pageSize}, nil
|
return &PaginatedResult{Items: items, Total: total, Page: page, PageSize: pageSize}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) FindByID(id uint64) (*AdminUserDTO, error) {
|
func (r *Repository) FindByID(ctx context.Context, id uint64) (*AdminUserDTO, error) {
|
||||||
var admin model.AdminUser
|
var admin model.AdminUser
|
||||||
if err := r.db.First(&admin, id).Error; err != nil {
|
if err := r.db.WithContext(ctx).First(&admin, id).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
roles, _ := r.getAdminRoles(admin.ID)
|
roles, _ := r.getAdminRoles(ctx, admin.ID)
|
||||||
dto := AdminUserDTO{
|
dto := AdminUserDTO{
|
||||||
ID: admin.ID,
|
ID: admin.ID,
|
||||||
Username: admin.Username,
|
Username: admin.Username,
|
||||||
@@ -69,7 +70,7 @@ func (r *Repository) FindByID(id uint64) (*AdminUserDTO, error) {
|
|||||||
return &dto, nil
|
return &dto, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Create(req CreateAdminRequest) (*AdminUserDTO, error) {
|
func (r *Repository) Create(ctx context.Context, req CreateAdminRequest) (*AdminUserDTO, error) {
|
||||||
hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -80,15 +81,16 @@ func (r *Repository) Create(req CreateAdminRequest) (*AdminUserDTO, error) {
|
|||||||
Nickname: req.Nickname,
|
Nickname: req.Nickname,
|
||||||
Status: "active",
|
Status: "active",
|
||||||
}
|
}
|
||||||
if err := r.db.Create(&admin).Error; err != nil {
|
if err := r.db.WithContext(ctx).Create(&admin).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return r.FindByID(admin.ID)
|
return r.FindByID(ctx, admin.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Update(id uint64, req UpdateAdminRequest) (*AdminUserDTO, error) {
|
func (r *Repository) Update(ctx context.Context, id uint64, req UpdateAdminRequest) (*AdminUserDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var admin model.AdminUser
|
var admin model.AdminUser
|
||||||
if err := r.db.First(&admin, id).Error; err != nil {
|
if err := db.First(&admin, id).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if req.Nickname != "" {
|
if req.Nickname != "" {
|
||||||
@@ -97,46 +99,48 @@ func (r *Repository) Update(id uint64, req UpdateAdminRequest) (*AdminUserDTO, e
|
|||||||
if req.Status != "" {
|
if req.Status != "" {
|
||||||
admin.Status = req.Status
|
admin.Status = req.Status
|
||||||
}
|
}
|
||||||
if err := r.db.Save(&admin).Error; err != nil {
|
if err := db.Save(&admin).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return r.FindByID(id)
|
return r.FindByID(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Delete(id uint64, currentAdminID uint64) error {
|
func (r *Repository) Delete(ctx context.Context, id uint64, currentAdminID uint64) error {
|
||||||
if id == currentAdminID {
|
if id == currentAdminID {
|
||||||
return ErrCannotDeleteSelf
|
return ErrCannotDeleteSelf
|
||||||
}
|
}
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var admin model.AdminUser
|
var admin model.AdminUser
|
||||||
if err := r.db.First(&admin, id).Error; err != nil {
|
if err := db.First(&admin, id).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 检查是否是最后一个 super_admin
|
// 检查是否是最后一个 super_admin
|
||||||
isLastSuper, err := r.isLastSuperAdmin(id)
|
isLastSuper, err := r.isLastSuperAdmin(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if isLastSuper {
|
if isLastSuper {
|
||||||
return ErrLastSuperAdmin
|
return ErrLastSuperAdmin
|
||||||
}
|
}
|
||||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
return db.Transaction(func(tx *gorm.DB) error {
|
||||||
if err := tx.Where("admin_user_id = ?", id).Delete(&model.AdminUserRole{}).Error; err != nil {
|
if err := tx.Where("admin_user_id = ?", id).Delete(&model.AdminUserRole{}).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tx.Delete(&model.AdminUser{}, id).Error; err != nil {
|
if err := tx.Delete(&model.AdminUser{}, id).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r.invalidatePermCache(id)
|
r.invalidatePermCache(ctx, id)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) AssignRoles(adminID uint64, roleIDs []uint64) error {
|
func (r *Repository) AssignRoles(ctx context.Context, adminID uint64, roleIDs []uint64) error {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var admin model.AdminUser
|
var admin model.AdminUser
|
||||||
if err := r.db.First(&admin, adminID).Error; err != nil {
|
if err := db.First(&admin, adminID).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
err := db.Transaction(func(tx *gorm.DB) error {
|
||||||
if err := tx.Where("admin_user_id = ?", adminID).Delete(&model.AdminUserRole{}).Error; err != nil {
|
if err := tx.Where("admin_user_id = ?", adminID).Delete(&model.AdminUserRole{}).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -151,13 +155,13 @@ func (r *Repository) AssignRoles(adminID uint64, roleIDs []uint64) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r.invalidatePermCache(adminID)
|
r.invalidatePermCache(ctx, adminID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) ChangePassword(id uint64, oldPwd, newPwd string) error {
|
func (r *Repository) ChangePassword(ctx context.Context, id uint64, oldPwd, newPwd string) error {
|
||||||
var admin model.AdminUser
|
var admin model.AdminUser
|
||||||
if err := r.db.First(&admin, id).Error; err != nil {
|
if err := r.db.WithContext(ctx).First(&admin, id).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := bcrypt.CompareHashAndPassword([]byte(admin.PasswordHash), []byte(oldPwd)); err != nil {
|
if err := bcrypt.CompareHashAndPassword([]byte(admin.PasswordHash), []byte(oldPwd)); err != nil {
|
||||||
@@ -167,12 +171,12 @@ func (r *Repository) ChangePassword(id uint64, oldPwd, newPwd string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return r.db.Model(&admin).Update("password_hash", string(hash)).Error
|
return r.db.WithContext(ctx).Model(&admin).Update("password_hash", string(hash)).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) GetPermissionCodes(adminID uint64) ([]string, error) {
|
func (r *Repository) GetPermissionCodes(ctx context.Context, adminID uint64) ([]string, error) {
|
||||||
var codes []string
|
var codes []string
|
||||||
err := r.db.Table("admin_user_roles aur").
|
err := r.db.WithContext(ctx).Table("admin_user_roles aur").
|
||||||
Select("DISTINCT p.code").
|
Select("DISTINCT p.code").
|
||||||
Joins("JOIN role_permissions rp ON rp.role_id = aur.role_id").
|
Joins("JOIN role_permissions rp ON rp.role_id = aur.role_id").
|
||||||
Joins("JOIN permissions p ON p.id = rp.permission_id").
|
Joins("JOIN permissions p ON p.id = rp.permission_id").
|
||||||
@@ -181,9 +185,9 @@ func (r *Repository) GetPermissionCodes(adminID uint64) ([]string, error) {
|
|||||||
return codes, err
|
return codes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) getAdminRoles(adminID uint64) ([]adminrole.RoleDTO, error) {
|
func (r *Repository) getAdminRoles(ctx context.Context, adminID uint64) ([]adminrole.RoleDTO, error) {
|
||||||
var roles []model.Role
|
var roles []model.Role
|
||||||
err := r.db.Table("roles").
|
err := r.db.WithContext(ctx).Table("roles").
|
||||||
Joins("JOIN admin_user_roles aur ON aur.role_id = roles.id").
|
Joins("JOIN admin_user_roles aur ON aur.role_id = roles.id").
|
||||||
Where("aur.admin_user_id = ?", adminID).
|
Where("aur.admin_user_id = ?", adminID).
|
||||||
Find(&roles).Error
|
Find(&roles).Error
|
||||||
@@ -199,23 +203,23 @@ func (r *Repository) getAdminRoles(adminID uint64) ([]adminrole.RoleDTO, error)
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) isLastSuperAdmin(adminID uint64) (bool, error) {
|
func (r *Repository) isLastSuperAdmin(ctx context.Context, adminID uint64) (bool, error) {
|
||||||
var superRole model.Role
|
var superRole model.Role
|
||||||
if err := r.db.Where("code = ?", "super_admin").First(&superRole).Error; err != nil {
|
db := r.db.WithContext(ctx)
|
||||||
|
if err := db.Where("code = ?", "super_admin").First(&superRole).Error; err != nil {
|
||||||
return false, nil // 没有 super_admin 角色,不限制
|
return false, nil // 没有 super_admin 角色,不限制
|
||||||
}
|
}
|
||||||
var count int64
|
var count int64
|
||||||
err := r.db.Model(&model.AdminUserRole{}).
|
err := db.Model(&model.AdminUserRole{}).
|
||||||
Where("role_id = ? AND admin_user_id != ?", superRole.ID, adminID).
|
Where("role_id = ? AND admin_user_id != ?", superRole.ID, adminID).
|
||||||
Count(&count).Error
|
Count(&count).Error
|
||||||
return count == 0, err
|
return count == 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) invalidatePermCache(adminID uint64) {
|
func (r *Repository) invalidatePermCache(ctx context.Context, adminID uint64) {
|
||||||
if r.redis == nil {
|
if r.redis == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx := context.Background()
|
|
||||||
r.redis.Del(ctx, permCacheKey(adminID))
|
r.redis.Del(ctx, permCacheKey(adminID))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package adminmgr
|
package adminmgr
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
var ErrDependencyUnavailable = errors.New("dependency unavailable")
|
var ErrDependencyUnavailable = errors.New("dependency unavailable")
|
||||||
|
|
||||||
@@ -12,7 +15,7 @@ func NewService(repo *Repository) *Service {
|
|||||||
return &Service{repo: repo}
|
return &Service{repo: repo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) List(page, pageSize int) (*PaginatedResult, error) {
|
func (s *Service) List(ctx context.Context, page, pageSize int) (*PaginatedResult, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
@@ -22,53 +25,53 @@ func (s *Service) List(page, pageSize int) (*PaginatedResult, error) {
|
|||||||
if pageSize < 1 || pageSize > 100 {
|
if pageSize < 1 || pageSize > 100 {
|
||||||
pageSize = 20
|
pageSize = 20
|
||||||
}
|
}
|
||||||
return s.repo.List(page, pageSize)
|
return s.repo.List(ctx, page, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FindByID(id uint64) (*AdminUserDTO, error) {
|
func (s *Service) FindByID(ctx context.Context, id uint64) (*AdminUserDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.FindByID(id)
|
return s.repo.FindByID(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Create(req CreateAdminRequest) (*AdminUserDTO, error) {
|
func (s *Service) Create(ctx context.Context, req CreateAdminRequest) (*AdminUserDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
if len(req.Password) < 6 {
|
if len(req.Password) < 6 {
|
||||||
return nil, errors.New("password too short")
|
return nil, errors.New("password too short")
|
||||||
}
|
}
|
||||||
return s.repo.Create(req)
|
return s.repo.Create(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Update(id uint64, req UpdateAdminRequest) (*AdminUserDTO, error) {
|
func (s *Service) Update(ctx context.Context, id uint64, req UpdateAdminRequest) (*AdminUserDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Update(id, req)
|
return s.repo.Update(ctx, id, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Delete(id uint64, currentAdminID uint64) error {
|
func (s *Service) Delete(ctx context.Context, id uint64, currentAdminID uint64) error {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return ErrDependencyUnavailable
|
return ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Delete(id, currentAdminID)
|
return s.repo.Delete(ctx, id, currentAdminID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) AssignRoles(adminID uint64, req AssignRolesRequest) error {
|
func (s *Service) AssignRoles(ctx context.Context, adminID uint64, req AssignRolesRequest) error {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return ErrDependencyUnavailable
|
return ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.AssignRoles(adminID, req.RoleIDs)
|
return s.repo.AssignRoles(ctx, adminID, req.RoleIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) ChangePassword(id uint64, req ChangePasswordRequest) error {
|
func (s *Service) ChangePassword(ctx context.Context, id uint64, req ChangePasswordRequest) error {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return ErrDependencyUnavailable
|
return ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
if len(req.NewPassword) < 6 {
|
if len(req.NewPassword) < 6 {
|
||||||
return errors.New("new password too short")
|
return errors.New("new password too short")
|
||||||
}
|
}
|
||||||
return s.repo.ChangePassword(id, req.OldPassword, req.NewPassword)
|
return s.repo.ChangePassword(ctx, id, req.OldPassword, req.NewPassword)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ func NewHandler(service *Service) *Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) List(c *gin.Context) {
|
func (h *Handler) List(c *gin.Context) {
|
||||||
items, err := h.service.List()
|
items, err := h.service.List(c.Request.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -32,7 +32,7 @@ func (h *Handler) FindByID(c *gin.Context) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item, err := h.service.FindByID(id)
|
item, err := h.service.FindByID(c.Request.Context(), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -46,7 +46,7 @@ func (h *Handler) Create(c *gin.Context) {
|
|||||||
response.BadRequest(c, "角色编码和名称不能为空")
|
response.BadRequest(c, "角色编码和名称不能为空")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item, err := h.service.Create(req)
|
item, err := h.service.Create(c.Request.Context(), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -64,7 +64,7 @@ func (h *Handler) Update(c *gin.Context) {
|
|||||||
response.BadRequest(c, "角色名称不能为空")
|
response.BadRequest(c, "角色名称不能为空")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item, err := h.service.Update(id, req)
|
item, err := h.service.Update(c.Request.Context(), id, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -77,7 +77,7 @@ func (h *Handler) Delete(c *gin.Context) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := h.service.Delete(id); err != nil {
|
if err := h.service.Delete(c.Request.Context(), id); err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ func (h *Handler) AssignPermissions(c *gin.Context) {
|
|||||||
response.BadRequest(c, "请求格式不正确")
|
response.BadRequest(c, "请求格式不正确")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := h.service.AssignPermissions(id, req); err != nil {
|
if err := h.service.AssignPermissions(c.Request.Context(), id, req); err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ func (h *Handler) AssignPermissions(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) ListPermissions(c *gin.Context) {
|
func (h *Handler) ListPermissions(c *gin.Context) {
|
||||||
items, err := h.service.ListPermissions()
|
items, err := h.service.ListPermissions(c.Request.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package adminrole
|
package adminrole
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"hfb_sys/backend/internal/model"
|
"hfb_sys/backend/internal/model"
|
||||||
@@ -17,18 +18,19 @@ func NewRepository(db *gorm.DB) *Repository {
|
|||||||
return &Repository{db: db}
|
return &Repository{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) List() ([]RoleDTO, error) {
|
func (r *Repository) List(ctx context.Context) ([]RoleDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var roles []model.Role
|
var roles []model.Role
|
||||||
if err := r.db.Order("id ASC").Find(&roles).Error; err != nil {
|
if err := db.Order("id ASC").Find(&roles).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := make([]RoleDTO, 0, len(roles))
|
result := make([]RoleDTO, 0, len(roles))
|
||||||
for _, role := range roles {
|
for _, role := range roles {
|
||||||
var count int64
|
var count int64
|
||||||
if role.Code == "super_admin" {
|
if role.Code == "super_admin" {
|
||||||
r.db.Model(&model.Permission{}).Count(&count)
|
db.Model(&model.Permission{}).Count(&count)
|
||||||
} else {
|
} else {
|
||||||
r.db.Model(&model.RolePermission{}).Where("role_id = ?", role.ID).Count(&count)
|
db.Model(&model.RolePermission{}).Where("role_id = ?", role.ID).Count(&count)
|
||||||
}
|
}
|
||||||
result = append(result, RoleDTO{
|
result = append(result, RoleDTO{
|
||||||
ID: role.ID,
|
ID: role.ID,
|
||||||
@@ -43,17 +45,17 @@ func (r *Repository) List() ([]RoleDTO, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) FindByID(id uint64) (*RoleDTO, error) {
|
func (r *Repository) FindByID(ctx context.Context, id uint64) (*RoleDTO, error) {
|
||||||
var role model.Role
|
var role model.Role
|
||||||
if err := r.db.First(&role, id).Error; err != nil {
|
if err := r.db.WithContext(ctx).First(&role, id).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var perms []PermissionDTO
|
var perms []PermissionDTO
|
||||||
var err error
|
var err error
|
||||||
if role.Code == "super_admin" {
|
if role.Code == "super_admin" {
|
||||||
perms, err = r.ListPermissions()
|
perms, err = r.ListPermissions(ctx)
|
||||||
} else {
|
} else {
|
||||||
perms, err = r.getRolePermissions(id)
|
perms, err = r.getRolePermissions(ctx, id)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -71,40 +73,42 @@ func (r *Repository) FindByID(id uint64) (*RoleDTO, error) {
|
|||||||
return &dto, nil
|
return &dto, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Create(req CreateRoleRequest) (*RoleDTO, error) {
|
func (r *Repository) Create(ctx context.Context, req CreateRoleRequest) (*RoleDTO, error) {
|
||||||
role := model.Role{
|
role := model.Role{
|
||||||
Code: req.Code,
|
Code: req.Code,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
}
|
}
|
||||||
if err := r.db.Create(&role).Error; err != nil {
|
if err := r.db.WithContext(ctx).Create(&role).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return r.FindByID(role.ID)
|
return r.FindByID(ctx, role.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Update(id uint64, req UpdateRoleRequest) (*RoleDTO, error) {
|
func (r *Repository) Update(ctx context.Context, id uint64, req UpdateRoleRequest) (*RoleDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var role model.Role
|
var role model.Role
|
||||||
if err := r.db.First(&role, id).Error; err != nil {
|
if err := db.First(&role, id).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
role.Name = req.Name
|
role.Name = req.Name
|
||||||
role.Description = req.Description
|
role.Description = req.Description
|
||||||
if err := r.db.Save(&role).Error; err != nil {
|
if err := db.Save(&role).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return r.FindByID(id)
|
return r.FindByID(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Delete(id uint64) error {
|
func (r *Repository) Delete(ctx context.Context, id uint64) error {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var role model.Role
|
var role model.Role
|
||||||
if err := r.db.First(&role, id).Error; err != nil {
|
if err := db.First(&role, id).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if role.Code == "super_admin" {
|
if role.Code == "super_admin" {
|
||||||
return ErrProtectedRole
|
return ErrProtectedRole
|
||||||
}
|
}
|
||||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
return db.Transaction(func(tx *gorm.DB) error {
|
||||||
if err := tx.Where("role_id = ?", id).Delete(&model.RolePermission{}).Error; err != nil {
|
if err := tx.Where("role_id = ?", id).Delete(&model.RolePermission{}).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -115,12 +119,13 @@ func (r *Repository) Delete(id uint64) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) AssignPermissions(roleID uint64, permIDs []uint64) error {
|
func (r *Repository) AssignPermissions(ctx context.Context, roleID uint64, permIDs []uint64) error {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var role model.Role
|
var role model.Role
|
||||||
if err := r.db.First(&role, roleID).Error; err != nil {
|
if err := db.First(&role, roleID).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
return db.Transaction(func(tx *gorm.DB) error {
|
||||||
if role.Code == "super_admin" {
|
if role.Code == "super_admin" {
|
||||||
var allPermIDs []uint64
|
var allPermIDs []uint64
|
||||||
if err := tx.Model(&model.Permission{}).Pluck("id", &allPermIDs).Error; err != nil {
|
if err := tx.Model(&model.Permission{}).Pluck("id", &allPermIDs).Error; err != nil {
|
||||||
@@ -141,9 +146,9 @@ func (r *Repository) AssignPermissions(roleID uint64, permIDs []uint64) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) ListPermissions() ([]PermissionDTO, error) {
|
func (r *Repository) ListPermissions(ctx context.Context) ([]PermissionDTO, error) {
|
||||||
var perms []model.Permission
|
var perms []model.Permission
|
||||||
if err := r.db.Order("resource ASC, action ASC").Find(&perms).Error; err != nil {
|
if err := r.db.WithContext(ctx).Order("resource ASC, action ASC").Find(&perms).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := make([]PermissionDTO, 0, len(perms))
|
result := make([]PermissionDTO, 0, len(perms))
|
||||||
@@ -155,9 +160,10 @@ func (r *Repository) ListPermissions() ([]PermissionDTO, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) getRolePermissions(roleID uint64) ([]PermissionDTO, error) {
|
func (r *Repository) getRolePermissions(ctx context.Context, roleID uint64) ([]PermissionDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var rps []model.RolePermission
|
var rps []model.RolePermission
|
||||||
if err := r.db.Where("role_id = ?", roleID).Find(&rps).Error; err != nil {
|
if err := db.Where("role_id = ?", roleID).Find(&rps).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(rps) == 0 {
|
if len(rps) == 0 {
|
||||||
@@ -168,7 +174,7 @@ func (r *Repository) getRolePermissions(roleID uint64) ([]PermissionDTO, error)
|
|||||||
ids = append(ids, rp.PermissionID)
|
ids = append(ids, rp.PermissionID)
|
||||||
}
|
}
|
||||||
var perms []model.Permission
|
var perms []model.Permission
|
||||||
if err := r.db.Where("id IN ?", ids).Find(&perms).Error; err != nil {
|
if err := db.Where("id IN ?", ids).Find(&perms).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := make([]PermissionDTO, 0, len(perms))
|
result := make([]PermissionDTO, 0, len(perms))
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package adminrole
|
package adminrole
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
var ErrDependencyUnavailable = errors.New("dependency unavailable")
|
var ErrDependencyUnavailable = errors.New("dependency unavailable")
|
||||||
|
|
||||||
@@ -12,54 +15,54 @@ func NewService(repo *Repository) *Service {
|
|||||||
return &Service{repo: repo}
|
return &Service{repo: repo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) List() ([]RoleDTO, error) {
|
func (s *Service) List(ctx context.Context) ([]RoleDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.List()
|
return s.repo.List(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FindByID(id uint64) (*RoleDTO, error) {
|
func (s *Service) FindByID(ctx context.Context, id uint64) (*RoleDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.FindByID(id)
|
return s.repo.FindByID(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Create(req CreateRoleRequest) (*RoleDTO, error) {
|
func (s *Service) Create(ctx context.Context, req CreateRoleRequest) (*RoleDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
if req.Code == "" || req.Name == "" {
|
if req.Code == "" || req.Name == "" {
|
||||||
return nil, errors.New("code and name are required")
|
return nil, errors.New("code and name are required")
|
||||||
}
|
}
|
||||||
return s.repo.Create(req)
|
return s.repo.Create(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Update(id uint64, req UpdateRoleRequest) (*RoleDTO, error) {
|
func (s *Service) Update(ctx context.Context, id uint64, req UpdateRoleRequest) (*RoleDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Update(id, req)
|
return s.repo.Update(ctx, id, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Delete(id uint64) error {
|
func (s *Service) Delete(ctx context.Context, id uint64) error {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return ErrDependencyUnavailable
|
return ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Delete(id)
|
return s.repo.Delete(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) AssignPermissions(roleID uint64, req AssignPermissionsRequest) error {
|
func (s *Service) AssignPermissions(ctx context.Context, roleID uint64, req AssignPermissionsRequest) error {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return ErrDependencyUnavailable
|
return ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.AssignPermissions(roleID, req.PermissionIDs)
|
return s.repo.AssignPermissions(ctx, roleID, req.PermissionIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) ListPermissions() ([]PermissionDTO, error) {
|
func (s *Service) ListPermissions(ctx context.Context) ([]PermissionDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.ListPermissions()
|
return s.repo.ListPermissions(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func (h *Handler) List(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
query.Page, query.PageSize = parsePagination(c)
|
query.Page, query.PageSize = parsePagination(c)
|
||||||
|
|
||||||
result, err := h.service.List(query)
|
result, err := h.service.List(c.Request.Context(), query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.InternalServerError(c, "获取公告列表失败")
|
response.InternalServerError(c, "获取公告列表失败")
|
||||||
return
|
return
|
||||||
@@ -44,7 +44,7 @@ func (h *Handler) GetByID(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
announcement, err := h.service.GetByID(id)
|
announcement, err := h.service.GetByID(c.Request.Context(), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, ErrNotFound) {
|
if errors.Is(err, ErrNotFound) {
|
||||||
response.NotFound(c, "公告不存在")
|
response.NotFound(c, "公告不存在")
|
||||||
@@ -65,7 +65,7 @@ func (h *Handler) AdminList(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
query.Page, query.PageSize = parsePagination(c)
|
query.Page, query.PageSize = parsePagination(c)
|
||||||
|
|
||||||
result, err := h.service.AdminList(query)
|
result, err := h.service.AdminList(c.Request.Context(), query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.InternalServerError(c, "获取公告列表失败")
|
response.InternalServerError(c, "获取公告列表失败")
|
||||||
return
|
return
|
||||||
@@ -82,7 +82,7 @@ func (h *Handler) AdminGetByID(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
announcement, err := h.service.AdminGetByID(id)
|
announcement, err := h.service.AdminGetByID(c.Request.Context(), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
response.NotFound(c, "公告不存在")
|
response.NotFound(c, "公告不存在")
|
||||||
@@ -109,7 +109,7 @@ func (h *Handler) Create(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
announcement, err := h.service.Create(req, adminID)
|
announcement, err := h.service.Create(c.Request.Context(), req, adminID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.InternalServerError(c, "创建公告失败")
|
response.InternalServerError(c, "创建公告失败")
|
||||||
return
|
return
|
||||||
@@ -132,7 +132,7 @@ func (h *Handler) Update(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
announcement, err := h.service.Update(id, req)
|
announcement, err := h.service.Update(c.Request.Context(), id, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.InternalServerError(c, "更新公告失败")
|
response.InternalServerError(c, "更新公告失败")
|
||||||
return
|
return
|
||||||
@@ -149,7 +149,7 @@ func (h *Handler) Publish(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.service.Publish(id); err != nil {
|
if err := h.service.Publish(c.Request.Context(), id); err != nil {
|
||||||
response.InternalServerError(c, "发布公告失败")
|
response.InternalServerError(c, "发布公告失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ func (h *Handler) Archive(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.service.Archive(id); err != nil {
|
if err := h.service.Archive(c.Request.Context(), id); err != nil {
|
||||||
response.InternalServerError(c, "归档公告失败")
|
response.InternalServerError(c, "归档公告失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ func (h *Handler) Delete(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.service.Delete(id); err != nil {
|
if err := h.service.Delete(c.Request.Context(), id); err != nil {
|
||||||
response.InternalServerError(c, "删除公告失败")
|
response.InternalServerError(c, "删除公告失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package announcement
|
package announcement
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hfb_sys/backend/internal/model"
|
"hfb_sys/backend/internal/model"
|
||||||
@@ -17,9 +18,9 @@ func NewRepository(db *gorm.DB) *Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List 获取公告列表(前台用户)
|
// List 获取公告列表(前台用户)
|
||||||
func (r *Repository) List(query AnnouncementListQuery) (*PaginatedResult, error) {
|
func (r *Repository) List(ctx context.Context, query AnnouncementListQuery) (*PaginatedResult, error) {
|
||||||
var total int64
|
var total int64
|
||||||
tx := r.db.Model(&model.Announcement{}).Where("status = ?", "published")
|
tx := r.db.WithContext(ctx).Model(&model.Announcement{}).Where("status = ?", "published")
|
||||||
|
|
||||||
if query.Category != "" {
|
if query.Category != "" {
|
||||||
tx = tx.Where("category = ?", query.Category)
|
tx = tx.Where("category = ?", query.Category)
|
||||||
@@ -52,23 +53,24 @@ func (r *Repository) List(query AnnouncementListQuery) (*PaginatedResult, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetByID 获取公告详情
|
// GetByID 获取公告详情
|
||||||
func (r *Repository) GetByID(id uint64) (*AnnouncementDTO, error) {
|
func (r *Repository) GetByID(ctx context.Context, id uint64) (*AnnouncementDTO, error) {
|
||||||
var announcement model.Announcement
|
var announcement model.Announcement
|
||||||
if err := r.db.Where("id = ? AND status = ?", id, "published").First(&announcement).Error; err != nil {
|
db := r.db.WithContext(ctx)
|
||||||
|
if err := db.Where("id = ? AND status = ?", id, "published").First(&announcement).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 增加查看次数
|
// 增加查看次数
|
||||||
r.db.Model(&model.Announcement{}).Where("id = ?", id).UpdateColumn("view_count", gorm.Expr("view_count + ?", 1))
|
db.Model(&model.Announcement{}).Where("id = ?", id).UpdateColumn("view_count", gorm.Expr("view_count + ?", 1))
|
||||||
|
|
||||||
dto := toAnnouncementDTO(announcement)
|
dto := toAnnouncementDTO(announcement)
|
||||||
return &dto, nil
|
return &dto, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdminList 管理员获取公告列表
|
// AdminList 管理员获取公告列表
|
||||||
func (r *Repository) AdminList(query AnnouncementListQuery) (*PaginatedResult, error) {
|
func (r *Repository) AdminList(ctx context.Context, query AnnouncementListQuery) (*PaginatedResult, error) {
|
||||||
var total int64
|
var total int64
|
||||||
tx := r.db.Model(&model.Announcement{})
|
tx := r.db.WithContext(ctx).Model(&model.Announcement{})
|
||||||
|
|
||||||
if query.Status != "" {
|
if query.Status != "" {
|
||||||
tx = tx.Where("status = ?", query.Status)
|
tx = tx.Where("status = ?", query.Status)
|
||||||
@@ -104,9 +106,9 @@ func (r *Repository) AdminList(query AnnouncementListQuery) (*PaginatedResult, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AdminGetByID 管理员获取公告详情
|
// AdminGetByID 管理员获取公告详情
|
||||||
func (r *Repository) AdminGetByID(id uint64) (*AnnouncementDTO, error) {
|
func (r *Repository) AdminGetByID(ctx context.Context, id uint64) (*AnnouncementDTO, error) {
|
||||||
var announcement model.Announcement
|
var announcement model.Announcement
|
||||||
if err := r.db.Where("id = ?", id).First(&announcement).Error; err != nil {
|
if err := r.db.WithContext(ctx).Where("id = ?", id).First(&announcement).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +117,7 @@ func (r *Repository) AdminGetByID(id uint64) (*AnnouncementDTO, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create 创建公告
|
// Create 创建公告
|
||||||
func (r *Repository) Create(req CreateAnnouncementRequest, createdBy uint64) (*AnnouncementDTO, error) {
|
func (r *Repository) Create(ctx context.Context, req CreateAnnouncementRequest, createdBy uint64) (*AnnouncementDTO, error) {
|
||||||
announcement := model.Announcement{
|
announcement := model.Announcement{
|
||||||
Title: req.Title,
|
Title: req.Title,
|
||||||
Content: req.Content,
|
Content: req.Content,
|
||||||
@@ -127,7 +129,7 @@ func (r *Repository) Create(req CreateAnnouncementRequest, createdBy uint64) (*A
|
|||||||
CreatedBy: &createdBy,
|
CreatedBy: &createdBy,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.db.Create(&announcement).Error; err != nil {
|
if err := r.db.WithContext(ctx).Create(&announcement).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +138,7 @@ func (r *Repository) Create(req CreateAnnouncementRequest, createdBy uint64) (*A
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update 更新公告
|
// Update 更新公告
|
||||||
func (r *Repository) Update(id uint64, req UpdateAnnouncementRequest) (*AnnouncementDTO, error) {
|
func (r *Repository) Update(ctx context.Context, id uint64, req UpdateAnnouncementRequest) (*AnnouncementDTO, error) {
|
||||||
updates := make(map[string]interface{})
|
updates := make(map[string]interface{})
|
||||||
|
|
||||||
if req.Title != "" {
|
if req.Title != "" {
|
||||||
@@ -152,17 +154,17 @@ func (r *Repository) Update(id uint64, req UpdateAnnouncementRequest) (*Announce
|
|||||||
updates["is_pinned"] = req.IsPinned
|
updates["is_pinned"] = req.IsPinned
|
||||||
updates["is_important"] = req.IsImportant
|
updates["is_important"] = req.IsImportant
|
||||||
|
|
||||||
if err := r.db.Model(&model.Announcement{}).Where("id = ?", id).Updates(updates).Error; err != nil {
|
if err := r.db.WithContext(ctx).Model(&model.Announcement{}).Where("id = ?", id).Updates(updates).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.AdminGetByID(id)
|
return r.AdminGetByID(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish 发布公告
|
// Publish 发布公告
|
||||||
func (r *Repository) Publish(id uint64) error {
|
func (r *Repository) Publish(ctx context.Context, id uint64) error {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
return r.db.Model(&model.Announcement{}).
|
return r.db.WithContext(ctx).Model(&model.Announcement{}).
|
||||||
Where("id = ?", id).
|
Where("id = ?", id).
|
||||||
Updates(map[string]interface{}{
|
Updates(map[string]interface{}{
|
||||||
"status": "published",
|
"status": "published",
|
||||||
@@ -171,15 +173,15 @@ func (r *Repository) Publish(id uint64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Archive 归档公告
|
// Archive 归档公告
|
||||||
func (r *Repository) Archive(id uint64) error {
|
func (r *Repository) Archive(ctx context.Context, id uint64) error {
|
||||||
return r.db.Model(&model.Announcement{}).
|
return r.db.WithContext(ctx).Model(&model.Announcement{}).
|
||||||
Where("id = ?", id).
|
Where("id = ?", id).
|
||||||
Update("status", "archived").Error
|
Update("status", "archived").Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete 删除公告
|
// Delete 删除公告
|
||||||
func (r *Repository) Delete(id uint64) error {
|
func (r *Repository) Delete(ctx context.Context, id uint64) error {
|
||||||
return r.db.Where("id = ?", id).Delete(&model.Announcement{}).Error
|
return r.db.WithContext(ctx).Where("id = ?", id).Delete(&model.Announcement{}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func toAnnouncementDTO(a model.Announcement) AnnouncementDTO {
|
func toAnnouncementDTO(a model.Announcement) AnnouncementDTO {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package announcement
|
package announcement
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -15,13 +16,13 @@ func NewService(repo *Repository) *Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrNotFound = errors.New("公告不存在")
|
ErrNotFound = errors.New("公告不存在")
|
||||||
ErrInvalidRequest = errors.New("请求参数不正确")
|
ErrInvalidRequest = errors.New("请求参数不正确")
|
||||||
ErrUnauthorized = errors.New("未授权")
|
ErrUnauthorized = errors.New("未授权")
|
||||||
)
|
)
|
||||||
|
|
||||||
// List 获取公告列表(前台用户)
|
// List 获取公告列表(前台用户)
|
||||||
func (s *Service) List(query AnnouncementListQuery) (*PaginatedResult, error) {
|
func (s *Service) List(ctx context.Context, query AnnouncementListQuery) (*PaginatedResult, error) {
|
||||||
if query.Page < 1 {
|
if query.Page < 1 {
|
||||||
query.Page = 1
|
query.Page = 1
|
||||||
}
|
}
|
||||||
@@ -32,12 +33,12 @@ func (s *Service) List(query AnnouncementListQuery) (*PaginatedResult, error) {
|
|||||||
query.PageSize = 100
|
query.PageSize = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.repo.List(query)
|
return s.repo.List(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetByID 获取公告详情
|
// GetByID 获取公告详情
|
||||||
func (s *Service) GetByID(id uint64) (*AnnouncementDTO, error) {
|
func (s *Service) GetByID(ctx context.Context, id uint64) (*AnnouncementDTO, error) {
|
||||||
dto, err := s.repo.GetByID(id)
|
dto, err := s.repo.GetByID(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, ErrNotFound
|
return nil, ErrNotFound
|
||||||
@@ -48,7 +49,7 @@ func (s *Service) GetByID(id uint64) (*AnnouncementDTO, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AdminList 管理员获取公告列表
|
// AdminList 管理员获取公告列表
|
||||||
func (s *Service) AdminList(query AnnouncementListQuery) (*PaginatedResult, error) {
|
func (s *Service) AdminList(ctx context.Context, query AnnouncementListQuery) (*PaginatedResult, error) {
|
||||||
if query.Page < 1 {
|
if query.Page < 1 {
|
||||||
query.Page = 1
|
query.Page = 1
|
||||||
}
|
}
|
||||||
@@ -59,12 +60,12 @@ func (s *Service) AdminList(query AnnouncementListQuery) (*PaginatedResult, erro
|
|||||||
query.PageSize = 100
|
query.PageSize = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.repo.AdminList(query)
|
return s.repo.AdminList(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdminGetByID 管理员获取公告详情
|
// AdminGetByID 管理员获取公告详情
|
||||||
func (s *Service) AdminGetByID(id uint64) (*AnnouncementDTO, error) {
|
func (s *Service) AdminGetByID(ctx context.Context, id uint64) (*AnnouncementDTO, error) {
|
||||||
dto, err := s.repo.AdminGetByID(id)
|
dto, err := s.repo.AdminGetByID(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, ErrNotFound
|
return nil, ErrNotFound
|
||||||
@@ -75,26 +76,26 @@ func (s *Service) AdminGetByID(id uint64) (*AnnouncementDTO, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create 创建公告
|
// Create 创建公告
|
||||||
func (s *Service) Create(req CreateAnnouncementRequest, createdBy uint64) (*AnnouncementDTO, error) {
|
func (s *Service) Create(ctx context.Context, req CreateAnnouncementRequest, createdBy uint64) (*AnnouncementDTO, error) {
|
||||||
return s.repo.Create(req, createdBy)
|
return s.repo.Create(ctx, req, createdBy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update 更新公告
|
// Update 更新公告
|
||||||
func (s *Service) Update(id uint64, req UpdateAnnouncementRequest) (*AnnouncementDTO, error) {
|
func (s *Service) Update(ctx context.Context, id uint64, req UpdateAnnouncementRequest) (*AnnouncementDTO, error) {
|
||||||
return s.repo.Update(id, req)
|
return s.repo.Update(ctx, id, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish 发布公告
|
// Publish 发布公告
|
||||||
func (s *Service) Publish(id uint64) error {
|
func (s *Service) Publish(ctx context.Context, id uint64) error {
|
||||||
return s.repo.Publish(id)
|
return s.repo.Publish(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Archive 归档公告
|
// Archive 归档公告
|
||||||
func (s *Service) Archive(id uint64) error {
|
func (s *Service) Archive(ctx context.Context, id uint64) error {
|
||||||
return s.repo.Archive(id)
|
return s.repo.Archive(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete 删除公告
|
// Delete 删除公告
|
||||||
func (s *Service) Delete(id uint64) error {
|
func (s *Service) Delete(ctx context.Context, id uint64) error {
|
||||||
return s.repo.Delete(id)
|
return s.repo.Delete(ctx, id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func (h *Handler) List(c *gin.Context) {
|
|||||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||||
|
|
||||||
result, err := h.service.List(userID, page, pageSize)
|
result, err := h.service.List(c.Request.Context(), userID, page, pageSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -46,7 +46,7 @@ func (h *Handler) FindByID(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
account, err := h.service.FindByID(userID, id)
|
account, err := h.service.FindByID(c.Request.Context(), userID, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -68,7 +68,7 @@ func (h *Handler) Create(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
account, err := h.service.Create(userID, req)
|
account, err := h.service.Create(c.Request.Context(), userID, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -95,7 +95,7 @@ func (h *Handler) Update(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
account, err := h.service.Update(userID, id, req)
|
account, err := h.service.Update(c.Request.Context(), userID, id, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -116,7 +116,7 @@ func (h *Handler) Delete(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.service.Delete(userID, id); err != nil {
|
if err := h.service.Delete(c.Request.Context(), userID, id); err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ func (h *Handler) SetDefault(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.service.SetDefault(userID, id); err != nil {
|
if err := h.service.SetDefault(c.Request.Context(), userID, id); err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package paymentaccount
|
package paymentaccount
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -22,9 +23,10 @@ func NewRepository(db *gorm.DB) *Repository {
|
|||||||
return &Repository{db: db}
|
return &Repository{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
func (r *Repository) List(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var total int64
|
var total int64
|
||||||
if err := r.db.Model(&model.UserPaymentAccount{}).
|
if err := db.Model(&model.UserPaymentAccount{}).
|
||||||
Where("user_id = ? AND status = ?", userID, "active").
|
Where("user_id = ? AND status = ?", userID, "active").
|
||||||
Count(&total).Error; err != nil {
|
Count(&total).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -32,7 +34,7 @@ func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult,
|
|||||||
|
|
||||||
offset := (page - 1) * pageSize
|
offset := (page - 1) * pageSize
|
||||||
var accounts []model.UserPaymentAccount
|
var accounts []model.UserPaymentAccount
|
||||||
if err := r.db.Where("user_id = ? AND status = ?", userID, "active").
|
if err := db.Where("user_id = ? AND status = ?", userID, "active").
|
||||||
Order("is_default DESC, created_at DESC").
|
Order("is_default DESC, created_at DESC").
|
||||||
Offset(offset).Limit(pageSize).
|
Offset(offset).Limit(pageSize).
|
||||||
Find(&accounts).Error; err != nil {
|
Find(&accounts).Error; err != nil {
|
||||||
@@ -56,9 +58,9 @@ func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) FindByID(userID, id uint64) (*PaymentAccountDTO, error) {
|
func (r *Repository) FindByID(ctx context.Context, userID, id uint64) (*PaymentAccountDTO, error) {
|
||||||
var account model.UserPaymentAccount
|
var account model.UserPaymentAccount
|
||||||
if err := r.db.Where("id = ? AND user_id = ? AND status = ?", id, userID, "active").
|
if err := r.db.WithContext(ctx).Where("id = ? AND user_id = ? AND status = ?", id, userID, "active").
|
||||||
First(&account).Error; err != nil {
|
First(&account).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, ErrAccountNotFound
|
return nil, ErrAccountNotFound
|
||||||
@@ -68,7 +70,8 @@ func (r *Repository) FindByID(userID, id uint64) (*PaymentAccountDTO, error) {
|
|||||||
return r.toDTO(account)
|
return r.toDTO(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Create(userID uint64, req CreatePaymentAccountRequest) (*PaymentAccountDTO, error) {
|
func (r *Repository) Create(ctx context.Context, userID uint64, req CreatePaymentAccountRequest) (*PaymentAccountDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
// 加密账号
|
// 加密账号
|
||||||
encryptedNo, err := crypto.Encrypt(req.AccountNo)
|
encryptedNo, err := crypto.Encrypt(req.AccountNo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -84,7 +87,7 @@ func (r *Repository) Create(userID uint64, req CreatePaymentAccountRequest) (*Pa
|
|||||||
// 如果是第一个账号,自动设为默认
|
// 如果是第一个账号,自动设为默认
|
||||||
isDefault := false
|
isDefault := false
|
||||||
var count int64
|
var count int64
|
||||||
r.db.Model(&model.UserPaymentAccount{}).Where("user_id = ? AND status = ?", userID, "active").Count(&count)
|
db.Model(&model.UserPaymentAccount{}).Where("user_id = ? AND status = ?", userID, "active").Count(&count)
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
isDefault = true
|
isDefault = true
|
||||||
}
|
}
|
||||||
@@ -101,16 +104,17 @@ func (r *Repository) Create(userID uint64, req CreatePaymentAccountRequest) (*Pa
|
|||||||
Status: "active",
|
Status: "active",
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.db.Create(&account).Error; err != nil {
|
if err := db.Create(&account).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.FindByID(userID, account.ID)
|
return r.FindByID(ctx, userID, account.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Update(userID, id uint64, req UpdatePaymentAccountRequest) (*PaymentAccountDTO, error) {
|
func (r *Repository) Update(ctx context.Context, userID, id uint64, req UpdatePaymentAccountRequest) (*PaymentAccountDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var account model.UserPaymentAccount
|
var account model.UserPaymentAccount
|
||||||
if err := r.db.Where("id = ? AND user_id = ? AND status = ?", id, userID, "active").
|
if err := db.Where("id = ? AND user_id = ? AND status = ?", id, userID, "active").
|
||||||
First(&account).Error; err != nil {
|
First(&account).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, ErrAccountNotFound
|
return nil, ErrAccountNotFound
|
||||||
@@ -131,24 +135,25 @@ func (r *Repository) Update(userID, id uint64, req UpdatePaymentAccountRequest)
|
|||||||
|
|
||||||
if req.IsDefault != nil && *req.IsDefault {
|
if req.IsDefault != nil && *req.IsDefault {
|
||||||
// 先取消其他默认账号
|
// 先取消其他默认账号
|
||||||
r.db.Model(&model.UserPaymentAccount{}).
|
db.Model(&model.UserPaymentAccount{}).
|
||||||
Where("user_id = ? AND id != ?", userID, id).
|
Where("user_id = ? AND id != ?", userID, id).
|
||||||
Update("is_default", false)
|
Update("is_default", false)
|
||||||
updates["is_default"] = true
|
updates["is_default"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(updates) > 0 {
|
if len(updates) > 0 {
|
||||||
if err := r.db.Model(&account).Updates(updates).Error; err != nil {
|
if err := db.Model(&account).Updates(updates).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.FindByID(userID, id)
|
return r.FindByID(ctx, userID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) Delete(userID, id uint64) error {
|
func (r *Repository) Delete(ctx context.Context, userID, id uint64) error {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var account model.UserPaymentAccount
|
var account model.UserPaymentAccount
|
||||||
if err := r.db.Where("id = ? AND user_id = ? AND status = ?", id, userID, "active").
|
if err := db.Where("id = ? AND user_id = ? AND status = ?", id, userID, "active").
|
||||||
First(&account).Error; err != nil {
|
First(&account).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return ErrAccountNotFound
|
return ErrAccountNotFound
|
||||||
@@ -157,13 +162,13 @@ func (r *Repository) Delete(userID, id uint64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 软删除
|
// 软删除
|
||||||
return r.db.Model(&account).Update("status", "disabled").Error
|
return db.Model(&account).Update("status", "disabled").Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) SetDefault(userID, id uint64) error {
|
func (r *Repository) SetDefault(ctx context.Context, userID, id uint64) error {
|
||||||
// 验证账号存在
|
// 验证账号存在
|
||||||
var account model.UserPaymentAccount
|
var account model.UserPaymentAccount
|
||||||
if err := r.db.Where("id = ? AND user_id = ? AND status = ?", id, userID, "active").
|
if err := r.db.WithContext(ctx).Where("id = ? AND user_id = ? AND status = ?", id, userID, "active").
|
||||||
First(&account).Error; err != nil {
|
First(&account).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return ErrAccountNotFound
|
return ErrAccountNotFound
|
||||||
@@ -171,7 +176,7 @@ func (r *Repository) SetDefault(userID, id uint64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
// 取消其他默认账号
|
// 取消其他默认账号
|
||||||
if err := tx.Model(&model.UserPaymentAccount{}).
|
if err := tx.Model(&model.UserPaymentAccount{}).
|
||||||
Where("user_id = ? AND id != ?", userID, id).
|
Where("user_id = ? AND id != ?", userID, id).
|
||||||
@@ -183,17 +188,18 @@ func (r *Repository) SetDefault(userID, id uint64) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) CountByUser(userID uint64) (int64, error) {
|
func (r *Repository) CountByUser(ctx context.Context, userID uint64) (int64, error) {
|
||||||
var count int64
|
var count int64
|
||||||
err := r.db.Model(&model.UserPaymentAccount{}).
|
err := r.db.WithContext(ctx).Model(&model.UserPaymentAccount{}).
|
||||||
Where("user_id = ? AND status = ?", userID, "active").
|
Where("user_id = ? AND status = ?", userID, "active").
|
||||||
Count(&count).Error
|
Count(&count).Error
|
||||||
return count, err
|
return count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) ValidateRealname(userID uint64, accountName string) error {
|
func (r *Repository) ValidateRealname(ctx context.Context, userID uint64, accountName string) error {
|
||||||
var user model.User
|
var user model.User
|
||||||
if err := r.db.First(&user, userID).Error; err != nil {
|
db := r.db.WithContext(ctx)
|
||||||
|
if err := db.First(&user, userID).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +209,7 @@ func (r *Repository) ValidateRealname(userID uint64, accountName string) error {
|
|||||||
|
|
||||||
// 获取实名信息
|
// 获取实名信息
|
||||||
var realname model.UserRealname
|
var realname model.UserRealname
|
||||||
if err := r.db.Where("user_id = ? AND status = ?", userID, "verified").
|
if err := db.Where("user_id = ? AND status = ?", userID, "verified").
|
||||||
First(&realname).Error; err != nil {
|
First(&realname).Error; err != nil {
|
||||||
return ErrRealnameRequired
|
return ErrRealnameRequired
|
||||||
}
|
}
|
||||||
@@ -303,9 +309,9 @@ func maskAccountNo(accountNo, accountType string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取解密后的账号(仅供内部使用,如提现申请时)
|
// 获取解密后的账号(仅供内部使用,如提现申请时)
|
||||||
func (r *Repository) GetDecryptedAccountNo(userID, id uint64) (string, error) {
|
func (r *Repository) GetDecryptedAccountNo(ctx context.Context, userID, id uint64) (string, error) {
|
||||||
var account model.UserPaymentAccount
|
var account model.UserPaymentAccount
|
||||||
if err := r.db.Where("id = ? AND user_id = ?", id, userID).First(&account).Error; err != nil {
|
if err := r.db.WithContext(ctx).Where("id = ? AND user_id = ?", id, userID).First(&account).Error; err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return crypto.Decrypt(account.AccountNo)
|
return crypto.Decrypt(account.AccountNo)
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package paymentaccount
|
package paymentaccount
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrDependencyUnavailable = errors.New("dependency unavailable")
|
ErrDependencyUnavailable = errors.New("dependency unavailable")
|
||||||
@@ -19,7 +22,7 @@ func NewService(repo *Repository) *Service {
|
|||||||
return &Service{repo: repo}
|
return &Service{repo: repo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) List(userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
func (s *Service) List(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
@@ -29,52 +32,52 @@ func (s *Service) List(userID uint64, page, pageSize int) (*PaginatedResult, err
|
|||||||
if pageSize < 1 || pageSize > 100 {
|
if pageSize < 1 || pageSize > 100 {
|
||||||
pageSize = 20
|
pageSize = 20
|
||||||
}
|
}
|
||||||
return s.repo.List(userID, page, pageSize)
|
return s.repo.List(ctx, userID, page, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FindByID(userID, id uint64) (*PaymentAccountDTO, error) {
|
func (s *Service) FindByID(ctx context.Context, userID, id uint64) (*PaymentAccountDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.FindByID(userID, id)
|
return s.repo.FindByID(ctx, userID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Create(userID uint64, req CreatePaymentAccountRequest) (*PaymentAccountDTO, error) {
|
func (s *Service) Create(ctx context.Context, userID uint64, req CreatePaymentAccountRequest) (*PaymentAccountDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
// 验证实名状态
|
// 验证实名状态
|
||||||
if err := s.repo.ValidateRealname(userID, req.AccountName); err != nil {
|
if err := s.repo.ValidateRealname(ctx, userID, req.AccountName); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// 检查账号数量限制(最多5个)
|
// 检查账号数量限制(最多5个)
|
||||||
count, err := s.repo.CountByUser(userID)
|
count, err := s.repo.CountByUser(ctx, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if count >= 5 {
|
if count >= 5 {
|
||||||
return nil, ErrAccountLimit
|
return nil, ErrAccountLimit
|
||||||
}
|
}
|
||||||
return s.repo.Create(userID, req)
|
return s.repo.Create(ctx, userID, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Update(userID, id uint64, req UpdatePaymentAccountRequest) (*PaymentAccountDTO, error) {
|
func (s *Service) Update(ctx context.Context, userID, id uint64, req UpdatePaymentAccountRequest) (*PaymentAccountDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Update(userID, id, req)
|
return s.repo.Update(ctx, userID, id, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Delete(userID, id uint64) error {
|
func (s *Service) Delete(ctx context.Context, userID, id uint64) error {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return ErrDependencyUnavailable
|
return ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Delete(userID, id)
|
return s.repo.Delete(ctx, userID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) SetDefault(userID, id uint64) error {
|
func (s *Service) SetDefault(ctx context.Context, userID, id uint64) error {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return ErrDependencyUnavailable
|
return ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.SetDefault(userID, id)
|
return s.repo.SetDefault(ctx, userID, id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func (h *Handler) Create(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
withdrawal, err := h.service.Create(userID, req)
|
withdrawal, err := h.service.Create(c.Request.Context(), userID, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -49,7 +49,7 @@ func (h *Handler) List(c *gin.Context) {
|
|||||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||||
|
|
||||||
result, err := h.service.List(userID, page, pageSize)
|
result, err := h.service.List(c.Request.Context(), userID, page, pageSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -70,7 +70,7 @@ func (h *Handler) FindByID(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
withdrawal, err := h.service.FindByID(userID, id)
|
withdrawal, err := h.service.FindByID(c.Request.Context(), userID, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -91,7 +91,7 @@ func (h *Handler) Cancel(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.service.Cancel(userID, id); err != nil {
|
if err := h.service.Cancel(c.Request.Context(), userID, id); err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ func (h *Handler) AdminList(c *gin.Context) {
|
|||||||
query.Size = 20
|
query.Size = 20
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := h.service.AdminList(query)
|
result, err := h.service.AdminList(c.Request.Context(), query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -123,7 +123,7 @@ func (h *Handler) AdminFindByID(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
withdrawal, err := h.service.AdminFindByID(id)
|
withdrawal, err := h.service.AdminFindByID(c.Request.Context(), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -150,7 +150,7 @@ func (h *Handler) Review(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
withdrawal, err := h.service.Review(adminID, id, req)
|
withdrawal, err := h.service.Review(c.Request.Context(), adminID, id, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
@@ -177,7 +177,7 @@ func (h *Handler) ConfirmPayment(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
withdrawal, err := h.service.ConfirmPayment(adminID, id, req)
|
withdrawal, err := h.service.ConfirmPayment(c.Request.Context(), adminID, id, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(c, err)
|
writeError(c, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package withdrawal
|
package withdrawal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -28,10 +29,11 @@ func NewRepository(db *gorm.DB, walletRepo *wallet.Repository) *Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 用户创建提现申请
|
// 用户创建提现申请
|
||||||
func (r *Repository) Create(userID uint64, req CreateWithdrawalRequest) (*WithdrawalDTO, error) {
|
func (r *Repository) Create(ctx context.Context, userID uint64, req CreateWithdrawalRequest) (*WithdrawalDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
// 验证收款账号
|
// 验证收款账号
|
||||||
var paymentAccount model.UserPaymentAccount
|
var paymentAccount model.UserPaymentAccount
|
||||||
if err := r.db.Where("id = ? AND user_id = ? AND status = ?", req.PaymentAccountID, userID, "active").
|
if err := db.Where("id = ? AND user_id = ? AND status = ?", req.PaymentAccountID, userID, "active").
|
||||||
First(&paymentAccount).Error; err != nil {
|
First(&paymentAccount).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, errors.New("payment account not found")
|
return nil, errors.New("payment account not found")
|
||||||
@@ -71,7 +73,7 @@ func (r *Repository) Create(userID uint64, req CreateWithdrawalRequest) (*Withdr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 事务处理
|
// 事务处理
|
||||||
err = r.db.Transaction(func(tx *gorm.DB) error {
|
err = db.Transaction(func(tx *gorm.DB) error {
|
||||||
// 创建提现申请
|
// 创建提现申请
|
||||||
if err := tx.Create(&withdrawal).Error; err != nil {
|
if err := tx.Create(&withdrawal).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -105,13 +107,14 @@ func (r *Repository) Create(userID uint64, req CreateWithdrawalRequest) (*Withdr
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.FindByID(userID, withdrawal.ID)
|
return r.FindByID(ctx, userID, withdrawal.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户查询提现列表
|
// 用户查询提现列表
|
||||||
func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
func (r *Repository) List(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var total int64
|
var total int64
|
||||||
if err := r.db.Model(&model.WithdrawalRequest{}).
|
if err := db.Model(&model.WithdrawalRequest{}).
|
||||||
Where("user_id = ?", userID).
|
Where("user_id = ?", userID).
|
||||||
Count(&total).Error; err != nil {
|
Count(&total).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -119,7 +122,7 @@ func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult,
|
|||||||
|
|
||||||
offset := (page - 1) * pageSize
|
offset := (page - 1) * pageSize
|
||||||
var withdrawals []model.WithdrawalRequest
|
var withdrawals []model.WithdrawalRequest
|
||||||
if err := r.db.Where("user_id = ?", userID).
|
if err := db.Where("user_id = ?", userID).
|
||||||
Order("created_at DESC").
|
Order("created_at DESC").
|
||||||
Offset(offset).Limit(pageSize).
|
Offset(offset).Limit(pageSize).
|
||||||
Find(&withdrawals).Error; err != nil {
|
Find(&withdrawals).Error; err != nil {
|
||||||
@@ -140,9 +143,9 @@ func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 用户查询提现详情
|
// 用户查询提现详情
|
||||||
func (r *Repository) FindByID(userID, id uint64) (*WithdrawalDTO, error) {
|
func (r *Repository) FindByID(ctx context.Context, userID, id uint64) (*WithdrawalDTO, error) {
|
||||||
var withdrawal model.WithdrawalRequest
|
var withdrawal model.WithdrawalRequest
|
||||||
if err := r.db.Where("id = ? AND user_id = ?", id, userID).
|
if err := r.db.WithContext(ctx).Where("id = ? AND user_id = ?", id, userID).
|
||||||
First(&withdrawal).Error; err != nil {
|
First(&withdrawal).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, ErrWithdrawalNotFound
|
return nil, ErrWithdrawalNotFound
|
||||||
@@ -154,9 +157,10 @@ func (r *Repository) FindByID(userID, id uint64) (*WithdrawalDTO, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 用户取消提现
|
// 用户取消提现
|
||||||
func (r *Repository) Cancel(userID, id uint64) error {
|
func (r *Repository) Cancel(ctx context.Context, userID, id uint64) error {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var withdrawal model.WithdrawalRequest
|
var withdrawal model.WithdrawalRequest
|
||||||
if err := r.db.Where("id = ? AND user_id = ?", id, userID).
|
if err := db.Where("id = ? AND user_id = ?", id, userID).
|
||||||
First(&withdrawal).Error; err != nil {
|
First(&withdrawal).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return ErrWithdrawalNotFound
|
return ErrWithdrawalNotFound
|
||||||
@@ -169,7 +173,7 @@ func (r *Repository) Cancel(userID, id uint64) error {
|
|||||||
return ErrWithdrawalLocked
|
return ErrWithdrawalLocked
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
return db.Transaction(func(tx *gorm.DB) error {
|
||||||
// 更新状态
|
// 更新状态
|
||||||
if err := tx.Model(&withdrawal).Update("status", "cancelled").Error; err != nil {
|
if err := tx.Model(&withdrawal).Update("status", "cancelled").Error; err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -201,8 +205,8 @@ func (r *Repository) Cancel(userID, id uint64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 管理员查询提现列表
|
// 管理员查询提现列表
|
||||||
func (r *Repository) AdminList(query AdminListQuery) (*AdminPaginatedResult, error) {
|
func (r *Repository) AdminList(ctx context.Context, query AdminListQuery) (*AdminPaginatedResult, error) {
|
||||||
db := r.db.Model(&model.WithdrawalRequest{})
|
db := r.db.WithContext(ctx).Model(&model.WithdrawalRequest{})
|
||||||
|
|
||||||
if query.Status != "" {
|
if query.Status != "" {
|
||||||
db = db.Where("status = ?", query.Status)
|
db = db.Where("status = ?", query.Status)
|
||||||
@@ -226,7 +230,7 @@ func (r *Repository) AdminList(query AdminListQuery) (*AdminPaginatedResult, err
|
|||||||
|
|
||||||
items := make([]WithdrawalDetailDTO, 0, len(withdrawals))
|
items := make([]WithdrawalDetailDTO, 0, len(withdrawals))
|
||||||
for _, w := range withdrawals {
|
for _, w := range withdrawals {
|
||||||
dto, err := r.toDetailDTO(w)
|
dto, err := r.toDetailDTO(ctx, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -242,21 +246,22 @@ func (r *Repository) AdminList(query AdminListQuery) (*AdminPaginatedResult, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 管理员查询提现详情
|
// 管理员查询提现详情
|
||||||
func (r *Repository) AdminFindByID(id uint64) (*WithdrawalDetailDTO, error) {
|
func (r *Repository) AdminFindByID(ctx context.Context, id uint64) (*WithdrawalDetailDTO, error) {
|
||||||
var withdrawal model.WithdrawalRequest
|
var withdrawal model.WithdrawalRequest
|
||||||
if err := r.db.First(&withdrawal, id).Error; err != nil {
|
if err := r.db.WithContext(ctx).First(&withdrawal, id).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, ErrWithdrawalNotFound
|
return nil, ErrWithdrawalNotFound
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return r.toDetailDTO(withdrawal)
|
return r.toDetailDTO(ctx, withdrawal)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 管理员审核提现
|
// 管理员审核提现
|
||||||
func (r *Repository) Review(adminID, id uint64, req ReviewWithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
func (r *Repository) Review(ctx context.Context, adminID, id uint64, req ReviewWithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var withdrawal model.WithdrawalRequest
|
var withdrawal model.WithdrawalRequest
|
||||||
if err := r.db.First(&withdrawal, id).Error; err != nil {
|
if err := db.First(&withdrawal, id).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, ErrWithdrawalNotFound
|
return nil, ErrWithdrawalNotFound
|
||||||
}
|
}
|
||||||
@@ -282,7 +287,7 @@ func (r *Repository) Review(adminID, id uint64, req ReviewWithdrawalRequest) (*W
|
|||||||
withdrawal.ReviewedAt = &now
|
withdrawal.ReviewedAt = &now
|
||||||
withdrawal.ReviewRemark = req.Remark
|
withdrawal.ReviewRemark = req.Remark
|
||||||
|
|
||||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
err := db.Transaction(func(tx *gorm.DB) error {
|
||||||
if err := tx.Save(&withdrawal).Error; err != nil {
|
if err := tx.Save(&withdrawal).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -317,13 +322,14 @@ func (r *Repository) Review(adminID, id uint64, req ReviewWithdrawalRequest) (*W
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.AdminFindByID(id)
|
return r.AdminFindByID(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 管理员确认打款
|
// 管理员确认打款
|
||||||
func (r *Repository) ConfirmPayment(adminID, id uint64, req ConfirmPaymentRequest) (*WithdrawalDetailDTO, error) {
|
func (r *Repository) ConfirmPayment(ctx context.Context, adminID, id uint64, req ConfirmPaymentRequest) (*WithdrawalDetailDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
var withdrawal model.WithdrawalRequest
|
var withdrawal model.WithdrawalRequest
|
||||||
if err := r.db.First(&withdrawal, id).Error; err != nil {
|
if err := db.First(&withdrawal, id).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, ErrWithdrawalNotFound
|
return nil, ErrWithdrawalNotFound
|
||||||
}
|
}
|
||||||
@@ -342,7 +348,7 @@ func (r *Repository) ConfirmPayment(adminID, id uint64, req ConfirmPaymentReques
|
|||||||
withdrawal.PaymentProofURL = req.PaymentProofURL
|
withdrawal.PaymentProofURL = req.PaymentProofURL
|
||||||
withdrawal.PaymentRemark = req.Remark
|
withdrawal.PaymentRemark = req.Remark
|
||||||
|
|
||||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
err := db.Transaction(func(tx *gorm.DB) error {
|
||||||
if err := tx.Save(&withdrawal).Error; err != nil {
|
if err := tx.Save(&withdrawal).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -367,7 +373,7 @@ func (r *Repository) ConfirmPayment(adminID, id uint64, req ConfirmPaymentReques
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.AdminFindByID(id)
|
return r.AdminFindByID(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转换为用户DTO
|
// 转换为用户DTO
|
||||||
@@ -393,16 +399,17 @@ func toDTO(w model.WithdrawalRequest) WithdrawalDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 转换为管理员详细DTO
|
// 转换为管理员详细DTO
|
||||||
func (r *Repository) toDetailDTO(w model.WithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
func (r *Repository) toDetailDTO(ctx context.Context, w model.WithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||||||
|
db := r.db.WithContext(ctx)
|
||||||
// 查询用户信息
|
// 查询用户信息
|
||||||
var user model.User
|
var user model.User
|
||||||
r.db.Select("nickname, phone").First(&user, w.UserID)
|
db.Select("nickname, phone").First(&user, w.UserID)
|
||||||
|
|
||||||
// 查询审核人信息
|
// 查询审核人信息
|
||||||
var reviewedByName string
|
var reviewedByName string
|
||||||
if w.ReviewedBy != nil {
|
if w.ReviewedBy != nil {
|
||||||
var admin model.AdminUser
|
var admin model.AdminUser
|
||||||
if err := r.db.Select("nickname").First(&admin, *w.ReviewedBy).Error; err == nil {
|
if err := db.Select("nickname").First(&admin, *w.ReviewedBy).Error; err == nil {
|
||||||
reviewedByName = admin.Nickname
|
reviewedByName = admin.Nickname
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -411,7 +418,7 @@ func (r *Repository) toDetailDTO(w model.WithdrawalRequest) (*WithdrawalDetailDT
|
|||||||
var paidByName string
|
var paidByName string
|
||||||
if w.PaidBy != nil {
|
if w.PaidBy != nil {
|
||||||
var admin model.AdminUser
|
var admin model.AdminUser
|
||||||
if err := r.db.Select("nickname").First(&admin, *w.PaidBy).Error; err == nil {
|
if err := db.Select("nickname").First(&admin, *w.PaidBy).Error; err == nil {
|
||||||
paidByName = admin.Nickname
|
paidByName = admin.Nickname
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,7 +428,7 @@ func (r *Repository) toDetailDTO(w model.WithdrawalRequest) (*WithdrawalDetailDT
|
|||||||
var certificateURLs []string
|
var certificateURLs []string
|
||||||
if w.PaymentAccountID != nil {
|
if w.PaymentAccountID != nil {
|
||||||
var paymentAccount model.UserPaymentAccount
|
var paymentAccount model.UserPaymentAccount
|
||||||
if err := r.db.First(&paymentAccount, *w.PaymentAccountID).Error; err == nil {
|
if err := db.First(&paymentAccount, *w.PaymentAccountID).Error; err == nil {
|
||||||
// 解密账号
|
// 解密账号
|
||||||
decrypted, err := crypto.Decrypt(paymentAccount.AccountNo)
|
decrypted, err := crypto.Decrypt(paymentAccount.AccountNo)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package withdrawal
|
package withdrawal
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrDependencyUnavailable = errors.New("dependency unavailable")
|
ErrDependencyUnavailable = errors.New("dependency unavailable")
|
||||||
@@ -14,7 +17,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MinWithdrawalAmountCent = 1000 // 最低提现金额:10元 = 1000分
|
MinWithdrawalAmountCent = 1000 // 最低提现金额:10元 = 1000分
|
||||||
MaxWithdrawalAmountCent = 500000 // 单笔最高提现金额:5000元 = 500000分
|
MaxWithdrawalAmountCent = 500000 // 单笔最高提现金额:5000元 = 500000分
|
||||||
WithdrawalFeeRate = 0.0 // 手续费率(暂时0%)
|
WithdrawalFeeRate = 0.0 // 手续费率(暂时0%)
|
||||||
)
|
)
|
||||||
@@ -28,7 +31,7 @@ func NewService(repo *Repository) *Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 用户端方法
|
// 用户端方法
|
||||||
func (s *Service) Create(userID uint64, req CreateWithdrawalRequest) (*WithdrawalDTO, error) {
|
func (s *Service) Create(ctx context.Context, userID uint64, req CreateWithdrawalRequest) (*WithdrawalDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
@@ -41,10 +44,10 @@ func (s *Service) Create(userID uint64, req CreateWithdrawalRequest) (*Withdrawa
|
|||||||
return nil, ErrMaxWithdrawalAmount
|
return nil, ErrMaxWithdrawalAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.repo.Create(userID, req)
|
return s.repo.Create(ctx, userID, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) List(userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
func (s *Service) List(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
@@ -54,25 +57,25 @@ func (s *Service) List(userID uint64, page, pageSize int) (*PaginatedResult, err
|
|||||||
if pageSize < 1 || pageSize > 100 {
|
if pageSize < 1 || pageSize > 100 {
|
||||||
pageSize = 20
|
pageSize = 20
|
||||||
}
|
}
|
||||||
return s.repo.List(userID, page, pageSize)
|
return s.repo.List(ctx, userID, page, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FindByID(userID, id uint64) (*WithdrawalDTO, error) {
|
func (s *Service) FindByID(ctx context.Context, userID, id uint64) (*WithdrawalDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.FindByID(userID, id)
|
return s.repo.FindByID(ctx, userID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Cancel(userID, id uint64) error {
|
func (s *Service) Cancel(ctx context.Context, userID, id uint64) error {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return ErrDependencyUnavailable
|
return ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Cancel(userID, id)
|
return s.repo.Cancel(ctx, userID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 管理员端方法
|
// 管理员端方法
|
||||||
func (s *Service) AdminList(query AdminListQuery) (*AdminPaginatedResult, error) {
|
func (s *Service) AdminList(ctx context.Context, query AdminListQuery) (*AdminPaginatedResult, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
@@ -82,26 +85,26 @@ func (s *Service) AdminList(query AdminListQuery) (*AdminPaginatedResult, error)
|
|||||||
if query.Size < 1 || query.Size > 100 {
|
if query.Size < 1 || query.Size > 100 {
|
||||||
query.Size = 20
|
query.Size = 20
|
||||||
}
|
}
|
||||||
return s.repo.AdminList(query)
|
return s.repo.AdminList(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) AdminFindByID(id uint64) (*WithdrawalDetailDTO, error) {
|
func (s *Service) AdminFindByID(ctx context.Context, id uint64) (*WithdrawalDetailDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.AdminFindByID(id)
|
return s.repo.AdminFindByID(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Review(adminID, id uint64, req ReviewWithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
func (s *Service) Review(ctx context.Context, adminID, id uint64, req ReviewWithdrawalRequest) (*WithdrawalDetailDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.Review(adminID, id, req)
|
return s.repo.Review(ctx, adminID, id, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) ConfirmPayment(adminID, id uint64, req ConfirmPaymentRequest) (*WithdrawalDetailDTO, error) {
|
func (s *Service) ConfirmPayment(ctx context.Context, adminID, id uint64, req ConfirmPaymentRequest) (*WithdrawalDetailDTO, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.ConfirmPayment(adminID, id, req)
|
return s.repo.ConfirmPayment(ctx, adminID, id, req)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user